| @@ -277,6 +277,12 @@ | |||||
| </or> | </or> | ||||
| </selector> | </selector> | ||||
| <selector id="needs.jakartamail"> | |||||
| <or> | |||||
| <filename name="${ant.package}/taskdefs/email/JakartaMimeMailer*"/> | |||||
| </or> | |||||
| </selector> | |||||
| <selector id="needs.netrexx"> | <selector id="needs.netrexx"> | ||||
| <filename name="${optional.package}/NetRexxC*"/> | <filename name="${optional.package}/NetRexxC*"/> | ||||
| </selector> | </selector> | ||||
| @@ -360,6 +366,7 @@ | |||||
| <selector refid="needs.imageio"/> | <selector refid="needs.imageio"/> | ||||
| <selector refid="needs.jai"/> | <selector refid="needs.jai"/> | ||||
| <selector refid="needs.javamail"/> | <selector refid="needs.javamail"/> | ||||
| <selector refid="needs.jakartamail"/> | |||||
| <selector refid="needs.jdepend"/> | <selector refid="needs.jdepend"/> | ||||
| <selector refid="needs.jmf"/> | <selector refid="needs.jmf"/> | ||||
| <selector refid="needs.jsch"/> | <selector refid="needs.jsch"/> | ||||
| @@ -507,6 +514,9 @@ | |||||
| <available property="javamail.present" | <available property="javamail.present" | ||||
| classname="javax.mail.Transport" | classname="javax.mail.Transport" | ||||
| classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/> | classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/> | ||||
| <available property="jakartamail.present" | |||||
| classname="jakarta.mail.Transport" | |||||
| classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/> | |||||
| <available property="graaljs.present" | <available property="graaljs.present" | ||||
| classname="com.oracle.truffle.js.scriptengine.GraalJSScriptEngine" | classname="com.oracle.truffle.js.scriptengine.GraalJSScriptEngine" | ||||
| classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/> | classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/> | ||||
| @@ -704,6 +714,7 @@ | |||||
| <selector refid="needs.commons-logging" unless="commons.logging.present"/> | <selector refid="needs.commons-logging" unless="commons.logging.present"/> | ||||
| <selector refid="needs.apache-bsf" unless="bsf.present"/> | <selector refid="needs.apache-bsf" unless="bsf.present"/> | ||||
| <selector refid="needs.javamail" unless="javamail.present"/> | <selector refid="needs.javamail" unless="javamail.present"/> | ||||
| <selector refid="needs.jakartamail" unless="jakartamail.present"/> | |||||
| <selector refid="needs.netrexx" unless="netrexx.present"/> | <selector refid="needs.netrexx" unless="netrexx.present"/> | ||||
| <selector refid="needs.commons-net" unless="commons.net.present"/> | <selector refid="needs.commons-net" unless="commons.net.present"/> | ||||
| <selector refid="needs.antlr" unless="antlr.present"/> | <selector refid="needs.antlr" unless="antlr.present"/> | ||||
| @@ -867,6 +878,7 @@ | |||||
| <optional-jar dep="commons-logging"/> | <optional-jar dep="commons-logging"/> | ||||
| <optional-jar dep="apache-bsf"/> | <optional-jar dep="apache-bsf"/> | ||||
| <optional-jar dep="javamail"/> | <optional-jar dep="javamail"/> | ||||
| <optional-jar dep="jakartamail"/> | |||||
| <optional-jar dep="netrexx"/> | <optional-jar dep="netrexx"/> | ||||
| <optional-jar dep="commons-net"/> | <optional-jar dep="commons-net"/> | ||||
| <optional-jar dep="antlr"/> | <optional-jar dep="antlr"/> | ||||
| @@ -962,6 +974,7 @@ | |||||
| <optional-src-jar dep="commons-logging"/> | <optional-src-jar dep="commons-logging"/> | ||||
| <optional-src-jar dep="apache-bsf"/> | <optional-src-jar dep="apache-bsf"/> | ||||
| <optional-src-jar dep="javamail"/> | <optional-src-jar dep="javamail"/> | ||||
| <optional-src-jar dep="jakartamail"/> | |||||
| <optional-src-jar dep="netrexx"/> | <optional-src-jar dep="netrexx"/> | ||||
| <optional-src-jar dep="commons-net"/> | <optional-src-jar dep="commons-net"/> | ||||
| <optional-src-jar dep="antlr"/> | <optional-src-jar dep="antlr"/> | ||||
| @@ -335,6 +335,12 @@ Set -Ddest=LOCATION on the command line | |||||
| <f2 project="which"/> | <f2 project="which"/> | ||||
| </target> | </target> | ||||
| <target name="javamail" | |||||
| description="load Java Mail" | |||||
| depends="init"> | |||||
| <f2 project="com.sun.mail" archive="javax.mail"/> | |||||
| </target> | |||||
| <target name="jakartamail" | <target name="jakartamail" | ||||
| description="load Jakarta Mail" | description="load Jakarta Mail" | ||||
| depends="init"> | depends="init"> | ||||
| @@ -48,7 +48,9 @@ hamcrest-core.version=1.3 | |||||
| hamcrest-library.version=${hamcrest-core.version} | hamcrest-library.version=${hamcrest-core.version} | ||||
| jai-core.version=1.1.3 | jai-core.version=1.1.3 | ||||
| jai-codec.version=1.1.3 | jai-codec.version=1.1.3 | ||||
| jakarta.mail.version=1.6.4 | |||||
| # Later 1.6 versions call themselves "jakarta.mail" but do not use the namespace yet | |||||
| javax.mail.version=1.6.2 | |||||
| jakarta.mail.version=2.0.1 | |||||
| jakarta-regexp.version=1.4 | jakarta-regexp.version=1.4 | ||||
| # Later versions of Tomcat provide a jspc task | # Later versions of Tomcat provide a jspc task | ||||
| jasper-compiler.version=4.1.36 | jasper-compiler.version=4.1.36 | ||||
| @@ -0,0 +1,98 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| https://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <!-- | |||||
| This POM has been created manually by the Ant Development Team. | |||||
| Please contact us if you are not satisfied with the data contained in this POM. | |||||
| URL : https://ant.apache.org | |||||
| --> | |||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> | |||||
| <parent> | |||||
| <groupId>org.apache.ant</groupId> | |||||
| <artifactId>ant-parent</artifactId> | |||||
| <relativePath>../pom.xml</relativePath> | |||||
| <version>1.10.12-SNAPSHOT</version> | |||||
| </parent> | |||||
| <modelVersion>4.0.0</modelVersion> | |||||
| <url>https://ant.apache.org/</url> | |||||
| <groupId>org.apache.ant</groupId> | |||||
| <artifactId>ant-jakartamail</artifactId> | |||||
| <version>1.10.12-SNAPSHOT</version> | |||||
| <name>Apache Ant + JakartaMail</name> | |||||
| <description>implementation of the mail task based on Jakarta EE mail. | |||||
| Required to send emails to SMTP servers using user/password combinations | |||||
| or to send mail over SSL</description> | |||||
| <dependencies> | |||||
| <dependency> | |||||
| <groupId>org.apache.ant</groupId> | |||||
| <artifactId>ant</artifactId> | |||||
| <version>1.10.12-SNAPSHOT</version> | |||||
| <scope>compile</scope> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <!-- This brings in the necessary dependencies. | |||||
| See https://eclipse-ee4j.github.io/mail/ --> | |||||
| <groupId>com.sun.mail</groupId> | |||||
| <artifactId>jakarta.mail</artifactId> | |||||
| <version>2.0.1</version> | |||||
| <scope>compile</scope> | |||||
| </dependency> | |||||
| </dependencies> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-compiler-plugin</artifactId> | |||||
| <configuration> | |||||
| <includes> | |||||
| <include>org/apache/tools/ant/taskdefs/email/JakartaMimeMailer*</include> | |||||
| </includes> | |||||
| </configuration> | |||||
| </plugin> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-jar-plugin</artifactId> | |||||
| <configuration> | |||||
| <archive> | |||||
| <index>true</index> | |||||
| <manifest> | |||||
| <addExtensions>true</addExtensions> | |||||
| <addDefaultImplementationEntries>true</addDefaultImplementationEntries> | |||||
| <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> | |||||
| </manifest> | |||||
| </archive> | |||||
| </configuration> | |||||
| </plugin> | |||||
| </plugins> | |||||
| <resources> | |||||
| <resource> | |||||
| <directory>../../../..</directory> | |||||
| <targetPath>META-INF</targetPath> | |||||
| <includes> | |||||
| <include>LICENSE</include> | |||||
| <include>NOTICE</include> | |||||
| </includes> | |||||
| </resource> | |||||
| </resources> | |||||
| <sourceDirectory>../../../../src/main</sourceDirectory> | |||||
| <testSourceDirectory>../../../../src/testcases</testSourceDirectory> | |||||
| <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory> | |||||
| <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory> | |||||
| <directory>../../../../target/${project.artifactId}</directory> | |||||
| </build> | |||||
| </project> | |||||
| @@ -48,8 +48,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/m | |||||
| <!-- This brings in the necessary dependencies. | <!-- This brings in the necessary dependencies. | ||||
| See https://eclipse-ee4j.github.io/mail/ --> | See https://eclipse-ee4j.github.io/mail/ --> | ||||
| <groupId>com.sun.mail</groupId> | <groupId>com.sun.mail</groupId> | ||||
| <artifactId>jakarta.mail</artifactId> | |||||
| <version>1.6.4</version> | |||||
| <artifactId>javax.mail</artifactId> | |||||
| <version>1.6.2</version> | |||||
| <scope>compile</scope> | <scope>compile</scope> | ||||
| </dependency> | </dependency> | ||||
| </dependencies> | </dependencies> | ||||
| @@ -160,7 +160,7 @@ | |||||
| <exclude>org/apache/tools/ant/launch/</exclude> | <exclude>org/apache/tools/ant/launch/</exclude> | ||||
| <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude> | <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude> | ||||
| <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude> | <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude> | ||||
| <exclude>org/apache/tools/ant/taskdefs/email/MimeMailer*</exclude> | |||||
| <exclude>org/apache/tools/ant/taskdefs/email/*MimeMailer*</exclude> | |||||
| <exclude>${modules.exclude}</exclude> | <exclude>${modules.exclude}</exclude> | ||||
| <exclude>org/apache/tools/ant/taskdefs/optional/NetRexxC*</exclude> | <exclude>org/apache/tools/ant/taskdefs/optional/NetRexxC*</exclude> | ||||
| <exclude>org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport*</exclude> | <exclude>org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport*</exclude> | ||||
| @@ -95,6 +95,7 @@ | |||||
| <module>ant-imageio</module> | <module>ant-imageio</module> | ||||
| <module>ant-jai</module> | <module>ant-jai</module> | ||||
| <module>ant-javamail</module> | <module>ant-javamail</module> | ||||
| <module>ant-jakartamail</module> | |||||
| <module>ant-jdepend</module> | <module>ant-jdepend</module> | ||||
| <module>ant-jmf</module> | <module>ant-jmf</module> | ||||
| <module>ant-jsch</module> | <module>ant-jsch</module> | ||||
| @@ -449,16 +449,9 @@ public class EmailTask extends Task { | |||||
| // prepare for the auto select mechanism | // prepare for the auto select mechanism | ||||
| boolean autoFound = false; | boolean autoFound = false; | ||||
| // try MIME format | // try MIME format | ||||
| if (MIME.equals(encoding) | |||||
| || (AUTO.equals(encoding) && !autoFound)) { | |||||
| if (MIME.equals(encoding) || AUTO.equals(encoding)) { | |||||
| try { | try { | ||||
| //check to make sure that activation.jar | |||||
| //and mail.jar are available - see bug 31969 | |||||
| Class.forName("javax.activation.DataHandler"); | |||||
| Class.forName("javax.mail.internet.MimeMessage"); | |||||
| mailer = ClasspathUtils.newInstance( | |||||
| "org.apache.tools.ant.taskdefs.email.MimeMailer", | |||||
| mailer = ClasspathUtils.newInstance(getMailerImplementation(), | |||||
| EmailTask.class.getClassLoader(), Mailer.class); | EmailTask.class.getClassLoader(), Mailer.class); | ||||
| autoFound = true; | autoFound = true; | ||||
| @@ -600,6 +593,32 @@ public class EmailTask extends Task { | |||||
| } | } | ||||
| } | } | ||||
| private String getMailerImplementation() { | |||||
| //check to make sure that activation.jar | |||||
| //and mail.jar are available - see bug 31969 | |||||
| try { | |||||
| Class.forName("jakarta.activation.DataHandler"); | |||||
| Class.forName("jakarta.mail.internet.MimeMessage"); | |||||
| return "org.apache.tools.ant.taskdefs.email.JakartaMimeMailer"; | |||||
| } catch (ClassNotFoundException cnfe) { | |||||
| logBuildException("Could not find Jakarta MIME mail: ", | |||||
| new BuildException(cnfe)); | |||||
| } | |||||
| try { | |||||
| Class.forName("javax.activation.DataHandler"); | |||||
| Class.forName("javax.mail.internet.MimeMessage"); | |||||
| return "org.apache.tools.ant.taskdefs.email.MimeMailer"; | |||||
| } catch (ClassNotFoundException cnfe) { | |||||
| logBuildException("Could not find MIME mail: ", | |||||
| new BuildException(cnfe)); | |||||
| } | |||||
| return "org.apache.tools.ant.taskdefs.email.Mailer"; | |||||
| } | |||||
| private void logBuildException(String reason, BuildException e) { | private void logBuildException(String reason, BuildException e) { | ||||
| Throwable t = e.getCause() == null ? e : e.getCause(); | Throwable t = e.getCause() == null ? e : e.getCause(); | ||||
| log(reason + t.getMessage(), Project.MSG_WARN); | log(reason + t.getMessage(), Project.MSG_WARN); | ||||
| @@ -0,0 +1,340 @@ | |||||
| /* | |||||
| * Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| * contributor license agreements. See the NOTICE file distributed with | |||||
| * this work for additional information regarding copyright ownership. | |||||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| * (the "License"); you may not use this file except in compliance with | |||||
| * the License. You may obtain a copy of the License at | |||||
| * | |||||
| * https://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| * | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs.email; | |||||
| import java.io.ByteArrayInputStream; | |||||
| import java.io.ByteArrayOutputStream; | |||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.OutputStream; | |||||
| import java.io.PrintStream; | |||||
| import java.io.UnsupportedEncodingException; | |||||
| import java.security.Provider; | |||||
| import java.security.Security; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| import java.util.Locale; | |||||
| import java.util.Properties; | |||||
| import java.util.StringTokenizer; | |||||
| import java.util.Vector; | |||||
| import jakarta.activation.DataHandler; | |||||
| import jakarta.activation.DataSource; | |||||
| import jakarta.activation.FileDataSource; | |||||
| import jakarta.mail.Address; | |||||
| import jakarta.mail.Authenticator; | |||||
| import jakarta.mail.Message; | |||||
| import jakarta.mail.MessagingException; | |||||
| import jakarta.mail.PasswordAuthentication; | |||||
| import jakarta.mail.SendFailedException; | |||||
| import jakarta.mail.Session; | |||||
| import jakarta.mail.Transport; | |||||
| import jakarta.mail.internet.AddressException; | |||||
| import jakarta.mail.internet.InternetAddress; | |||||
| import jakarta.mail.internet.MimeBodyPart; | |||||
| import jakarta.mail.internet.MimeMessage; | |||||
| import jakarta.mail.internet.MimeMultipart; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.Project; | |||||
| /** | |||||
| * Uses the JakartaMail classes to send Mime format email. | |||||
| * | |||||
| * @since Ant 1.10.12 | |||||
| */ | |||||
| public class JakartaMimeMailer extends Mailer { | |||||
| private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; | |||||
| private static final String GENERIC_ERROR = | |||||
| "Problem while sending mime mail:"; | |||||
| /** Default character set */ | |||||
| private static final String DEFAULT_CHARSET | |||||
| = System.getProperty("file.encoding"); | |||||
| // To work properly with national charsets we have to use | |||||
| // implementation of interface jakarta.activation.DataSource | |||||
| /** | |||||
| * String data source implementation. | |||||
| */ | |||||
| class StringDataSource implements DataSource { | |||||
| private String data = null; | |||||
| private String type = null; | |||||
| private String charset = null; | |||||
| private ByteArrayOutputStream out; | |||||
| @Override | |||||
| public InputStream getInputStream() throws IOException { | |||||
| if (data == null && out == null) { | |||||
| throw new IOException("No data"); | |||||
| } | |||||
| if (out != null) { | |||||
| final String encodedOut = out.toString(charset); | |||||
| data = (data != null) ? data.concat(encodedOut) : encodedOut; | |||||
| out = null; | |||||
| } | |||||
| return new ByteArrayInputStream(data.getBytes(charset)); | |||||
| } | |||||
| @Override | |||||
| public OutputStream getOutputStream() throws IOException { | |||||
| out = (out == null) ? new ByteArrayOutputStream() : out; | |||||
| return out; | |||||
| } | |||||
| public void setContentType(final String type) { | |||||
| this.type = type.toLowerCase(Locale.ENGLISH); | |||||
| } | |||||
| @Override | |||||
| public String getContentType() { | |||||
| if (type != null && type.indexOf("charset") > 0 | |||||
| && type.startsWith("text/")) { | |||||
| return type; | |||||
| } | |||||
| // Must be like "text/plain; charset=windows-1251" | |||||
| return (type != null ? type : "text/plain") + | |||||
| "; charset=" + charset; | |||||
| } | |||||
| @Override | |||||
| public String getName() { | |||||
| return "StringDataSource"; | |||||
| } | |||||
| public void setCharset(final String charset) { | |||||
| this.charset = charset; | |||||
| } | |||||
| public String getCharset() { | |||||
| return charset; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Send the email. | |||||
| * | |||||
| * @throws BuildException if the email can't be sent. | |||||
| */ | |||||
| @Override | |||||
| public void send() { | |||||
| try { | |||||
| final Properties props = new Properties(); | |||||
| props.put("mail.smtp.host", host); | |||||
| props.put("mail.smtp.port", String.valueOf(port)); | |||||
| // Aside, the JDK is clearly unaware of the Scottish | |||||
| // 'session', which involves excessive quantities of | |||||
| // alcohol :-) | |||||
| Session sesh; | |||||
| Authenticator auth = null; | |||||
| if (SSL) { | |||||
| try { | |||||
| final Provider p = | |||||
| Class.forName("com.sun.net.ssl.internal.ssl.Provider") | |||||
| .asSubclass(Provider.class).getDeclaredConstructor().newInstance(); | |||||
| Security.addProvider(p); | |||||
| } catch (final Exception e) { | |||||
| throw new BuildException( | |||||
| "could not instantiate ssl security provider, check that you have JSSE in your classpath"); | |||||
| } | |||||
| // SMTP provider | |||||
| props.put("mail.smtp.socketFactory.class", SSL_FACTORY); | |||||
| props.put("mail.smtp.socketFactory.fallback", "false"); | |||||
| props.put("mail.smtps.host", host); | |||||
| if (isPortExplicitlySpecified()) { | |||||
| props.put("mail.smtps.port", String.valueOf(port)); | |||||
| props.put("mail.smtp.socketFactory.port", | |||||
| String.valueOf(port)); | |||||
| } | |||||
| } | |||||
| if (user != null || password != null) { | |||||
| props.put("mail.smtp.auth", "true"); | |||||
| auth = new SimpleAuthenticator(user, password); | |||||
| } | |||||
| if (isStartTLSEnabled()) { | |||||
| props.put("mail.smtp.starttls.enable", "true"); | |||||
| } | |||||
| sesh = Session.getInstance(props, auth); | |||||
| //create the message | |||||
| final MimeMessage msg = new MimeMessage(sesh); | |||||
| final MimeMultipart attachments = new MimeMultipart(); | |||||
| //set the sender | |||||
| if (from.getName() == null) { | |||||
| msg.setFrom(new InternetAddress(from.getAddress())); | |||||
| } else { | |||||
| msg.setFrom(new InternetAddress(from.getAddress(), | |||||
| from.getName())); | |||||
| } | |||||
| // set the reply to addresses | |||||
| msg.setReplyTo(internetAddresses(replyToList)); | |||||
| msg.setRecipients(Message.RecipientType.TO, | |||||
| internetAddresses(toList)); | |||||
| msg.setRecipients(Message.RecipientType.CC, | |||||
| internetAddresses(ccList)); | |||||
| msg.setRecipients(Message.RecipientType.BCC, | |||||
| internetAddresses(bccList)); | |||||
| // Choosing character set of the mail message | |||||
| // First: looking it from MimeType | |||||
| String charset = parseCharSetFromMimeType(message.getMimeType()); | |||||
| if (charset != null) { | |||||
| // Assign/reassign message charset from MimeType | |||||
| message.setCharset(charset); | |||||
| } else { | |||||
| // Next: looking if charset having explicit definition | |||||
| charset = message.getCharset(); | |||||
| if (charset == null) { | |||||
| // Using default | |||||
| charset = DEFAULT_CHARSET; | |||||
| message.setCharset(charset); | |||||
| } | |||||
| } | |||||
| // Using jakarta.activation.DataSource paradigm | |||||
| final StringDataSource sds = new StringDataSource(); | |||||
| sds.setContentType(message.getMimeType()); | |||||
| sds.setCharset(charset); | |||||
| if (subject != null) { | |||||
| msg.setSubject(subject, charset); | |||||
| } | |||||
| msg.addHeader("Date", getDate()); | |||||
| if (headers != null) { | |||||
| for (Header h : headers) { | |||||
| msg.addHeader(h.getName(), h.getValue()); | |||||
| } | |||||
| } | |||||
| final PrintStream out = new PrintStream(sds.getOutputStream()); | |||||
| message.print(out); | |||||
| out.close(); | |||||
| final MimeBodyPart textbody = new MimeBodyPart(); | |||||
| textbody.setDataHandler(new DataHandler(sds)); | |||||
| attachments.addBodyPart(textbody); | |||||
| for (File file : files) { | |||||
| MimeBodyPart body = new MimeBodyPart(); | |||||
| if (!file.exists() || !file.canRead()) { | |||||
| throw new BuildException( | |||||
| "File \"%s\" does not exist or is not readable.", | |||||
| file.getAbsolutePath()); | |||||
| } | |||||
| final FileDataSource fileData = new FileDataSource(file); | |||||
| final DataHandler fileDataHandler = new DataHandler(fileData); | |||||
| body.setDataHandler(fileDataHandler); | |||||
| body.setFileName(file.getName()); | |||||
| attachments.addBodyPart(body); | |||||
| } | |||||
| msg.setContent(attachments); | |||||
| try { | |||||
| // Send the message using SMTP, or SMTPS if the host uses SSL | |||||
| final Transport transport = sesh.getTransport(SSL ? "smtps" : "smtp"); | |||||
| transport.connect(host, user, password); | |||||
| transport.sendMessage(msg, msg.getAllRecipients()); | |||||
| } catch (final SendFailedException sfe) { | |||||
| if (!shouldIgnoreInvalidRecipients()) { | |||||
| throw new BuildException(GENERIC_ERROR, sfe); | |||||
| } | |||||
| if (sfe.getValidSentAddresses() == null | |||||
| || sfe.getValidSentAddresses().length == 0) { | |||||
| throw new BuildException("Couldn't reach any recipient", | |||||
| sfe); | |||||
| } | |||||
| Address[] invalid = sfe.getInvalidAddresses(); | |||||
| if (invalid == null) { | |||||
| invalid = new Address[0]; | |||||
| } | |||||
| for (Address address : invalid) { | |||||
| didntReach(address, "invalid", sfe); | |||||
| } | |||||
| Address[] validUnsent = sfe.getValidUnsentAddresses(); | |||||
| if (validUnsent == null) { | |||||
| validUnsent = new Address[0]; | |||||
| } | |||||
| for (Address address : validUnsent) { | |||||
| didntReach(address, "valid", sfe); | |||||
| } | |||||
| } | |||||
| } catch (MessagingException | IOException e) { | |||||
| throw new BuildException(GENERIC_ERROR, e); | |||||
| } | |||||
| } | |||||
| private static InternetAddress[] internetAddresses(final Vector<EmailAddress> list) | |||||
| throws AddressException, UnsupportedEncodingException { | |||||
| final List<InternetAddress> addrs = new ArrayList<>(); | |||||
| for (final EmailAddress addr : list) { | |||||
| final String name = addr.getName(); | |||||
| addrs.add((name == null) | |||||
| ? new InternetAddress(addr.getAddress()) | |||||
| : new InternetAddress(addr.getAddress(), name)); | |||||
| } | |||||
| return addrs.toArray(new InternetAddress[addrs.size()]); | |||||
| } | |||||
| private String parseCharSetFromMimeType(final String type) { | |||||
| if (type == null) { | |||||
| return null; | |||||
| } | |||||
| final int pos = type.indexOf("charset"); | |||||
| if (pos < 0) { | |||||
| return null; | |||||
| } | |||||
| // Assuming mime type in form "text/XXXX; charset=XXXXXX" | |||||
| final StringTokenizer token = new StringTokenizer(type.substring(pos), "=; "); | |||||
| token.nextToken(); // Skip 'charset=' | |||||
| return token.nextToken(); | |||||
| } | |||||
| private void didntReach(final Address addr, final String category, | |||||
| final MessagingException ex) { | |||||
| final String msg = "Failed to send mail to " + category + " address " | |||||
| + addr + " because of " + ex.getMessage(); | |||||
| if (task != null) { | |||||
| task.log(msg, Project.MSG_WARN); | |||||
| } else { | |||||
| System.err.println(msg); | |||||
| } | |||||
| } | |||||
| static class SimpleAuthenticator extends Authenticator { | |||||
| private String user = null; | |||||
| private String password = null; | |||||
| public SimpleAuthenticator(final String user, final String password) { | |||||
| this.user = user; | |||||
| this.password = password; | |||||
| } | |||||
| @Override | |||||
| public PasswordAuthentication getPasswordAuthentication() { | |||||
| return new PasswordAuthentication(user, password); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -58,7 +58,9 @@ import org.apache.tools.ant.Project; | |||||
| * Uses the JavaMail classes to send Mime format email. | * Uses the JavaMail classes to send Mime format email. | ||||
| * | * | ||||
| * @since Ant 1.5 | * @since Ant 1.5 | ||||
| * @deprecated see org.apache.tools.ant.taskdefs.email.JakartaMimeMailer | |||||
| */ | */ | ||||
| @Deprecated | |||||
| public class MimeMailer extends Mailer { | public class MimeMailer extends Mailer { | ||||
| private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; | private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; | ||||
| @@ -26,6 +26,7 @@ import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.types.Reference; | import org.apache.tools.ant.types.Reference; | ||||
| import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Modifier; | |||||
| // CheckStyle:HideUtilityClassConstructorCheck OFF - bc | // CheckStyle:HideUtilityClassConstructorCheck OFF - bc | ||||
| @@ -251,6 +252,9 @@ public class ClasspathUtils { | |||||
| try { | try { | ||||
| @SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||||
| Class<T> clazz = (Class<T>) Class.forName(className, true, userDefinedLoader); | Class<T> clazz = (Class<T>) Class.forName(className, true, userDefinedLoader); | ||||
| if (Modifier.isAbstract(clazz.getModifiers())) { | |||||
| throw new BuildException("Abstract class " + className); | |||||
| } | |||||
| T o = clazz.getDeclaredConstructor().newInstance(); | T o = clazz.getDeclaredConstructor().newInstance(); | ||||
| if (!expectedType.isInstance(o)) { | if (!expectedType.isInstance(o)) { | ||||
| throw new BuildException( | throw new BuildException( | ||||