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