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