View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de 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.init;
35  
36  import fr.paris.lutece.portal.service.admin.AdminAuthenticationService;
37  import fr.paris.lutece.portal.service.admin.AdminUserService;
38  import fr.paris.lutece.portal.service.content.ContentPostProcessorService;
39  import fr.paris.lutece.portal.service.content.ContentService;
40  import fr.paris.lutece.portal.service.daemon.AppDaemonService;
41  import fr.paris.lutece.portal.service.database.AppConnectionService;
42  import fr.paris.lutece.portal.service.datastore.CoreDataKeys;
43  import fr.paris.lutece.portal.service.datastore.DatastoreService;
44  import fr.paris.lutece.portal.service.fileimage.FileImageService;
45  import fr.paris.lutece.portal.service.filter.FilterService;
46  import fr.paris.lutece.portal.service.html.XmlTransformerCacheService;
47  import fr.paris.lutece.portal.service.i18n.I18nService;
48  import fr.paris.lutece.portal.service.mailinglist.AdminMailingListService;
49  import fr.paris.lutece.portal.service.plugin.PluginService;
50  import fr.paris.lutece.portal.service.portal.PortalService;
51  import fr.paris.lutece.portal.service.search.IndexationService;
52  import fr.paris.lutece.portal.service.security.SecurityService;
53  import fr.paris.lutece.portal.service.servlet.ServletService;
54  import fr.paris.lutece.portal.service.spring.SpringContextService;
55  import fr.paris.lutece.portal.service.template.AppTemplateService;
56  import fr.paris.lutece.portal.service.util.AppLogService;
57  import fr.paris.lutece.portal.service.util.AppPathService;
58  import fr.paris.lutece.portal.service.util.AppPropertiesService;
59  import fr.paris.lutece.util.html.HtmlTemplate;
60  
61  import java.io.FileInputStream;
62  import java.io.FileWriter;
63  import java.io.IOException;
64  
65  import java.text.SimpleDateFormat;
66  
67  import java.util.Date;
68  import java.util.HashMap;
69  import java.util.Locale;
70  import java.util.Map;
71  import java.util.Properties;
72  
73  import javax.servlet.ServletContext;
74  
75  
76  /**
77   * This class initializes all the application services
78   * @since 1.1
79   */
80  public final class AppInit
81  {
82      private static final String PROPERTY_AUTOINIT = "autoInit";
83      private static final String PROPERTY_INIT_WEBAPP_PROD_URL = "init.webapp.prod.url";
84      private static final String PROPERTY_SENDMAIL_SUBJECT = "portal.system.log4j.sendmail.subject";
85      private static final String PROPERTY_SITE_NAME = "lutece.name";
86      private static final String MARK_WEBAPP_HOME = "webapp_home";
87      private static final String MARK_PROD_URL = "lutece_prod_url";
88      private static final String MARK_SENDMAIL_SUBJECT = "sendmail_subject";
89      private static final String MARK_AUTOINIT = "autoinit";
90      private static final String PATH_CONFIG = "/WEB-INF/conf/";
91      private static final String FILE_PROPERTIES_CONFIG = "config.properties";
92      private static final String FILE_PROPERTIES_DATABASE = "db.properties";
93      private static final String PATH_TEMPLATES = "/WEB-INF/templates/";
94      private static final String CONFIG_PROPERTIES_TEMPLATE = "admin/system/config_properties.html";
95      private static boolean _bInitSuccessfull;
96      private static String _strLoadingFailureCause;
97      private static String _strLoadingFailureDetails;
98  
99      /**
100      * Constructor
101      */
102     private AppInit(  )
103     {
104     }
105 
106     /**
107      * Initializes all the application services (used for junit tests)
108      * @param strConfPath The relative path to the config files
109      */
110     public static void initServices( String strConfPath )
111     {
112         initServices( null, strConfPath, null );
113     }
114 
115     /**
116      * Initializes all the application services
117      * @param context The servlet context
118      * @param strConfPath The relative path to the config files
119      * @param strRealPath The real path to the config files
120      */
121     public static void initServices( ServletContext context, String strConfPath, String strRealPath )
122     {
123         try
124         {
125             Thread.currentThread(  ).setName( "Lutece-MainThread" );
126             // Initializes a very basic logging system (everything to stdout)
127             AppLogService.preinit();
128             // Initializes the properties download files containing the variables used by the application
129             AppPropertiesService.init( strConfPath );
130 
131             // Initializes the template services from the servlet context information
132             AppTemplateService.init( PATH_TEMPLATES );
133 
134             // Initializes the Datastore Service
135             DatastoreService.init(  );
136 
137             if ( strRealPath != null )
138             {
139                 // Initializes the properties download files containing the
140                 // variables used by the application
141                 initProperties( strRealPath );
142             }
143 
144             // Initializes the log service from the property files
145             AppLogService.init( strConfPath, FILE_PROPERTIES_CONFIG );
146             AppLogService.info( "Starting LUTECE ..." );
147             AppLogService.info( "Running version " + AppInfo.getVersion(  ) );
148 
149             // Initializes the connection pools
150             AppConnectionService.init( strConfPath, FILE_PROPERTIES_DATABASE, "portal" );
151             AppLogService.info( "Creating connexions pool 'portal'." );
152 
153             // Spring ApplicationContext initialization
154             AppLogService.info( "Loading context files ..." );
155             SpringContextService.init( context );
156 
157             // Initialize and run StartUp services
158             AppLogService.info( "Running extra startup services ..." );
159             StartUpServiceManager.init(  );
160 
161             // XmlTransformer service cache manager
162             XmlTransformerCacheService.init(  );
163 
164             AdminMailingListService.init(  );
165 
166             // Initializes Search Engine Indexation Service
167             IndexationService.init(  );
168 
169             // Initializes PluginService
170             AppLogService.info( "Initializing plugins ..." );
171             PluginService.init(  );
172 
173             // Initializes FilterService and ServletService
174             AppLogService.info( "Initializing plugins filters ..." );
175             FilterService.init( context );
176             AppLogService.info( "Initializing plugins servlets ..." );
177             ServletService.init( context );
178 
179             // Trace Contents services loading
180             traceContentServicesLoading(  );
181 
182             // Initializes the SecurityService
183             SecurityService.init(  );
184 
185             // Initializes plugins autoincludes - needs to be launched before the daemons (indexer could fail)
186             AppTemplateService.initAutoIncludes(  );
187 
188             // Initializes the daemons service
189             AppDaemonService.init(  );
190 
191             // Initializes the admin authentication module
192             AdminAuthenticationService.init(  );
193 
194             // Initialize FileImageService
195             FileImageService.init(  );
196 
197             // Initialize AdminUserService
198             AdminUserService.init(  );
199 
200             // Process post startup services
201             AppLogService.info( "Running post startup services ..." );
202             PostStartUpServiceManager.init(  );
203 
204             // Initialize Content Post Processor Service
205             ContentPostProcessorService.init(  );
206 
207             _bInitSuccessfull = true;
208 
209             logStartupTime(  );
210 
211             // Start datastore's cache after all processes that may use Datastore 
212             DatastoreService.startCache(  );
213         }
214         catch ( LuteceInitException e )
215         {
216             _strLoadingFailureCause = e.getMessage(  );
217 
218             Throwable cause = e.getCause(  );
219 
220             while ( cause != null )
221             {
222                 _strLoadingFailureDetails = cause.getMessage(  );
223                 cause = cause.getCause(  );
224             }
225         }
226     }
227 
228     /**
229      * Tells if Lutece Startup was successful
230      * @return True, if no error, otherwise false
231      */
232     public static boolean isWebappSuccessfullyLoaded(  )
233     {
234         return _bInitSuccessfull;
235     }
236 
237     /**
238      * Returns the cause of the startup failure
239      * @return the cause of the startup failure
240      */
241     public static String getLoadingFailureCause(  )
242     {
243         return _strLoadingFailureCause;
244     }
245 
246     /**
247      * Returns details of the startup failure
248      * @return details of the startup failure
249      */
250     public static String getLoadingFailureDetails(  )
251     {
252         return _strLoadingFailureDetails;
253     }
254 
255     /**
256      * Traces Content Services loading
257      */
258     private static void traceContentServicesLoading(  )
259     {
260         for ( ContentService cs : PortalService.getContentServicesList(  ) )
261         {
262             AppLogService.info( "Content Service '" + cs.getName(  ) + "' is loaded " +
263                 ( cs.isCacheEnable(  ) ? " [ cache enable ] " : " [ cache disable ] " ) );
264         }
265     }
266 
267     /**
268      * Initializes the config.properties file after first installation
269      *
270      * @param strRealPath The real path to the configuration file
271      */
272     private static void initProperties( String strRealPath )
273     {
274         Map<String, Object> model = new HashMap<String, Object>(  );
275         Properties p = new Properties(  );
276 
277         FileInputStream fis = null;
278 
279         try
280         {
281             fis = new FileInputStream( strRealPath + PATH_CONFIG + FILE_PROPERTIES_CONFIG );
282             p.load( fis );
283         }
284         catch ( Exception e )
285         {
286             AppLogService.error( e.getMessage(  ), e );
287         }
288         finally
289         {
290             if ( fis != null )
291             {
292                 try
293                 {
294                     fis.close(  );
295                 }
296                 catch ( IOException e )
297                 {
298                     AppLogService.error( e.getMessage(  ), e );
299                 }
300             }
301         }
302 
303         if ( Boolean.parseBoolean( p.getProperty( PROPERTY_AUTOINIT ) ) )
304         {
305             Object[] params = { AppPropertiesService.getProperty( PROPERTY_SITE_NAME ) };
306             String strSendMailSubject = I18nService.getLocalizedString( PROPERTY_SENDMAIL_SUBJECT, params,
307                     I18nService.getDefaultLocale(  ) );
308             model.put( MARK_SENDMAIL_SUBJECT, strSendMailSubject );
309             model.put( MARK_WEBAPP_HOME, AppPathService.getWebAppPath(  ) );
310             model.put( MARK_PROD_URL, p.getProperty( PROPERTY_INIT_WEBAPP_PROD_URL ) );
311             model.put( MARK_AUTOINIT, Boolean.FALSE.toString(  ) );
312 
313             HtmlTemplate configTemplate = AppTemplateService.getTemplate( CONFIG_PROPERTIES_TEMPLATE,
314                     Locale.getDefault(  ), model );
315             // reset configuration cache to avoid configuration caching before macros are set. See LUTECE-1460
316             AppTemplateService.resetConfiguration(  );
317 
318             FileWriter fw = null;
319 
320             try
321             {
322                 fw = new FileWriter( strRealPath + PATH_CONFIG + FILE_PROPERTIES_CONFIG );
323                 fw.write( configTemplate.getHtml(  ) );
324             }
325             catch ( Exception io )
326             {
327                 io.printStackTrace(  );
328             }
329             finally
330             {
331                 if ( fw != null )
332                 {
333                     try
334                     {
335                         fw.close(  );
336                     }
337                     catch ( IOException e )
338                     {
339                         AppLogService.error( e.getMessage(  ), e );
340                     }
341                 }
342             }
343         }
344     }
345 
346     /**
347      * Log startup time.
348      */
349     private static void logStartupTime(  )
350     {
351         String strStartupTime = SimpleDateFormat.getDateTimeInstance(  ).format( new Date(  ) );
352         DatastoreService.setDataValue( CoreDataKeys.KEY_STARTUP_TIME, strStartupTime );
353     }
354 }