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