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