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