MailUtil.java

  1. /*
  2.  * Copyright (c) 2002-2022, City of Paris
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  *  1. Redistributions of source code must retain the above copyright notice
  10.  *     and the following disclaimer.
  11.  *
  12.  *  2. Redistributions in binary form must reproduce the above copyright notice
  13.  *     and the following disclaimer in the documentation and/or other materials
  14.  *     provided with the distribution.
  15.  *
  16.  *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
  17.  *     contributors may be used to endorse or promote products derived from
  18.  *     this software without specific prior written permission.
  19.  *
  20.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  24.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30.  * POSSIBILITY OF SUCH DAMAGE.
  31.  *
  32.  * License 1.0
  33.  */
  34. package fr.paris.lutece.portal.service.mail;

  35. import java.io.ByteArrayOutputStream;
  36. import java.io.IOException;
  37. import java.io.InputStream;
  38. import java.io.UnsupportedEncodingException;
  39. import java.util.ArrayList;
  40. import java.util.Date;
  41. import java.util.List;
  42. import java.util.Properties;
  43. import java.util.StringTokenizer;

  44. import javax.activation.CommandInfo;
  45. import javax.activation.CommandMap;
  46. import javax.activation.DataHandler;
  47. import javax.activation.FileTypeMap;
  48. import javax.activation.MailcapCommandMap;
  49. import javax.activation.MimetypesFileTypeMap;
  50. import javax.mail.Authenticator;
  51. import javax.mail.BodyPart;
  52. import javax.mail.Message;
  53. import javax.mail.MessagingException;
  54. import javax.mail.NoSuchProviderException;
  55. import javax.mail.PasswordAuthentication;
  56. import javax.mail.SendFailedException;
  57. import javax.mail.Session;
  58. import javax.mail.Transport;
  59. import javax.mail.internet.AddressException;
  60. import javax.mail.internet.InternetAddress;
  61. import javax.mail.internet.MimeBodyPart;
  62. import javax.mail.internet.MimeMessage;
  63. import javax.mail.internet.MimeMultipart;
  64. import javax.mail.internet.MimeUtility;

  65. import org.apache.commons.collections.CollectionUtils;
  66. import org.apache.commons.lang3.StringUtils;

  67. import fr.paris.lutece.portal.service.util.AppException;
  68. import fr.paris.lutece.portal.service.util.AppLogService;
  69. import fr.paris.lutece.portal.service.util.AppPropertiesService;
  70. import fr.paris.lutece.util.mail.ByteArrayDataSource;
  71. import fr.paris.lutece.util.mail.FileAttachment;
  72. import fr.paris.lutece.util.mail.HtmlDocument;
  73. import fr.paris.lutece.util.mail.UrlAttachment;

  74. /**
  75.  * This class provides mail utils.
  76.  */
  77. final class MailUtil
  78. {
  79.     // Properties
  80.     private static final String PROPERTY_CHARSET = "mail.charset";
  81.     private static final String PROPERTY_MAIL_LIST_SEPARATOR = "mail.list.separator";
  82.     private static final String PROPERTY_MAIL_TYPE_HTML = "mail.type.html";
  83.     private static final String PROPERTY_MAIL_TYPE_PLAIN = "mail.type.plain";
  84.     private static final String PROPERTY_MAIL_TYPE_CALENDAR = "mail.type.calendar";
  85.     private static final String PROPERTY_MAIL_SESSION_DEBUG = "mail.session.debug";
  86.     private static final String PROPERTY_CALENDAR_SEPARATOR = "mail.type.calendar.separator";
  87.     private static final String PROPERTY_CALENDAR_METHOD_CREATE = "mail.type.calendar.create";
  88.     private static final String PROPERTY_CALENDAR_METHOD_CANCEL = "mail.type.calendar.cancel";

  89.     // Javax.mail properties
  90.     private static final String SMTP = "smtp";
  91.     private static final String MAIL = "mail.";
  92.     private static final String MAIL_HOST = "mail.host";
  93.     private static final String MAIL_TRANSPORT_PROTOCOL = "mail.transport.protocol";
  94.     private static final String MAIL_SMTP_AUTH = "mail.smtp.auth";
  95.     private static final String MAIL_PROPTOCOL_HOST = MAIL + SMTP + ".host";
  96.     private static final String MAIL_PROPTOCOL_PORT = MAIL + SMTP + ".port";

  97.     // Constants
  98.     private static final String TRUE = "true";
  99.     private static final String ENCODING = "Q";
  100.     private static final String HEADER_NAME = "Content-Transfer-Encoding";
  101.     private static final String HEADER_VALUE = "quoted-printable";
  102.     private static final String HEADER_CONTENT_LOCATION = "Content-Location";
  103.     private static final String CONTENT_HANDLER = "content-handler";
  104.     private static final String MULTIPART_RELATED = "related";
  105.     private static final String MSG_ATTACHMENT_NOT_FOUND = " not found, document ignored.";
  106.     private static final int CONSTANTE_FILE_ATTACHMET_BUFFER = 4096;
  107.     private static final String MIME_TYPE_TEXT_PLAIN = "text/plain";
  108.     private static final String MIME_TYPE_TEXT_CALENDAR = "text/calendar";
  109.     private static final String CONSTANT_REGISTER_MIME_TYPE_HANDLER = ";; x-java-content-handler=";
  110.     private static final String DEFAULT_PLAIN_TEXT_HANDLER = "com.sun.mail.handlers.text_plain";
  111.     private static final String CONSTANT_DISPOSITION_ATTACHMENT = "attachment";
  112.     private static final String CONSTANT_BASE64 = "base64";

  113.     static
  114.     {
  115.         // We create the mime text/calendar mime type
  116.         MimetypesFileTypeMap mimetypes = (MimetypesFileTypeMap) FileTypeMap.getDefaultFileTypeMap( );
  117.         mimetypes.addMimeTypes( MIME_TYPE_TEXT_CALENDAR );

  118.         // We register the handler for the text/calendar mime type
  119.         MailcapCommandMap mailcap = (MailcapCommandMap) CommandMap.getDefaultCommandMap( );

  120.         // We try to get the default handler for plain text
  121.         CommandInfo [ ] commandInfos = mailcap.getAllCommands( MIME_TYPE_TEXT_PLAIN );
  122.         CommandInfo commandInfoText = null;

  123.         if ( ( commandInfos != null ) && ( commandInfos.length > 0 ) )
  124.         {
  125.             for ( CommandInfo commandInfo : commandInfos )
  126.             {
  127.                 if ( StringUtils.equals( commandInfo.getCommandName( ), CONTENT_HANDLER ) )
  128.                 {
  129.                     commandInfoText = commandInfo;

  130.                     break;
  131.                 }
  132.             }

  133.             if ( commandInfoText == null )
  134.             {
  135.                 commandInfoText = commandInfos [0];
  136.             }
  137.         }

  138.         // If the default handler for plain text was not found, we just use the default
  139.         // one
  140.         String strHandler = ( commandInfoText != null ) ? commandInfoText.getCommandClass( ) : DEFAULT_PLAIN_TEXT_HANDLER;
  141.         mailcap.addMailcap( MIME_TYPE_TEXT_CALENDAR + CONSTANT_REGISTER_MIME_TYPE_HANDLER + strHandler + "\n" );
  142.     }

  143.     /**
  144.      * Creates a new MailUtil object
  145.      */
  146.     private MailUtil( )
  147.     {
  148.     }

  149.     /**
  150.      * Send a text message.
  151.      *
  152.      * @param mail
  153.      *            The mail to send
  154.      * @param transport
  155.      *            the smtp transport object
  156.      * @param session
  157.      *            the smtp session object
  158.      * @throws AddressException
  159.      *             If invalid address
  160.      * @throws SendFailedException
  161.      *             If an error occured during sending
  162.      * @throws MessagingException
  163.      *             If a messaging error occured
  164.      */
  165.     protected static void sendMessageText( MailItem mail, Transport transport, Session session ) throws MessagingException
  166.     {
  167.         Message msg = prepareMessage( mail, session );
  168.         msg.setDataHandler( new DataHandler( new ByteArrayDataSource( mail.getMessage( ),
  169.                 AppPropertiesService.getProperty( PROPERTY_MAIL_TYPE_PLAIN ) + AppPropertiesService.getProperty( PROPERTY_CHARSET ) ) ) );

  170.         sendMessage( msg, transport );
  171.     }

  172.     /**
  173.      * Send a HTML formated message.
  174.      *
  175.      * @param mail
  176.      *            The mail to send
  177.      * @param transport
  178.      *            the smtp transport object
  179.      * @param session
  180.      *            the smtp session object
  181.      * @throws AddressException
  182.      *             If invalid address
  183.      * @throws SendFailedException
  184.      *             If an error occured during sending
  185.      * @throws MessagingException
  186.      *             If a messaging error occured
  187.      */
  188.     protected static void sendMessageHtml( MailItem mail, Transport transport, Session session ) throws MessagingException
  189.     {
  190.         Message msg = prepareMessage( mail, session );

  191.         msg.setHeader( HEADER_NAME, HEADER_VALUE );
  192.         // Message body formated in HTML
  193.         msg.setDataHandler( new DataHandler( new ByteArrayDataSource( mail.getMessage( ),
  194.                 AppPropertiesService.getProperty( PROPERTY_MAIL_TYPE_HTML ) + AppPropertiesService.getProperty( PROPERTY_CHARSET ) ) ) );

  195.         sendMessage( msg, transport );
  196.     }

  197.     /**
  198.      * Send a Multipart HTML message with the attachements associated to the message and attached files.
  199.      *
  200.      * @param mail
  201.      *            The mail to send
  202.      * @param transport
  203.      *            the smtp transport object
  204.      * @param session
  205.      *            the smtp session object
  206.      * @throws AddressException
  207.      *             If invalid address
  208.      * @throws SendFailedException
  209.      *             If an error occured during sending
  210.      * @throws MessagingException
  211.      *             If a messaging error occurred
  212.      */
  213.     protected static void sendMultipartMessageHtml( MailItem mail, Transport transport, Session session ) throws MessagingException
  214.     {
  215.         Message msg = prepareMessage( mail, session );
  216.         msg.setHeader( HEADER_NAME, HEADER_VALUE );

  217.         // Creation of the root part containing all the elements of the message
  218.         MimeMultipart multipart = CollectionUtils.isEmpty( mail.getFilesAttachement( ) ) ? new MimeMultipart( MULTIPART_RELATED ) : new MimeMultipart( );

  219.         // Creation of the html part, the "core" of the message
  220.         BodyPart msgBodyPart = new MimeBodyPart( );
  221.         msgBodyPart.setDataHandler( new DataHandler( new ByteArrayDataSource( mail.getMessage( ),
  222.                 AppPropertiesService.getProperty( PROPERTY_MAIL_TYPE_HTML ) + AppPropertiesService.getProperty( PROPERTY_CHARSET ) ) ) );
  223.         multipart.addBodyPart( msgBodyPart );

  224.         if ( mail.getUrlsAttachement( ) != null )
  225.         {
  226.             ByteArrayDataSource urlByteArrayDataSource;

  227.             for ( UrlAttachment urlAttachement : mail.getUrlsAttachement( ) )
  228.             {
  229.                 urlByteArrayDataSource = convertUrlAttachmentDataSourceToByteArrayDataSource( urlAttachement );

  230.                 if ( urlByteArrayDataSource != null )
  231.                 {
  232.                     msgBodyPart = new MimeBodyPart( );
  233.                     // Fill this part, then add it to the root part with the
  234.                     // good headers
  235.                     msgBodyPart.setDataHandler( new DataHandler( urlByteArrayDataSource ) );
  236.                     msgBodyPart.setHeader( HEADER_CONTENT_LOCATION, urlAttachement.getContentLocation( ) );
  237.                     multipart.addBodyPart( msgBodyPart );
  238.                 }
  239.             }
  240.         }

  241.         // add File Attachement
  242.         if ( mail.getFilesAttachement( ) != null )
  243.         {
  244.             for ( FileAttachment fileAttachement : mail.getFilesAttachement( ) )
  245.             {
  246.                 String strFileName = fileAttachement.getFileName( );
  247.                 byte [ ] bContentFile = fileAttachement.getData( );
  248.                 String strContentType = fileAttachement.getType( );
  249.                 ByteArrayDataSource dataSource = new ByteArrayDataSource( bContentFile, strContentType );
  250.                 msgBodyPart = new MimeBodyPart( );
  251.                 msgBodyPart.setDataHandler( new DataHandler( dataSource ) );
  252.                 msgBodyPart.setFileName( strFileName );
  253.                 msgBodyPart.setDisposition( CONSTANT_DISPOSITION_ATTACHMENT );
  254.                 multipart.addBodyPart( msgBodyPart );
  255.             }
  256.         }

  257.         msg.setContent( multipart );

  258.         sendMessage( msg, transport );
  259.     }

  260.     /**
  261.      * Send a Multipart text message with attached files.
  262.      *
  263.      * @param mail
  264.      *            The mail to send
  265.      * @param transport
  266.      *            the smtp transport object
  267.      * @param session
  268.      *            the smtp session object
  269.      * @throws AddressException
  270.      *             If invalid address
  271.      * @throws SendFailedException
  272.      *             If an error occured during sending
  273.      * @throws MessagingException
  274.      *             If a messaging error occured
  275.      */
  276.     protected static void sendMultipartMessageText( MailItem mail, Transport transport, Session session ) throws MessagingException
  277.     {
  278.         Message msg = prepareMessage( mail, session );
  279.         msg.setHeader( HEADER_NAME, HEADER_VALUE );

  280.         // Creation of the root part containing all the elements of the message
  281.         MimeMultipart multipart = new MimeMultipart( );

  282.         // Creation of the html part, the "core" of the message
  283.         BodyPart msgBodyPart = new MimeBodyPart( );
  284.         msgBodyPart.setDataHandler( new DataHandler( new ByteArrayDataSource( mail.getMessage( ),
  285.                 AppPropertiesService.getProperty( PROPERTY_MAIL_TYPE_PLAIN ) + AppPropertiesService.getProperty( PROPERTY_CHARSET ) ) ) );
  286.         multipart.addBodyPart( msgBodyPart );

  287.         // add File Attachement
  288.         if ( mail.getFilesAttachement( ) != null )
  289.         {
  290.             for ( FileAttachment fileAttachement : mail.getFilesAttachement( ) )
  291.             {
  292.                 String strFileName = fileAttachement.getFileName( );
  293.                 byte [ ] bContentFile = fileAttachement.getData( );
  294.                 String strContentType = fileAttachement.getType( );
  295.                 ByteArrayDataSource dataSource = new ByteArrayDataSource( bContentFile, strContentType );
  296.                 msgBodyPart = new MimeBodyPart( );
  297.                 msgBodyPart.setDataHandler( new DataHandler( dataSource ) );
  298.                 msgBodyPart.setFileName( strFileName );
  299.                 msgBodyPart.setDisposition( CONSTANT_DISPOSITION_ATTACHMENT );
  300.                 multipart.addBodyPart( msgBodyPart );
  301.             }
  302.         }

  303.         msg.setContent( multipart );

  304.         sendMessage( msg, transport );
  305.     }

  306.     /**
  307.      * Send a calendar message.
  308.      *
  309.      * @param mail
  310.      *            The mail to send
  311.      * @param transport
  312.      *            the smtp transport object
  313.      * @param session
  314.      *            the smtp session object
  315.      * @throws AddressException
  316.      *             If invalid address
  317.      * @throws SendFailedException
  318.      *             If an error occurred during sending
  319.      * @throws MessagingException
  320.      *             If a messaging error occurred
  321.      */
  322.     protected static void sendMessageCalendar( MailItem mail, Transport transport, Session session ) throws MessagingException
  323.     {
  324.         Message msg = prepareMessage( mail, session );
  325.         msg.setHeader( HEADER_NAME, HEADER_VALUE );

  326.         MimeMultipart multipart = new MimeMultipart( );
  327.         BodyPart msgBodyPart = new MimeBodyPart( );
  328.         msgBodyPart.setDataHandler( new DataHandler( new ByteArrayDataSource( mail.getMessage( ),
  329.                 AppPropertiesService.getProperty( PROPERTY_MAIL_TYPE_HTML ) + AppPropertiesService.getProperty( PROPERTY_CHARSET ) ) ) );

  330.         multipart.addBodyPart( msgBodyPart );

  331.         BodyPart calendarBodyPart = new MimeBodyPart( );
  332.         calendarBodyPart.setContent( mail.getCalendarMessage( ),
  333.                 AppPropertiesService.getProperty( PROPERTY_MAIL_TYPE_CALENDAR ) + AppPropertiesService.getProperty( PROPERTY_CHARSET )
  334.                         + AppPropertiesService.getProperty( PROPERTY_CALENDAR_SEPARATOR )
  335.                         + AppPropertiesService.getProperty( mail.getCreateEvent( ) ? PROPERTY_CALENDAR_METHOD_CREATE : PROPERTY_CALENDAR_METHOD_CANCEL ) );
  336.         calendarBodyPart.addHeader( HEADER_NAME, CONSTANT_BASE64 );
  337.         multipart.addBodyPart( calendarBodyPart );

  338.         msg.setContent( multipart );

  339.         sendMessage( msg, transport );
  340.     }

  341.     /**
  342.      * Send the message
  343.      *
  344.      * @param msg
  345.      *            the message to send
  346.      * @param transport
  347.      *            the transport used to send the message
  348.      * @throws MessagingException
  349.      *             If a messaging error occured
  350.      * @throws AddressException
  351.      *             If invalid address
  352.      */
  353.     private static void sendMessage( Message msg, Transport transport ) throws MessagingException
  354.     {
  355.         if ( msg.getAllRecipients( ) != null )
  356.         {
  357.             // Send the message
  358.             transport.sendMessage( msg, msg.getAllRecipients( ) );
  359.         }
  360.         else
  361.         {
  362.             throw new AddressException( "Mail adress is null" );
  363.         }
  364.     }

  365.     /**
  366.      * Extract a collection of elements to be attached to a mail from an HTML string. The collection contains the Url used for created DataHandler for each url
  367.      * associated with an HTML tag img, script or link. Those urls must start with the url strBaseUrl.
  368.      *
  369.      * @param strHtml
  370.      *            The HTML code.
  371.      * @param strBaseUrl
  372.      *            The base url, can be null in order to extract all urls.
  373.      * @param useAbsoluteUrl
  374.      *            Determine if we use absolute or relative url for attachement content-location
  375.      * @return a collection of UrlAttachment Object for created DataHandler associated with attachment urls.
  376.      */
  377.     protected static List<UrlAttachment> getUrlAttachmentList( String strHtml, String strBaseUrl, boolean useAbsoluteUrl )
  378.     {
  379.         List<UrlAttachment> listUrlAttachement = new ArrayList<>( );
  380.         HtmlDocument doc = new HtmlDocument( strHtml, strBaseUrl, useAbsoluteUrl );
  381.         listUrlAttachement.addAll( doc.getAllUrlsAttachement( HtmlDocument.ELEMENT_IMG ) );
  382.         listUrlAttachement.addAll( doc.getAllUrlsAttachement( HtmlDocument.ELEMENT_CSS ) );
  383.         listUrlAttachement.addAll( doc.getAllUrlsAttachement( HtmlDocument.ELEMENT_JAVASCRIPT ) );

  384.         return listUrlAttachement;
  385.     }

  386.     /**
  387.      * Common part for sending message process :
  388.      * <ul>
  389.      * <li>initializes a mail session with the SMTP server</li>
  390.      * <li>activates debugging</li>
  391.      * <li>instantiates and initializes a mime message</li>
  392.      * <li>sets the sent date, the from field, the subject field</li>
  393.      * <li>sets the recipients</li>
  394.      * </ul>
  395.      *
  396.      *
  397.      * @return the message object initialized with the common settings
  398.      * @param mail
  399.      *            The mail to send
  400.      * @param session
  401.      *            The SMTP session object
  402.      * @throws AddressException
  403.      *             If invalid address
  404.      * @throws MessagingException
  405.      *             If a messaging error occurred
  406.      */
  407.     protected static Message prepareMessage( MailItem mail, Session session ) throws MessagingException
  408.     {
  409.         // Instantiate and initialize a mime message
  410.         Message msg = new MimeMessage( session );
  411.         msg.setSentDate( new Date( ) );

  412.         try
  413.         {
  414.             msg.setFrom( new InternetAddress( mail.getSenderEmail( ), mail.getSenderName( ), AppPropertiesService.getProperty( PROPERTY_CHARSET ) ) );
  415.             msg.setSubject( MimeUtility.encodeText( mail.getSubject( ), AppPropertiesService.getProperty( PROPERTY_CHARSET ), ENCODING ) );
  416.         }
  417.         catch( UnsupportedEncodingException e )
  418.         {
  419.             throw new AppException( e.toString( ) );
  420.         }

  421.         // Instantiation of the list of address
  422.         if ( mail.getRecipientsTo( ) != null )
  423.         {
  424.             msg.setRecipients( Message.RecipientType.TO, getAllAdressOfRecipients( mail.getRecipientsTo( ) ) );
  425.         }

  426.         if ( mail.getRecipientsCc( ) != null )
  427.         {
  428.             msg.setRecipients( Message.RecipientType.CC, getAllAdressOfRecipients( mail.getRecipientsCc( ) ) );
  429.         }

  430.         if ( mail.getRecipientsBcc( ) != null )
  431.         {
  432.             msg.setRecipients( Message.RecipientType.BCC, getAllAdressOfRecipients( mail.getRecipientsBcc( ) ) );
  433.         }

  434.         return msg;
  435.     }

  436.     /**
  437.      * Open mail session with the SMTP server using the given credentials. Will use no authentication if strUsername is null or blank.
  438.      *
  439.      * @param strHost
  440.      *            The SMTP name or IP address.
  441.      * @param nPort
  442.      *            The port to use
  443.      * @param strUsername
  444.      *            the username
  445.      * @param strPassword
  446.      *            the password
  447.      * @return the mails session object
  448.      */
  449.     protected static Session getMailSession( String strHost, int nPort, final String strUsername, final String strPassword )
  450.     {
  451.         String strDebug = AppPropertiesService.getProperty( PROPERTY_MAIL_SESSION_DEBUG, Boolean.FALSE.toString( ) );
  452.         boolean bSessionDebug = Boolean.parseBoolean( strDebug );

  453.         // Initializes a mail session with the SMTP server
  454.         Properties props = System.getProperties( );
  455.         props.put( MAIL_HOST, strHost );
  456.         props.put( MAIL_TRANSPORT_PROTOCOL, SMTP );
  457.         props.put( MAIL_PROPTOCOL_HOST, strHost );
  458.         props.put( MAIL_PROPTOCOL_PORT, nPort );

  459.         Authenticator auth;

  460.         if ( StringUtils.isNotBlank( strUsername ) )
  461.         {
  462.             props.put( MAIL_SMTP_AUTH, TRUE );
  463.             // using authenticator class that return a PasswordAuthentication
  464.             auth = new Authenticator( )
  465.             {
  466.                 @Override
  467.                 protected PasswordAuthentication getPasswordAuthentication( )
  468.                 {
  469.                     return new PasswordAuthentication( strUsername, strPassword );
  470.                 }
  471.             };
  472.         }
  473.         else
  474.         {
  475.             // no authentication data provided, no authenticator
  476.             auth = null;
  477.         }

  478.         Session mailSession = Session.getDefaultInstance( props, auth );
  479.         // Activate debugging
  480.         mailSession.setDebug( bSessionDebug );

  481.         return mailSession;
  482.     }

  483.     /**
  484.      * return the transport object of the SMTP session
  485.      *
  486.      * @return the transport object of the SMTP session
  487.      * @param session
  488.      *            the SMTP session
  489.      * @throws NoSuchProviderException
  490.      *             If the provider is not found
  491.      */
  492.     protected static Transport getTransport( Session session ) throws NoSuchProviderException
  493.     {
  494.         return session.getTransport( SMTP );
  495.     }

  496.     /**
  497.      * extract The list of Internet Address content in the string strRecipients
  498.      *
  499.      * @return The list of Internet Address content in the string strRecipients
  500.      * @param strRecipients
  501.      *            The list of recipient separated by the mail separator defined in config.properties
  502.      * @throws AddressException
  503.      *             If invalid address
  504.      */
  505.     private static InternetAddress [ ] getAllAdressOfRecipients( String strRecipients ) throws AddressException
  506.     {
  507.         List<String> listRecipients = getAllStringAdressOfRecipients( strRecipients );
  508.         InternetAddress [ ] address = new InternetAddress [ listRecipients.size( )];

  509.         // Initialization of the address array
  510.         for ( int i = 0; i < listRecipients.size( ); i++ )
  511.         {
  512.             address [i] = new InternetAddress( listRecipients.get( i ) );
  513.         }

  514.         return address;
  515.     }

  516.     /**
  517.      * Extract The list of String Address content in the string strRecipients
  518.      *
  519.      * @return The list of String Address content in the string strRecipients
  520.      * @param strRecipients
  521.      *            The list of recipient separated by the mail separator defined in config.properties
  522.      *
  523.      */
  524.     public static List<String> getAllStringAdressOfRecipients( String strRecipients )
  525.     {
  526.         StringTokenizer st = new StringTokenizer( strRecipients, AppPropertiesService.getProperty( PROPERTY_MAIL_LIST_SEPARATOR, ";" ) );
  527.         List<String> listRecipients = new ArrayList<>( );

  528.         while ( st.hasMoreTokens( ) )
  529.         {
  530.             listRecipients.add( st.nextToken( ) );
  531.         }

  532.         return listRecipients;
  533.     }

  534.     /**
  535.      * Return a String that contains a list of recipients separated with mail separator
  536.      *
  537.      * @param listRecipients
  538.      *            a list of string recipients
  539.      * @return A String that contains a list of recipients separated with mail separator
  540.      */
  541.     protected static String getStrRecipients( List<String> listRecipients )
  542.     {
  543.         String strMailListSeparator = AppPropertiesService.getProperty( PROPERTY_MAIL_LIST_SEPARATOR, ";" );
  544.         StringBuilder strRecipients = new StringBuilder( );
  545.         int ncpt = 0;

  546.         if ( listRecipients != null )
  547.         {
  548.             for ( String strRecipient : listRecipients )
  549.             {
  550.                 strRecipients.append( strRecipient );

  551.                 if ( ++ncpt < listRecipients.size( ) )
  552.                 {
  553.                     strRecipients.append( strMailListSeparator );
  554.                 }
  555.             }
  556.         }

  557.         return strRecipients.toString( );
  558.     }

  559.     /**
  560.      * This Method convert a UrlAttachmentDataSource to a ByteArrayDataSource and used MailAttachmentCacheService for caching resource.
  561.      *
  562.      * @param urlAttachement
  563.      *            {@link UrlAttachment}
  564.      * @return a {@link ByteArrayDataSource}
  565.      */
  566.     private static ByteArrayDataSource convertUrlAttachmentDataSourceToByteArrayDataSource( UrlAttachment urlAttachement )
  567.     {
  568.         String strKey = MailAttachmentCacheService.getInstance( ).getKey( urlAttachement.getUrlData( ).toString( ) );
  569.         ByteArrayDataSource urlAttachmentDataSource = null;

  570.         if ( MailAttachmentCacheService.getInstance( ).isCacheEnable( ) && MailAttachmentCacheService.getInstance( ).getFromCache( strKey ) != null )
  571.         {
  572.             return (ByteArrayDataSource) MailAttachmentCacheService.getInstance( ).getFromCache( strKey );
  573.         }

  574.         DataHandler handler = new DataHandler( urlAttachement.getUrlData( ) );
  575.         ByteArrayOutputStream bo = null;
  576.         InputStream input = null;
  577.         String strType = handler.getContentType( );

  578.         try
  579.         {
  580.             Object o = handler.getContent( );
  581.             if ( o instanceof InputStream )
  582.             {
  583.                 input = (InputStream) o;
  584.                 bo = new ByteArrayOutputStream( );

  585.                 int read;
  586.                 byte [ ] tab = new byte [ CONSTANTE_FILE_ATTACHMET_BUFFER];

  587.                 do
  588.                 {
  589.                     read = input.read( tab );

  590.                     if ( read > 0 )
  591.                     {
  592.                         bo.write( tab, 0, read );
  593.                     }
  594.                 }
  595.                 while ( read > 0 );
  596.             }
  597.         }
  598.         catch( IOException e )
  599.         {
  600.             // Document is ignored
  601.             AppLogService.info( "{} {} ", urlAttachement.getContentLocation( ), MSG_ATTACHMENT_NOT_FOUND );
  602.         }
  603.         finally
  604.         {
  605.             // closed inputstream and outputstream
  606.             try
  607.             {
  608.                 if ( input != null )
  609.                 {
  610.                     input.close( );
  611.                 }

  612.                 if ( bo != null )
  613.                 {
  614.                     bo.close( );
  615.                     urlAttachmentDataSource = new ByteArrayDataSource( bo.toByteArray( ), strType );
  616.                 }
  617.             }
  618.             catch( IOException e )
  619.             {
  620.                 AppLogService.error( e.getMessage( ), e );
  621.             }
  622.         }

  623.         if ( MailAttachmentCacheService.getInstance( ).isCacheEnable( ) )
  624.         {
  625.             // add resource in cache
  626.             MailAttachmentCacheService.getInstance( ).putInCache( strKey, urlAttachmentDataSource );
  627.         }

  628.         return urlAttachmentDataSource;
  629.     }
  630. }