1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.deploy.hot;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.events.EventsProcessorUtil;
27  import com.liferay.portal.kernel.bean.ContextClassLoaderBeanHandler;
28  import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
29  import com.liferay.portal.kernel.configuration.Configuration;
30  import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
31  import com.liferay.portal.kernel.deploy.auto.AutoDeployDir;
32  import com.liferay.portal.kernel.deploy.auto.AutoDeployListener;
33  import com.liferay.portal.kernel.deploy.auto.AutoDeployUtil;
34  import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
35  import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
36  import com.liferay.portal.kernel.deploy.hot.HotDeployException;
37  import com.liferay.portal.kernel.deploy.hot.HotDeployListener;
38  import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
39  import com.liferay.portal.kernel.events.Action;
40  import com.liferay.portal.kernel.events.InvokerAction;
41  import com.liferay.portal.kernel.events.InvokerSessionAction;
42  import com.liferay.portal.kernel.events.InvokerSimpleAction;
43  import com.liferay.portal.kernel.events.SessionAction;
44  import com.liferay.portal.kernel.events.SimpleAction;
45  import com.liferay.portal.kernel.language.LanguageUtil;
46  import com.liferay.portal.kernel.log.Log;
47  import com.liferay.portal.kernel.log.LogFactoryUtil;
48  import com.liferay.portal.kernel.upgrade.UpgradeException;
49  import com.liferay.portal.kernel.util.ArrayUtil;
50  import com.liferay.portal.kernel.util.FileUtil;
51  import com.liferay.portal.kernel.util.GetterUtil;
52  import com.liferay.portal.kernel.util.HttpUtil;
53  import com.liferay.portal.kernel.util.ListUtil;
54  import com.liferay.portal.kernel.util.LocaleUtil;
55  import com.liferay.portal.kernel.util.PropsKeys;
56  import com.liferay.portal.kernel.util.StringPool;
57  import com.liferay.portal.kernel.util.StringUtil;
58  import com.liferay.portal.kernel.util.Validator;
59  import com.liferay.portal.kernel.xml.Document;
60  import com.liferay.portal.kernel.xml.Element;
61  import com.liferay.portal.kernel.xml.SAXReaderUtil;
62  import com.liferay.portal.language.LanguageResources;
63  import com.liferay.portal.model.BaseModel;
64  import com.liferay.portal.model.ModelListener;
65  import com.liferay.portal.model.Release;
66  import com.liferay.portal.security.auth.AuthFailure;
67  import com.liferay.portal.security.auth.AuthPipeline;
68  import com.liferay.portal.security.auth.Authenticator;
69  import com.liferay.portal.security.auth.AutoLogin;
70  import com.liferay.portal.security.auth.CompanyThreadLocal;
71  import com.liferay.portal.security.auth.EmailAddressGenerator;
72  import com.liferay.portal.security.auth.EmailAddressGeneratorFactory;
73  import com.liferay.portal.security.auth.FullNameValidator;
74  import com.liferay.portal.security.auth.FullNameValidatorFactory;
75  import com.liferay.portal.security.auth.ScreenNameGenerator;
76  import com.liferay.portal.security.auth.ScreenNameGeneratorFactory;
77  import com.liferay.portal.security.auth.ScreenNameValidator;
78  import com.liferay.portal.security.auth.ScreenNameValidatorFactory;
79  import com.liferay.portal.security.ldap.AttributesTransformer;
80  import com.liferay.portal.security.ldap.AttributesTransformerFactory;
81  import com.liferay.portal.service.ReleaseLocalServiceUtil;
82  import com.liferay.portal.service.persistence.BasePersistence;
83  import com.liferay.portal.servlet.filters.autologin.AutoLoginFilter;
84  import com.liferay.portal.servlet.filters.cache.CacheUtil;
85  import com.liferay.portal.spring.aop.ServiceHookAdvice;
86  import com.liferay.portal.struts.MultiMessageResources;
87  import com.liferay.portal.struts.MultiMessageResourcesFactory;
88  import com.liferay.portal.upgrade.UpgradeProcessUtil;
89  import com.liferay.portal.util.PortalInstances;
90  import com.liferay.portal.util.PortalUtil;
91  import com.liferay.portal.util.PropsUtil;
92  import com.liferay.portal.util.PropsValues;
93  import com.liferay.portlet.ControlPanelEntry;
94  import com.liferay.portlet.DefaultControlPanelEntryFactory;
95  import com.liferay.util.UniqueList;
96  
97  import java.io.File;
98  import java.io.InputStream;
99  
100 import java.lang.reflect.Constructor;
101 import java.lang.reflect.Field;
102 import java.lang.reflect.Proxy;
103 
104 import java.net.URL;
105 
106 import java.util.ArrayList;
107 import java.util.HashMap;
108 import java.util.HashSet;
109 import java.util.Iterator;
110 import java.util.List;
111 import java.util.Locale;
112 import java.util.Map;
113 import java.util.Properties;
114 import java.util.Set;
115 
116 import javax.servlet.ServletContext;
117 
118 /**
119  * <a href="HookHotDeployListener.java.html"><b><i>View Source</i></b></a>
120  *
121  * @author Brian Wing Shun Chan
122  * @author Bruno Farache
123  */
124 public class HookHotDeployListener
125     extends BaseHotDeployListener implements PropsKeys {
126 
127     public HookHotDeployListener() {
128         for (String key : _PROPS_VALUES_STRING_ARRAY) {
129             _stringArraysContainerMap.put(key, new StringArraysContainer(key));
130         }
131     }
132 
133     public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
134         try {
135             doInvokeDeploy(event);
136         }
137         catch (Throwable t) {
138             throwHotDeployException(event, "Error registering hook for ", t);
139         }
140     }
141 
142     public void invokeUndeploy(HotDeployEvent event) throws HotDeployException {
143         try {
144             doInvokeUndeploy(event);
145         }
146         catch (Throwable t) {
147             throwHotDeployException(event, "Error unregistering hook for ", t);
148         }
149     }
150 
151     protected boolean containsKey(Properties portalProperties, String key) {
152         if (_log.isDebugEnabled()) {
153             return true;
154         }
155         else {
156             return portalProperties.containsKey(key);
157         }
158     }
159 
160     protected void destroyCustomJspBag(CustomJspBag customJspBag) {
161         String customJspDir = customJspBag.getCustomJspDir();
162         List<String> customJsps = customJspBag.getCustomJsps();
163         //String timestamp = customJspBag.getTimestamp();
164 
165         String portalWebDir = PortalUtil.getPortalWebDir();
166 
167         for (String customJsp : customJsps) {
168             int pos = customJsp.indexOf(customJspDir);
169 
170             String portalJsp = customJsp.substring(
171                 pos + customJspDir.length(), customJsp.length());
172 
173             File portalJspFile = new File(portalWebDir + portalJsp);
174             File portalJspBackupFile = getPortalJspBackupFile(portalJspFile);
175 
176             if (portalJspBackupFile.exists()) {
177                 FileUtil.copyFile(portalJspBackupFile, portalJspFile);
178 
179                 portalJspBackupFile.delete();
180             }
181             else if (portalJspFile.exists()) {
182                 portalJspFile.delete();
183             }
184         }
185     }
186 
187     protected void destroyPortalProperties(
188             String servletContextName, Properties portalProperties)
189         throws Exception {
190 
191         PropsUtil.removeProperties(portalProperties);
192 
193         if (_log.isDebugEnabled() && portalProperties.containsKey(LOCALES)) {
194             _log.debug(
195                 "Portlet locales " + portalProperties.getProperty(LOCALES));
196             _log.debug("Original locales " + PropsUtil.get(LOCALES));
197             _log.debug(
198                 "Original locales array length " +
199                     PropsUtil.getArray(LOCALES).length);
200         }
201 
202         resetPortalProperties(servletContextName, portalProperties, false);
203 
204         if (portalProperties.containsKey(
205                 PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS)) {
206 
207             DefaultControlPanelEntryFactory.setInstance(null);
208         }
209 
210         if (portalProperties.containsKey(PropsKeys.DL_HOOK_IMPL)) {
211             com.liferay.documentlibrary.util.HookFactory.setInstance(null);
212         }
213 
214         if (portalProperties.containsKey(PropsKeys.IMAGE_HOOK_IMPL)) {
215             com.liferay.portal.image.HookFactory.setInstance(null);
216         }
217 
218         if (portalProperties.containsKey(
219                 PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL)) {
220 
221             AttributesTransformerFactory.setInstance(null);
222         }
223 
224         if (portalProperties.containsKey(PropsKeys.MAIL_HOOK_IMPL)) {
225             com.liferay.mail.util.HookFactory.setInstance(null);
226         }
227 
228         if (portalProperties.containsKey(
229                 PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR)) {
230 
231             EmailAddressGeneratorFactory.setInstance(null);
232         }
233 
234         if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_VALIDATOR)) {
235             FullNameValidatorFactory.setInstance(null);
236         }
237 
238         if (portalProperties.containsKey(
239                 PropsKeys.USERS_SCREEN_NAME_GENERATOR)) {
240 
241             ScreenNameGeneratorFactory.setInstance(null);
242         }
243 
244         if (portalProperties.containsKey(
245                 PropsKeys.USERS_SCREEN_NAME_VALIDATOR)) {
246 
247             ScreenNameValidatorFactory.setInstance(null);
248         }
249     }
250 
251     protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
252         ServletContext servletContext = event.getServletContext();
253 
254         String servletContextName = servletContext.getServletContextName();
255 
256         if (_log.isDebugEnabled()) {
257             _log.debug("Invoking deploy for " + servletContextName);
258         }
259 
260         String xml = HttpUtil.URLtoString(
261             servletContext.getResource("/WEB-INF/liferay-hook.xml"));
262 
263         if (xml == null) {
264             return;
265         }
266 
267         if (_log.isInfoEnabled()) {
268             _log.info("Registering hook for " + servletContextName);
269         }
270 
271         _servletContextNames.add(servletContextName);
272 
273         ClassLoader portletClassLoader = event.getContextClassLoader();
274 
275         Document doc = SAXReaderUtil.read(xml, true);
276 
277         Element root = doc.getRootElement();
278 
279         String portalPropertiesLocation = root.elementText("portal-properties");
280 
281         if (Validator.isNotNull(portalPropertiesLocation)) {
282             Configuration portalPropertiesConfiguration = null;
283 
284             try {
285                 String name = portalPropertiesLocation;
286 
287                 int pos = name.lastIndexOf(".properties");
288 
289                 if (pos != -1) {
290                     name = name.substring(0, pos);
291                 }
292 
293                 portalPropertiesConfiguration =
294                     ConfigurationFactoryUtil.getConfiguration(
295                         portletClassLoader, name);
296             }
297             catch (Exception e) {
298                 _log.error("Unable to read " + portalPropertiesLocation, e);
299             }
300 
301             if (portalPropertiesConfiguration != null) {
302                 Properties portalProperties =
303                     portalPropertiesConfiguration.getProperties();
304 
305                 if (portalProperties.size() > 0) {
306                     _portalPropertiesMap.put(
307                         servletContextName, portalProperties);
308 
309                     // Initialize properties, auto logins, model listeners, and
310                     // events in that specific order. Events have to be loaded
311                     // last because they may require model listeners to have
312                     // been registered.
313 
314                     initPortalProperties(
315                         servletContextName, portletClassLoader,
316                         portalProperties);
317                     initAuthFailures(
318                         servletContextName, portletClassLoader,
319                         portalProperties);
320                     initAutoDeployListeners(
321                         servletContextName, portletClassLoader,
322                         portalProperties);
323                     initAutoLogins(
324                         servletContextName, portletClassLoader,
325                         portalProperties);
326                     initHotDeployListeners(
327                         servletContextName, portletClassLoader,
328                         portalProperties);
329                     initModelListeners(
330                         servletContextName, portletClassLoader,
331                         portalProperties);
332                     initEvents(
333                         servletContextName, portletClassLoader,
334                         portalProperties);
335                 }
336             }
337         }
338 
339         LanguagesContainer languagesContainer = new LanguagesContainer();
340 
341         _languagesContainerMap.put(servletContextName, languagesContainer);
342 
343         List<Element> languagePropertiesEls = root.elements(
344             "language-properties");
345 
346         for (Element languagePropertiesEl : languagePropertiesEls) {
347             String languagePropertiesLocation = languagePropertiesEl.getText();
348 
349             try {
350                 URL url = portletClassLoader.getResource(
351                     languagePropertiesLocation);
352 
353                 if (url == null) {
354                     continue;
355                 }
356 
357                 InputStream is = url.openStream();
358 
359                 Properties properties = new Properties();
360 
361                 properties.load(is);
362 
363                 is.close();
364 
365                 String localeKey = getLocaleKey(languagePropertiesLocation);
366 
367                 if (localeKey != null) {
368                     languagesContainer.addLanguage(localeKey, properties);
369                 }
370             }
371             catch (Exception e) {
372                 _log.error("Unable to read " + languagePropertiesLocation, e);
373             }
374         }
375 
376         String customJspDir = root.elementText("custom-jsp-dir");
377 
378         if (Validator.isNotNull(customJspDir)) {
379             if (_log.isDebugEnabled()) {
380                 _log.debug("Custom JSP directory: " + customJspDir);
381             }
382 
383             List<String> customJsps = new ArrayList<String>();
384 
385             String webDir = servletContext.getRealPath(StringPool.SLASH);
386 
387             getCustomJsps(servletContext, webDir, customJspDir, customJsps);
388 
389             if (customJsps.size() > 0) {
390                 CustomJspBag customJspBag = new CustomJspBag(
391                     customJspDir, customJsps);
392 
393                 if (_log.isDebugEnabled()) {
394                     StringBuilder sb = new StringBuilder();
395 
396                     sb.append("Custom JSP files:\n");
397 
398                     Iterator<String> itr = customJsps.iterator();
399 
400                     while (itr.hasNext()) {
401                         String customJsp = itr.next();
402 
403                         sb.append(customJsp);
404 
405                         if (itr.hasNext()) {
406                             sb.append(StringPool.NEW_LINE);
407                         }
408                     }
409 
410                     _log.debug(sb.toString());
411                 }
412 
413                 _customJspBagsMap.put(servletContextName, customJspBag);
414 
415                 initCustomJspBag(customJspBag);
416             }
417         }
418 
419         ServicesContainer servicesContainer = new ServicesContainer();
420 
421         _servicesContainerMap.put(servletContextName, servicesContainer);
422 
423         List<Element> serviceEls = root.elements("service");
424 
425         for (Element serviceEl : serviceEls) {
426             String serviceType = serviceEl.elementText("service-type");
427             String serviceImpl = serviceEl.elementText("service-impl");
428 
429             Class<?> serviceTypeClass = portletClassLoader.loadClass(
430                 serviceType);
431             Class<?> serviceImplClass = portletClassLoader.loadClass(
432                 serviceImpl);
433 
434             Constructor<?> serviceImplConstructor =
435                 serviceImplClass.getConstructor(new Class[] {serviceTypeClass});
436 
437             Object serviceImplInstance = serviceImplConstructor.newInstance(
438                 PortalBeanLocatorUtil.locate(serviceType));
439 
440             serviceImplInstance = Proxy.newProxyInstance(
441                 portletClassLoader, new Class[] {serviceTypeClass},
442                 new ContextClassLoaderBeanHandler(
443                     serviceImplInstance, portletClassLoader));
444 
445             servicesContainer.addService(serviceType, serviceImplInstance);
446         }
447 
448         // Begin backwards compatibility for 5.1.0
449 
450         ModelListenersContainer modelListenersContainer =
451             _modelListenersContainerMap.get(servletContextName);
452 
453         if (modelListenersContainer == null) {
454             modelListenersContainer = new ModelListenersContainer();
455 
456             _modelListenersContainerMap.put(
457                 servletContextName, modelListenersContainer);
458         }
459 
460         List<Element> modelListenerEls = root.elements("model-listener");
461 
462         for (Element modelListenerEl : modelListenerEls) {
463             String modelName = modelListenerEl.elementText("model-name");
464             String modelListenerClassName = modelListenerEl.elementText(
465                 "model-listener-class");
466 
467             ModelListener<BaseModel<?>> modelListener = initModelListener(
468                 modelName, modelListenerClassName, portletClassLoader);
469 
470             if (modelListener != null) {
471                 modelListenersContainer.registerModelListener(
472                     modelName, modelListener);
473             }
474         }
475 
476         EventsContainer eventsContainer = _eventsContainerMap.get(
477             servletContextName);
478 
479         if (eventsContainer == null) {
480             eventsContainer = new EventsContainer();
481 
482             _eventsContainerMap.put(servletContextName, eventsContainer);
483         }
484 
485         List<Element> eventEls = root.elements("event");
486 
487         for (Element eventEl : eventEls) {
488             String eventName = eventEl.elementText("event-type");
489             String eventClassName = eventEl.elementText("event-class");
490 
491             Object obj = initEvent(
492                 eventName, eventClassName, portletClassLoader);
493 
494             if (obj != null) {
495                 eventsContainer.registerEvent(eventName, obj);
496             }
497         }
498 
499         // End backwards compatibility for 5.1.0
500 
501         registerClpMessageListeners(servletContext, portletClassLoader);
502 
503         if (_log.isInfoEnabled()) {
504             _log.info(
505                 "Hook for " + servletContextName + " is available for use");
506         }
507     }
508 
509     protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
510         ServletContext servletContext = event.getServletContext();
511 
512         String servletContextName = servletContext.getServletContextName();
513 
514         if (_log.isDebugEnabled()) {
515             _log.debug("Invoking undeploy for " + servletContextName);
516         }
517 
518         if (!_servletContextNames.remove(servletContextName)) {
519             return;
520         }
521 
522         AuthenticatorsContainer authenticatorsContainer =
523             _authenticatorsContainerMap.remove(servletContextName);
524 
525         if (authenticatorsContainer != null) {
526             authenticatorsContainer.unregisterAuthenticators();
527         }
528 
529         AuthFailuresContainer authFailuresContainer =
530             _authFailuresContainerMap.remove(servletContextName);
531 
532         if (authFailuresContainer != null) {
533             authFailuresContainer.unregisterAuthFailures();
534         }
535 
536         AutoDeployListenersContainer autoDeployListenersContainer =
537             _autoDeployListenersContainerMap.remove(servletContextName);
538 
539         if (autoDeployListenersContainer != null) {
540             autoDeployListenersContainer.unregisterAutoDeployListeners();
541         }
542 
543         AutoLoginsContainer autoLoginsContainer =
544             _autoLoginsContainerMap.remove(servletContextName);
545 
546         if (autoLoginsContainer != null) {
547             autoLoginsContainer.unregisterAutoLogins();
548         }
549 
550         CustomJspBag customJspBag = _customJspBagsMap.remove(
551             servletContextName);
552 
553         if (customJspBag != null) {
554             destroyCustomJspBag(customJspBag);
555         }
556 
557         EventsContainer eventsContainer = _eventsContainerMap.remove(
558             servletContextName);
559 
560         if (eventsContainer != null) {
561             eventsContainer.unregisterEvents();
562         }
563 
564         HotDeployListenersContainer hotDeployListenersContainer =
565             _hotDeployListenersContainerMap.remove(servletContextName);
566 
567         if (hotDeployListenersContainer != null) {
568             hotDeployListenersContainer.unregisterHotDeployListeners();
569         }
570 
571         LanguagesContainer languagesContainer = _languagesContainerMap.remove(
572             servletContextName);
573 
574         if (languagesContainer != null) {
575             languagesContainer.unregisterLanguages();
576         }
577 
578         ModelListenersContainer modelListenersContainer =
579             _modelListenersContainerMap.remove(servletContextName);
580 
581         if (modelListenersContainer != null) {
582             modelListenersContainer.unregisterModelListeners();
583         }
584 
585         Properties portalProperties = _portalPropertiesMap.remove(
586             servletContextName);
587 
588         if (portalProperties != null) {
589             destroyPortalProperties(servletContextName, portalProperties);
590         }
591 
592         ServicesContainer servicesContainer = _servicesContainerMap.remove(
593             servletContextName);
594 
595         if (servicesContainer != null) {
596             servicesContainer.unregisterServices();
597         }
598 
599         unregisterClpMessageListeners(servletContext);
600 
601         if (_log.isInfoEnabled()) {
602             _log.info("Hook for " + servletContextName + " was unregistered");
603         }
604     }
605 
606     protected void getCustomJsps(
607         ServletContext servletContext, String webDir, String resourcePath,
608         List<String> customJsps) {
609 
610         Set<String> resourcePaths = servletContext.getResourcePaths(
611             resourcePath);
612 
613         for (String curResourcePath : resourcePaths) {
614             if (curResourcePath.endsWith(StringPool.SLASH)) {
615                 getCustomJsps(
616                     servletContext, webDir, curResourcePath, customJsps);
617             }
618             else {
619                 String customJsp = webDir + curResourcePath;
620 
621                 customJsp = StringUtil.replace(
622                     customJsp, StringPool.DOUBLE_SLASH, StringPool.SLASH);
623 
624                 customJsps.add(customJsp);
625             }
626         }
627     }
628 
629     protected String getLocaleKey(String languagePropertiesLocation) {
630         int x = languagePropertiesLocation.indexOf(StringPool.UNDERLINE);
631         int y = languagePropertiesLocation.indexOf(".properties");
632 
633         if ((x != -1) && (y != 1)) {
634             String localeKey = languagePropertiesLocation.substring(x + 1, y);
635 
636             Locale locale = LocaleUtil.fromLanguageId(localeKey);
637 
638             locale = LanguageUtil.getLocale(locale.getLanguage());
639 
640             if (locale != null) {
641                 return locale.toString();
642             }
643         }
644 
645         return null;
646     }
647 
648     protected BasePersistence<?> getPersistence(String modelName) {
649         int pos = modelName.lastIndexOf(StringPool.PERIOD);
650 
651         String entityName = modelName.substring(pos + 1);
652 
653         pos = modelName.lastIndexOf(".model.");
654 
655         String packagePath = modelName.substring(0, pos);
656 
657         return (BasePersistence<?>)PortalBeanLocatorUtil.locate(
658             packagePath + ".service.persistence." + entityName + "Persistence");
659     }
660 
661     protected File getPortalJspBackupFile(File portalJspFile) {
662         String fileName = portalJspFile.toString();
663 
664         if (fileName.endsWith(".jsp")) {
665             fileName =
666                 fileName.substring(0, fileName.length() - 4) + ".portal.jsp";
667         }
668         else if (fileName.endsWith(".jspf")) {
669             fileName =
670                 fileName.substring(0, fileName.length() - 5) + ".portal.jspf";
671         }
672 
673         return new File(fileName);
674     }
675 
676     protected void initAuthenticators(
677             ClassLoader portletClassLoader, Properties portalProperties,
678             String key, AuthenticatorsContainer authenticatorsContainer)
679         throws Exception {
680 
681         String[] authenticatorClassNames = StringUtil.split(
682             portalProperties.getProperty(key));
683 
684         for (String authenticatorClassName : authenticatorClassNames) {
685             Authenticator authenticator =
686                 (Authenticator)portletClassLoader.loadClass(
687                     authenticatorClassName).newInstance();
688 
689             authenticator = (Authenticator)Proxy.newProxyInstance(
690                 portletClassLoader, new Class[] {Authenticator.class},
691                 new ContextClassLoaderBeanHandler(
692                     authenticator, portletClassLoader));
693 
694             authenticatorsContainer.registerAuthenticator(
695                 key, authenticator);
696         }
697     }
698 
699     protected void initAuthenticators(
700             String servletContextName, ClassLoader portletClassLoader,
701             Properties portalProperties)
702         throws Exception {
703 
704         AuthenticatorsContainer authenticatorsContainer =
705             new AuthenticatorsContainer();
706 
707         _authenticatorsContainerMap.put(
708             servletContextName, authenticatorsContainer);
709 
710         initAuthenticators(
711             portletClassLoader, portalProperties, AUTH_PIPELINE_PRE,
712             authenticatorsContainer);
713         initAuthenticators(
714             portletClassLoader, portalProperties, AUTH_PIPELINE_POST,
715             authenticatorsContainer);
716     }
717 
718     protected void initAuthFailures(
719             ClassLoader portletClassLoader, Properties portalProperties,
720             String key, AuthFailuresContainer authFailuresContainer)
721         throws Exception {
722 
723         String[] authFailureClassNames = StringUtil.split(
724             portalProperties.getProperty(key));
725 
726         for (String authFailureClassName : authFailureClassNames) {
727             AuthFailure authFailure = (AuthFailure)portletClassLoader.loadClass(
728                 authFailureClassName).newInstance();
729 
730             authFailure = (AuthFailure)Proxy.newProxyInstance(
731                 portletClassLoader, new Class[] {AuthFailure.class},
732                 new ContextClassLoaderBeanHandler(
733                     authFailure, portletClassLoader));
734 
735             authFailuresContainer.registerAuthFailure(
736                 key, authFailure);
737         }
738     }
739 
740     protected void initAuthFailures(
741             String servletContextName, ClassLoader portletClassLoader,
742             Properties portalProperties)
743         throws Exception {
744 
745         AuthFailuresContainer authFailuresContainer =
746             new AuthFailuresContainer();
747 
748         _authFailuresContainerMap.put(
749             servletContextName, authFailuresContainer);
750 
751         initAuthFailures(
752             portletClassLoader, portalProperties, AUTH_FAILURE,
753             authFailuresContainer);
754         initAuthFailures(
755             portletClassLoader, portalProperties, AUTH_MAX_FAILURES,
756             authFailuresContainer);
757     }
758 
759     protected void initAutoDeployListeners(
760             String servletContextName, ClassLoader portletClassLoader,
761             Properties portalProperties)
762         throws Exception {
763 
764         String[] autoDeployListenerClassNames = StringUtil.split(
765             portalProperties.getProperty(PropsKeys.AUTO_DEPLOY_LISTENERS));
766 
767         if (autoDeployListenerClassNames.length == 0) {
768             return;
769         }
770 
771         AutoDeployListenersContainer autoDeployListenersContainer =
772             new AutoDeployListenersContainer();
773 
774         _autoDeployListenersContainerMap.put(
775             servletContextName, autoDeployListenersContainer);
776 
777         for (String autoDeployListenerClassName :
778                 autoDeployListenerClassNames) {
779 
780             AutoDeployListener autoDeployListener =
781                 (AutoDeployListener)portletClassLoader.loadClass(
782                     autoDeployListenerClassName).newInstance();
783 
784             autoDeployListener = (AutoDeployListener)Proxy.newProxyInstance(
785                 portletClassLoader, new Class[] {AutoDeployListener.class},
786                 new ContextClassLoaderBeanHandler(
787                     autoDeployListener, portletClassLoader));
788 
789             autoDeployListenersContainer.registerAutoDeployListener(
790                 autoDeployListener);
791         }
792     }
793 
794     protected void initAutoLogins(
795             String servletContextName, ClassLoader portletClassLoader,
796             Properties portalProperties)
797         throws Exception {
798 
799         AutoLoginsContainer autoLoginsContainer = new AutoLoginsContainer();
800 
801         _autoLoginsContainerMap.put(servletContextName, autoLoginsContainer);
802 
803         String[] autoLoginClassNames = StringUtil.split(
804             portalProperties.getProperty(AUTO_LOGIN_HOOKS));
805 
806         for (String autoLoginClassName : autoLoginClassNames) {
807             AutoLogin autoLogin = (AutoLogin)portletClassLoader.loadClass(
808                 autoLoginClassName).newInstance();
809 
810             autoLogin = (AutoLogin)Proxy.newProxyInstance(
811                 portletClassLoader, new Class[] {AutoLogin.class},
812                 new ContextClassLoaderBeanHandler(
813                     autoLogin, portletClassLoader));
814 
815             autoLoginsContainer.registerAutoLogin(autoLogin);
816         }
817     }
818 
819     protected void initCustomJspBag(CustomJspBag customJspBag)
820         throws Exception {
821 
822         String customJspDir = customJspBag.getCustomJspDir();
823         List<String> customJsps = customJspBag.getCustomJsps();
824         //String timestamp = customJspBag.getTimestamp();
825 
826         String portalWebDir = PortalUtil.getPortalWebDir();
827 
828         for (String customJsp : customJsps) {
829             int pos = customJsp.indexOf(customJspDir);
830 
831             String portalJsp = customJsp.substring(
832                 pos + customJspDir.length(), customJsp.length());
833 
834             File portalJspFile = new File(portalWebDir + portalJsp);
835             File portalJspBackupFile = getPortalJspBackupFile(portalJspFile);
836 
837             if (portalJspFile.exists() && !portalJspBackupFile.exists()) {
838                 FileUtil.copyFile(portalJspFile, portalJspBackupFile);
839             }
840 
841             String customJspContent = FileUtil.read(customJsp);
842 
843             FileUtil.write(portalJspFile, customJspContent);
844         }
845     }
846 
847     protected Object initEvent(
848             String eventName, String eventClassName,
849             ClassLoader portletClassLoader)
850         throws Exception {
851 
852         if (eventName.equals(APPLICATION_STARTUP_EVENTS)) {
853             SimpleAction simpleAction =
854                 (SimpleAction)portletClassLoader.loadClass(
855                     eventClassName).newInstance();
856 
857             simpleAction = new InvokerSimpleAction(
858                 simpleAction, portletClassLoader);
859 
860             long companyId = CompanyThreadLocal.getCompanyId();
861 
862             long[] companyIds = PortalInstances.getCompanyIds();
863 
864             for (long curCompanyId : companyIds) {
865                 CompanyThreadLocal.setCompanyId(curCompanyId);
866 
867                 simpleAction.run(new String[] {String.valueOf(curCompanyId)});
868             }
869 
870             CompanyThreadLocal.setCompanyId(companyId);
871 
872             return null;
873         }
874 
875         if (ArrayUtil.contains(_PROPS_KEYS_EVENTS, eventName)) {
876             Action action = (Action)portletClassLoader.loadClass(
877                 eventClassName).newInstance();
878 
879             action = new InvokerAction(action, portletClassLoader);
880 
881             EventsProcessorUtil.registerEvent(eventName, action);
882 
883             return action;
884         }
885 
886         if (ArrayUtil.contains(_PROPS_KEYS_SESSION_EVENTS, eventName)) {
887             SessionAction sessionAction =
888                 (SessionAction)portletClassLoader.loadClass(
889                     eventClassName).newInstance();
890 
891             sessionAction = new InvokerSessionAction(
892                 sessionAction, portletClassLoader);
893 
894             EventsProcessorUtil.registerEvent(eventName, sessionAction);
895 
896             return sessionAction;
897         }
898 
899         return null;
900     }
901 
902     protected void initEvents(
903             String servletContextName, ClassLoader portletClassLoader,
904             Properties portalProperties)
905         throws Exception {
906 
907         EventsContainer eventsContainer = new EventsContainer();
908 
909         _eventsContainerMap.put(servletContextName, eventsContainer);
910 
911         Iterator<Object> itr = portalProperties.keySet().iterator();
912 
913         while (itr.hasNext()) {
914             String key = (String)itr.next();
915 
916             if (!key.equals(APPLICATION_STARTUP_EVENTS) &&
917                 !ArrayUtil.contains(_PROPS_KEYS_EVENTS, key) &&
918                 !ArrayUtil.contains(_PROPS_KEYS_SESSION_EVENTS, key)) {
919 
920                 continue;
921             }
922 
923             String eventName = key;
924             String[] eventClassNames = StringUtil.split(
925                 portalProperties.getProperty(key));
926 
927             for (String eventClassName : eventClassNames) {
928                 Object obj = initEvent(
929                     eventName, eventClassName, portletClassLoader);
930 
931                 if (obj == null) {
932                     continue;
933                 }
934 
935                 eventsContainer.registerEvent(eventName, obj);
936             }
937         }
938     }
939 
940     protected void initHotDeployListeners(
941             String servletContextName, ClassLoader portletClassLoader,
942             Properties portalProperties)
943         throws Exception {
944 
945         String[] hotDeployListenerClassNames = StringUtil.split(
946             portalProperties.getProperty(PropsKeys.HOT_DEPLOY_LISTENERS));
947 
948         if (hotDeployListenerClassNames.length == 0) {
949             return;
950         }
951 
952         HotDeployListenersContainer hotDeployListenersContainer =
953             new HotDeployListenersContainer();
954 
955         _hotDeployListenersContainerMap.put(
956             servletContextName, hotDeployListenersContainer);
957 
958         for (String hotDeployListenerClassName : hotDeployListenerClassNames) {
959             HotDeployListener hotDeployListener =
960                 (HotDeployListener)portletClassLoader.loadClass(
961                     hotDeployListenerClassName).newInstance();
962 
963             hotDeployListener = (HotDeployListener)Proxy.newProxyInstance(
964                 portletClassLoader, new Class[] {HotDeployListener.class},
965                 new ContextClassLoaderBeanHandler(
966                     hotDeployListener, portletClassLoader));
967 
968             hotDeployListenersContainer.registerHotDeployListener(
969                 hotDeployListener);
970         }
971     }
972 
973     @SuppressWarnings("unchecked")
974     protected ModelListener<BaseModel<?>> initModelListener(
975             String modelName, String modelListenerClassName,
976             ClassLoader portletClassLoader)
977         throws Exception {
978 
979         ModelListener<BaseModel<?>> modelListener =
980             (ModelListener<BaseModel<?>>)portletClassLoader.loadClass(
981                 modelListenerClassName).newInstance();
982 
983         modelListener = (ModelListener<BaseModel<?>>)Proxy.newProxyInstance(
984             portletClassLoader, new Class[] {ModelListener.class},
985             new ContextClassLoaderBeanHandler(
986                 modelListener, portletClassLoader));
987 
988         BasePersistence persistence = getPersistence(modelName);
989 
990         persistence.registerListener(modelListener);
991 
992         return modelListener;
993     }
994 
995     protected void initModelListeners(
996             String servletContextName, ClassLoader portletClassLoader,
997             Properties portalProperties)
998         throws Exception {
999 
1000        ModelListenersContainer modelListenersContainer =
1001            new ModelListenersContainer();
1002
1003        _modelListenersContainerMap.put(
1004            servletContextName, modelListenersContainer);
1005
1006        Iterator<Object> itr = portalProperties.keySet().iterator();
1007
1008        while (itr.hasNext()) {
1009            String key = (String)itr.next();
1010
1011            if (!key.startsWith(VALUE_OBJECT_LISTENER)) {
1012                continue;
1013            }
1014
1015            String modelName = key.substring(VALUE_OBJECT_LISTENER.length());
1016            String modelListenerClassName = portalProperties.getProperty(key);
1017
1018            ModelListener<BaseModel<?>> modelListener = initModelListener(
1019                modelName, modelListenerClassName, portletClassLoader);
1020
1021            if (modelListener != null) {
1022                modelListenersContainer.registerModelListener(
1023                    modelName, modelListener);
1024            }
1025        }
1026    }
1027
1028    protected void initPortalProperties(
1029            String servletContextName, ClassLoader portletClassLoader,
1030            Properties portalProperties)
1031        throws Exception {
1032
1033        PropsUtil.addProperties(portalProperties);
1034
1035        if (_log.isDebugEnabled() && portalProperties.containsKey(LOCALES)) {
1036            _log.debug(
1037                "Portlet locales " + portalProperties.getProperty(LOCALES));
1038            _log.debug("Merged locales " + PropsUtil.get(LOCALES));
1039            _log.debug(
1040                "Merged locales array length " +
1041                    PropsUtil.getArray(LOCALES).length);
1042        }
1043
1044        resetPortalProperties(servletContextName, portalProperties, true);
1045
1046        if (portalProperties.containsKey(
1047                PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS)) {
1048
1049            String controlPanelEntryClassName = portalProperties.getProperty(
1050                PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS);
1051
1052            ControlPanelEntry controlPanelEntry =
1053                (ControlPanelEntry)portletClassLoader.loadClass(
1054                    controlPanelEntryClassName).newInstance();
1055
1056            controlPanelEntry = (ControlPanelEntry)Proxy.newProxyInstance(
1057                portletClassLoader, new Class[] {ControlPanelEntry.class},
1058                new ContextClassLoaderBeanHandler(
1059                    controlPanelEntry, portletClassLoader));
1060
1061            DefaultControlPanelEntryFactory.setInstance(controlPanelEntry);
1062        }
1063
1064        if (portalProperties.containsKey(PropsKeys.DL_HOOK_IMPL)) {
1065            String dlHookClassName = portalProperties.getProperty(
1066                PropsKeys.DL_HOOK_IMPL);
1067
1068            com.liferay.documentlibrary.util.Hook dlHook =
1069                (com.liferay.documentlibrary.util.Hook)
1070                    portletClassLoader.loadClass(dlHookClassName).newInstance();
1071
1072            dlHook =
1073                (com.liferay.documentlibrary.util.Hook)Proxy.newProxyInstance(
1074                    portletClassLoader,
1075                    new Class[] {com.liferay.documentlibrary.util.Hook.class},
1076                    new ContextClassLoaderBeanHandler(
1077                        dlHook, portletClassLoader));
1078
1079            com.liferay.documentlibrary.util.HookFactory.setInstance(dlHook);
1080        }
1081
1082        if (portalProperties.containsKey(PropsKeys.IMAGE_HOOK_IMPL)) {
1083            String imageHookClassName = portalProperties.getProperty(
1084                PropsKeys.IMAGE_HOOK_IMPL);
1085
1086            com.liferay.portal.image.Hook imageHook =
1087                (com.liferay.portal.image.Hook)portletClassLoader.loadClass(
1088                    imageHookClassName).newInstance();
1089
1090            imageHook =
1091                (com.liferay.portal.image.Hook)Proxy.newProxyInstance(
1092                    portletClassLoader,
1093                    new Class[] {com.liferay.portal.image.Hook.class},
1094                    new ContextClassLoaderBeanHandler(
1095                        imageHook, portletClassLoader));
1096
1097            com.liferay.portal.image.HookFactory.setInstance(imageHook);
1098        }
1099
1100        if (portalProperties.containsKey(
1101                PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL)) {
1102
1103            String attributesTransformerClassName =
1104                portalProperties.getProperty(
1105                    PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL);
1106
1107            AttributesTransformer attributesTransformer =
1108                (AttributesTransformer)portletClassLoader.loadClass(
1109                    attributesTransformerClassName).newInstance();
1110
1111            attributesTransformer =
1112                (AttributesTransformer)Proxy.newProxyInstance(
1113                    portletClassLoader,
1114                    new Class[] {AttributesTransformer.class},
1115                    new ContextClassLoaderBeanHandler(
1116                        attributesTransformer, portletClassLoader));
1117
1118            AttributesTransformerFactory.setInstance(attributesTransformer);
1119        }
1120
1121        if (portalProperties.containsKey(PropsKeys.MAIL_HOOK_IMPL)) {
1122            String mailHookClassName = portalProperties.getProperty(
1123                PropsKeys.MAIL_HOOK_IMPL);
1124
1125            com.liferay.mail.util.Hook mailHook =
1126                (com.liferay.mail.util.Hook)portletClassLoader.loadClass(
1127                    mailHookClassName).newInstance();
1128
1129            mailHook =
1130                (com.liferay.mail.util.Hook)Proxy.newProxyInstance(
1131                    portletClassLoader,
1132                    new Class[] {com.liferay.mail.util.Hook.class},
1133                    new ContextClassLoaderBeanHandler(
1134                        mailHook, portletClassLoader));
1135
1136            com.liferay.mail.util.HookFactory.setInstance(mailHook);
1137        }
1138
1139        if (portalProperties.containsKey(
1140                PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR)) {
1141
1142            String emailAddressGeneratorClassName =
1143                portalProperties.getProperty(
1144                    PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR);
1145
1146            EmailAddressGenerator emailAddressGenerator =
1147                (EmailAddressGenerator)portletClassLoader.loadClass(
1148                    emailAddressGeneratorClassName).newInstance();
1149
1150            emailAddressGenerator =
1151                (EmailAddressGenerator)Proxy.newProxyInstance(
1152                    portletClassLoader,
1153                    new Class[] {EmailAddressGenerator.class},
1154                    new ContextClassLoaderBeanHandler(
1155                        emailAddressGenerator, portletClassLoader));
1156
1157            EmailAddressGeneratorFactory.setInstance(emailAddressGenerator);
1158        }
1159
1160        if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_VALIDATOR)) {
1161            String fullNameValidatorClassName = portalProperties.getProperty(
1162                PropsKeys.USERS_FULL_NAME_VALIDATOR);
1163
1164            FullNameValidator fullNameValidator =
1165                (FullNameValidator)portletClassLoader.loadClass(
1166                    fullNameValidatorClassName).newInstance();
1167
1168            fullNameValidator = (FullNameValidator)Proxy.newProxyInstance(
1169                portletClassLoader, new Class[] {FullNameValidator.class},
1170                new ContextClassLoaderBeanHandler(
1171                    fullNameValidator, portletClassLoader));
1172
1173            FullNameValidatorFactory.setInstance(fullNameValidator);
1174        }
1175
1176        if (portalProperties.containsKey(
1177                PropsKeys.USERS_SCREEN_NAME_GENERATOR)) {
1178
1179            String screenNameGeneratorClassName = portalProperties.getProperty(
1180                PropsKeys.USERS_SCREEN_NAME_GENERATOR);
1181
1182            ScreenNameGenerator screenNameGenerator =
1183                (ScreenNameGenerator)portletClassLoader.loadClass(
1184                    screenNameGeneratorClassName).newInstance();
1185
1186            screenNameGenerator = (ScreenNameGenerator)Proxy.newProxyInstance(
1187                portletClassLoader, new Class[] {ScreenNameGenerator.class},
1188                new ContextClassLoaderBeanHandler(
1189                    screenNameGenerator, portletClassLoader));
1190
1191            ScreenNameGeneratorFactory.setInstance(screenNameGenerator);
1192        }
1193
1194        if (portalProperties.containsKey(
1195                PropsKeys.USERS_SCREEN_NAME_VALIDATOR)) {
1196
1197            String screenNameValidatorClassName = portalProperties.getProperty(
1198                PropsKeys.USERS_SCREEN_NAME_VALIDATOR);
1199
1200            ScreenNameValidator screenNameValidator =
1201                (ScreenNameValidator)portletClassLoader.loadClass(
1202                    screenNameValidatorClassName).newInstance();
1203
1204            screenNameValidator = (ScreenNameValidator)Proxy.newProxyInstance(
1205                portletClassLoader, new Class[] {ScreenNameValidator.class},
1206                new ContextClassLoaderBeanHandler(
1207                    screenNameValidator, portletClassLoader));
1208
1209            ScreenNameValidatorFactory.setInstance(screenNameValidator);
1210        }
1211
1212        if (portalProperties.containsKey(PropsKeys.RELEASE_INFO_BUILD_NUMBER) ||
1213            portalProperties.containsKey(PropsKeys.UPGRADE_PROCESSES)) {
1214
1215            updateRelease(
1216                servletContextName, portletClassLoader, portalProperties);
1217        }
1218    }
1219
1220    protected void resetPortalProperties(
1221            String servletContextName, Properties portalProperties,
1222            boolean initPhase)
1223        throws Exception {
1224
1225        for (String key : _PROPS_VALUES_BOOLEAN) {
1226            String fieldName = StringUtil.replace(
1227                key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1228
1229            if (!containsKey(portalProperties, key)) {
1230                continue;
1231            }
1232
1233            try {
1234                Field field = PropsValues.class.getField(fieldName);
1235
1236                Boolean value = Boolean.valueOf(GetterUtil.getBoolean(
1237                    PropsUtil.get(key)));
1238
1239                field.setBoolean(null, value);
1240            }
1241            catch (Exception e) {
1242                _log.error(
1243                    "Error setting field " + fieldName + ": " + e.getMessage());
1244            }
1245        }
1246
1247        for (String key : _PROPS_VALUES_INTEGER) {
1248            String fieldName = StringUtil.replace(
1249                key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1250
1251            if (!containsKey(portalProperties, key)) {
1252                continue;
1253            }
1254
1255            try {
1256                Field field = PropsValues.class.getField(fieldName);
1257
1258                Integer value = Integer.valueOf(GetterUtil.getInteger(
1259                    PropsUtil.get(key)));
1260
1261                field.setInt(null, value);
1262            }
1263            catch (Exception e) {
1264                _log.error(
1265                    "Error setting field " + fieldName + ": " + e.getMessage());
1266            }
1267        }
1268
1269        for (String key : _PROPS_VALUES_LONG) {
1270            String fieldName = StringUtil.replace(
1271                key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1272
1273            if (!containsKey(portalProperties, key)) {
1274                continue;
1275            }
1276
1277            try {
1278                Field field = PropsValues.class.getField(fieldName);
1279
1280                Long value = Long.valueOf(GetterUtil.getLong(
1281                    PropsUtil.get(key)));
1282
1283                field.setLong(null, value);
1284            }
1285            catch (Exception e) {
1286                _log.error(
1287                    "Error setting field " + fieldName + ": " + e.getMessage());
1288            }
1289        }
1290
1291        for (String key : _PROPS_VALUES_STRING) {
1292            String fieldName = StringUtil.replace(
1293                key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1294
1295            if (!containsKey(portalProperties, key)) {
1296                continue;
1297            }
1298
1299            try {
1300                Field field = PropsValues.class.getField(fieldName);
1301
1302                String value = GetterUtil.getString(PropsUtil.get(key));
1303
1304                field.set(null, value);
1305            }
1306            catch (Exception e) {
1307                _log.error(
1308                    "Error setting field " + fieldName + ": " + e.getMessage());
1309            }
1310        }
1311
1312        for (String key : _PROPS_VALUES_STRING_ARRAY) {
1313            String fieldName = StringUtil.replace(
1314                key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1315
1316            if (!containsKey(portalProperties, key)) {
1317                continue;
1318            }
1319
1320            try {
1321                Field field = PropsValues.class.getField(fieldName);
1322
1323                StringArraysContainer stringArraysContainer =
1324                    _stringArraysContainerMap.get(key);
1325
1326                String[] value = null;
1327
1328                if (initPhase) {
1329                    value = PropsUtil.getArray(key);
1330                }
1331
1332                stringArraysContainer.setPluginStringArray(
1333                    servletContextName, value);
1334
1335                value = stringArraysContainer.getMergedStringArray();
1336
1337                field.set(null, value);
1338            }
1339            catch (Exception e) {
1340                _log.error(
1341                    "Error setting field " + fieldName + ": " + e.getMessage());
1342            }
1343        }
1344
1345        if (containsKey(portalProperties, LOCALES)) {
1346            PropsValues.LOCALES = PropsUtil.getArray(LOCALES);
1347
1348            LanguageUtil.init();
1349        }
1350
1351        CacheUtil.clearCache();
1352    }
1353
1354    protected void updateRelease(
1355            String servletContextName, ClassLoader portletClassLoader,
1356            Properties portalProperties)
1357        throws Exception {
1358
1359        int buildNumber = GetterUtil.getInteger(
1360            portalProperties.getProperty(PropsKeys.RELEASE_INFO_BUILD_NUMBER));
1361
1362        if (buildNumber <= 0) {
1363            _log.error(
1364                "Skipping upgrade processes for " + servletContextName +
1365                    " because \"release.info.build.number\" is not specified");
1366
1367            return;
1368        }
1369
1370        Release release = null;
1371
1372        try {
1373            release = ReleaseLocalServiceUtil.getRelease(
1374                servletContextName, buildNumber);
1375        }
1376        catch (PortalException pe) {
1377            int previousBuildNumber = GetterUtil.getInteger(
1378                portalProperties.getProperty(
1379                    PropsKeys.RELEASE_INFO_PREVIOUS_BUILD_NUMBER),
1380                buildNumber);
1381
1382            release = ReleaseLocalServiceUtil.addRelease(
1383                servletContextName, previousBuildNumber);
1384        }
1385
1386        if (buildNumber == release.getBuildNumber()) {
1387            if (_log.isDebugEnabled()) {
1388                _log.debug(
1389                    "Skipping upgrade processes for " + servletContextName +
1390                        " because it is already up to date");
1391            }
1392        }
1393        else if (buildNumber < release.getBuildNumber()) {
1394            throw new UpgradeException(
1395                "Skipping upgrade processes for " + servletContextName +
1396                    " because you are trying to upgrade with an older version");
1397        }
1398        else {
1399            String[] upgradeProcessClassNames = StringUtil.split(
1400                portalProperties.getProperty(PropsKeys.UPGRADE_PROCESSES));
1401
1402            UpgradeProcessUtil.upgradeProcess(
1403                release.getBuildNumber(), upgradeProcessClassNames,
1404                portletClassLoader);
1405        }
1406
1407        ReleaseLocalServiceUtil.updateRelease(
1408            release.getReleaseId(), buildNumber, null, true);
1409    }
1410
1411    private static final String[] _PROPS_KEYS_EVENTS = new String[] {
1412        LOGIN_EVENTS_POST,
1413        LOGIN_EVENTS_PRE,
1414        LOGOUT_EVENTS_POST,
1415        LOGOUT_EVENTS_PRE,
1416        SERVLET_SERVICE_EVENTS_POST,
1417        SERVLET_SERVICE_EVENTS_PRE
1418    };
1419
1420    private static final String[] _PROPS_KEYS_SESSION_EVENTS = new String[] {
1421        SERVLET_SESSION_CREATE_EVENTS,
1422        SERVLET_SESSION_DESTROY_EVENTS
1423    };
1424
1425    private static final String[] _PROPS_VALUES_BOOLEAN = new String[] {
1426        "auth.forward.by.last.path",
1427        "captcha.check.portal.create_account",
1428        "field.enable.com.liferay.portal.model.Contact.birthday",
1429        "field.enable.com.liferay.portal.model.Contact.male",
1430        "field.enable.com.liferay.portal.model.Organization.status",
1431        "javascript.fast.load",
1432        "layout.template.cache.enabled",
1433        "layout.user.private.layouts.auto.create",
1434        "layout.user.private.layouts.enabled",
1435        "layout.user.private.layouts.modifiable",
1436        "layout.user.public.layouts.auto.create",
1437        "layout.user.public.layouts.enabled",
1438        "layout.user.public.layouts.modifiable",
1439        "login.create.account.allow.custom.password",
1440        "my.places.show.community.private.sites.with.no.layouts",
1441        "my.places.show.community.public.sites.with.no.layouts",
1442        "my.places.show.organization.private.sites.with.no.layouts",
1443        "my.places.show.organization.public.sites.with.no.layouts",
1444        "my.places.show.user.private.sites.with.no.layouts",
1445        "my.places.show.user.public.sites.with.no.layouts",
1446        "terms.of.use.required",
1447        "theme.css.fast.load",
1448        "theme.images.fast.load",
1449        "users.email.address.required",
1450        "users.screen.name.always.autogenerate"
1451    };
1452
1453    private static final String[] _PROPS_VALUES_INTEGER = new String[] {
1454    };
1455
1456    private static final String[] _PROPS_VALUES_LONG = new String[] {
1457    };
1458
1459    private static final String[] _PROPS_VALUES_STRING = new String[] {
1460        "default.landing.page.path",
1461        "passwords.passwordpolicytoolkit.generator",
1462        "passwords.passwordpolicytoolkit.static"
1463    };
1464
1465    private static final String[] _PROPS_VALUES_STRING_ARRAY = new String[] {
1466        "layout.static.portlets.all",
1467        "session.phishing.protected.attributes"
1468    };
1469
1470    private static Log _log =
1471        LogFactoryUtil.getLog(HookHotDeployListener.class);
1472
1473    private Map<String, AuthenticatorsContainer> _authenticatorsContainerMap =
1474        new HashMap<String, AuthenticatorsContainer>();
1475    private Map<String, AuthFailuresContainer> _authFailuresContainerMap =
1476        new HashMap<String, AuthFailuresContainer>();
1477    private Map<String, AutoDeployListenersContainer>
1478        _autoDeployListenersContainerMap =
1479            new HashMap<String, AutoDeployListenersContainer>();
1480    private Map<String, AutoLoginsContainer> _autoLoginsContainerMap =
1481        new HashMap<String, AutoLoginsContainer>();
1482    private Map<String, CustomJspBag> _customJspBagsMap =
1483        new HashMap<String, CustomJspBag>();
1484    private Map<String, EventsContainer> _eventsContainerMap =
1485        new HashMap<String, EventsContainer>();
1486    private Map<String, HotDeployListenersContainer>
1487        _hotDeployListenersContainerMap =
1488            new HashMap<String, HotDeployListenersContainer>();
1489    private Map<String, LanguagesContainer> _languagesContainerMap =
1490        new HashMap<String, LanguagesContainer>();
1491    private Map<String, ModelListenersContainer> _modelListenersContainerMap =
1492        new HashMap<String, ModelListenersContainer>();
1493    private Map<String, Properties> _portalPropertiesMap =
1494        new HashMap<String, Properties>();
1495    private Map<String, ServicesContainer> _servicesContainerMap =
1496        new HashMap<String, ServicesContainer>();
1497    private Set<String> _servletContextNames = new HashSet<String>();
1498    private Map<String, StringArraysContainer> _stringArraysContainerMap =
1499        new HashMap<String, StringArraysContainer>();
1500
1501    private class AuthenticatorsContainer {
1502
1503        public void registerAuthenticator(
1504            String key, Authenticator authenticator) {
1505
1506            List<Authenticator> authenticators = _authenticators.get(key);
1507
1508            if (authenticators == null) {
1509                authenticators = new ArrayList<Authenticator>();
1510
1511                _authenticators.put(key, authenticators);
1512            }
1513
1514            AuthPipeline.registerAuthenticator(key, authenticator);
1515
1516            authenticators.add(authenticator);
1517        }
1518
1519        public void unregisterAuthenticators() {
1520            for (Map.Entry<String, List<Authenticator>> entry :
1521                    _authenticators.entrySet()) {
1522
1523                String key = entry.getKey();
1524                List<Authenticator> authenticators = entry.getValue();
1525
1526                for (Authenticator authenticator : authenticators) {
1527                    AuthPipeline.unregisterAuthenticator(key, authenticator);
1528                }
1529            }
1530        }
1531
1532        Map<String, List<Authenticator>> _authenticators =
1533            new HashMap<String, List<Authenticator>>();
1534
1535    }
1536
1537    private class AuthFailuresContainer {
1538
1539        public void registerAuthFailure(String key, AuthFailure authFailure) {
1540            List<AuthFailure> authFailures = _authFailures.get(key);
1541
1542            if (authFailures == null) {
1543                authFailures = new ArrayList<AuthFailure>();
1544
1545                _authFailures.put(key, authFailures);
1546            }
1547
1548            AuthPipeline.registerAuthFailure(key, authFailure);
1549
1550            authFailures.add(authFailure);
1551        }
1552
1553        public void unregisterAuthFailures() {
1554            for (Map.Entry<String, List<AuthFailure>> entry :
1555                    _authFailures.entrySet()) {
1556
1557                String key = entry.getKey();
1558                List<AuthFailure> authFailures = entry.getValue();
1559
1560                for (AuthFailure authFailure : authFailures) {
1561                    AuthPipeline.unregisterAuthFailure(key, authFailure);
1562                }
1563            }
1564        }
1565
1566        Map<String, List<AuthFailure>> _authFailures =
1567            new HashMap<String, List<AuthFailure>>();
1568
1569    }
1570
1571    private class AutoDeployListenersContainer {
1572
1573        public void registerAutoDeployListener(
1574            AutoDeployListener autoDeployListener) {
1575
1576            AutoDeployDir autoDeployDir = AutoDeployUtil.getDir(
1577                AutoDeployDir.DEFAULT_NAME);
1578
1579            if (autoDeployDir == null) {
1580                return;
1581            }
1582
1583            autoDeployDir.registerListener(autoDeployListener);
1584
1585            _autoDeployListeners.add(autoDeployListener);
1586        }
1587
1588        public void unregisterAutoDeployListeners() {
1589            AutoDeployDir autoDeployDir = AutoDeployUtil.getDir(
1590                AutoDeployDir.DEFAULT_NAME);
1591
1592            if (autoDeployDir == null) {
1593                return;
1594            }
1595
1596            for (AutoDeployListener autoDeployListener : _autoDeployListeners) {
1597                autoDeployDir.unregisterListener(autoDeployListener);
1598            }
1599        }
1600
1601        private List<AutoDeployListener> _autoDeployListeners =
1602            new ArrayList<AutoDeployListener>();
1603
1604    }
1605
1606    private class AutoLoginsContainer {
1607
1608        public void registerAutoLogin(AutoLogin autoLogin) {
1609            AutoLoginFilter.registerAutoLogin(autoLogin);
1610
1611            _autoLogins.add(autoLogin);
1612        }
1613
1614        public void unregisterAutoLogins() {
1615            for (AutoLogin autoLogin : _autoLogins) {
1616                AutoLoginFilter.unregisterAutoLogin(autoLogin);
1617            }
1618        }
1619
1620        List<AutoLogin> _autoLogins = new ArrayList<AutoLogin>();
1621
1622    }
1623
1624    private class CustomJspBag {
1625
1626        public CustomJspBag(String customJspDir, List<String> customJsps) {
1627            _customJspDir = customJspDir;
1628            _customJsps = customJsps;
1629        }
1630
1631        public String getCustomJspDir() {
1632            return _customJspDir;
1633        }
1634
1635        public List<String> getCustomJsps() {
1636            return _customJsps;
1637        }
1638
1639        private String _customJspDir;
1640        private List<String> _customJsps;
1641
1642    }
1643
1644    private class EventsContainer {
1645
1646        public void registerEvent(String eventName, Object event) {
1647            List<Object> events = _eventsMap.get(eventName);
1648
1649            if (events == null) {
1650                events = new ArrayList<Object>();
1651
1652                _eventsMap.put(eventName, events);
1653            }
1654
1655            events.add(event);
1656        }
1657
1658        public void unregisterEvents() {
1659            for (Map.Entry<String, List<Object>> entry :
1660                    _eventsMap.entrySet()) {
1661
1662                String eventName = entry.getKey();
1663                List<Object> events = entry.getValue();
1664
1665                for (Object event : events) {
1666                    EventsProcessorUtil.unregisterEvent(eventName, event);
1667                }
1668            }
1669        }
1670
1671        private Map<String, List<Object>> _eventsMap =
1672            new HashMap<String, List<Object>>();
1673
1674    }
1675
1676    private class HotDeployListenersContainer {
1677
1678        public void registerHotDeployListener(
1679            HotDeployListener hotDeployListener) {
1680
1681            HotDeployUtil.registerListener(hotDeployListener);
1682
1683            _hotDeployListeners.add(hotDeployListener);
1684        }
1685
1686        public void unregisterHotDeployListeners() {
1687            for (HotDeployListener hotDeployListener : _hotDeployListeners) {
1688                HotDeployUtil.unregisterListener(hotDeployListener);
1689            }
1690        }
1691
1692        private List<HotDeployListener> _hotDeployListeners =
1693            new ArrayList<HotDeployListener>();
1694
1695    }
1696
1697    private class LanguagesContainer {
1698
1699        public void addLanguage(String localeKey, Properties properties) {
1700            _multiMessageResources.putLocale(localeKey);
1701
1702            Properties oldProperties = _multiMessageResources.putMessages(
1703                properties, localeKey);
1704
1705            _languagesMap.put(localeKey, oldProperties);
1706
1707            LanguageResources.clearCache();
1708        }
1709
1710        public void unregisterLanguages() {
1711            for (String key : _languagesMap.keySet()) {
1712                Properties properties = _languagesMap.get(key);
1713
1714                _multiMessageResources.putMessages(properties, key);
1715            }
1716
1717            LanguageResources.clearCache();
1718        }
1719
1720        private Map<String, Properties> _languagesMap =
1721            new HashMap<String, Properties>();
1722        private MultiMessageResources _multiMessageResources =
1723            MultiMessageResourcesFactory.getInstance();
1724
1725    }
1726
1727    private class ModelListenersContainer {
1728
1729        public void registerModelListener(
1730            String modelName, ModelListener<BaseModel<?>> modelListener) {
1731
1732            List<ModelListener<BaseModel<?>>> modelListeners =
1733                _modelListenersMap.get(modelName);
1734
1735            if (modelListeners == null) {
1736                modelListeners = new ArrayList<ModelListener<BaseModel<?>>>();
1737
1738                _modelListenersMap.put(modelName, modelListeners);
1739            }
1740
1741            modelListeners.add(modelListener);
1742        }
1743
1744        @SuppressWarnings("unchecked")
1745        public void unregisterModelListeners() {
1746            for (Map.Entry<String, List<ModelListener<BaseModel<?>>>> entry :
1747                    _modelListenersMap.entrySet()) {
1748
1749                String modelName = entry.getKey();
1750                List<ModelListener<BaseModel<?>>> modelListeners =
1751                    entry.getValue();
1752
1753                BasePersistence persistence = getPersistence(modelName);
1754
1755                for (ModelListener<BaseModel<?>> modelListener :
1756                        modelListeners) {
1757
1758                    persistence.unregisterListener(modelListener);
1759                }
1760            }
1761        }
1762
1763        private Map<String, List<ModelListener<BaseModel<?>>>>
1764            _modelListenersMap =
1765                new HashMap<String, List<ModelListener<BaseModel<?>>>>();
1766
1767    }
1768
1769    private class ServicesContainer {
1770
1771        public void addService(String serviceType, Object serviceImplInstance) {
1772            ServiceHookAdvice.setService(serviceType, serviceImplInstance);
1773
1774            _serviceTypes.add(serviceType);
1775        }
1776
1777        public void unregisterServices() {
1778            for (String serviceType : _serviceTypes) {
1779                ServiceHookAdvice.setService(serviceType, null);
1780            }
1781        }
1782
1783        private List<String> _serviceTypes = new ArrayList<String>();
1784
1785    }
1786
1787    private class StringArraysContainer {
1788
1789        private StringArraysContainer(String key) {
1790            _portalStringArray = PropsUtil.getArray(key);
1791        }
1792
1793        public String[] getMergedStringArray() {
1794            List<String> mergedStringList = new UniqueList<String>();
1795
1796            mergedStringList.addAll(ListUtil.fromArray(_portalStringArray));
1797
1798            for (Map.Entry<String, String[]> entry :
1799                    _pluginStringArrayMap.entrySet()) {
1800
1801                String[] pluginStringArray = entry.getValue();
1802
1803                mergedStringList.addAll(ListUtil.fromArray(pluginStringArray));
1804            }
1805
1806            return mergedStringList.toArray(
1807                new String[mergedStringList.size()]);
1808        }
1809
1810        public void setPluginStringArray(
1811            String servletContextName, String[] pluginStringArray) {
1812
1813            if (pluginStringArray != null) {
1814                _pluginStringArrayMap.put(
1815                    servletContextName, pluginStringArray);
1816            }
1817            else {
1818                _pluginStringArrayMap.remove(servletContextName);
1819            }
1820        }
1821
1822        private String[] _portalStringArray;
1823        private Map<String, String[]> _pluginStringArrayMap =
1824            new HashMap<String, String[]>();
1825
1826    }
1827
1828}