001    /**
002     * Copyright (c) 2000-present 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.document.library.kernel.antivirus.AntivirusScanner;
018    import com.liferay.document.library.kernel.antivirus.AntivirusScannerUtil;
019    import com.liferay.document.library.kernel.antivirus.AntivirusScannerWrapper;
020    import com.liferay.document.library.kernel.util.DLProcessor;
021    import com.liferay.document.library.kernel.util.DLProcessorRegistryUtil;
022    import com.liferay.portal.captcha.CaptchaImpl;
023    import com.liferay.portal.kernel.bean.BeanLocatorException;
024    import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler;
025    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
026    import com.liferay.portal.kernel.bean.PortletBeanLocatorUtil;
027    import com.liferay.portal.kernel.captcha.Captcha;
028    import com.liferay.portal.kernel.captcha.CaptchaUtil;
029    import com.liferay.portal.kernel.configuration.Configuration;
030    import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
031    import com.liferay.portal.kernel.deploy.DeployManagerUtil;
032    import com.liferay.portal.kernel.deploy.auto.AutoDeployListener;
033    import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
034    import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
035    import com.liferay.portal.kernel.deploy.hot.HotDeployException;
036    import com.liferay.portal.kernel.deploy.hot.HotDeployListener;
037    import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
038    import com.liferay.portal.kernel.events.Action;
039    import com.liferay.portal.kernel.events.InvokerAction;
040    import com.liferay.portal.kernel.events.InvokerSessionAction;
041    import com.liferay.portal.kernel.events.InvokerSimpleAction;
042    import com.liferay.portal.kernel.events.LifecycleAction;
043    import com.liferay.portal.kernel.events.SessionAction;
044    import com.liferay.portal.kernel.events.SimpleAction;
045    import com.liferay.portal.kernel.format.PhoneNumberFormat;
046    import com.liferay.portal.kernel.language.LanguageUtil;
047    import com.liferay.portal.kernel.lock.LockListener;
048    import com.liferay.portal.kernel.log.Log;
049    import com.liferay.portal.kernel.log.LogFactoryUtil;
050    import com.liferay.portal.kernel.model.ModelListener;
051    import com.liferay.portal.kernel.plugin.PluginPackage;
052    import com.liferay.portal.kernel.portlet.ControlPanelEntry;
053    import com.liferay.portal.kernel.sanitizer.Sanitizer;
054    import com.liferay.portal.kernel.search.IndexerPostProcessor;
055    import com.liferay.portal.kernel.security.auth.AuthFailure;
056    import com.liferay.portal.kernel.security.auth.AuthToken;
057    import com.liferay.portal.kernel.security.auth.Authenticator;
058    import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
059    import com.liferay.portal.kernel.security.auth.EmailAddressGenerator;
060    import com.liferay.portal.kernel.security.auth.EmailAddressValidator;
061    import com.liferay.portal.kernel.security.auth.FullNameGenerator;
062    import com.liferay.portal.kernel.security.auth.FullNameValidator;
063    import com.liferay.portal.kernel.security.auth.InterruptedPortletRequestWhitelistUtil;
064    import com.liferay.portal.kernel.security.auth.ScreenNameGenerator;
065    import com.liferay.portal.kernel.security.auth.ScreenNameValidator;
066    import com.liferay.portal.kernel.security.auth.verifier.AuthVerifier;
067    import com.liferay.portal.kernel.security.auto.login.AutoLogin;
068    import com.liferay.portal.kernel.security.ldap.AttributesTransformer;
069    import com.liferay.portal.kernel.security.membershippolicy.OrganizationMembershipPolicy;
070    import com.liferay.portal.kernel.security.membershippolicy.RoleMembershipPolicy;
071    import com.liferay.portal.kernel.security.membershippolicy.SiteMembershipPolicy;
072    import com.liferay.portal.kernel.security.membershippolicy.UserGroupMembershipPolicy;
073    import com.liferay.portal.kernel.security.pacl.PACLConstants;
074    import com.liferay.portal.kernel.security.pacl.permission.PortalHookPermission;
075    import com.liferay.portal.kernel.security.pwd.Toolkit;
076    import com.liferay.portal.kernel.service.ReleaseLocalServiceUtil;
077    import com.liferay.portal.kernel.service.ServiceWrapper;
078    import com.liferay.portal.kernel.service.persistence.BasePersistence;
079    import com.liferay.portal.kernel.servlet.DirectServletRegistryUtil;
080    import com.liferay.portal.kernel.servlet.LiferayFilter;
081    import com.liferay.portal.kernel.servlet.LiferayFilterTracker;
082    import com.liferay.portal.kernel.servlet.TryFilter;
083    import com.liferay.portal.kernel.servlet.TryFinallyFilter;
084    import com.liferay.portal.kernel.servlet.WrapHttpServletRequestFilter;
085    import com.liferay.portal.kernel.servlet.WrapHttpServletResponseFilter;
086    import com.liferay.portal.kernel.servlet.taglib.ui.FormNavigatorConstants;
087    import com.liferay.portal.kernel.servlet.taglib.ui.FormNavigatorEntry;
088    import com.liferay.portal.kernel.struts.StrutsAction;
089    import com.liferay.portal.kernel.struts.StrutsPortletAction;
090    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
091    import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
092    import com.liferay.portal.kernel.url.ServletContextURLContainer;
093    import com.liferay.portal.kernel.util.CacheResourceBundleLoader;
094    import com.liferay.portal.kernel.util.CharPool;
095    import com.liferay.portal.kernel.util.ClassResourceBundleLoader;
096    import com.liferay.portal.kernel.util.GetterUtil;
097    import com.liferay.portal.kernel.util.HttpUtil;
098    import com.liferay.portal.kernel.util.InstanceFactory;
099    import com.liferay.portal.kernel.util.LocaleUtil;
100    import com.liferay.portal.kernel.util.PropertiesUtil;
101    import com.liferay.portal.kernel.util.PropsKeys;
102    import com.liferay.portal.kernel.util.ProxyUtil;
103    import com.liferay.portal.kernel.util.ReflectionUtil;
104    import com.liferay.portal.kernel.util.ResourceBundleLoader;
105    import com.liferay.portal.kernel.util.SetUtil;
106    import com.liferay.portal.kernel.util.StringPool;
107    import com.liferay.portal.kernel.util.StringUtil;
108    import com.liferay.portal.kernel.util.Tuple;
109    import com.liferay.portal.kernel.util.Validator;
110    import com.liferay.portal.kernel.xml.Document;
111    import com.liferay.portal.kernel.xml.Element;
112    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
113    import com.liferay.portal.language.LiferayResourceBundle;
114    import com.liferay.portal.repository.registry.RepositoryClassDefinitionCatalogUtil;
115    import com.liferay.portal.repository.util.ExternalRepositoryFactory;
116    import com.liferay.portal.repository.util.ExternalRepositoryFactoryImpl;
117    import com.liferay.portal.security.auth.AuthVerifierPipeline;
118    import com.liferay.portal.security.lang.DoPrivilegedBean;
119    import com.liferay.portal.servlet.filters.cache.CacheUtil;
120    import com.liferay.portal.servlet.taglib.ui.DeprecatedFormNavigatorEntry;
121    import com.liferay.portal.spring.aop.ServiceBeanAopProxy;
122    import com.liferay.portal.spring.context.PortalContextLoaderListener;
123    import com.liferay.portal.util.JavaScriptBundleUtil;
124    import com.liferay.portal.util.PortalInstances;
125    import com.liferay.portal.util.PropsUtil;
126    import com.liferay.portal.util.PropsValues;
127    import com.liferay.portlet.documentlibrary.store.StoreFactory;
128    import com.liferay.registry.Registry;
129    import com.liferay.registry.RegistryUtil;
130    import com.liferay.registry.ServiceRegistration;
131    import com.liferay.taglib.FileAvailabilityUtil;
132    
133    import java.io.InputStream;
134    
135    import java.lang.reflect.Constructor;
136    import java.lang.reflect.Field;
137    
138    import java.net.URL;
139    
140    import java.util.ArrayList;
141    import java.util.Arrays;
142    import java.util.HashMap;
143    import java.util.HashSet;
144    import java.util.Iterator;
145    import java.util.LinkedHashSet;
146    import java.util.List;
147    import java.util.Locale;
148    import java.util.Map;
149    import java.util.Properties;
150    import java.util.ResourceBundle;
151    import java.util.Set;
152    import java.util.concurrent.ConcurrentHashMap;
153    
154    import javax.servlet.Filter;
155    import javax.servlet.ServletContext;
156    
157    import org.springframework.aop.TargetSource;
158    import org.springframework.aop.framework.AdvisedSupport;
159    
160    /**
161     * @author Brian Wing Shun Chan
162     * @author Bruno Farache
163     * @author Wesley Gong
164     * @author Ryan Park
165     * @author Mika Koivisto
166     * @author Peter Fellwock
167     * @author Raymond Aug??
168     * @author Kamesh Sampath
169     */
170    public class HookHotDeployListener
171            extends BaseHotDeployListener implements PropsKeys {
172    
173            public static final String[] SUPPORTED_PROPERTIES = {
174                    "admin.default.group.names", "admin.default.role.names",
175                    "admin.default.user.group.names",
176                    "asset.publisher.asset.entry.query.processors",
177                    "asset.publisher.display.styles", "auth.forward.by.last.path",
178                    "auth.public.paths", "auth.verifier.pipeline", "auto.deploy.listeners",
179                    "application.startup.events", "auth.failure", "auth.max.failures",
180                    "auth.token.ignore.actions", "auth.token.ignore.origins",
181                    "auth.token.ignore.portlets", "auth.token.impl", "auth.pipeline.post",
182                    "auth.pipeline.pre", "auto.login.hooks",
183                    "captcha.check.portal.create_account", "captcha.engine.impl",
184                    "company.default.locale", "company.default.time.zone",
185                    "company.settings.form.authentication",
186                    "company.settings.form.configuration",
187                    "company.settings.form.identification",
188                    "company.settings.form.miscellaneous", "company.settings.form.social",
189                    "control.panel.entry.class.default", "default.landing.page.path",
190                    "default.regular.color.scheme.id", "default.regular.theme.id",
191                    "dl.file.entry.drafts.enabled",
192                    "dl.file.entry.open.in.ms.office.manual.check.in.required",
193                    "dl.file.entry.processors", "dl.repository.impl",
194                    "dl.store.antivirus.impl", "dl.store.impl",
195                    "field.enable.com.liferay.portal.kernel.model.Contact.birthday",
196                    "field.enable.com.liferay.portal.kernel.model.Contact.male",
197                    "field.enable.com.liferay.portal.kernel.model.Organization.status",
198                    "hot.deploy.listeners", "javascript.fast.load",
199                    "journal.article.form.add", "journal.article.form.translate",
200                    "journal.article.form.update", "layout.form.add", "layout.form.update",
201                    "layout.set.form.update", "layout.static.portlets.all",
202                    "layout.template.cache.enabled", "layout.types",
203                    "layout.user.private.layouts.auto.create",
204                    "layout.user.private.layouts.enabled",
205                    "layout.user.private.layouts.power.user.required",
206                    "layout.user.public.layouts.auto.create",
207                    "layout.user.public.layouts.enabled",
208                    "layout.user.public.layouts.power.user.required",
209                    "ldap.attrs.transformer.impl", "locales", "locales.beta",
210                    "locales.enabled", "lock.listeners",
211                    "login.create.account.allow.custom.password", "login.dialog.disabled",
212                    "login.events.post", "login.events.pre", "login.form.navigation.post",
213                    "login.form.navigation.pre", "logout.events.post", "logout.events.pre",
214                    "mail.hook.impl", "my.sites.show.private.sites.with.no.layouts",
215                    "my.sites.show.public.sites.with.no.layouts",
216                    "my.sites.show.user.private.sites.with.no.layouts",
217                    "my.sites.show.user.public.sites.with.no.layouts",
218                    "organizations.form.add.identification", "organizations.form.add.main",
219                    "organizations.form.add.miscellaneous",
220                    "passwords.passwordpolicytoolkit.generator",
221                    "passwords.passwordpolicytoolkit.static", "phone.number.format.impl",
222                    "phone.number.format.international.regexp",
223                    "phone.number.format.usa.regexp",
224                    "portlet.add.default.resource.check.enabled",
225                    "portlet.add.default.resource.check.whitelist",
226                    "portlet.add.default.resource.check.whitelist.actions",
227                    "rss.feeds.enabled", "sanitizer.impl", "servlet.session.create.events",
228                    "servlet.session.destroy.events", "servlet.service.events.post",
229                    "servlet.service.events.pre", "session.max.allowed",
230                    "session.phishing.protected.attributes", "session.store.password",
231                    "sites.form.add.advanced", "sites.form.add.main",
232                    "sites.form.add.miscellaneous", "sites.form.add.seo",
233                    "sites.form.update.advanced", "sites.form.update.main",
234                    "sites.form.update.miscellaneous", "sites.form.update.seo",
235                    "social.activity.sets.bundling.enabled", "social.activity.sets.enabled",
236                    "social.activity.sets.selector", "social.bookmark.*",
237                    "terms.of.use.required", "theme.css.fast.load",
238                    "theme.images.fast.load", "theme.jsp.override.enabled",
239                    "theme.loader.new.theme.id.on.import", "theme.portlet.decorate.default",
240                    "theme.portlet.sharing.default", "theme.shortcut.icon", "time.zones",
241                    "upgrade.processes", "user.notification.event.confirmation.enabled",
242                    "users.email.address.generator", "users.email.address.validator",
243                    "users.email.address.required", "users.form.add.identification",
244                    "users.form.add.main", "users.form.add.miscellaneous",
245                    "users.form.my.account.identification", "users.form.my.account.main",
246                    "users.form.my.account.miscellaneous",
247                    "users.form.update.identification", "users.form.update.main",
248                    "users.form.update.miscellaneous", "users.full.name.generator",
249                    "users.full.name.validator", "users.image.check.token",
250                    "users.image.max.height", "users.image.max.width",
251                    "users.screen.name.always.autogenerate", "users.screen.name.generator",
252                    "users.screen.name.validator", "value.object.listener.*"
253            };
254    
255            public HookHotDeployListener() {
256                    for (String key : _PROPS_VALUES_MERGE_STRING_ARRAY) {
257                            _mergeStringArraysContainerMap.put(
258                                    key, new MergeStringArraysContainer(key));
259                    }
260    
261                    for (String key : _PROPS_VALUES_OVERRIDE_STRING_ARRAY) {
262                            _overrideStringArraysContainerMap.put(
263                                    key, new OverrideStringArraysContainer(key));
264                    }
265            }
266    
267            @Override
268            public void invokeDeploy(HotDeployEvent hotDeployEvent)
269                    throws HotDeployException {
270    
271                    try {
272                            doInvokeDeploy(hotDeployEvent);
273                    }
274                    catch (Throwable t) {
275                            throwHotDeployException(
276                                    hotDeployEvent, "Error registering hook for ", t);
277                    }
278            }
279    
280            @Override
281            public void invokeUndeploy(HotDeployEvent hotDeployEvent)
282                    throws HotDeployException {
283    
284                    try {
285                            doInvokeUndeploy(hotDeployEvent);
286                    }
287                    catch (Throwable t) {
288                            throwHotDeployException(
289                                    hotDeployEvent, "Error unregistering hook for ", t);
290                    }
291            }
292    
293            public <T> void registerService(
294                    String servletContextName, Object serviceRegistrationKey,
295                    Class<T> clazz, T service, Map<String, Object> properties) {
296    
297                    Map<Object, ServiceRegistration<?>> serviceRegistrations =
298                            getServiceRegistrations(servletContextName);
299    
300                    Registry registry = RegistryUtil.getRegistry();
301    
302                    ServiceRegistration<T> serviceRegistration = registry.registerService(
303                            clazz, service, properties);
304    
305                    serviceRegistrations.put(serviceRegistrationKey, serviceRegistration);
306            }
307    
308            public <T> void registerService(
309                    String servletContextName, Object serviceRegistrationKey,
310                    Class<T> clazz, T service, Object... propertyKVPs) {
311    
312                    if ((propertyKVPs.length % 2) != 0) {
313                            throw new IllegalArgumentException(
314                                    "Properties length is not an even number");
315                    }
316    
317                    Map<String, Object> properties = new HashMap<>();
318    
319                    for (int i = 0; i < propertyKVPs.length; i += 2) {
320                            String propertyName = String.valueOf(propertyKVPs[i]);
321                            Object propertyValue = propertyKVPs[i + 1];
322    
323                            properties.put(propertyName, propertyValue);
324                    }
325    
326                    registerService(
327                            servletContextName, serviceRegistrationKey, clazz, service,
328                            properties);
329            }
330    
331            public <T> void registerService(
332                    String servletContextName, Object serviceRegistrationKey,
333                    Class<T> clazz, T service, Properties properties) {
334    
335                    registerService(
336                            servletContextName, serviceRegistrationKey, clazz, service,
337                            PropertiesUtil.toMap(properties));
338            }
339    
340            protected boolean checkPermission(
341                    String name, ClassLoader portletClassLoader, Object subject,
342                    String message) {
343    
344                    try {
345                            PortalHookPermission.checkPermission(
346                                    name, portletClassLoader, subject);
347                    }
348                    catch (SecurityException se) {
349                            if (_log.isInfoEnabled()) {
350                                    _log.info(message);
351                            }
352    
353                            return false;
354                    }
355    
356                    return true;
357            }
358    
359            protected boolean containsKey(Properties portalProperties, String key) {
360                    if (_log.isDebugEnabled()) {
361                            return true;
362                    }
363                    else {
364                            return portalProperties.containsKey(key);
365                    }
366            }
367    
368            protected void destroyCustomJspBag(
369                            String servletContextName, CustomJspBag customJspBag)
370                    throws Exception {
371            }
372    
373            protected void destroyPortalProperties(
374                            String servletContextName, Properties portalProperties)
375                    throws Exception {
376    
377                    PropsUtil.removeProperties(portalProperties);
378    
379                    if (_log.isDebugEnabled() && portalProperties.containsKey(LOCALES)) {
380                            _log.debug(
381                                    "Portlet locales " + portalProperties.getProperty(LOCALES));
382                            _log.debug("Original locales " + PropsUtil.get(LOCALES));
383                            _log.debug(
384                                    "Original locales array length " +
385                                            PropsUtil.getArray(LOCALES).length);
386                    }
387    
388                    resetPortalProperties(servletContextName, portalProperties, false);
389    
390                    if (portalProperties.containsKey(PropsKeys.CAPTCHA_ENGINE_IMPL)) {
391                            CaptchaImpl captchaImpl = null;
392    
393                            Captcha captcha = CaptchaUtil.getCaptcha();
394    
395                            if (captcha instanceof DoPrivilegedBean) {
396                                    DoPrivilegedBean doPrivilegedBean = (DoPrivilegedBean)captcha;
397    
398                                    captchaImpl = (CaptchaImpl)doPrivilegedBean.getActualBean();
399                            }
400                            else {
401                                    captchaImpl = (CaptchaImpl)captcha;
402                            }
403    
404                            captchaImpl.setCaptcha(null);
405                    }
406    
407                    if (portalProperties.containsKey(PropsKeys.DL_FILE_ENTRY_PROCESSORS)) {
408                            DLFileEntryProcessorContainer dlFileEntryProcessorContainer =
409                                    _dlFileEntryProcessorContainerMap.remove(servletContextName);
410    
411                            dlFileEntryProcessorContainer.unregisterDLProcessors();
412                    }
413    
414                    if (portalProperties.containsKey(PropsKeys.DL_REPOSITORY_IMPL)) {
415                            DLRepositoryContainer dlRepositoryContainer =
416                                    _dlRepositoryContainerMap.remove(servletContextName);
417    
418                            dlRepositoryContainer.unregisterRepositoryFactories();
419                    }
420    
421                    if (portalProperties.containsKey(PropsKeys.DL_STORE_ANTIVIRUS_IMPL)) {
422                            AntivirusScannerWrapper antivirusScannerWrapper =
423                                    (AntivirusScannerWrapper)
424                                            AntivirusScannerUtil.getAntivirusScanner();
425    
426                            antivirusScannerWrapper.setAntivirusScanner(null);
427                    }
428    
429                    if (portalProperties.containsKey(PropsKeys.DL_STORE_IMPL)) {
430                            StoreFactory storeFactory = StoreFactory.getInstance();
431    
432                            storeFactory.setStore(null);
433                    }
434    
435                    Set<String> liferayFilterClassNames =
436                            LiferayFilterTracker.getClassNames();
437    
438                    for (String liferayFilterClassName : liferayFilterClassNames) {
439                            if (!portalProperties.containsKey(liferayFilterClassName)) {
440                                    continue;
441                            }
442    
443                            boolean filterEnabled = GetterUtil.getBoolean(
444                                    PropsUtil.get(liferayFilterClassName));
445    
446                            Set<LiferayFilter> liferayFilters =
447                                    LiferayFilterTracker.getLiferayFilters(liferayFilterClassName);
448    
449                            for (LiferayFilter liferayFilter : liferayFilters) {
450                                    liferayFilter.setFilterEnabled(filterEnabled);
451                            }
452                    }
453            }
454    
455            protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
456                    throws Exception {
457    
458                    ServletContext servletContext = hotDeployEvent.getServletContext();
459    
460                    String servletContextName = servletContext.getServletContextName();
461    
462                    if (_log.isDebugEnabled()) {
463                            _log.debug("Invoking deploy for " + servletContextName);
464                    }
465    
466                    String xml = HttpUtil.URLtoString(
467                            servletContext.getResource("/WEB-INF/liferay-hook.xml"));
468    
469                    if (xml == null) {
470                            return;
471                    }
472    
473                    if (_log.isInfoEnabled()) {
474                            _log.info("Registering hook for " + servletContextName);
475                    }
476    
477                    _servletContextNames.add(servletContextName);
478    
479                    Document document = UnsecureSAXReaderUtil.read(xml, true);
480    
481                    Element rootElement = document.getRootElement();
482    
483                    ClassLoader portletClassLoader = hotDeployEvent.getContextClassLoader();
484    
485                    initPortalProperties(
486                            servletContextName, portletClassLoader, rootElement);
487    
488                    initLanguageProperties(
489                            servletContextName, portletClassLoader, rootElement);
490    
491                    try {
492                            initCustomJspDir(
493                                    servletContext, servletContextName, portletClassLoader,
494                                    hotDeployEvent.getPluginPackage(), rootElement);
495                    }
496                    catch (DuplicateCustomJspException dcje) {
497                            if (_log.isWarnEnabled()) {
498                                    _log.warn(servletContextName + " will be undeployed");
499                            }
500    
501                            HotDeployUtil.fireUndeployEvent(
502                                    new HotDeployEvent(servletContext, portletClassLoader));
503    
504                            DeployManagerUtil.undeploy(servletContextName);
505    
506                            return;
507                    }
508    
509                    initIndexerPostProcessors(
510                            servletContextName, portletClassLoader, rootElement);
511    
512                    initServices(servletContextName, portletClassLoader, rootElement);
513    
514                    initServletFilters(
515                            servletContext, servletContextName, portletClassLoader,
516                            rootElement);
517    
518                    initStrutsActions(servletContextName, portletClassLoader, rootElement);
519    
520                    List<Element> modelListenerElements = rootElement.elements(
521                            "model-listener");
522    
523                    for (Element modelListenerElement : modelListenerElements) {
524                            String modelName = modelListenerElement.elementText("model-name");
525                            String modelListenerClassName = modelListenerElement.elementText(
526                                    "model-listener-class");
527    
528                            initModelListener(
529                                    servletContextName, portletClassLoader, modelName,
530                                    modelListenerClassName);
531                    }
532    
533                    List<Element> eventElements = rootElement.elements("event");
534    
535                    for (Element eventElement : eventElements) {
536                            String eventName = eventElement.elementText("event-type");
537                            String eventClassName = eventElement.elementText("event-class");
538    
539                            initEvent(
540                                    servletContextName, portletClassLoader, eventName,
541                                    eventClassName);
542                    }
543    
544                    // End backwards compatibility for 5.1.0
545    
546                    DirectServletRegistryUtil.clearServlets();
547                    FileAvailabilityUtil.clearAvailabilities();
548    
549                    if (_log.isInfoEnabled()) {
550                            _log.info(
551                                    "Hook for " + servletContextName + " is available for use");
552                    }
553            }
554    
555            protected void doInvokeUndeploy(HotDeployEvent hotDeployEvent)
556                    throws Exception {
557    
558                    ServletContext servletContext = hotDeployEvent.getServletContext();
559    
560                    String servletContextName = servletContext.getServletContextName();
561    
562                    if (_log.isDebugEnabled()) {
563                            _log.debug("Invoking undeploy for " + servletContextName);
564                    }
565    
566                    if (!_servletContextNames.remove(servletContextName)) {
567                            return;
568                    }
569    
570                    HotDeployListenersContainer hotDeployListenersContainer =
571                            _hotDeployListenersContainerMap.remove(servletContextName);
572    
573                    if (hotDeployListenersContainer != null) {
574                            hotDeployListenersContainer.unregisterHotDeployListeners();
575                    }
576    
577                    Properties portalProperties = _portalPropertiesMap.remove(
578                            servletContextName);
579    
580                    if (portalProperties != null) {
581                            destroyPortalProperties(servletContextName, portalProperties);
582                    }
583    
584                    Map<Object, ServiceRegistration<?>> serviceRegistrations =
585                            _serviceRegistrations.remove(servletContextName);
586    
587                    if (serviceRegistrations != null) {
588                            for (ServiceRegistration<?> serviceRegistration :
589                                            serviceRegistrations.values()) {
590    
591                                    serviceRegistration.unregister();
592                            }
593    
594                            serviceRegistrations.clear();
595                    }
596    
597                    if (_log.isInfoEnabled()) {
598                            _log.info("Hook for " + servletContextName + " was unregistered");
599                    }
600            }
601    
602            protected Locale getLocale(String languagePropertiesLocation) {
603                    int x = languagePropertiesLocation.indexOf(CharPool.UNDERLINE);
604                    int y = languagePropertiesLocation.indexOf(".properties");
605    
606                    if ((x == -1) && (y != -1)) {
607                            return new Locale(StringPool.BLANK);
608                    }
609    
610                    Locale locale = null;
611    
612                    if ((x != -1) && (y != -1)) {
613                            String localeKey = languagePropertiesLocation.substring(x + 1, y);
614    
615                            locale = LocaleUtil.fromLanguageId(localeKey, true, false);
616                    }
617    
618                    return locale;
619            }
620    
621            protected BasePersistence<?> getPersistence(
622                    String servletContextName, String modelName) {
623    
624                    int pos = modelName.lastIndexOf(CharPool.PERIOD);
625    
626                    String entityName = modelName.substring(pos + 1);
627    
628                    pos = modelName.lastIndexOf(".model.");
629    
630                    String packagePath = modelName.substring(0, pos);
631    
632                    String beanName =
633                            packagePath + ".service.persistence." + entityName + "Persistence";
634    
635                    try {
636                            return (BasePersistence<?>)PortalBeanLocatorUtil.locate(beanName);
637                    }
638                    catch (BeanLocatorException ble) {
639                            return (BasePersistence<?>)PortletBeanLocatorUtil.locate(
640                                    servletContextName, beanName);
641                    }
642            }
643    
644            protected Map<Object, ServiceRegistration<?>> getServiceRegistrations(
645                    String servletContextName) {
646    
647                    Map<Object, ServiceRegistration<?>> serviceRegistrations =
648                            _serviceRegistrations.get(servletContextName);
649    
650                    if (serviceRegistrations == null) {
651                            serviceRegistrations = newMap();
652    
653                            _serviceRegistrations.put(servletContextName, serviceRegistrations);
654                    }
655    
656                    return serviceRegistrations;
657            }
658    
659            protected void initAuthenticators(
660                            String servletContextName, ClassLoader portletClassLoader,
661                            Properties portalProperties)
662                    throws Exception {
663    
664                    initAuthenticators(
665                            servletContextName, portletClassLoader, portalProperties,
666                            AUTH_PIPELINE_PRE);
667                    initAuthenticators(
668                            servletContextName, portletClassLoader, portalProperties,
669                            AUTH_PIPELINE_POST);
670            }
671    
672            protected void initAuthenticators(
673                            String servletContextName, ClassLoader portletClassLoader,
674                            Properties portalProperties, String key)
675                    throws Exception {
676    
677                    String[] authenticatorClassNames = StringUtil.split(
678                            portalProperties.getProperty(key));
679    
680                    for (String authenticatorClassName : authenticatorClassNames) {
681                            Authenticator authenticator = (Authenticator)newInstance(
682                                    portletClassLoader, Authenticator.class,
683                                    authenticatorClassName);
684    
685                            registerService(
686                                    servletContextName, authenticatorClassName, Authenticator.class,
687                                    authenticator, "key", key);
688                    }
689            }
690    
691            protected void initAuthFailures(
692                            String servletContextName, ClassLoader portletClassLoader,
693                            Properties portalProperties)
694                    throws Exception {
695    
696                    initAuthFailures(
697                            servletContextName, portletClassLoader, portalProperties,
698                            AUTH_FAILURE);
699                    initAuthFailures(
700                            servletContextName, portletClassLoader, portalProperties,
701                            AUTH_MAX_FAILURES);
702            }
703    
704            protected void initAuthFailures(
705                            String servletContextName, ClassLoader portletClassLoader,
706                            Properties portalProperties, String key)
707                    throws Exception {
708    
709                    String[] authFailureClassNames = StringUtil.split(
710                            portalProperties.getProperty(key));
711    
712                    for (String authFailureClassName : authFailureClassNames) {
713                            AuthFailure authFailure = (AuthFailure)newInstance(
714                                    portletClassLoader, AuthFailure.class, authFailureClassName);
715    
716                            registerService(
717                                    servletContextName, authFailureClassName, AuthFailure.class,
718                                    authFailure, "key", key);
719                    }
720            }
721    
722            protected void initAuthPublicPaths(
723                            String servletContextName, Properties portalProperties)
724                    throws Exception {
725    
726                    String[] authPublicPaths = StringUtil.split(
727                            portalProperties.getProperty(AUTH_PUBLIC_PATHS));
728    
729                    for (String authPublicPath : authPublicPaths) {
730                            registerService(
731                                    servletContextName, AUTH_PUBLIC_PATHS + authPublicPath,
732                                    Object.class, new Object(), "auth.public.path", authPublicPath);
733                    }
734            }
735    
736            protected void initAuthVerifiers(
737                            String servletContextName, ClassLoader portletClassLoader,
738                            Properties portalProperties)
739                    throws Exception {
740    
741                    String[] authVerifierClassNames = StringUtil.split(
742                            portalProperties.getProperty(AUTH_VERIFIER_PIPELINE));
743    
744                    for (String authVerifierClassName : authVerifierClassNames) {
745                            AuthVerifier authVerifier = (AuthVerifier)newInstance(
746                                    portletClassLoader, AuthVerifier.class, authVerifierClassName);
747    
748                            Properties properties = PropertiesUtil.getProperties(
749                                    portalProperties,
750                                    AuthVerifierPipeline.getAuthVerifierPropertyName(
751                                            authVerifierClassName),
752                                    true);
753    
754                            registerService(
755                                    servletContextName, authVerifierClassName, AuthVerifier.class,
756                                    authVerifier, properties);
757                    }
758            }
759    
760            protected void initAutoDeployListeners(
761                            String servletContextName, ClassLoader portletClassLoader,
762                            Properties portalProperties)
763                    throws Exception {
764    
765                    String[] autoDeployListenerClassNames = StringUtil.split(
766                            portalProperties.getProperty(PropsKeys.AUTO_DEPLOY_LISTENERS));
767    
768                    if (autoDeployListenerClassNames.length == 0) {
769                            return;
770                    }
771    
772                    for (String autoDeployListenerClassName :
773                                    autoDeployListenerClassNames) {
774    
775                            AutoDeployListener autoDeployListener =
776                                    (AutoDeployListener)newInstance(
777                                            portletClassLoader, AutoDeployListener.class,
778                                            autoDeployListenerClassName);
779    
780                            registerService(
781                                    servletContextName, autoDeployListenerClassName,
782                                    AutoDeployListener.class, autoDeployListener);
783                    }
784            }
785    
786            protected void initAutoLogins(
787                            String servletContextName, ClassLoader portletClassLoader,
788                            Properties portalProperties)
789                    throws Exception {
790    
791                    String[] autoLoginClassNames = StringUtil.split(
792                            portalProperties.getProperty(AUTO_LOGIN_HOOKS));
793    
794                    for (String autoLoginClassName : autoLoginClassNames) {
795                            AutoLogin autoLogin = (AutoLogin)newInstance(
796                                    portletClassLoader, AutoLogin.class, autoLoginClassName);
797    
798                            registerService(
799                                    servletContextName, autoLoginClassName, AutoLogin.class,
800                                    autoLogin);
801                    }
802            }
803    
804            protected void initCustomJspDir(
805                            ServletContext servletContext, String servletContextName,
806                            ClassLoader portletClassLoader, PluginPackage pluginPackage,
807                            Element rootElement)
808                    throws Exception {
809    
810                    String customJspDir = rootElement.elementText("custom-jsp-dir");
811    
812                    if (Validator.isNull(customJspDir)) {
813                            return;
814                    }
815    
816                    if (!checkPermission(
817                                    PACLConstants.PORTAL_HOOK_PERMISSION_CUSTOM_JSP_DIR,
818                                    portletClassLoader, null, "Rejecting custom JSP directory")) {
819    
820                            return;
821                    }
822    
823                    if (_log.isDebugEnabled()) {
824                            _log.debug("Custom JSP directory: " + customJspDir);
825                    }
826    
827                    boolean customJspGlobal = GetterUtil.getBoolean(
828                            rootElement.elementText("custom-jsp-global"), true);
829    
830                    CustomJspBag customJspBag = new CustomJspBagImpl(
831                            new ServletContextURLContainer(servletContext), customJspDir,
832                            customJspGlobal);
833    
834                    registerService(
835                            servletContextName, "customJsp", CustomJspBag.class, customJspBag,
836                            "context.id", servletContextName, "context.name",
837                            pluginPackage.getName());
838            }
839    
840            protected void initEvent(
841                            String servletContextName, ClassLoader portletClassLoader,
842                            String eventName, String eventClassName)
843                    throws Exception {
844    
845                    if (eventName.equals(APPLICATION_STARTUP_EVENTS)) {
846                            Class<?> clazz = portletClassLoader.loadClass(eventClassName);
847    
848                            SimpleAction simpleAction = (SimpleAction)clazz.newInstance();
849    
850                            simpleAction = new InvokerSimpleAction(
851                                    simpleAction, portletClassLoader);
852    
853                            Long companyId = CompanyThreadLocal.getCompanyId();
854    
855                            try {
856                                    long[] companyIds = PortalInstances.getCompanyIds();
857    
858                                    for (long curCompanyId : companyIds) {
859                                            CompanyThreadLocal.setCompanyId(curCompanyId);
860    
861                                            simpleAction.run(
862                                                    new String[] {String.valueOf(curCompanyId)});
863                                    }
864                            }
865                            finally {
866                                    CompanyThreadLocal.setCompanyId(companyId);
867                            }
868                    }
869    
870                    if (_propsKeysEvents.contains(eventName)) {
871                            Class<?> clazz = portletClassLoader.loadClass(eventClassName);
872    
873                            Action action = (Action)clazz.newInstance();
874    
875                            action = new InvokerAction(action, portletClassLoader);
876    
877                            registerService(
878                                    servletContextName, eventClassName, LifecycleAction.class,
879                                    action, "key", eventName);
880                    }
881    
882                    if (_propsKeysSessionEvents.contains(eventName)) {
883                            Class<?> clazz = portletClassLoader.loadClass(eventClassName);
884    
885                            SessionAction sessionAction = (SessionAction)clazz.newInstance();
886    
887                            sessionAction = new InvokerSessionAction(
888                                    sessionAction, portletClassLoader);
889    
890                            registerService(
891                                    servletContextName, eventClassName, LifecycleAction.class,
892                                    sessionAction, "key", eventName);
893                    }
894            }
895    
896            protected void initEvents(
897                            String servletContextName, ClassLoader portletClassLoader,
898                            Properties portalProperties)
899                    throws Exception {
900    
901                    for (Map.Entry<Object, Object> entry : portalProperties.entrySet()) {
902                            String key = (String)entry.getKey();
903    
904                            if (!key.equals(APPLICATION_STARTUP_EVENTS) &&
905                                    !_propsKeysEvents.contains(key) &&
906                                    !_propsKeysSessionEvents.contains(key)) {
907    
908                                    continue;
909                            }
910    
911                            String eventName = key;
912                            String[] eventClassNames = StringUtil.split(
913                                    (String)entry.getValue());
914    
915                            for (String eventClassName : eventClassNames) {
916                                    initEvent(
917                                            servletContextName, portletClassLoader, eventName,
918                                            eventClassName);
919                            }
920                    }
921            }
922    
923            protected void initFormNavigatorEntries(
924                            String servletContextName, Properties portalProperties)
925                    throws Exception {
926    
927                    initFormNavigatorEntry(
928                            servletContextName, portalProperties,
929                            COMPANY_SETTINGS_FORM_CONFIGURATION,
930                            FormNavigatorConstants.CATEGORY_KEY_COMPANY_SETTINGS_CONFIGURATION,
931                            FormNavigatorConstants.FORM_NAVIGATOR_ID_COMPANY_SETTINGS,
932                            "portal_settings");
933                    initFormNavigatorEntry(
934                            servletContextName, portalProperties,
935                            COMPANY_SETTINGS_FORM_IDENTIFICATION,
936                            FormNavigatorConstants.CATEGORY_KEY_COMPANY_SETTINGS_IDENTIFICATION,
937                            FormNavigatorConstants.FORM_NAVIGATOR_ID_COMPANY_SETTINGS,
938                            "portal_settings");
939                    initFormNavigatorEntry(
940                            servletContextName, portalProperties,
941                            COMPANY_SETTINGS_FORM_MISCELLANEOUS,
942                            FormNavigatorConstants.CATEGORY_KEY_COMPANY_SETTINGS_MISCELLANEOUS,
943                            FormNavigatorConstants.FORM_NAVIGATOR_ID_COMPANY_SETTINGS,
944                            "portal_settings");
945                    initFormNavigatorEntry(
946                            servletContextName, portalProperties, COMPANY_SETTINGS_FORM_SOCIAL,
947                            FormNavigatorConstants.CATEGORY_KEY_COMPANY_SETTINGS_SOCIAL,
948                            FormNavigatorConstants.FORM_NAVIGATOR_ID_COMPANY_SETTINGS,
949                            "portal_settings");
950    
951                    initFormNavigatorEntry(
952                            servletContextName, portalProperties, LAYOUT_FORM_ADD,
953                            StringPool.BLANK, FormNavigatorConstants.FORM_NAVIGATOR_ID_LAYOUT,
954                            "layouts_admin/layout");
955                    initFormNavigatorEntry(
956                            servletContextName, portalProperties, LAYOUT_FORM_UPDATE,
957                            StringPool.BLANK, FormNavigatorConstants.FORM_NAVIGATOR_ID_LAYOUT,
958                            "layouts_admin/layout");
959    
960                    initFormNavigatorEntry(
961                            servletContextName, portalProperties, LAYOUT_SET_FORM_UPDATE,
962                            StringPool.BLANK,
963                            FormNavigatorConstants.FORM_NAVIGATOR_ID_LAYOUT_SET,
964                            "layouts_admin/layout_set");
965    
966                    initFormNavigatorEntry(
967                            servletContextName, portalProperties,
968                            ORGANIZATIONS_FORM_ADD_IDENTIFICATION,
969                            FormNavigatorConstants.CATEGORY_KEY_ORGANIZATION_IDENTIFICATION,
970                            FormNavigatorConstants.FORM_NAVIGATOR_ID_ORGANIZATIONS,
971                            "users_admin/organization");
972                    initFormNavigatorEntry(
973                            servletContextName, portalProperties, ORGANIZATIONS_FORM_ADD_MAIN,
974                            FormNavigatorConstants.
975                                    CATEGORY_KEY_ORGANIZATION_ORGANIZATION_INFORMATION,
976                            FormNavigatorConstants.FORM_NAVIGATOR_ID_ORGANIZATIONS,
977                            "users_admin/organization");
978                    initFormNavigatorEntry(
979                            servletContextName, portalProperties,
980                            ORGANIZATIONS_FORM_ADD_MISCELLANEOUS,
981                            FormNavigatorConstants.CATEGORY_KEY_ORGANIZATION_MISCELLANEOUS,
982                            FormNavigatorConstants.FORM_NAVIGATOR_ID_ORGANIZATIONS,
983                            "users_admin/organization");
984                    initFormNavigatorEntry(
985                            servletContextName, portalProperties,
986                            ORGANIZATIONS_FORM_UPDATE_IDENTIFICATION,
987                            FormNavigatorConstants.CATEGORY_KEY_ORGANIZATION_IDENTIFICATION,
988                            FormNavigatorConstants.FORM_NAVIGATOR_ID_ORGANIZATIONS,
989                            "users_admin/organization");
990                    initFormNavigatorEntry(
991                            servletContextName, portalProperties,
992                            ORGANIZATIONS_FORM_UPDATE_MAIN,
993                            FormNavigatorConstants.
994                                    CATEGORY_KEY_ORGANIZATION_ORGANIZATION_INFORMATION,
995                            FormNavigatorConstants.FORM_NAVIGATOR_ID_ORGANIZATIONS,
996                            "users_admin/organization");
997                    initFormNavigatorEntry(
998                            servletContextName, portalProperties,
999                            ORGANIZATIONS_FORM_UPDATE_MISCELLANEOUS,
1000                            FormNavigatorConstants.CATEGORY_KEY_ORGANIZATION_MISCELLANEOUS,
1001                            FormNavigatorConstants.FORM_NAVIGATOR_ID_ORGANIZATIONS,
1002                            "users_admin/organization");
1003    
1004                    initFormNavigatorEntry(
1005                            servletContextName, portalProperties, SITES_FORM_ADD_ADVANCED,
1006                            FormNavigatorConstants.CATEGORY_KEY_SITES_ADVANCED,
1007                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1008                    initFormNavigatorEntry(
1009                            servletContextName, portalProperties, SITES_FORM_ADD_MAIN,
1010                            FormNavigatorConstants.CATEGORY_KEY_SITES_GENERAL,
1011                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1012                    initFormNavigatorEntry(
1013                            servletContextName, portalProperties, SITES_FORM_ADD_MISCELLANEOUS,
1014                            FormNavigatorConstants.CATEGORY_KEY_SITES_LANGUAGES,
1015                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1016                    initFormNavigatorEntry(
1017                            servletContextName, portalProperties, SITES_FORM_ADD_SEO,
1018                            FormNavigatorConstants.CATEGORY_KEY_SITES_SEO,
1019                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1020                    initFormNavigatorEntry(
1021                            servletContextName, portalProperties, SITES_FORM_UPDATE_ADVANCED,
1022                            FormNavigatorConstants.CATEGORY_KEY_SITES_ADVANCED,
1023                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1024                    initFormNavigatorEntry(
1025                            servletContextName, portalProperties, SITES_FORM_UPDATE_MAIN,
1026                            FormNavigatorConstants.CATEGORY_KEY_SITES_GENERAL,
1027                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1028                    initFormNavigatorEntry(
1029                            servletContextName, portalProperties,
1030                            SITES_FORM_UPDATE_MISCELLANEOUS,
1031                            FormNavigatorConstants.CATEGORY_KEY_SITES_LANGUAGES,
1032                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1033                    initFormNavigatorEntry(
1034                            servletContextName, portalProperties, SITES_FORM_UPDATE_SEO,
1035                            FormNavigatorConstants.CATEGORY_KEY_SITES_SEO,
1036                            FormNavigatorConstants.FORM_NAVIGATOR_ID_SITES, "sites_admin/site");
1037    
1038                    initFormNavigatorEntry(
1039                            servletContextName, portalProperties, USERS_FORM_ADD_IDENTIFICATION,
1040                            FormNavigatorConstants.CATEGORY_KEY_USER_IDENTIFICATION,
1041                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1042                    initFormNavigatorEntry(
1043                            servletContextName, portalProperties, USERS_FORM_ADD_MAIN,
1044                            FormNavigatorConstants.CATEGORY_KEY_USER_USER_INFORMATION,
1045                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1046                    initFormNavigatorEntry(
1047                            servletContextName, portalProperties, USERS_FORM_ADD_MISCELLANEOUS,
1048                            FormNavigatorConstants.CATEGORY_KEY_USER_MISCELLANEOUS,
1049                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1050                    initFormNavigatorEntry(
1051                            servletContextName, portalProperties,
1052                            USERS_FORM_MY_ACCOUNT_IDENTIFICATION,
1053                            FormNavigatorConstants.CATEGORY_KEY_USER_IDENTIFICATION,
1054                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1055                    initFormNavigatorEntry(
1056                            servletContextName, portalProperties, USERS_FORM_MY_ACCOUNT_MAIN,
1057                            FormNavigatorConstants.CATEGORY_KEY_USER_USER_INFORMATION,
1058                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1059                    initFormNavigatorEntry(
1060                            servletContextName, portalProperties,
1061                            USERS_FORM_MY_ACCOUNT_MISCELLANEOUS,
1062                            FormNavigatorConstants.CATEGORY_KEY_USER_MISCELLANEOUS,
1063                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1064                    initFormNavigatorEntry(
1065                            servletContextName, portalProperties,
1066                            USERS_FORM_UPDATE_IDENTIFICATION,
1067                            FormNavigatorConstants.CATEGORY_KEY_USER_IDENTIFICATION,
1068                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1069                    initFormNavigatorEntry(
1070                            servletContextName, portalProperties, USERS_FORM_UPDATE_MAIN,
1071                            FormNavigatorConstants.CATEGORY_KEY_USER_USER_INFORMATION,
1072                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1073                    initFormNavigatorEntry(
1074                            servletContextName, portalProperties,
1075                            USERS_FORM_UPDATE_MISCELLANEOUS,
1076                            FormNavigatorConstants.CATEGORY_KEY_USER_MISCELLANEOUS,
1077                            FormNavigatorConstants.FORM_NAVIGATOR_ID_USERS, "users_admin/user");
1078            }
1079    
1080            protected void initFormNavigatorEntry(
1081                    String servletContextName, Properties portalProperties,
1082                    String portalPropertiesKey, String categoryKey, String formNavigatorId,
1083                    String jspPath) {
1084    
1085                    String[] formNavigatorSections = StringUtil.split(
1086                            portalProperties.getProperty(portalPropertiesKey));
1087    
1088                    for (int i = 0; i < formNavigatorSections.length; i++) {
1089                            String formNavigatorSection = formNavigatorSections[i];
1090    
1091                            FormNavigatorEntry<Object> deprecatedFormNavigatorEntry =
1092                                    new DeprecatedFormNavigatorEntry(
1093                                            formNavigatorSection, formNavigatorSection, categoryKey,
1094                                            formNavigatorId,
1095                                            "/html/portlet/" + jspPath + "/" + formNavigatorSection +
1096                                                    ".jsp");
1097    
1098                            registerService(
1099                                    servletContextName,
1100                                    formNavigatorId + categoryKey + formNavigatorSection,
1101                                    FormNavigatorEntry.class, deprecatedFormNavigatorEntry,
1102                                    "service.ranking", -i);
1103                    }
1104            }
1105    
1106            protected void initHotDeployListeners(
1107                            String servletContextName, ClassLoader portletClassLoader,
1108                            Properties portalProperties)
1109                    throws Exception {
1110    
1111                    String[] hotDeployListenerClassNames = StringUtil.split(
1112                            portalProperties.getProperty(PropsKeys.HOT_DEPLOY_LISTENERS));
1113    
1114                    if (hotDeployListenerClassNames.length == 0) {
1115                            return;
1116                    }
1117    
1118                    HotDeployListenersContainer hotDeployListenersContainer =
1119                            new HotDeployListenersContainer();
1120    
1121                    _hotDeployListenersContainerMap.put(
1122                            servletContextName, hotDeployListenersContainer);
1123    
1124                    for (String hotDeployListenerClassName : hotDeployListenerClassNames) {
1125                            HotDeployListener hotDeployListener =
1126                                    (HotDeployListener)newInstance(
1127                                            portletClassLoader, HotDeployListener.class,
1128                                            hotDeployListenerClassName);
1129    
1130                            hotDeployListenersContainer.registerHotDeployListener(
1131                                    hotDeployListener);
1132                    }
1133            }
1134    
1135            protected void initIndexerPostProcessors(
1136                            String servletContextName, ClassLoader portletClassLoader,
1137                            Element parentElement)
1138                    throws Exception {
1139    
1140                    List<Element> indexerPostProcessorElements = parentElement.elements(
1141                            "indexer-post-processor");
1142    
1143                    for (Element indexerPostProcessorElement :
1144                                    indexerPostProcessorElements) {
1145    
1146                            String indexerClassName = indexerPostProcessorElement.elementText(
1147                                    "indexer-class-name");
1148    
1149                            if (!checkPermission(
1150                                            PACLConstants.PORTAL_HOOK_PERMISSION_INDEXER,
1151                                            portletClassLoader, indexerClassName,
1152                                            "Rejecting indexer " + indexerClassName)) {
1153    
1154                                    continue;
1155                            }
1156    
1157                            String indexerPostProcessorImpl =
1158                                    indexerPostProcessorElement.elementText(
1159                                            "indexer-post-processor-impl");
1160    
1161                            IndexerPostProcessor indexerPostProcessor =
1162                                    (IndexerPostProcessor)InstanceFactory.newInstance(
1163                                            portletClassLoader, indexerPostProcessorImpl);
1164    
1165                            registerService(
1166                                    servletContextName, indexerPostProcessorImpl,
1167                                    IndexerPostProcessor.class, indexerPostProcessor,
1168                                    "indexer.class.name", indexerClassName);
1169                    }
1170            }
1171    
1172            protected void initLanguageProperties(
1173                            String servletContextName, ClassLoader portletClassLoader,
1174                            Element parentElement)
1175                    throws Exception {
1176    
1177                    List<Element> languagePropertiesElements = parentElement.elements(
1178                            "language-properties");
1179    
1180                    for (Element languagePropertiesElement : languagePropertiesElements) {
1181                            String languagePropertiesLocation =
1182                                    languagePropertiesElement.getText();
1183    
1184                            Locale locale = getLocale(languagePropertiesLocation);
1185    
1186                            if (locale == null) {
1187                                    if (_log.isInfoEnabled()) {
1188                                            _log.info("Ignoring " + languagePropertiesLocation);
1189                                    }
1190    
1191                                    continue;
1192                            }
1193    
1194                            String languageId = LocaleUtil.toLanguageId(locale);
1195    
1196                            if (!StringPool.BLANK.equals(languageId) &&
1197                                    !checkPermission(
1198                                            PACLConstants.
1199                                                    PORTAL_HOOK_PERMISSION_LANGUAGE_PROPERTIES_LOCALE,
1200                                            portletClassLoader, locale, "Rejecting locale " + locale)) {
1201    
1202                                    continue;
1203                            }
1204    
1205                            URL url = portletClassLoader.getResource(
1206                                    languagePropertiesLocation);
1207    
1208                            if (url == null) {
1209                                    continue;
1210                            }
1211    
1212                            try (InputStream inputStream = url.openStream()) {
1213                                    ResourceBundle resourceBundle = new LiferayResourceBundle(
1214                                            inputStream, StringPool.UTF8);
1215    
1216                                    Map<String, Object> properties = new HashMap<>();
1217    
1218                                    properties.put("language.id", languageId);
1219    
1220                                    registerService(
1221                                            servletContextName, languagePropertiesLocation,
1222                                            ResourceBundle.class, resourceBundle, properties);
1223                            }
1224                    }
1225            }
1226    
1227            protected void initModelListener(
1228                            String servletContextName, ClassLoader portletClassLoader,
1229                            String modelName, String modelListenerClassName)
1230                    throws Exception {
1231    
1232                    ModelListener<?> modelListener = (ModelListener<?>)newInstance(
1233                            portletClassLoader, ModelListener.class, modelListenerClassName);
1234    
1235                    registerService(
1236                            servletContextName, modelListenerClassName, ModelListener.class,
1237                            modelListener);
1238            }
1239    
1240            protected void initModelListeners(
1241                            String servletContextName, ClassLoader portletClassLoader,
1242                            Properties portalProperties)
1243                    throws Exception {
1244    
1245                    for (Map.Entry<Object, Object> entry : portalProperties.entrySet()) {
1246                            String key = (String)entry.getKey();
1247    
1248                            if (!key.startsWith(VALUE_OBJECT_LISTENER)) {
1249                                    continue;
1250                            }
1251    
1252                            String modelName = key.substring(VALUE_OBJECT_LISTENER.length());
1253    
1254                            String[] modelListenerClassNames = StringUtil.split(
1255                                    (String)entry.getValue());
1256    
1257                            for (String modelListenerClassName : modelListenerClassNames) {
1258                                    initModelListener(
1259                                            servletContextName, portletClassLoader, modelName,
1260                                            modelListenerClassName);
1261                            }
1262                    }
1263            }
1264    
1265            protected void initPortalProperties(
1266                            String servletContextName, ClassLoader portletClassLoader,
1267                            Element parentElement)
1268                    throws Exception {
1269    
1270                    String portalPropertiesLocation = parentElement.elementText(
1271                            "portal-properties");
1272    
1273                    if (Validator.isNull(portalPropertiesLocation)) {
1274                            return;
1275                    }
1276    
1277                    Configuration portalPropertiesConfiguration = null;
1278    
1279                    try {
1280                            String name = portalPropertiesLocation;
1281    
1282                            int pos = name.lastIndexOf(".properties");
1283    
1284                            if (pos != -1) {
1285                                    name = name.substring(0, pos);
1286                            }
1287    
1288                            portalPropertiesConfiguration =
1289                                    ConfigurationFactoryUtil.getConfiguration(
1290                                            portletClassLoader, name);
1291                    }
1292                    catch (Exception e) {
1293                            _log.error("Unable to read " + portalPropertiesLocation, e);
1294                    }
1295    
1296                    if (portalPropertiesConfiguration == null) {
1297                            return;
1298                    }
1299    
1300                    Properties portalProperties =
1301                            portalPropertiesConfiguration.getProperties();
1302    
1303                    if (portalProperties.isEmpty()) {
1304                            return;
1305                    }
1306    
1307                    Set<Object> set = portalProperties.keySet();
1308    
1309                    Iterator<Object> iterator = set.iterator();
1310    
1311                    while (iterator.hasNext()) {
1312                            String key = (String)iterator.next();
1313    
1314                            if (!checkPermission(
1315                                            PACLConstants.PORTAL_HOOK_PERMISSION_PORTAL_PROPERTIES_KEY,
1316                                            portletClassLoader, key,
1317                                            "Rejecting portal.properties key " + key)) {
1318    
1319                                    iterator.remove();
1320                            }
1321                    }
1322    
1323                    Properties unfilteredPortalProperties =
1324                            (Properties)portalProperties.clone();
1325    
1326                    portalProperties.remove(PropsKeys.RELEASE_INFO_BUILD_NUMBER);
1327                    portalProperties.remove(PropsKeys.RELEASE_INFO_PREVIOUS_BUILD_NUMBER);
1328                    portalProperties.remove(PropsKeys.UPGRADE_PROCESSES);
1329    
1330                    _portalPropertiesMap.put(servletContextName, portalProperties);
1331    
1332                    // Initialize properties, auto logins, model listeners, and events in
1333                    // that specific order. Events have to be loaded last because they may
1334                    // require model listeners to have been registered.
1335    
1336                    initPortalProperties(
1337                            servletContextName, portletClassLoader, portalProperties,
1338                            unfilteredPortalProperties);
1339                    initAuthFailures(
1340                            servletContextName, portletClassLoader, portalProperties);
1341                    initAutoDeployListeners(
1342                            servletContextName, portletClassLoader, portalProperties);
1343                    initAutoLogins(
1344                            servletContextName, portletClassLoader, portalProperties);
1345                    initAuthenticators(
1346                            servletContextName, portletClassLoader, portalProperties);
1347                    initAuthVerifiers(
1348                            servletContextName, portletClassLoader, portalProperties);
1349                    initFormNavigatorEntries(servletContextName, portalProperties);
1350                    initHotDeployListeners(
1351                            servletContextName, portletClassLoader, portalProperties);
1352                    initModelListeners(
1353                            servletContextName, portletClassLoader, portalProperties);
1354                    initEvents(servletContextName, portletClassLoader, portalProperties);
1355            }
1356    
1357            protected void initPortalProperties(
1358                            String servletContextName, ClassLoader portletClassLoader,
1359                            Properties portalProperties, Properties unfilteredPortalProperties)
1360                    throws Exception {
1361    
1362                    PropsUtil.addProperties(portalProperties);
1363    
1364                    if (_log.isDebugEnabled() && portalProperties.containsKey(LOCALES)) {
1365                            _log.debug(
1366                                    "Portlet locales " + portalProperties.getProperty(LOCALES));
1367                            _log.debug("Merged locales " + PropsUtil.get(LOCALES));
1368                            _log.debug(
1369                                    "Merged locales array length " +
1370                                            PropsUtil.getArray(LOCALES).length);
1371                    }
1372    
1373                    for (String key : _PROPS_VALUES_OBSOLETE) {
1374                            if (_log.isInfoEnabled() && portalProperties.contains(key)) {
1375                                    _log.info("Portal property \"" + key + "\" is obsolete");
1376                            }
1377                    }
1378    
1379                    resetPortalProperties(servletContextName, portalProperties, true);
1380    
1381                    if (portalProperties.containsKey(PropsKeys.AUTH_PUBLIC_PATHS)) {
1382                            initAuthPublicPaths(servletContextName, portalProperties);
1383                    }
1384    
1385                    if (portalProperties.containsKey(PropsKeys.AUTH_TOKEN_IMPL)) {
1386                            String authTokenClassName = portalProperties.getProperty(
1387                                    PropsKeys.AUTH_TOKEN_IMPL);
1388    
1389                            AuthToken authToken = (AuthToken)newInstance(
1390                                    portletClassLoader, AuthToken.class, authTokenClassName);
1391    
1392                            registerService(
1393                                    servletContextName, authTokenClassName, AuthToken.class,
1394                                    authToken);
1395                    }
1396    
1397                    if (portalProperties.containsKey(PropsKeys.CAPTCHA_ENGINE_IMPL)) {
1398                            String captchaClassName = portalProperties.getProperty(
1399                                    PropsKeys.CAPTCHA_ENGINE_IMPL);
1400    
1401                            Captcha captcha = (Captcha)newInstance(
1402                                    portletClassLoader, Captcha.class, captchaClassName);
1403    
1404                            CaptchaImpl captchaImpl = null;
1405    
1406                            Captcha currentCaptcha = CaptchaUtil.getCaptcha();
1407    
1408                            if (currentCaptcha instanceof DoPrivilegedBean) {
1409                                    DoPrivilegedBean doPrivilegedBean =
1410                                            (DoPrivilegedBean)currentCaptcha;
1411    
1412                                    captchaImpl = (CaptchaImpl)doPrivilegedBean.getActualBean();
1413                            }
1414                            else {
1415                                    captchaImpl = (CaptchaImpl)currentCaptcha;
1416                            }
1417    
1418                            captchaImpl.setCaptcha(captcha);
1419                    }
1420    
1421                    if (portalProperties.containsKey(
1422                                    PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS)) {
1423    
1424                            String controlPanelEntryClassName = portalProperties.getProperty(
1425                                    PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS);
1426    
1427                            ControlPanelEntry controlPanelEntry =
1428                                    (ControlPanelEntry)newInstance(
1429                                            portletClassLoader, ControlPanelEntry.class,
1430                                            controlPanelEntryClassName);
1431    
1432                            registerService(
1433                                    servletContextName, controlPanelEntryClassName,
1434                                    ControlPanelEntry.class, controlPanelEntry);
1435                    }
1436    
1437                    if (portalProperties.containsKey(PropsKeys.DL_FILE_ENTRY_PROCESSORS)) {
1438                            String[] dlProcessorClassNames = StringUtil.split(
1439                                    portalProperties.getProperty(
1440                                            PropsKeys.DL_FILE_ENTRY_PROCESSORS));
1441    
1442                            DLFileEntryProcessorContainer dlFileEntryProcessorContainer =
1443                                    new DLFileEntryProcessorContainer();
1444    
1445                            _dlFileEntryProcessorContainerMap.put(
1446                                    servletContextName, dlFileEntryProcessorContainer);
1447    
1448                            for (String dlProcessorClassName : dlProcessorClassNames) {
1449                                    DLProcessor dlProcessor =
1450                                            (DLProcessor)InstanceFactory.newInstance(
1451                                                    portletClassLoader, dlProcessorClassName);
1452    
1453                                    dlProcessor = (DLProcessor)newInstance(
1454                                            portletClassLoader,
1455                                            ReflectionUtil.getInterfaces(
1456                                                    dlProcessor, portletClassLoader),
1457                                            dlProcessorClassName);
1458    
1459                                    dlFileEntryProcessorContainer.registerDLProcessor(dlProcessor);
1460                            }
1461                    }
1462    
1463                    if (portalProperties.containsKey(PropsKeys.DL_REPOSITORY_IMPL)) {
1464                            String[] dlRepositoryClassNames = StringUtil.split(
1465                                    portalProperties.getProperty(PropsKeys.DL_REPOSITORY_IMPL));
1466    
1467                            DLRepositoryContainer dlRepositoryContainer =
1468                                    new DLRepositoryContainer();
1469    
1470                            _dlRepositoryContainerMap.put(
1471                                    servletContextName, dlRepositoryContainer);
1472    
1473                            for (String dlRepositoryClassName : dlRepositoryClassNames) {
1474                                    ExternalRepositoryFactory externalRepositoryFactory =
1475                                            new ExternalRepositoryFactoryImpl(
1476                                                    dlRepositoryClassName, portletClassLoader);
1477    
1478                                    ResourceBundleLoader resourceBundleLoader =
1479                                            new CacheResourceBundleLoader(
1480                                                    new ClassResourceBundleLoader(
1481                                                            "content.Language", portletClassLoader));
1482    
1483                                    dlRepositoryContainer.registerRepositoryFactory(
1484                                            dlRepositoryClassName, externalRepositoryFactory,
1485                                            resourceBundleLoader);
1486                            }
1487                    }
1488    
1489                    if (portalProperties.containsKey(PropsKeys.DL_STORE_ANTIVIRUS_IMPL)) {
1490                            String antivirusScannerClassName = portalProperties.getProperty(
1491                                    PropsKeys.DL_STORE_ANTIVIRUS_IMPL);
1492    
1493                            AntivirusScanner antivirusScanner = (AntivirusScanner)newInstance(
1494                                    portletClassLoader, AntivirusScanner.class,
1495                                    antivirusScannerClassName);
1496    
1497                            AntivirusScannerWrapper antivirusScannerWrapper =
1498                                    (AntivirusScannerWrapper)
1499                                            AntivirusScannerUtil.getAntivirusScanner();
1500    
1501                            antivirusScannerWrapper.setAntivirusScanner(antivirusScanner);
1502                    }
1503    
1504                    if (portalProperties.containsKey(PropsKeys.DL_STORE_IMPL)) {
1505                            StoreFactory storeFactory = StoreFactory.getInstance();
1506    
1507                            String storeClassName = portalProperties.getProperty(
1508                                    PropsKeys.DL_STORE_IMPL);
1509    
1510                            storeFactory.setStore(storeClassName);
1511                    }
1512    
1513                    if (portalProperties.containsKey(
1514                                    PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL)) {
1515    
1516                            String attributesTransformerClassName =
1517                                    portalProperties.getProperty(
1518                                            PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL);
1519    
1520                            AttributesTransformer attributesTransformer =
1521                                    (AttributesTransformer)newInstance(
1522                                            portletClassLoader, AttributesTransformer.class,
1523                                            attributesTransformerClassName);
1524    
1525                            registerService(
1526                                    servletContextName, attributesTransformerClassName,
1527                                    AttributesTransformer.class, attributesTransformer);
1528                    }
1529    
1530                    if (portalProperties.containsKey(LOCK_LISTENERS)) {
1531                            String[] lockListenerClassNames = StringUtil.split(
1532                                    portalProperties.getProperty(LOCK_LISTENERS));
1533    
1534                            for (String lockListenerClassName : lockListenerClassNames) {
1535                                    LockListener lockListener = (LockListener)newInstance(
1536                                            portletClassLoader, LockListener.class,
1537                                            lockListenerClassName);
1538    
1539                                    registerService(
1540                                            servletContextName, lockListenerClassName,
1541                                            LockListener.class, lockListener);
1542                            }
1543                    }
1544    
1545                    if (portalProperties.containsKey(PropsKeys.MAIL_HOOK_IMPL)) {
1546                            String mailHookClassName = portalProperties.getProperty(
1547                                    PropsKeys.MAIL_HOOK_IMPL);
1548    
1549                            com.liferay.mail.kernel.util.Hook mailHook =
1550                                    (com.liferay.mail.kernel.util.Hook)newInstance(
1551                                            portletClassLoader, com.liferay.mail.kernel.util.Hook.class,
1552                                            mailHookClassName);
1553    
1554                            registerService(
1555                                    servletContextName, mailHookClassName,
1556                                    com.liferay.mail.kernel.util.Hook.class, mailHook);
1557                    }
1558    
1559                    if (portalProperties.containsKey(
1560                                    PropsKeys.MEMBERSHIP_POLICY_ORGANIZATIONS)) {
1561    
1562                            String organizationMembershipPolicyClassName =
1563                                    portalProperties.getProperty(
1564                                            PropsKeys.MEMBERSHIP_POLICY_ORGANIZATIONS);
1565    
1566                            OrganizationMembershipPolicy organizationMembershipPolicy =
1567                                    (OrganizationMembershipPolicy)newInstance(
1568                                            portletClassLoader, OrganizationMembershipPolicy.class,
1569                                            organizationMembershipPolicyClassName);
1570    
1571                            registerService(
1572                                    servletContextName, organizationMembershipPolicyClassName,
1573                                    OrganizationMembershipPolicy.class,
1574                                    organizationMembershipPolicy);
1575                    }
1576    
1577                    if (portalProperties.containsKey(PropsKeys.MEMBERSHIP_POLICY_ROLES)) {
1578                            String roleMembershipPolicyClassName = portalProperties.getProperty(
1579                                    PropsKeys.MEMBERSHIP_POLICY_ROLES);
1580    
1581                            RoleMembershipPolicy roleMembershipPolicy =
1582                                    (RoleMembershipPolicy)newInstance(
1583                                            portletClassLoader, RoleMembershipPolicy.class,
1584                                            roleMembershipPolicyClassName);
1585    
1586                            registerService(
1587                                    servletContextName, roleMembershipPolicyClassName,
1588                                    RoleMembershipPolicy.class, roleMembershipPolicy);
1589                    }
1590    
1591                    if (portalProperties.containsKey(PropsKeys.MEMBERSHIP_POLICY_SITES)) {
1592                            String siteMembershipPolicyClassName = portalProperties.getProperty(
1593                                    PropsKeys.MEMBERSHIP_POLICY_SITES);
1594    
1595                            SiteMembershipPolicy siteMembershipPolicy =
1596                                    (SiteMembershipPolicy)newInstance(
1597                                            portletClassLoader, SiteMembershipPolicy.class,
1598                                            siteMembershipPolicyClassName);
1599    
1600                            registerService(
1601                                    servletContextName, siteMembershipPolicyClassName,
1602                                    SiteMembershipPolicy.class, siteMembershipPolicy);
1603                    }
1604    
1605                    if (portalProperties.containsKey(
1606                                    PropsKeys.MEMBERSHIP_POLICY_USER_GROUPS)) {
1607    
1608                            String userGroupMembershipPolicyClassName =
1609                                    portalProperties.getProperty(
1610                                            PropsKeys.MEMBERSHIP_POLICY_USER_GROUPS);
1611    
1612                            UserGroupMembershipPolicy userGroupMembershipPolicy =
1613                                    (UserGroupMembershipPolicy)newInstance(
1614                                            portletClassLoader, UserGroupMembershipPolicy.class,
1615                                            userGroupMembershipPolicyClassName);
1616    
1617                            registerService(
1618                                    servletContextName, userGroupMembershipPolicyClassName,
1619                                    UserGroupMembershipPolicy.class, userGroupMembershipPolicy);
1620                    }
1621    
1622                    if (portalProperties.containsKey(PropsKeys.PASSWORDS_TOOLKIT)) {
1623                            String toolkitClassName = portalProperties.getProperty(
1624                                    PropsKeys.PASSWORDS_TOOLKIT);
1625    
1626                            Toolkit toolkit = (Toolkit)newInstance(
1627                                    portletClassLoader, Toolkit.class, toolkitClassName);
1628    
1629                            registerService(
1630                                    servletContextName, toolkitClassName, Toolkit.class, toolkit);
1631                    }
1632    
1633                    if (portalProperties.containsKey(PropsKeys.PHONE_NUMBER_FORMAT_IMPL)) {
1634                            String phoneNumberFormatClassName = portalProperties.getProperty(
1635                                    PropsKeys.PHONE_NUMBER_FORMAT_IMPL);
1636    
1637                            PhoneNumberFormat phoneNumberFormat =
1638                                    (PhoneNumberFormat)newInstance(
1639                                            portletClassLoader, PhoneNumberFormat.class,
1640                                            phoneNumberFormatClassName);
1641    
1642                            registerService(
1643                                    servletContextName, phoneNumberFormatClassName,
1644                                    PhoneNumberFormat.class, phoneNumberFormat);
1645                    }
1646    
1647                    if (portalProperties.containsKey(PropsKeys.SANITIZER_IMPL)) {
1648                            String[] sanitizerClassNames = StringUtil.split(
1649                                    portalProperties.getProperty(PropsKeys.SANITIZER_IMPL));
1650    
1651                            for (String sanitizerClassName : sanitizerClassNames) {
1652                                    Sanitizer sanitizer = (Sanitizer)newInstance(
1653                                            portletClassLoader, Sanitizer.class, sanitizerClassName);
1654    
1655                                    registerService(
1656                                            servletContextName, sanitizerClassName, Sanitizer.class,
1657                                            sanitizer);
1658                            }
1659                    }
1660    
1661                    if (portalProperties.containsKey(
1662                                    PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR)) {
1663    
1664                            String emailAddressGeneratorClassName =
1665                                    portalProperties.getProperty(
1666                                            PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR);
1667    
1668                            EmailAddressGenerator emailAddressGenerator =
1669                                    (EmailAddressGenerator)newInstance(
1670                                            portletClassLoader, EmailAddressGenerator.class,
1671                                            emailAddressGeneratorClassName);
1672    
1673                            registerService(
1674                                    servletContextName, emailAddressGeneratorClassName,
1675                                    EmailAddressGenerator.class, emailAddressGenerator);
1676                    }
1677    
1678                    if (portalProperties.containsKey(
1679                                    PropsKeys.USERS_EMAIL_ADDRESS_VALIDATOR)) {
1680    
1681                            String emailAddressValidatorClassName =
1682                                    portalProperties.getProperty(
1683                                            PropsKeys.USERS_EMAIL_ADDRESS_VALIDATOR);
1684    
1685                            EmailAddressValidator emailAddressValidator =
1686                                    (EmailAddressValidator)newInstance(
1687                                            portletClassLoader, EmailAddressValidator.class,
1688                                            emailAddressValidatorClassName);
1689    
1690                            registerService(
1691                                    servletContextName, emailAddressValidatorClassName,
1692                                    EmailAddressValidator.class, emailAddressValidator);
1693                    }
1694    
1695                    if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_GENERATOR)) {
1696                            String fullNameGeneratorClassName = portalProperties.getProperty(
1697                                    PropsKeys.USERS_FULL_NAME_GENERATOR);
1698    
1699                            FullNameGenerator fullNameGenerator =
1700                                    (FullNameGenerator)newInstance(
1701                                            portletClassLoader, FullNameGenerator.class,
1702                                            fullNameGeneratorClassName);
1703    
1704                            registerService(
1705                                    servletContextName, fullNameGeneratorClassName,
1706                                    FullNameGenerator.class, fullNameGenerator);
1707                    }
1708    
1709                    if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_VALIDATOR)) {
1710                            String fullNameValidatorClassName = portalProperties.getProperty(
1711                                    PropsKeys.USERS_FULL_NAME_VALIDATOR);
1712    
1713                            FullNameValidator fullNameValidator =
1714                                    (FullNameValidator)newInstance(
1715                                            portletClassLoader, FullNameValidator.class,
1716                                            fullNameValidatorClassName);
1717    
1718                            registerService(
1719                                    servletContextName, fullNameValidatorClassName,
1720                                    FullNameValidator.class, fullNameValidator);
1721                    }
1722    
1723                    if (portalProperties.containsKey(
1724                                    PropsKeys.USERS_SCREEN_NAME_GENERATOR)) {
1725    
1726                            String screenNameGeneratorClassName = portalProperties.getProperty(
1727                                    PropsKeys.USERS_SCREEN_NAME_GENERATOR);
1728    
1729                            ScreenNameGenerator screenNameGenerator =
1730                                    (ScreenNameGenerator)newInstance(
1731                                            portletClassLoader, ScreenNameGenerator.class,
1732                                            screenNameGeneratorClassName);
1733    
1734                            registerService(
1735                                    servletContextName, screenNameGeneratorClassName,
1736                                    ScreenNameGenerator.class, screenNameGenerator);
1737                    }
1738    
1739                    if (portalProperties.containsKey(
1740                                    PropsKeys.USERS_SCREEN_NAME_VALIDATOR)) {
1741    
1742                            String screenNameValidatorClassName = portalProperties.getProperty(
1743                                    PropsKeys.USERS_SCREEN_NAME_VALIDATOR);
1744    
1745                            ScreenNameValidator screenNameValidator =
1746                                    (ScreenNameValidator)newInstance(
1747                                            portletClassLoader, ScreenNameValidator.class,
1748                                            screenNameValidatorClassName);
1749    
1750                            registerService(
1751                                    servletContextName, screenNameValidatorClassName,
1752                                    ScreenNameValidator.class, screenNameValidator);
1753                    }
1754    
1755                    for (String tokenWhitelistName : _TOKEN_WHITELIST_NAMES) {
1756                            if (containsKey(portalProperties, tokenWhitelistName)) {
1757                                    initTokensWhitelists(servletContextName, portalProperties);
1758    
1759                                    break;
1760                            }
1761                    }
1762    
1763                    Set<String> liferayFilterClassNames =
1764                            LiferayFilterTracker.getClassNames();
1765    
1766                    for (String liferayFilterClassName : liferayFilterClassNames) {
1767                            if (!portalProperties.containsKey(liferayFilterClassName)) {
1768                                    continue;
1769                            }
1770    
1771                            boolean filterEnabled = GetterUtil.getBoolean(
1772                                    portalProperties.getProperty(liferayFilterClassName));
1773    
1774                            Set<LiferayFilter> liferayFilters =
1775                                    LiferayFilterTracker.getLiferayFilters(liferayFilterClassName);
1776    
1777                            for (LiferayFilter liferayFilter : liferayFilters) {
1778                                    liferayFilter.setFilterEnabled(filterEnabled);
1779                            }
1780                    }
1781    
1782                    if (unfilteredPortalProperties.containsKey(
1783                                    PropsKeys.RELEASE_INFO_BUILD_NUMBER) ||
1784                            unfilteredPortalProperties.containsKey(
1785                                    PropsKeys.UPGRADE_PROCESSES)) {
1786    
1787                            String[] upgradeProcessClassNames = StringUtil.split(
1788                                    unfilteredPortalProperties.getProperty(
1789                                            PropsKeys.UPGRADE_PROCESSES));
1790    
1791                            List<UpgradeProcess> upgradeProcesses =
1792                                    UpgradeProcessUtil.initUpgradeProcesses(
1793                                            portletClassLoader, upgradeProcessClassNames);
1794    
1795                            ReleaseLocalServiceUtil.updateRelease(
1796                                    servletContextName, upgradeProcesses,
1797                                    unfilteredPortalProperties);
1798                    }
1799            }
1800    
1801            protected void initServices(
1802                            String servletContextName, ClassLoader portletClassLoader,
1803                            Element parentElement)
1804                    throws Exception {
1805    
1806                    List<Element> serviceElements = parentElement.elements("service");
1807    
1808                    for (Element serviceElement : serviceElements) {
1809                            String serviceType = serviceElement.elementText("service-type");
1810                            String serviceImpl = serviceElement.elementText("service-impl");
1811    
1812                            if (!checkPermission(
1813                                            PACLConstants.PORTAL_HOOK_PERMISSION_SERVICE,
1814                                            portletClassLoader, serviceType,
1815                                            "Rejecting service " + serviceImpl)) {
1816    
1817                                    continue;
1818                            }
1819    
1820                            Class<?> serviceTypeClass = portletClassLoader.loadClass(
1821                                    serviceType);
1822    
1823                            Class<?> serviceImplClass = portletClassLoader.loadClass(
1824                                    serviceImpl);
1825    
1826                            Constructor<?> serviceImplConstructor =
1827                                    serviceImplClass.getConstructor(
1828                                            new Class<?>[] {serviceTypeClass});
1829    
1830                            Object serviceProxy = null;
1831    
1832                            try {
1833                                    serviceProxy = PortalBeanLocatorUtil.locate(serviceType);
1834                            }
1835                            catch (BeanLocatorException ble) {
1836                                    Registry registry = RegistryUtil.getRegistry();
1837    
1838                                    serviceProxy = registry.getService(serviceTypeClass);
1839                            }
1840    
1841                            if (ProxyUtil.isProxyClass(serviceProxy.getClass())) {
1842                                    initServices(
1843                                            servletContextName, portletClassLoader, serviceType,
1844                                            serviceTypeClass, serviceImplConstructor, serviceProxy);
1845                            }
1846                            else {
1847                                    _log.error(
1848                                            "Service hooks require Spring to be configured to use " +
1849                                                    "JdkDynamicProxy and will not work with CGLIB");
1850                            }
1851                    }
1852            }
1853    
1854            protected void initServices(
1855                            String servletContextName, ClassLoader portletClassLoader,
1856                            String serviceType, Class<?> serviceTypeClass,
1857                            Constructor<?> serviceImplConstructor, Object serviceProxy)
1858                    throws Exception {
1859    
1860                    AdvisedSupport advisedSupport = ServiceBeanAopProxy.getAdvisedSupport(
1861                            serviceProxy);
1862    
1863                    TargetSource targetSource = advisedSupport.getTargetSource();
1864    
1865                    Object previousService = targetSource.getTarget();
1866    
1867                    ServiceWrapper<?> serviceWrapper =
1868                            (ServiceWrapper<?>)serviceImplConstructor.newInstance(
1869                                    previousService);
1870    
1871                    registerService(
1872                            servletContextName, serviceImplConstructor, ServiceWrapper.class,
1873                            serviceWrapper);
1874            }
1875    
1876            protected Filter initServletFilter(
1877                            String filterClassName, ClassLoader portletClassLoader)
1878                    throws Exception {
1879    
1880                    Filter filter = (Filter)InstanceFactory.newInstance(
1881                            portletClassLoader, filterClassName);
1882    
1883                    List<Class<?>> interfaces = new ArrayList<>();
1884    
1885                    if (filter instanceof TryFilter) {
1886                            interfaces.add(TryFilter.class);
1887                    }
1888    
1889                    if (filter instanceof TryFinallyFilter) {
1890                            interfaces.add(TryFinallyFilter.class);
1891                    }
1892    
1893                    if (filter instanceof WrapHttpServletRequestFilter) {
1894                            interfaces.add(WrapHttpServletRequestFilter.class);
1895                    }
1896    
1897                    if (filter instanceof WrapHttpServletResponseFilter) {
1898                            interfaces.add(WrapHttpServletResponseFilter.class);
1899                    }
1900    
1901                    if (filter instanceof LiferayFilter) {
1902                            interfaces.add(LiferayFilter.class);
1903                    }
1904                    else {
1905                            interfaces.add(Filter.class);
1906                    }
1907    
1908                    filter = (Filter)ProxyUtil.newProxyInstance(
1909                            portletClassLoader,
1910                            interfaces.toArray(new Class[interfaces.size()]),
1911                            new ClassLoaderBeanHandler(filter, portletClassLoader));
1912    
1913                    return filter;
1914            }
1915    
1916            protected void initServletFilters(
1917                            ServletContext servletContext, String servletContextName,
1918                            ClassLoader portletClassLoader, Element parentElement)
1919                    throws Exception {
1920    
1921                    List<Element> servletFilterElements = parentElement.elements(
1922                            "servlet-filter");
1923    
1924                    if (!servletFilterElements.isEmpty() &&
1925                            !checkPermission(
1926                                    PACLConstants.PORTAL_HOOK_PERMISSION_SERVLET_FILTERS,
1927                                    portletClassLoader, null, "Rejecting servlet filters")) {
1928    
1929                            return;
1930                    }
1931    
1932                    Map<String, Tuple> filterTuples = new HashMap<>();
1933    
1934                    List<Element> servletFilterMappingElements = parentElement.elements(
1935                            "servlet-filter-mapping");
1936    
1937                    for (Element servletFilterMappingElement :
1938                                    servletFilterMappingElements) {
1939    
1940                            String servletFilterName = servletFilterMappingElement.elementText(
1941                                    "servlet-filter-name");
1942                            String afterFilter = servletFilterMappingElement.elementText(
1943                                    "after-filter");
1944                            String beforeFilter = servletFilterMappingElement.elementText(
1945                                    "before-filter");
1946    
1947                            List<Element> urlPatternElements =
1948                                    servletFilterMappingElement.elements("url-pattern");
1949    
1950                            List<String> urlPatterns = new ArrayList<>();
1951    
1952                            for (Element urlPatternElement : urlPatternElements) {
1953                                    String urlPattern = urlPatternElement.getTextTrim();
1954    
1955                                    urlPatterns.add(urlPattern);
1956                            }
1957    
1958                            List<Element> dispatcherElements =
1959                                    servletFilterMappingElement.elements("dispatcher");
1960    
1961                            List<String> dispatchers = new ArrayList<>();
1962    
1963                            for (Element dispatcherElement : dispatcherElements) {
1964                                    String dispatcher = dispatcherElement.getTextTrim();
1965    
1966                                    dispatcher = StringUtil.toUpperCase(dispatcher);
1967    
1968                                    dispatchers.add(dispatcher);
1969                            }
1970    
1971                            filterTuples.put(
1972                                    servletFilterName,
1973                                    new Tuple(afterFilter, beforeFilter, dispatchers, urlPatterns));
1974                    }
1975    
1976                    for (Element servletFilterElement : servletFilterElements) {
1977                            String servletFilterName = servletFilterElement.elementText(
1978                                    "servlet-filter-name");
1979                            String servletFilterImpl = servletFilterElement.elementText(
1980                                    "servlet-filter-impl");
1981    
1982                            List<Element> initParamElements = servletFilterElement.elements(
1983                                    "init-param");
1984    
1985                            Map<String, Object> properties = new HashMap<>();
1986    
1987                            for (Element initParamElement : initParamElements) {
1988                                    String paramName = initParamElement.elementText("param-name");
1989                                    String paramValue = initParamElement.elementText("param-value");
1990    
1991                                    properties.put("init.param." + paramName, paramValue);
1992                            }
1993    
1994                            Tuple filterTuple = filterTuples.get(servletFilterName);
1995    
1996                            properties.put("after-filter", filterTuple.getObject(0));
1997                            properties.put("before-filter", filterTuple.getObject(1));
1998                            properties.put("dispatcher", filterTuple.getObject(2));
1999                            properties.put(
2000                                    "servlet-context-name",
2001                                    PortalContextLoaderListener.getPortalServletContextName());
2002                            properties.put("servlet-filter-name", servletFilterName);
2003                            properties.put("url-pattern", filterTuple.getObject(3));
2004    
2005                            Filter filter = initServletFilter(
2006                                    servletFilterImpl, portletClassLoader);
2007    
2008                            registerService(
2009                                    servletContextName, servletFilterName, Filter.class, filter,
2010                                    properties);
2011                    }
2012            }
2013    
2014            protected void initStrutsAction(
2015                            String servletContextName, ClassLoader portletClassLoader,
2016                            String strutsActionPath, String strutsActionClassName)
2017                    throws Exception {
2018    
2019                    Object strutsActionObject = InstanceFactory.newInstance(
2020                            portletClassLoader, strutsActionClassName);
2021    
2022                    if (strutsActionObject instanceof StrutsAction) {
2023                            StrutsAction strutsAction =
2024                                    (StrutsAction)ProxyUtil.newProxyInstance(
2025                                            portletClassLoader, new Class[] {StrutsAction.class},
2026                                            new ClassLoaderBeanHandler(
2027                                                    strutsActionObject, portletClassLoader));
2028    
2029                            registerService(
2030                                    servletContextName, strutsActionClassName, StrutsAction.class,
2031                                    strutsAction, "path", strutsActionPath);
2032                    }
2033                    else {
2034                            StrutsPortletAction strutsPortletAction =
2035                                    (StrutsPortletAction)ProxyUtil.newProxyInstance(
2036                                            portletClassLoader, new Class[] {StrutsPortletAction.class},
2037                                            new ClassLoaderBeanHandler(
2038                                                    strutsActionObject, portletClassLoader));
2039    
2040                            registerService(
2041                                    servletContextName, strutsActionClassName,
2042                                    StrutsPortletAction.class, strutsPortletAction, "path",
2043                                    strutsActionPath);
2044                    }
2045            }
2046    
2047            protected void initStrutsActions(
2048                            String servletContextName, ClassLoader portletClassLoader,
2049                            Element parentElement)
2050                    throws Exception {
2051    
2052                    List<Element> strutsActionElements = parentElement.elements(
2053                            "struts-action");
2054    
2055                    for (Element strutsActionElement : strutsActionElements) {
2056                            String strutsActionPath = strutsActionElement.elementText(
2057                                    "struts-action-path");
2058    
2059                            if (!checkPermission(
2060                                            PACLConstants.PORTAL_HOOK_PERMISSION_STRUTS_ACTION_PATH,
2061                                            portletClassLoader, strutsActionPath,
2062                                            "Rejecting struts action path " + strutsActionPath)) {
2063    
2064                                    continue;
2065                            }
2066    
2067                            String strutsActionImpl = strutsActionElement.elementText(
2068                                    "struts-action-impl");
2069    
2070                            initStrutsAction(
2071                                    servletContextName, portletClassLoader, strutsActionPath,
2072                                    strutsActionImpl);
2073                    }
2074            }
2075    
2076            protected void initTokensWhitelists(
2077                            String servletContextName, Properties portalProperties)
2078                    throws Exception {
2079    
2080                    for (String tokenWhitelistName : _TOKEN_WHITELIST_NAMES) {
2081                            String propertyValue = portalProperties.getProperty(
2082                                    tokenWhitelistName);
2083    
2084                            if (Validator.isBlank(propertyValue)) {
2085                                    continue;
2086                            }
2087    
2088                            registerService(
2089                                    servletContextName, tokenWhitelistName + propertyValue,
2090                                    Object.class, new Object(), tokenWhitelistName,
2091                                    StringUtil.split(propertyValue));
2092                    }
2093            }
2094    
2095            protected <S, T> Map<S, T> newMap() {
2096                    return new ConcurrentHashMap<>();
2097            }
2098    
2099            protected void resetPortalProperties(
2100                            String servletContextName, Properties portalProperties,
2101                            boolean initPhase)
2102                    throws Exception {
2103    
2104                    for (String key : _PROPS_VALUES_BOOLEAN) {
2105                            String fieldName = StringUtil.replace(
2106                                    StringUtil.toUpperCase(key), CharPool.PERIOD,
2107                                    CharPool.UNDERLINE);
2108    
2109                            if (!containsKey(portalProperties, key)) {
2110                                    continue;
2111                            }
2112    
2113                            try {
2114                                    Field field = PropsValues.class.getField(fieldName);
2115    
2116                                    Boolean value = Boolean.valueOf(
2117                                            GetterUtil.getBoolean(PropsUtil.get(key)));
2118    
2119                                    field.setBoolean(null, value);
2120                            }
2121                            catch (Exception e) {
2122                                    _log.error(
2123                                            "Error setting field " + fieldName + ": " + e.getMessage());
2124                            }
2125                    }
2126    
2127                    for (String key : _PROPS_VALUES_INTEGER) {
2128                            String fieldName = StringUtil.replace(
2129                                    StringUtil.toUpperCase(key), CharPool.PERIOD,
2130                                    CharPool.UNDERLINE);
2131    
2132                            if (!containsKey(portalProperties, key)) {
2133                                    continue;
2134                            }
2135    
2136                            try {
2137                                    Field field = PropsValues.class.getField(fieldName);
2138    
2139                                    Integer value = Integer.valueOf(
2140                                            GetterUtil.getInteger(PropsUtil.get(key)));
2141    
2142                                    field.setInt(null, value);
2143                            }
2144                            catch (Exception e) {
2145                                    _log.error(
2146                                            "Error setting field " + fieldName + ": " + e.getMessage());
2147                            }
2148                    }
2149    
2150                    for (String key : _PROPS_VALUES_LONG) {
2151                            String fieldName = StringUtil.replace(
2152                                    StringUtil.toUpperCase(key), CharPool.PERIOD,
2153                                    CharPool.UNDERLINE);
2154    
2155                            if (!containsKey(portalProperties, key)) {
2156                                    continue;
2157                            }
2158    
2159                            try {
2160                                    Field field = PropsValues.class.getField(fieldName);
2161    
2162                                    Long value = Long.valueOf(
2163                                            GetterUtil.getLong(PropsUtil.get(key)));
2164    
2165                                    field.setLong(null, value);
2166                            }
2167                            catch (Exception e) {
2168                                    _log.error(
2169                                            "Error setting field " + fieldName + ": " + e.getMessage());
2170                            }
2171                    }
2172    
2173                    for (String key : _PROPS_VALUES_STRING) {
2174                            String fieldName = StringUtil.replace(
2175                                    StringUtil.toUpperCase(key), CharPool.PERIOD,
2176                                    CharPool.UNDERLINE);
2177    
2178                            if (!containsKey(portalProperties, key)) {
2179                                    continue;
2180                            }
2181    
2182                            try {
2183                                    Field field = PropsValues.class.getField(fieldName);
2184    
2185                                    String value = GetterUtil.getString(PropsUtil.get(key));
2186    
2187                                    field.set(null, value);
2188                            }
2189                            catch (Exception e) {
2190                                    _log.error(
2191                                            "Error setting field " + fieldName + ": " + e.getMessage());
2192                            }
2193                    }
2194    
2195                    resetPortalPropertiesStringArray(
2196                            servletContextName, portalProperties, initPhase,
2197                            _PROPS_VALUES_MERGE_STRING_ARRAY, _mergeStringArraysContainerMap);
2198    
2199                    resetPortalPropertiesStringArray(
2200                            servletContextName, portalProperties, initPhase,
2201                            _PROPS_VALUES_OVERRIDE_STRING_ARRAY,
2202                            _overrideStringArraysContainerMap);
2203    
2204                    if (containsKey(portalProperties, LOCALES) ||
2205                            containsKey(portalProperties, LOCALES_BETA)) {
2206    
2207                            PropsValues.LOCALES = PropsUtil.getArray(LOCALES);
2208    
2209                            LanguageUtil.init();
2210                    }
2211    
2212                    if (containsKey(portalProperties, LOCALES_ENABLED)) {
2213                            PropsValues.LOCALES_ENABLED = PropsUtil.getArray(LOCALES_ENABLED);
2214    
2215                            LanguageUtil.init();
2216                    }
2217    
2218                    if (containsKey(
2219                                    portalProperties, PORTLET_INTERRUPTED_REQUEST_WHITELIST)) {
2220    
2221                            InterruptedPortletRequestWhitelistUtil.
2222                                    resetPortletInvocationWhitelist();
2223                    }
2224    
2225                    if (containsKey(
2226                                    portalProperties,
2227                                    PORTLET_INTERRUPTED_REQUEST_WHITELIST_ACTIONS)) {
2228    
2229                            InterruptedPortletRequestWhitelistUtil.
2230                                    resetPortletInvocationWhitelistActions();
2231                    }
2232    
2233                    CacheUtil.clearCache();
2234    
2235                    JavaScriptBundleUtil.clearCache();
2236            }
2237    
2238            protected void resetPortalPropertiesStringArray(
2239                    String servletContextName, Properties portalProperties,
2240                    boolean initPhase, String[] propsValuesStringArray,
2241                    Map<String, StringArraysContainer> stringArraysContainerMap) {
2242    
2243                    for (String key : propsValuesStringArray) {
2244                            String fieldName = StringUtil.replace(
2245                                    StringUtil.toUpperCase(key), CharPool.PERIOD,
2246                                    CharPool.UNDERLINE);
2247    
2248                            if (!containsKey(portalProperties, key)) {
2249                                    continue;
2250                            }
2251    
2252                            try {
2253                                    resetPortalPropertiesStringArray(
2254                                            servletContextName, portalProperties, initPhase,
2255                                            propsValuesStringArray, stringArraysContainerMap, key,
2256                                            fieldName);
2257                            }
2258                            catch (Exception e) {
2259                                    _log.error(
2260                                            "Error setting field " + fieldName + ": " + e.getMessage());
2261                            }
2262                    }
2263            }
2264    
2265            protected void resetPortalPropertiesStringArray(
2266                            String servletContextName, Properties portalProperties,
2267                            boolean initPhase, String[] propsValuesStringArray,
2268                            Map<String, StringArraysContainer> stringArraysContainerMap,
2269                            String key, String fieldName)
2270                    throws Exception {
2271    
2272                    Field field = PropsValues.class.getField(fieldName);
2273    
2274                    StringArraysContainer stringArraysContainer =
2275                            stringArraysContainerMap.get(key);
2276    
2277                    String[] value = null;
2278    
2279                    if (initPhase) {
2280                            if (stringArraysContainer
2281                                            instanceof OverrideStringArraysContainer) {
2282    
2283                                    OverrideStringArraysContainer overrideStringArraysContainer =
2284                                            (OverrideStringArraysContainer)stringArraysContainer;
2285    
2286                                    if (overrideStringArraysContainer.isOverridden()) {
2287                                            _log.error("Error setting overridden field " + fieldName);
2288    
2289                                            return;
2290                                    }
2291    
2292                                    value = StringUtil.split(portalProperties.getProperty(key));
2293                            }
2294                            else {
2295                                    value = PropsUtil.getArray(key);
2296                            }
2297                    }
2298    
2299                    stringArraysContainer.setPluginStringArray(servletContextName, value);
2300    
2301                    value = stringArraysContainer.getStringArray();
2302    
2303                    field.set(null, value);
2304            }
2305    
2306            private static final String[] _PROPS_KEYS_EVENTS = {
2307                    LOGIN_EVENTS_POST, LOGIN_EVENTS_PRE, LOGOUT_EVENTS_POST,
2308                    LOGOUT_EVENTS_PRE, SERVLET_SERVICE_EVENTS_POST,
2309                    SERVLET_SERVICE_EVENTS_PRE
2310            };
2311    
2312            private static final String[] _PROPS_KEYS_SESSION_EVENTS = {
2313                    SERVLET_SESSION_CREATE_EVENTS, SERVLET_SESSION_DESTROY_EVENTS
2314            };
2315    
2316            private static final String[] _PROPS_VALUES_BOOLEAN = {
2317                    "auth.forward.by.last.path", "captcha.check.portal.create_account",
2318                    "dl.file.entry.drafts.enabled",
2319                    "dl.file.entry.open.in.ms.office.manual.check.in.required",
2320                    "field.enable.com.liferay.portal.kernel.model.Contact.birthday",
2321                    "field.enable.com.liferay.portal.kernel.model.Contact.male",
2322                    "field.enable.com.liferay.portal.kernel.model.Organization.status",
2323                    "javascript.fast.load", "layout.template.cache.enabled",
2324                    "layout.user.private.layouts.auto.create",
2325                    "layout.user.private.layouts.enabled",
2326                    "layout.user.private.layouts.power.user.required",
2327                    "layout.user.public.layouts.auto.create",
2328                    "layout.user.public.layouts.enabled",
2329                    "layout.user.public.layouts.power.user.required",
2330                    "login.create.account.allow.custom.password", "login.dialog.disabled",
2331                    "my.sites.show.private.sites.with.no.layouts",
2332                    "my.sites.show.public.sites.with.no.layouts",
2333                    "my.sites.show.user.private.sites.with.no.layouts",
2334                    "my.sites.show.user.public.sites.with.no.layouts",
2335                    "portlet.add.default.resource.check.enabled", "rss.feeds.enabled",
2336                    "session.store.password", "social.activity.sets.bundling.enabled",
2337                    "social.activity.sets.enabled", "terms.of.use.required",
2338                    "theme.css.fast.load", "theme.images.fast.load",
2339                    "theme.jsp.override.enabled", "theme.loader.new.theme.id.on.import",
2340                    "theme.portlet.decorate.default", "theme.portlet.sharing.default",
2341                    "user.notification.event.confirmation.enabled",
2342                    "users.email.address.required", "users.image.check.token",
2343                    "users.screen.name.always.autogenerate"
2344            };
2345    
2346            private static final String[] _PROPS_VALUES_INTEGER = {
2347                    "session.max.allowed", "users.image.max.height", "users.image.max.width"
2348            };
2349    
2350            private static final String[] _PROPS_VALUES_LONG = {};
2351    
2352            private static final String[] _PROPS_VALUES_MERGE_STRING_ARRAY = {
2353                    "auth.token.ignore.actions", "auth.token.ignore.origins",
2354                    "auth.token.ignore.portlets", "admin.default.group.names",
2355                    "admin.default.role.names", "admin.default.user.group.names",
2356                    "asset.publisher.display.styles",
2357                    "company.settings.form.authentication",
2358                    "company.settings.form.configuration",
2359                    "company.settings.form.identification",
2360                    "company.settings.form.miscellaneous", "company.settings.form.social",
2361                    "journal.article.form.add", "journal.article.form.translate",
2362                    "journal.article.form.update", "layout.form.add", "layout.form.update",
2363                    "layout.set.form.update", "layout.static.portlets.all",
2364                    "login.form.navigation.post", "login.form.navigation.pre",
2365                    "organizations.form.add.identification", "organizations.form.add.main",
2366                    "organizations.form.add.miscellaneous",
2367                    "portlet.add.default.resource.check.whitelist",
2368                    "portlet.add.default.resource.check.whitelist.actions",
2369                    "portlet.interrupted.request.whitelist",
2370                    "portlet.interrupted.request.whitelist.actions",
2371                    "session.phishing.protected.attributes", "sites.form.add.advanced",
2372                    "sites.form.add.main", "sites.form.add.miscellaneous",
2373                    "sites.form.add.seo", "sites.form.update.advanced",
2374                    "sites.form.update.main", "sites.form.update.miscellaneous",
2375                    "sites.form.update.seo", "users.form.add.identification",
2376                    "users.form.add.main", "users.form.add.miscellaneous",
2377                    "users.form.my.account.identification", "users.form.my.account.main",
2378                    "users.form.my.account.miscellaneous",
2379                    "users.form.update.identification", "users.form.update.main",
2380                    "users.form.update.miscellaneous"
2381            };
2382    
2383            private static final String[] _PROPS_VALUES_OBSOLETE = {
2384                    "layout.user.private.layouts.modifiable",
2385                    "layout.user.public.layouts.modifiable"
2386            };
2387    
2388            private static final String[] _PROPS_VALUES_OVERRIDE_STRING_ARRAY = {
2389                    "locales.beta"
2390            };
2391    
2392            private static final String[] _PROPS_VALUES_STRING = {
2393                    "company.default.locale", "company.default.time.zone",
2394                    "default.landing.page.path", "default.regular.color.scheme.id",
2395                    "default.regular.theme.id", "passwords.passwordpolicytoolkit.generator",
2396                    "passwords.passwordpolicytoolkit.static",
2397                    "phone.number.format.international.regexp",
2398                    "phone.number.format.usa.regexp", "social.activity.sets.selector",
2399                    "theme.shortcut.icon"
2400            };
2401    
2402            private static final String[] _TOKEN_WHITELIST_NAMES = {
2403                    AUTH_TOKEN_IGNORE_ACTIONS, AUTH_TOKEN_IGNORE_ORIGINS,
2404                    AUTH_TOKEN_IGNORE_PORTLETS,
2405                    PORTLET_ADD_DEFAULT_RESOURCE_CHECK_WHITELIST,
2406                    PORTLET_ADD_DEFAULT_RESOURCE_CHECK_WHITELIST_ACTIONS
2407            };
2408    
2409            private static final Log _log = LogFactoryUtil.getLog(
2410                    HookHotDeployListener.class);
2411    
2412            private final Map<String, DLFileEntryProcessorContainer>
2413                    _dlFileEntryProcessorContainerMap = new HashMap<>();
2414            private final Map<String, DLRepositoryContainer> _dlRepositoryContainerMap =
2415                    new HashMap<>();
2416            private final Map<String, HotDeployListenersContainer>
2417                    _hotDeployListenersContainerMap = new HashMap<>();
2418            private final Map<String, StringArraysContainer>
2419                    _mergeStringArraysContainerMap = new HashMap<>();
2420            private final Map<String, StringArraysContainer>
2421                    _overrideStringArraysContainerMap = new HashMap<>();
2422            private final Map<String, Properties> _portalPropertiesMap =
2423                    new HashMap<>();
2424            private final Set<String> _propsKeysEvents = SetUtil.fromArray(
2425                    _PROPS_KEYS_EVENTS);
2426            private final Set<String> _propsKeysSessionEvents = SetUtil.fromArray(
2427                    _PROPS_KEYS_SESSION_EVENTS);
2428            private final Map<String, Map<Object, ServiceRegistration<?>>>
2429                    _serviceRegistrations = newMap();
2430            private final Set<String> _servletContextNames = new HashSet<>();
2431    
2432            private static class DLFileEntryProcessorContainer {
2433    
2434                    public void registerDLProcessor(DLProcessor dlProcessor) {
2435                            DLProcessorRegistryUtil.register(dlProcessor);
2436    
2437                            _dlProcessors.add(dlProcessor);
2438                    }
2439    
2440                    public void unregisterDLProcessors() {
2441                            for (DLProcessor dlProcessor : _dlProcessors) {
2442                                    DLProcessorRegistryUtil.unregister(dlProcessor);
2443                            }
2444    
2445                            _dlProcessors.clear();
2446                    }
2447    
2448                    private final List<DLProcessor> _dlProcessors = new ArrayList<>();
2449    
2450            }
2451    
2452            private static class DLRepositoryContainer {
2453    
2454                    public void registerRepositoryFactory(
2455                            String className,
2456                            ExternalRepositoryFactory externalRepositoryFactory,
2457                            ResourceBundleLoader resourceBundleLoader) {
2458    
2459                            RepositoryClassDefinitionCatalogUtil.
2460                                    registerLegacyExternalRepositoryFactory(
2461                                            className, externalRepositoryFactory, resourceBundleLoader);
2462    
2463                            _classNames.add(className);
2464                    }
2465    
2466                    public void unregisterRepositoryFactories() {
2467                            for (String className : _classNames) {
2468                                    RepositoryClassDefinitionCatalogUtil.
2469                                            unregisterLegacyExternalRepositoryFactory(className);
2470                            }
2471    
2472                            _classNames.clear();
2473                    }
2474    
2475                    private final List<String> _classNames = new ArrayList<>();
2476    
2477            }
2478    
2479            private static class HotDeployListenersContainer {
2480    
2481                    public void registerHotDeployListener(
2482                            HotDeployListener hotDeployListener) {
2483    
2484                            HotDeployUtil.registerListener(hotDeployListener);
2485    
2486                            _hotDeployListeners.add(hotDeployListener);
2487                    }
2488    
2489                    public void unregisterHotDeployListeners() {
2490                            for (HotDeployListener hotDeployListener : _hotDeployListeners) {
2491                                    HotDeployUtil.unregisterListener(hotDeployListener);
2492                            }
2493                    }
2494    
2495                    private final List<HotDeployListener> _hotDeployListeners =
2496                            new ArrayList<>();
2497    
2498            }
2499    
2500            private static class MergeStringArraysContainer
2501                    implements StringArraysContainer {
2502    
2503                    @Override
2504                    public String[] getStringArray() {
2505                            Set<String> mergedStringSet = new LinkedHashSet<>();
2506    
2507                            mergedStringSet.addAll(Arrays.asList(_portalStringArray));
2508    
2509                            for (Map.Entry<String, String[]> entry :
2510                                            _pluginStringArrayMap.entrySet()) {
2511    
2512                                    mergedStringSet.addAll(Arrays.asList(entry.getValue()));
2513                            }
2514    
2515                            return mergedStringSet.toArray(new String[mergedStringSet.size()]);
2516                    }
2517    
2518                    @Override
2519                    public void setPluginStringArray(
2520                            String servletContextName, String[] pluginStringArray) {
2521    
2522                            if (pluginStringArray != null) {
2523                                    _pluginStringArrayMap.put(
2524                                            servletContextName, pluginStringArray);
2525                            }
2526                            else {
2527                                    _pluginStringArrayMap.remove(servletContextName);
2528                            }
2529                    }
2530    
2531                    private MergeStringArraysContainer(String key) {
2532                            _portalStringArray = PropsUtil.getArray(key);
2533                    }
2534    
2535                    private final Map<String, String[]> _pluginStringArrayMap =
2536                            new HashMap<>();
2537                    private String[] _portalStringArray;
2538    
2539            }
2540    
2541            private static class OverrideStringArraysContainer
2542                    implements StringArraysContainer {
2543    
2544                    @Override
2545                    public String[] getStringArray() {
2546                            if (_pluginStringArray != null) {
2547                                    return _pluginStringArray;
2548                            }
2549    
2550                            return _portalStringArray;
2551                    }
2552    
2553                    public boolean isOverridden() {
2554                            if (Validator.isNotNull(_servletContextName)) {
2555                                    return true;
2556                            }
2557                            else {
2558                                    return false;
2559                            }
2560                    }
2561    
2562                    @Override
2563                    public void setPluginStringArray(
2564                            String servletContextName, String[] pluginStringArray) {
2565    
2566                            if (pluginStringArray != null) {
2567                                    if (!isOverridden()) {
2568                                            _servletContextName = servletContextName;
2569                                            _pluginStringArray = pluginStringArray;
2570                                    }
2571                            }
2572                            else {
2573                                    if (_servletContextName.equals(servletContextName)) {
2574                                            _servletContextName = null;
2575                                            _pluginStringArray = null;
2576                                    }
2577                            }
2578                    }
2579    
2580                    private OverrideStringArraysContainer(String key) {
2581                            _portalStringArray = PropsUtil.getArray(key);
2582                    }
2583    
2584                    private String[] _pluginStringArray;
2585                    private String[] _portalStringArray;
2586                    private String _servletContextName;
2587    
2588            }
2589    
2590            private interface StringArraysContainer {
2591    
2592                    public String[] getStringArray();
2593    
2594                    public void setPluginStringArray(
2595                            String servletContextName, String[] pluginStringArray);
2596    
2597            }
2598    
2599    }