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