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