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