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