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                    for (Map.Entry<Object, Object> entry : portalProperties.entrySet()) {
1045                            String key = (String)entry.getKey();
1046    
1047                            if (!key.equals(APPLICATION_STARTUP_EVENTS) &&
1048                                    !ArrayUtil.contains(_PROPS_KEYS_EVENTS, key) &&
1049                                    !ArrayUtil.contains(_PROPS_KEYS_SESSION_EVENTS, key)) {
1050    
1051                                    continue;
1052                            }
1053    
1054                            String eventName = key;
1055                            String[] eventClassNames = StringUtil.split(
1056                                    (String)entry.getValue());
1057    
1058                            for (String eventClassName : eventClassNames) {
1059                                    Object obj = initEvent(
1060                                            eventName, eventClassName, portletClassLoader);
1061    
1062                                    if (obj == null) {
1063                                            continue;
1064                                    }
1065    
1066                                    eventsContainer.registerEvent(eventName, obj);
1067                            }
1068                    }
1069            }
1070    
1071            protected void initHotDeployListeners(
1072                            String servletContextName, ClassLoader portletClassLoader,
1073                            Properties portalProperties)
1074                    throws Exception {
1075    
1076                    String[] hotDeployListenerClassNames = StringUtil.split(
1077                            portalProperties.getProperty(PropsKeys.HOT_DEPLOY_LISTENERS));
1078    
1079                    if (hotDeployListenerClassNames.length == 0) {
1080                            return;
1081                    }
1082    
1083                    HotDeployListenersContainer hotDeployListenersContainer =
1084                            new HotDeployListenersContainer();
1085    
1086                    _hotDeployListenersContainerMap.put(
1087                            servletContextName, hotDeployListenersContainer);
1088    
1089                    for (String hotDeployListenerClassName : hotDeployListenerClassNames) {
1090                            HotDeployListener hotDeployListener =
1091                                    (HotDeployListener)newInstance(
1092                                            portletClassLoader, HotDeployListener.class,
1093                                            hotDeployListenerClassName);
1094    
1095                            hotDeployListenersContainer.registerHotDeployListener(
1096                                    hotDeployListener);
1097                    }
1098            }
1099    
1100            protected void initLogger(ClassLoader portletClassLoader) {
1101                    Log4JUtil.configureLog4J(
1102                            portletClassLoader.getResource("META-INF/portal-log4j.xml"));
1103            }
1104    
1105            @SuppressWarnings("unchecked")
1106            protected ModelListener<BaseModel<?>> initModelListener(
1107                            String modelName, String modelListenerClassName,
1108                            ClassLoader portletClassLoader)
1109                    throws Exception {
1110    
1111                    ModelListener<BaseModel<?>> modelListener =
1112                            (ModelListener<BaseModel<?>>)newInstance(
1113                                    portletClassLoader, ModelListener.class,
1114                                    modelListenerClassName);
1115    
1116                    BasePersistence persistence = getPersistence(modelName);
1117    
1118                    persistence.registerListener(modelListener);
1119    
1120                    return modelListener;
1121            }
1122    
1123            protected void initModelListeners(
1124                            String servletContextName, ClassLoader portletClassLoader,
1125                            Properties portalProperties)
1126                    throws Exception {
1127    
1128                    ModelListenersContainer modelListenersContainer =
1129                            new ModelListenersContainer();
1130    
1131                    _modelListenersContainerMap.put(
1132                            servletContextName, modelListenersContainer);
1133    
1134                    for (Map.Entry<Object, Object> entry : portalProperties.entrySet()) {
1135                            String key = (String)entry.getKey();
1136    
1137                            if (!key.startsWith(VALUE_OBJECT_LISTENER)) {
1138                                    continue;
1139                            }
1140    
1141                            String modelName = key.substring(VALUE_OBJECT_LISTENER.length());
1142    
1143                            String[] modelListenerClassNames = StringUtil.split(
1144                                    (String)entry.getValue());
1145    
1146                            for (String modelListenerClassName : modelListenerClassNames) {
1147                                    ModelListener<BaseModel<?>> modelListener = initModelListener(
1148                                            modelName, modelListenerClassName, portletClassLoader);
1149    
1150                                    if (modelListener != null) {
1151                                            modelListenersContainer.registerModelListener(
1152                                                    modelName, modelListener);
1153                                    }
1154                            }
1155                    }
1156            }
1157    
1158            protected void initPortalProperties(
1159                            String servletContextName, ClassLoader portletClassLoader,
1160                            Properties portalProperties)
1161                    throws Exception {
1162    
1163                    PropsUtil.addProperties(portalProperties);
1164    
1165                    if (_log.isDebugEnabled() && portalProperties.containsKey(LOCALES)) {
1166                            _log.debug(
1167                                    "Portlet locales " + portalProperties.getProperty(LOCALES));
1168                            _log.debug("Merged locales " + PropsUtil.get(LOCALES));
1169                            _log.debug(
1170                                    "Merged locales array length " +
1171                                            PropsUtil.getArray(LOCALES).length);
1172                    }
1173    
1174                    resetPortalProperties(servletContextName, portalProperties, true);
1175    
1176                    if (portalProperties.containsKey(PropsKeys.AUTH_TOKEN_IMPL)) {
1177                            String authTokenClassName = portalProperties.getProperty(
1178                                    PropsKeys.AUTH_TOKEN_IMPL);
1179    
1180                            AuthToken authToken = (AuthToken)newInstance(
1181                                    portletClassLoader, AuthToken.class, authTokenClassName);
1182    
1183                            AuthTokenWrapper authTokenWrapper =
1184                                    (AuthTokenWrapper)AuthTokenUtil.getAuthToken();
1185    
1186                            authTokenWrapper.setAuthToken(authToken);
1187                    }
1188    
1189                    if (portalProperties.containsKey(PropsKeys.CAPTCHA_ENGINE_IMPL)) {
1190                            String captchaClassName = portalProperties.getProperty(
1191                                    PropsKeys.CAPTCHA_ENGINE_IMPL);
1192    
1193                            Captcha captcha = (Captcha)newInstance(
1194                                    portletClassLoader, Captcha.class, captchaClassName);
1195    
1196                            CaptchaWrapper captchaWrapper =
1197                                    (CaptchaWrapper)CaptchaUtil.getCaptcha();
1198    
1199                            captchaWrapper.setCaptcha(captcha);
1200                    }
1201    
1202                    if (portalProperties.containsKey(
1203                                    PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS)) {
1204    
1205                            String controlPanelEntryClassName = portalProperties.getProperty(
1206                                    PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS);
1207    
1208                            ControlPanelEntry controlPanelEntry =
1209                                    (ControlPanelEntry)newInstance(
1210                                            portletClassLoader, ControlPanelEntry.class,
1211                                            controlPanelEntryClassName);
1212    
1213                            DefaultControlPanelEntryFactory.setInstance(controlPanelEntry);
1214                    }
1215    
1216                    if (portalProperties.containsKey(PropsKeys.DL_HOOK_IMPL)) {
1217                            String dlHookClassName = portalProperties.getProperty(
1218                                    PropsKeys.DL_HOOK_IMPL);
1219    
1220                            com.liferay.documentlibrary.util.Hook dlHook =
1221                                    (com.liferay.documentlibrary.util.Hook)newInstance(
1222                                            portletClassLoader,
1223                                            com.liferay.documentlibrary.util.Hook.class,
1224                                            dlHookClassName);
1225    
1226                            com.liferay.documentlibrary.util.HookFactory.setInstance(dlHook);
1227                    }
1228    
1229                    if (portalProperties.containsKey(PropsKeys.IMAGE_HOOK_IMPL)) {
1230                            String imageHookClassName = portalProperties.getProperty(
1231                                    PropsKeys.IMAGE_HOOK_IMPL);
1232    
1233                            com.liferay.portal.kernel.image.Hook imageHook =
1234                                    (com.liferay.portal.kernel.image.Hook)newInstance(
1235                                            portletClassLoader,
1236                                            com.liferay.portal.kernel.image.Hook.class,
1237                                            imageHookClassName);
1238    
1239                            com.liferay.portal.image.HookFactory.setInstance(imageHook);
1240                    }
1241    
1242                    if (portalProperties.containsKey(
1243                                    PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL)) {
1244    
1245                            String attributesTransformerClassName =
1246                                    portalProperties.getProperty(
1247                                            PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL);
1248    
1249                            AttributesTransformer attributesTransformer =
1250                                    (AttributesTransformer)newInstance(
1251                                            portletClassLoader, AttributesTransformer.class,
1252                                            attributesTransformerClassName);
1253    
1254                            AttributesTransformerFactory.setInstance(attributesTransformer);
1255                    }
1256    
1257                    if (portalProperties.containsKey(PropsKeys.MAIL_HOOK_IMPL)) {
1258                            String mailHookClassName = portalProperties.getProperty(
1259                                    PropsKeys.MAIL_HOOK_IMPL);
1260    
1261                            com.liferay.mail.util.Hook mailHook =
1262                                    (com.liferay.mail.util.Hook)newInstance(
1263                                            portletClassLoader, com.liferay.mail.util.Hook.class,
1264                                            mailHookClassName);
1265    
1266                            com.liferay.mail.util.HookFactory.setInstance(mailHook);
1267                    }
1268    
1269                    if (portalProperties.containsKey(PropsKeys.SANITIZER_IMPL)) {
1270                            String sanitizerClassName = portalProperties.getProperty(
1271                                    PropsKeys.SANITIZER_IMPL);
1272    
1273                            Sanitizer sanitizer = (Sanitizer)newInstance(
1274                                    portletClassLoader, Sanitizer.class, sanitizerClassName);
1275    
1276                            SanitizerWrapper sanitizerWrapper =
1277                                    (SanitizerWrapper)SanitizerUtil.getSanitizer();
1278    
1279                            sanitizerWrapper.setSanitizer(sanitizer);
1280                    }
1281    
1282                    if (portalProperties.containsKey(
1283                                    PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR)) {
1284    
1285                            String emailAddressGeneratorClassName =
1286                                    portalProperties.getProperty(
1287                                            PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR);
1288    
1289                            EmailAddressGenerator emailAddressGenerator =
1290                                    (EmailAddressGenerator)newInstance(
1291                                            portletClassLoader, EmailAddressGenerator.class,
1292                                            emailAddressGeneratorClassName);
1293    
1294                            EmailAddressGeneratorFactory.setInstance(emailAddressGenerator);
1295                    }
1296    
1297                    if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_GENERATOR)) {
1298                            String fullNameGeneratorClassName = portalProperties.getProperty(
1299                                    PropsKeys.USERS_FULL_NAME_GENERATOR);
1300    
1301                            FullNameGenerator fullNameGenerator =
1302                                    (FullNameGenerator)newInstance(
1303                                            portletClassLoader, FullNameGenerator.class,
1304                                            fullNameGeneratorClassName);
1305    
1306                            FullNameGeneratorFactory.setInstance(fullNameGenerator);
1307                    }
1308    
1309                    if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_VALIDATOR)) {
1310                            String fullNameValidatorClassName = portalProperties.getProperty(
1311                                    PropsKeys.USERS_FULL_NAME_VALIDATOR);
1312    
1313                            FullNameValidator fullNameValidator =
1314                                    (FullNameValidator)newInstance(
1315                                            portletClassLoader, FullNameValidator.class,
1316                                            fullNameValidatorClassName);
1317    
1318                            FullNameValidatorFactory.setInstance(fullNameValidator);
1319                    }
1320    
1321                    if (portalProperties.containsKey(
1322                                    PropsKeys.USERS_SCREEN_NAME_GENERATOR)) {
1323    
1324                            String screenNameGeneratorClassName = portalProperties.getProperty(
1325                                    PropsKeys.USERS_SCREEN_NAME_GENERATOR);
1326    
1327                            ScreenNameGenerator screenNameGenerator =
1328                                    (ScreenNameGenerator)newInstance(
1329                                            portletClassLoader, ScreenNameGenerator.class,
1330                                            screenNameGeneratorClassName);
1331    
1332                            ScreenNameGeneratorFactory.setInstance(screenNameGenerator);
1333                    }
1334    
1335                    if (portalProperties.containsKey(
1336                                    PropsKeys.USERS_SCREEN_NAME_VALIDATOR)) {
1337    
1338                            String screenNameValidatorClassName = portalProperties.getProperty(
1339                                    PropsKeys.USERS_SCREEN_NAME_VALIDATOR);
1340    
1341                            ScreenNameValidator screenNameValidator =
1342                                    (ScreenNameValidator)newInstance(
1343                                            portletClassLoader, ScreenNameValidator.class,
1344                                            screenNameValidatorClassName);
1345    
1346                            ScreenNameValidatorFactory.setInstance(screenNameValidator);
1347                    }
1348    
1349                    if (portalProperties.containsKey(PropsKeys.RELEASE_INFO_BUILD_NUMBER) ||
1350                            portalProperties.containsKey(PropsKeys.UPGRADE_PROCESSES)) {
1351    
1352                            updateRelease(
1353                                    servletContextName, portletClassLoader, portalProperties);
1354                    }
1355            }
1356    
1357            protected void initServices(
1358                            String servletContextName, ClassLoader portletClassLoader,
1359                            String serviceType, Class<?> serviceTypeClass,
1360                            Constructor<?> serviceImplConstructor, Object serviceProxy)
1361                    throws Exception {
1362    
1363                    ServiceBag serviceBag = _servicesContainer.findByServiceType(
1364                            serviceType);
1365    
1366                    if (serviceBag != null) {
1367                            throw new IllegalStateException(
1368                                    serviceType + " is already overridden by " +
1369                                            serviceBag.getServletContextName());
1370                    }
1371    
1372                    AdvisedSupport advisedSupport = getAdvisedSupport(serviceProxy);
1373    
1374                    TargetSource targetSource = advisedSupport.getTargetSource();
1375    
1376                    Object originalService = targetSource.getTarget();
1377    
1378                    if (Proxy.isProxyClass(originalService.getClass())) {
1379                            InvocationHandler invocationHandler =
1380                                    Proxy.getInvocationHandler(originalService);
1381    
1382                            if (invocationHandler instanceof ClassLoaderBeanHandler) {
1383                                    ClassLoaderBeanHandler classLoaderBeanHandler =
1384                                            (ClassLoaderBeanHandler)invocationHandler;
1385    
1386                                    originalService =  classLoaderBeanHandler.getBean();
1387                            }
1388                    }
1389    
1390                    Object customService = serviceImplConstructor.newInstance(
1391                            originalService);
1392    
1393                    Object customTarget = Proxy.newProxyInstance(
1394                            portletClassLoader, new Class<?>[] {serviceTypeClass},
1395                            new ClassLoaderBeanHandler(customService, portletClassLoader));
1396    
1397                    TargetSource customTargetSource = new SingletonTargetSource(
1398                            customTarget);
1399    
1400                    advisedSupport.setTargetSource(customTargetSource);
1401    
1402                    _servicesContainer.addServiceBag(
1403                            servletContextName, serviceType, originalService);
1404            }
1405    
1406            protected void resetPortalProperties(
1407                            String servletContextName, Properties portalProperties,
1408                            boolean initPhase)
1409                    throws Exception {
1410    
1411                    for (String key : _PROPS_VALUES_BOOLEAN) {
1412                            String fieldName = StringUtil.replace(
1413                                    key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1414    
1415                            if (!containsKey(portalProperties, key)) {
1416                                    continue;
1417                            }
1418    
1419                            try {
1420                                    Field field = PropsValues.class.getField(fieldName);
1421    
1422                                    Boolean value = Boolean.valueOf(GetterUtil.getBoolean(
1423                                            PropsUtil.get(key)));
1424    
1425                                    field.setBoolean(null, value);
1426                            }
1427                            catch (Exception e) {
1428                                    _log.error(
1429                                            "Error setting field " + fieldName + ": " + e.getMessage());
1430                            }
1431                    }
1432    
1433                    for (String key : _PROPS_VALUES_INTEGER) {
1434                            String fieldName = StringUtil.replace(
1435                                    key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1436    
1437                            if (!containsKey(portalProperties, key)) {
1438                                    continue;
1439                            }
1440    
1441                            try {
1442                                    Field field = PropsValues.class.getField(fieldName);
1443    
1444                                    Integer value = Integer.valueOf(GetterUtil.getInteger(
1445                                            PropsUtil.get(key)));
1446    
1447                                    field.setInt(null, value);
1448                            }
1449                            catch (Exception e) {
1450                                    _log.error(
1451                                            "Error setting field " + fieldName + ": " + e.getMessage());
1452                            }
1453                    }
1454    
1455                    for (String key : _PROPS_VALUES_LONG) {
1456                            String fieldName = StringUtil.replace(
1457                                    key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1458    
1459                            if (!containsKey(portalProperties, key)) {
1460                                    continue;
1461                            }
1462    
1463                            try {
1464                                    Field field = PropsValues.class.getField(fieldName);
1465    
1466                                    Long value = Long.valueOf(GetterUtil.getLong(
1467                                            PropsUtil.get(key)));
1468    
1469                                    field.setLong(null, value);
1470                            }
1471                            catch (Exception e) {
1472                                    _log.error(
1473                                            "Error setting field " + fieldName + ": " + e.getMessage());
1474                            }
1475                    }
1476    
1477                    for (String key : _PROPS_VALUES_STRING) {
1478                            String fieldName = StringUtil.replace(
1479                                    key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1480    
1481                            if (!containsKey(portalProperties, key)) {
1482                                    continue;
1483                            }
1484    
1485                            try {
1486                                    Field field = PropsValues.class.getField(fieldName);
1487    
1488                                    String value = GetterUtil.getString(PropsUtil.get(key));
1489    
1490                                    field.set(null, value);
1491                            }
1492                            catch (Exception e) {
1493                                    _log.error(
1494                                            "Error setting field " + fieldName + ": " + e.getMessage());
1495                            }
1496                    }
1497    
1498                    for (String key : _PROPS_VALUES_STRING_ARRAY) {
1499                            String fieldName = StringUtil.replace(
1500                                    key.toUpperCase(), StringPool.PERIOD,  StringPool.UNDERLINE);
1501    
1502                            if (!containsKey(portalProperties, key)) {
1503                                    continue;
1504                            }
1505    
1506                            try {
1507                                    Field field = PropsValues.class.getField(fieldName);
1508    
1509                                    StringArraysContainer stringArraysContainer =
1510                                            _stringArraysContainerMap.get(key);
1511    
1512                                    String[] value = null;
1513    
1514                                    if (initPhase) {
1515                                            value = PropsUtil.getArray(key);
1516                                    }
1517    
1518                                    stringArraysContainer.setPluginStringArray(
1519                                            servletContextName, value);
1520    
1521                                    value = stringArraysContainer.getMergedStringArray();
1522    
1523                                    field.set(null, value);
1524                            }
1525                            catch (Exception e) {
1526                                    _log.error(
1527                                            "Error setting field " + fieldName + ": " + e.getMessage());
1528                            }
1529                    }
1530    
1531                    if (containsKey(portalProperties, LOCALES)) {
1532                            PropsValues.LOCALES = PropsUtil.getArray(LOCALES);
1533    
1534                            LanguageUtil.init();
1535                    }
1536    
1537                    CacheUtil.clearCache();
1538    
1539                    JavaScriptBundleUtil.clearCache();
1540            }
1541    
1542            protected void updateRelease(
1543                            String servletContextName, ClassLoader portletClassLoader,
1544                            Properties portalProperties)
1545                    throws Exception {
1546    
1547                    int buildNumber = GetterUtil.getInteger(
1548                            portalProperties.getProperty(PropsKeys.RELEASE_INFO_BUILD_NUMBER));
1549    
1550                    if (buildNumber <= 0) {
1551                            _log.error(
1552                                    "Skipping upgrade processes for " + servletContextName +
1553                                            " because \"release.info.build.number\" is not specified");
1554    
1555                            return;
1556                    }
1557    
1558                    Release release = null;
1559    
1560                    try {
1561                            release = ReleaseLocalServiceUtil.getRelease(
1562                                    servletContextName, buildNumber);
1563                    }
1564                    catch (PortalException pe) {
1565                            int previousBuildNumber = GetterUtil.getInteger(
1566                                    portalProperties.getProperty(
1567                                            PropsKeys.RELEASE_INFO_PREVIOUS_BUILD_NUMBER),
1568                                    buildNumber);
1569    
1570                            release = ReleaseLocalServiceUtil.addRelease(
1571                                    servletContextName, previousBuildNumber);
1572                    }
1573    
1574                    if (buildNumber == release.getBuildNumber()) {
1575                            if (_log.isDebugEnabled()) {
1576                                    _log.debug(
1577                                            "Skipping upgrade processes for " + servletContextName +
1578                                                    " because it is already up to date");
1579                            }
1580                    }
1581                    else if (buildNumber < release.getBuildNumber()) {
1582                            throw new UpgradeException(
1583                                    "Skipping upgrade processes for " + servletContextName +
1584                                            " because you are trying to upgrade with an older version");
1585                    }
1586                    else {
1587                            String[] upgradeProcessClassNames = StringUtil.split(
1588                                    portalProperties.getProperty(PropsKeys.UPGRADE_PROCESSES));
1589    
1590                            UpgradeProcessUtil.upgradeProcess(
1591                                    release.getBuildNumber(), upgradeProcessClassNames,
1592                                    portletClassLoader);
1593                    }
1594    
1595                    ReleaseLocalServiceUtil.updateRelease(
1596                            release.getReleaseId(), buildNumber, null, true);
1597            }
1598    
1599            private static final String[] _PROPS_KEYS_EVENTS = new String[] {
1600                    LOGIN_EVENTS_POST,
1601                    LOGIN_EVENTS_PRE,
1602                    LOGOUT_EVENTS_POST,
1603                    LOGOUT_EVENTS_PRE,
1604                    SERVLET_SERVICE_EVENTS_POST,
1605                    SERVLET_SERVICE_EVENTS_PRE
1606            };
1607    
1608            private static final String[] _PROPS_KEYS_SESSION_EVENTS = new String[] {
1609                    SERVLET_SESSION_CREATE_EVENTS,
1610                    SERVLET_SESSION_DESTROY_EVENTS
1611            };
1612    
1613            private static final String[] _PROPS_VALUES_BOOLEAN = new String[] {
1614                    "auth.forward.by.last.path",
1615                    "captcha.check.portal.create_account",
1616                    "dl.webdav.hold.lock",
1617                    "dl.webdav.save.to.single.version",
1618                    "field.enable.com.liferay.portal.model.Contact.birthday",
1619                    "field.enable.com.liferay.portal.model.Contact.male",
1620                    "field.enable.com.liferay.portal.model.Organization.status",
1621                    "javascript.fast.load",
1622                    "layout.template.cache.enabled",
1623                    "layout.user.private.layouts.auto.create",
1624                    "layout.user.private.layouts.enabled",
1625                    "layout.user.private.layouts.modifiable",
1626                    "layout.user.public.layouts.auto.create",
1627                    "layout.user.public.layouts.enabled",
1628                    "layout.user.public.layouts.modifiable",
1629                    "login.create.account.allow.custom.password",
1630                    "my.places.show.community.private.sites.with.no.layouts",
1631                    "my.places.show.community.public.sites.with.no.layouts",
1632                    "my.places.show.organization.private.sites.with.no.layouts",
1633                    "my.places.show.organization.public.sites.with.no.layouts",
1634                    "my.places.show.user.private.sites.with.no.layouts",
1635                    "my.places.show.user.public.sites.with.no.layouts",
1636                    "portlet.add.default.resource.check.enabled",
1637                    "terms.of.use.required",
1638                    "theme.css.fast.load",
1639                    "theme.images.fast.load",
1640                    "theme.loader.new.theme.id.on.import",
1641                    "theme.portlet.decorate.default",
1642                    "theme.portlet.sharing.default",
1643                    "users.email.address.required",
1644                    "users.screen.name.always.autogenerate"
1645            };
1646    
1647            private static final String[] _PROPS_VALUES_INTEGER = new String[] {
1648            };
1649    
1650            private static final String[] _PROPS_VALUES_LONG = new String[] {
1651            };
1652    
1653            private static final String[] _PROPS_VALUES_STRING = new String[] {
1654                    "default.landing.page.path",
1655                    "passwords.passwordpolicytoolkit.generator",
1656                    "passwords.passwordpolicytoolkit.static",
1657                    "theme.shortcut.icon"
1658            };
1659    
1660            private static final String[] _PROPS_VALUES_STRING_ARRAY = new String[] {
1661                    "admin.default.group.names",
1662                    "admin.default.role.names",
1663                    "admin.default.user.group.names",
1664                    "convert.processes",
1665                    "layout.static.portlets.all",
1666                    "layout.types",
1667                    "session.phishing.protected.attributes"
1668            };
1669    
1670            private static Log _log = LogFactoryUtil.getLog(
1671                    HookHotDeployListener.class);
1672    
1673            private Map<String, AuthenticatorsContainer> _authenticatorsContainerMap =
1674                    new HashMap<String, AuthenticatorsContainer>();
1675            private Map<String, AuthFailuresContainer> _authFailuresContainerMap =
1676                    new HashMap<String, AuthFailuresContainer>();
1677            private Map<String, AutoDeployListenersContainer>
1678                    _autoDeployListenersContainerMap =
1679                            new HashMap<String, AutoDeployListenersContainer>();
1680            private Map<String, AutoLoginsContainer> _autoLoginsContainerMap =
1681                    new HashMap<String, AutoLoginsContainer>();
1682            private Map<String, CustomJspBag> _customJspBagsMap =
1683                    new HashMap<String, CustomJspBag>();
1684            private Map<String, EventsContainer> _eventsContainerMap =
1685                    new HashMap<String, EventsContainer>();
1686            private Map<String, HotDeployListenersContainer>
1687                    _hotDeployListenersContainerMap =
1688                            new HashMap<String, HotDeployListenersContainer>();
1689            private Map<String, LanguagesContainer> _languagesContainerMap =
1690                    new HashMap<String, LanguagesContainer>();
1691            private Map<String, ModelListenersContainer> _modelListenersContainerMap =
1692                    new HashMap<String, ModelListenersContainer>();
1693            private Map<String, Properties> _portalPropertiesMap =
1694                    new HashMap<String, Properties>();
1695            private ServicesContainer _servicesContainer = new ServicesContainer();
1696            private Set<String> _servletContextNames = new HashSet<String>();
1697            private Map<String, StringArraysContainer> _stringArraysContainerMap =
1698                    new HashMap<String, StringArraysContainer>();
1699    
1700            private class AuthenticatorsContainer {
1701    
1702                    public void registerAuthenticator(
1703                            String key, Authenticator authenticator) {
1704    
1705                            List<Authenticator> authenticators = _authenticators.get(key);
1706    
1707                            if (authenticators == null) {
1708                                    authenticators = new ArrayList<Authenticator>();
1709    
1710                                    _authenticators.put(key, authenticators);
1711                            }
1712    
1713                            AuthPipeline.registerAuthenticator(key, authenticator);
1714    
1715                            authenticators.add(authenticator);
1716                    }
1717    
1718                    public void unregisterAuthenticators() {
1719                            for (Map.Entry<String, List<Authenticator>> entry :
1720                                            _authenticators.entrySet()) {
1721    
1722                                    String key = entry.getKey();
1723                                    List<Authenticator> authenticators = entry.getValue();
1724    
1725                                    for (Authenticator authenticator : authenticators) {
1726                                            AuthPipeline.unregisterAuthenticator(key, authenticator);
1727                                    }
1728                            }
1729                    }
1730    
1731                    Map<String, List<Authenticator>> _authenticators =
1732                            new HashMap<String, List<Authenticator>>();
1733    
1734            }
1735    
1736            private class AuthFailuresContainer {
1737    
1738                    public void registerAuthFailure(String key, AuthFailure authFailure) {
1739                            List<AuthFailure> authFailures = _authFailures.get(key);
1740    
1741                            if (authFailures == null) {
1742                                    authFailures = new ArrayList<AuthFailure>();
1743    
1744                                    _authFailures.put(key, authFailures);
1745                            }
1746    
1747                            AuthPipeline.registerAuthFailure(key, authFailure);
1748    
1749                            authFailures.add(authFailure);
1750                    }
1751    
1752                    public void unregisterAuthFailures() {
1753                            for (Map.Entry<String, List<AuthFailure>> entry :
1754                                            _authFailures.entrySet()) {
1755    
1756                                    String key = entry.getKey();
1757                                    List<AuthFailure> authFailures = entry.getValue();
1758    
1759                                    for (AuthFailure authFailure : authFailures) {
1760                                            AuthPipeline.unregisterAuthFailure(key, authFailure);
1761                                    }
1762                            }
1763                    }
1764    
1765                    Map<String, List<AuthFailure>> _authFailures =
1766                            new HashMap<String, List<AuthFailure>>();
1767    
1768            }
1769    
1770            private class AutoDeployListenersContainer {
1771    
1772                    public void registerAutoDeployListener(
1773                            AutoDeployListener autoDeployListener) {
1774    
1775                            AutoDeployDir autoDeployDir = AutoDeployUtil.getDir(
1776                                    AutoDeployDir.DEFAULT_NAME);
1777    
1778                            if (autoDeployDir == null) {
1779                                    return;
1780                            }
1781    
1782                            autoDeployDir.registerListener(autoDeployListener);
1783    
1784                            _autoDeployListeners.add(autoDeployListener);
1785                    }
1786    
1787                    public void unregisterAutoDeployListeners() {
1788                            AutoDeployDir autoDeployDir = AutoDeployUtil.getDir(
1789                                    AutoDeployDir.DEFAULT_NAME);
1790    
1791                            if (autoDeployDir == null) {
1792                                    return;
1793                            }
1794    
1795                            for (AutoDeployListener autoDeployListener : _autoDeployListeners) {
1796                                    autoDeployDir.unregisterListener(autoDeployListener);
1797                            }
1798                    }
1799    
1800                    private List<AutoDeployListener> _autoDeployListeners =
1801                            new ArrayList<AutoDeployListener>();
1802    
1803            }
1804    
1805            private class AutoLoginsContainer {
1806    
1807                    public void registerAutoLogin(AutoLogin autoLogin) {
1808                            AutoLoginFilter.registerAutoLogin(autoLogin);
1809    
1810                            _autoLogins.add(autoLogin);
1811                    }
1812    
1813                    public void unregisterAutoLogins() {
1814                            for (AutoLogin autoLogin : _autoLogins) {
1815                                    AutoLoginFilter.unregisterAutoLogin(autoLogin);
1816                            }
1817                    }
1818    
1819                    List<AutoLogin> _autoLogins = new ArrayList<AutoLogin>();
1820    
1821            }
1822    
1823            private class CustomJspBag {
1824    
1825                    public CustomJspBag(String customJspDir, List<String> customJsps) {
1826                            _customJspDir = customJspDir;
1827                            _customJsps = customJsps;
1828                    }
1829    
1830                    public String getCustomJspDir() {
1831                            return _customJspDir;
1832                    }
1833    
1834                    public List<String> getCustomJsps() {
1835                            return _customJsps;
1836                    }
1837    
1838                    private String _customJspDir;
1839                    private List<String> _customJsps;
1840    
1841            }
1842    
1843            private class EventsContainer {
1844    
1845                    public void registerEvent(String eventName, Object event) {
1846                            List<Object> events = _eventsMap.get(eventName);
1847    
1848                            if (events == null) {
1849                                    events = new ArrayList<Object>();
1850    
1851                                    _eventsMap.put(eventName, events);
1852                            }
1853    
1854                            events.add(event);
1855                    }
1856    
1857                    public void unregisterEvents() {
1858                            for (Map.Entry<String, List<Object>> entry :
1859                                            _eventsMap.entrySet()) {
1860    
1861                                    String eventName = entry.getKey();
1862                                    List<Object> events = entry.getValue();
1863    
1864                                    for (Object event : events) {
1865                                            EventsProcessorUtil.unregisterEvent(eventName, event);
1866                                    }
1867                            }
1868                    }
1869    
1870                    private Map<String, List<Object>> _eventsMap =
1871                            new HashMap<String, List<Object>>();
1872    
1873            }
1874    
1875            private class HotDeployListenersContainer {
1876    
1877                    public void registerHotDeployListener(
1878                            HotDeployListener hotDeployListener) {
1879    
1880                            HotDeployUtil.registerListener(hotDeployListener);
1881    
1882                            _hotDeployListeners.add(hotDeployListener);
1883                    }
1884    
1885                    public void unregisterHotDeployListeners() {
1886                            for (HotDeployListener hotDeployListener : _hotDeployListeners) {
1887                                    HotDeployUtil.unregisterListener(hotDeployListener);
1888                            }
1889                    }
1890    
1891                    private List<HotDeployListener> _hotDeployListeners =
1892                            new ArrayList<HotDeployListener>();
1893    
1894            }
1895    
1896            private class LanguagesContainer {
1897    
1898                    public void addLanguage(
1899                            Locale locale, Map<String, String> languageMap) {
1900    
1901                            Map<String, String> oldLanguageMap =
1902                                    LanguageResources.putLanguageMap(locale, languageMap);
1903    
1904                            _languagesMap.put(locale, oldLanguageMap);
1905                    }
1906    
1907                    public void unregisterLanguages() {
1908                            for (Map.Entry<Locale, Map<String, String>> entry :
1909                                            _languagesMap.entrySet()) {
1910    
1911                                    Locale locale = entry.getKey();
1912                                    Map<String, String> languageMap = entry.getValue();
1913    
1914                                    LanguageResources.putLanguageMap(locale, languageMap);
1915                            }
1916                    }
1917    
1918                    private Map<Locale, Map<String, String>> _languagesMap =
1919                            new HashMap<Locale, Map<String, String>>();
1920    
1921            }
1922    
1923            private class ModelListenersContainer {
1924    
1925                    public void registerModelListener(
1926                            String modelName, ModelListener<BaseModel<?>> modelListener) {
1927    
1928                            List<ModelListener<BaseModel<?>>> modelListeners =
1929                                    _modelListenersMap.get(modelName);
1930    
1931                            if (modelListeners == null) {
1932                                    modelListeners = new ArrayList<ModelListener<BaseModel<?>>>();
1933    
1934                                    _modelListenersMap.put(modelName, modelListeners);
1935                            }
1936    
1937                            modelListeners.add(modelListener);
1938                    }
1939    
1940                    @SuppressWarnings("unchecked")
1941                    public void unregisterModelListeners() {
1942                            for (Map.Entry<String, List<ModelListener<BaseModel<?>>>> entry :
1943                                            _modelListenersMap.entrySet()) {
1944    
1945                                    String modelName = entry.getKey();
1946                                    List<ModelListener<BaseModel<?>>> modelListeners =
1947                                            entry.getValue();
1948    
1949                                    BasePersistence persistence = getPersistence(modelName);
1950    
1951                                    for (ModelListener<BaseModel<?>> modelListener :
1952                                                    modelListeners) {
1953    
1954                                            persistence.unregisterListener(modelListener);
1955                                    }
1956                            }
1957                    }
1958    
1959                    private Map<String, List<ModelListener<BaseModel<?>>>>
1960                            _modelListenersMap =
1961                                    new HashMap<String, List<ModelListener<BaseModel<?>>>>();
1962    
1963            }
1964    
1965            private class ServiceBag {
1966    
1967                    public ServiceBag(
1968                            String servletContextName, String serviceType,
1969                            Object originalService) {
1970    
1971                            _servletContextName = servletContextName;
1972                            _serviceType = serviceType;
1973                            _originalService = originalService;
1974                    }
1975    
1976                    public Object getOriginalService() {
1977                            return _originalService;
1978                    }
1979    
1980                    public String getServiceType() {
1981                            return _serviceType;
1982                    }
1983    
1984                    public String getServletContextName() {
1985                            return _servletContextName;
1986                    }
1987    
1988                    private Object _originalService;
1989                    private String _serviceType;
1990                    private String _servletContextName;
1991    
1992            }
1993    
1994            private class ServicesContainer {
1995    
1996                    public void addServiceBag(
1997                            String servletContextName, String serviceType,
1998                            Object originalService) {
1999    
2000                            ServiceBag serviceBag = new ServiceBag(
2001                                    servletContextName, serviceType, originalService);
2002    
2003                            _serviceBags.add(serviceBag);
2004                    }
2005    
2006                    public ServiceBag findByServiceType(String serviceType) {
2007                            for (ServiceBag serviceBag : _serviceBags) {
2008                                    if (serviceBag.getServiceType().equals(serviceType)) {
2009                                            return serviceBag;
2010                                    }
2011                            }
2012    
2013                            return null;
2014                    }
2015    
2016                    public List<ServiceBag> findByServletContextName(
2017                            String servletContextName) {
2018    
2019                            List<ServiceBag> serviceBags = new ArrayList<ServiceBag>();
2020    
2021                            for (ServiceBag serviceBag : _serviceBags) {
2022                                    if (serviceBag.getServletContextName().equals(
2023                                                    servletContextName)) {
2024    
2025                                            serviceBags.add(serviceBag);
2026                                    }
2027                            }
2028    
2029                            return serviceBags;
2030                    }
2031    
2032                    public void removeByServletContextName(
2033                            String servletContextName) {
2034    
2035                            Iterator<ServiceBag> itr = _serviceBags.iterator();
2036    
2037                            while (itr.hasNext()) {
2038                                    ServiceBag serviceBag = itr.next();
2039    
2040                                    if (serviceBag.getServletContextName().equals(
2041                                                    servletContextName)) {
2042    
2043                                            itr.remove();
2044                                    }
2045                            }
2046                    }
2047    
2048                    private List<ServiceBag> _serviceBags = new ArrayList<ServiceBag>();
2049    
2050            }
2051    
2052            private class StringArraysContainer {
2053    
2054                    private StringArraysContainer(String key) {
2055                            _portalStringArray = PropsUtil.getArray(key);
2056                    }
2057    
2058                    public String[] getMergedStringArray() {
2059                            List<String> mergedStringList = new UniqueList<String>();
2060    
2061                            mergedStringList.addAll(ListUtil.fromArray(_portalStringArray));
2062    
2063                            for (Map.Entry<String, String[]> entry :
2064                                            _pluginStringArrayMap.entrySet()) {
2065    
2066                                    String[] pluginStringArray = entry.getValue();
2067    
2068                                    mergedStringList.addAll(ListUtil.fromArray(pluginStringArray));
2069                            }
2070    
2071                            return mergedStringList.toArray(
2072                                    new String[mergedStringList.size()]);
2073                    }
2074    
2075                    public void setPluginStringArray(
2076                            String servletContextName, String[] pluginStringArray) {
2077    
2078                            if (pluginStringArray != null) {
2079                                    _pluginStringArrayMap.put(
2080                                            servletContextName, pluginStringArray);
2081                            }
2082                            else {
2083                                    _pluginStringArrayMap.remove(servletContextName);
2084                            }
2085                    }
2086    
2087                    private String[] _portalStringArray;
2088                    private Map<String, String[]> _pluginStringArrayMap =
2089                            new HashMap<String, String[]>();
2090    
2091            }
2092    
2093    }