1
14
15 package com.liferay.portal.deploy.hot;
16
17 import com.liferay.portal.events.EventsProcessorUtil;
18 import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler;
19 import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
20 import com.liferay.portal.kernel.captcha.Captcha;
21 import com.liferay.portal.kernel.captcha.CaptchaUtil;
22 import com.liferay.portal.kernel.captcha.CaptchaWrapper;
23 import com.liferay.portal.kernel.configuration.Configuration;
24 import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
25 import com.liferay.portal.kernel.deploy.auto.AutoDeployDir;
26 import com.liferay.portal.kernel.deploy.auto.AutoDeployListener;
27 import com.liferay.portal.kernel.deploy.auto.AutoDeployUtil;
28 import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
29 import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
30 import com.liferay.portal.kernel.deploy.hot.HotDeployException;
31 import com.liferay.portal.kernel.deploy.hot.HotDeployListener;
32 import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
33 import com.liferay.portal.kernel.events.Action;
34 import com.liferay.portal.kernel.events.InvokerAction;
35 import com.liferay.portal.kernel.events.InvokerSessionAction;
36 import com.liferay.portal.kernel.events.InvokerSimpleAction;
37 import com.liferay.portal.kernel.events.SessionAction;
38 import com.liferay.portal.kernel.events.SimpleAction;
39 import com.liferay.portal.kernel.exception.PortalException;
40 import com.liferay.portal.kernel.language.LanguageUtil;
41 import com.liferay.portal.kernel.log.Log;
42 import com.liferay.portal.kernel.log.LogFactoryUtil;
43 import com.liferay.portal.kernel.sanitizer.Sanitizer;
44 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
45 import com.liferay.portal.kernel.sanitizer.SanitizerWrapper;
46 import com.liferay.portal.kernel.upgrade.UpgradeException;
47 import com.liferay.portal.kernel.util.ArrayUtil;
48 import com.liferay.portal.kernel.util.FileUtil;
49 import com.liferay.portal.kernel.util.GetterUtil;
50 import com.liferay.portal.kernel.util.HttpUtil;
51 import com.liferay.portal.kernel.util.ListUtil;
52 import com.liferay.portal.kernel.util.LocaleUtil;
53 import com.liferay.portal.kernel.util.PropsKeys;
54 import com.liferay.portal.kernel.util.StringBundler;
55 import com.liferay.portal.kernel.util.StringPool;
56 import com.liferay.portal.kernel.util.StringUtil;
57 import com.liferay.portal.kernel.util.Validator;
58 import com.liferay.portal.kernel.xml.Document;
59 import com.liferay.portal.kernel.xml.Element;
60 import com.liferay.portal.kernel.xml.SAXReaderUtil;
61 import com.liferay.portal.language.LanguageResources;
62 import com.liferay.portal.model.BaseModel;
63 import com.liferay.portal.model.ModelListener;
64 import com.liferay.portal.model.Release;
65 import com.liferay.portal.security.auth.AuthFailure;
66 import com.liferay.portal.security.auth.AuthPipeline;
67 import com.liferay.portal.security.auth.AuthToken;
68 import com.liferay.portal.security.auth.AuthTokenUtil;
69 import com.liferay.portal.security.auth.AuthTokenWrapper;
70 import com.liferay.portal.security.auth.Authenticator;
71 import com.liferay.portal.security.auth.AutoLogin;
72 import com.liferay.portal.security.auth.CompanyThreadLocal;
73 import com.liferay.portal.security.auth.EmailAddressGenerator;
74 import com.liferay.portal.security.auth.EmailAddressGeneratorFactory;
75 import com.liferay.portal.security.auth.FullNameGenerator;
76 import com.liferay.portal.security.auth.FullNameGeneratorFactory;
77 import com.liferay.portal.security.auth.FullNameValidator;
78 import com.liferay.portal.security.auth.FullNameValidatorFactory;
79 import com.liferay.portal.security.auth.ScreenNameGenerator;
80 import com.liferay.portal.security.auth.ScreenNameGeneratorFactory;
81 import com.liferay.portal.security.auth.ScreenNameValidator;
82 import com.liferay.portal.security.auth.ScreenNameValidatorFactory;
83 import com.liferay.portal.security.ldap.AttributesTransformer;
84 import com.liferay.portal.security.ldap.AttributesTransformerFactory;
85 import com.liferay.portal.service.ReleaseLocalServiceUtil;
86 import com.liferay.portal.service.persistence.BasePersistence;
87 import com.liferay.portal.servlet.filters.autologin.AutoLoginFilter;
88 import com.liferay.portal.servlet.filters.cache.CacheUtil;
89 import com.liferay.portal.upgrade.UpgradeProcessUtil;
90 import com.liferay.portal.util.JavaScriptBundleUtil;
91 import com.liferay.portal.util.PortalInstances;
92 import com.liferay.portal.util.PortalUtil;
93 import com.liferay.portal.util.PropsUtil;
94 import com.liferay.portal.util.PropsValues;
95 import com.liferay.portlet.ControlPanelEntry;
96 import com.liferay.portlet.DefaultControlPanelEntryFactory;
97 import com.liferay.util.UniqueList;
98
99 import java.io.File;
100 import java.io.InputStream;
101
102 import java.lang.reflect.Constructor;
103 import java.lang.reflect.Field;
104 import java.lang.reflect.InvocationHandler;
105 import java.lang.reflect.Proxy;
106
107 import java.net.URL;
108
109 import java.util.ArrayList;
110 import java.util.HashMap;
111 import java.util.HashSet;
112 import java.util.Iterator;
113 import java.util.List;
114 import java.util.Locale;
115 import java.util.Map;
116 import java.util.Properties;
117 import java.util.Set;
118
119 import javax.servlet.ServletContext;
120
121 import org.springframework.aop.TargetSource;
122 import org.springframework.aop.framework.AdvisedSupport;
123 import org.springframework.aop.target.SingletonTargetSource;
124
125
132 public class HookHotDeployListener
133 extends BaseHotDeployListener implements PropsKeys {
134
135 public static String[] SUPPORTED_PROPERTIES = {
136 "admin.default.group.names",
137 "admin.default.role.names",
138 "admin.default.user.group.names",
139 "auth.forward.by.last.path",
140 "auto.deploy.listeners",
141 "application.startup.events",
142 "auth.failure",
143 "auth.max.failures",
144 "auth.token.impl",
145 "auth.pipeline.post",
146 "auth.pipeline.pre",
147 "auto.login.hooks",
148 "captcha.check.portal.create_account",
149 "captcha.engine.impl",
150 "control.panel.entry.class.default",
151 "convert.processes",
152 "default.landing.page.path",
153 "dl.hook.impl",
154 "dl.webdav.hold.lock",
155 "dl.webdav.save.to.single.version",
156 "field.enable.com.liferay.portal.model.Contact.birthday",
157 "field.enable.com.liferay.portal.model.Contact.male",
158 "field.enable.com.liferay.portal.model.Organization.status",
159 "hot.deploy.listeners",
160 "image.hook.impl",
161 "javascript.fast.load",
162 "layout.static.portlets.all",
163 "layout.template.cache.enabled",
164 "layout.types",
165 "layout.user.private.layouts.auto.create",
166 "layout.user.private.layouts.enabled",
167 "layout.user.private.layouts.modifiable",
168 "layout.user.public.layouts.auto.create",
169 "layout.user.public.layouts.enabled",
170 "layout.user.public.layouts.modifiable",
171 "ldap.attrs.transformer.impl",
172 "login.create.account.allow.custom.password",
173 "login.events.post",
174 "login.events.pre",
175 "logout.events.post",
176 "logout.events.pre",
177 "mail.hook.impl",
178 "my.places.show.community.private.sites.with.no.layouts",
179 "my.places.show.community.public.sites.with.no.layouts",
180 "my.places.show.organization.private.sites.with.no.layouts",
181 "my.places.show.organization.public.sites.with.no.layouts",
182 "my.places.show.user.private.sites.with.no.layouts",
183 "my.places.show.user.public.sites.with.no.layouts",
184 "passwords.passwordpolicytoolkit.generator",
185 "passwords.passwordpolicytoolkit.static",
186 "portlet.add.default.resource.check.enabled",
187 "sanitizer.impl",
188 "servlet.session.create.events",
189 "servlet.session.destroy.events",
190 "servlet.service.events.post",
191 "servlet.service.events.pre",
192 "session.phishing.protected.attributes",
193 "terms.of.use.required",
194 "theme.css.fast.load",
195 "theme.images.fast.load",
196 "theme.loader.new.theme.id.on.import",
197 "theme.portlet.decorate.default",
198 "theme.portlet.sharing.default",
199 "theme.shortcut.icon",
200 "upgrade.processes",
201 "users.email.address.generator",
202 "users.email.address.required",
203 "users.full.name.generator",
204 "users.full.name.validator",
205 "users.screen.name.always.autogenerate",
206 "users.screen.name.generator",
207 "users.screen.name.validator",
208 "value.object.listener.*"
209 };
210
211 public HookHotDeployListener() {
212 for (String key : _PROPS_VALUES_STRING_ARRAY) {
213 _stringArraysContainerMap.put(key, new StringArraysContainer(key));
214 }
215 }
216
217 public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
218 try {
219 doInvokeDeploy(event);
220 }
221 catch (Throwable t) {
222 throwHotDeployException(event, "Error registering hook for ", t);
223 }
224 }
225
226 public void invokeUndeploy(HotDeployEvent event) throws HotDeployException {
227 try {
228 doInvokeUndeploy(event);
229 }
230 catch (Throwable t) {
231 throwHotDeployException(event, "Error unregistering hook for ", t);
232 }
233 }
234
235 protected boolean containsKey(Properties portalProperties, String key) {
236 if (_log.isDebugEnabled()) {
237 return true;
238 }
239 else {
240 return portalProperties.containsKey(key);
241 }
242 }
243
244 protected void destroyCustomJspBag(CustomJspBag customJspBag) {
245 String customJspDir = customJspBag.getCustomJspDir();
246 List<String> customJsps = customJspBag.getCustomJsps();
247
249 String portalWebDir = PortalUtil.getPortalWebDir();
250
251 for (String customJsp : customJsps) {
252 int pos = customJsp.indexOf(customJspDir);
253
254 String portalJsp = customJsp.substring(
255 pos + customJspDir.length(), customJsp.length());
256
257 File portalJspFile = new File(portalWebDir + portalJsp);
258 File portalJspBackupFile = getPortalJspBackupFile(portalJspFile);
259
260 if (portalJspBackupFile.exists()) {
261 FileUtil.copyFile(portalJspBackupFile, portalJspFile);
262
263 portalJspBackupFile.delete();
264 }
265 else if (portalJspFile.exists()) {
266 portalJspFile.delete();
267 }
268 }
269 }
270
271 protected void destroyPortalProperties(
272 String servletContextName, Properties portalProperties)
273 throws Exception {
274
275 PropsUtil.removeProperties(portalProperties);
276
277 if (_log.isDebugEnabled() && portalProperties.containsKey(LOCALES)) {
278 _log.debug(
279 "Portlet locales " + portalProperties.getProperty(LOCALES));
280 _log.debug("Original locales " + PropsUtil.get(LOCALES));
281 _log.debug(
282 "Original locales array length " +
283 PropsUtil.getArray(LOCALES).length);
284 }
285
286 resetPortalProperties(servletContextName, portalProperties, false);
287
288 if (portalProperties.containsKey(PropsKeys.AUTH_TOKEN_IMPL)) {
289 AuthTokenWrapper authTokenWrapper =
290 (AuthTokenWrapper)AuthTokenUtil.getAuthToken();
291
292 authTokenWrapper.setAuthToken(null);
293 }
294
295 if (portalProperties.containsKey(PropsKeys.CAPTCHA_ENGINE_IMPL)) {
296 CaptchaWrapper captchaWrapper =
297 (CaptchaWrapper)CaptchaUtil.getCaptcha();
298
299 captchaWrapper.setCaptcha(null);
300 }
301
302 if (portalProperties.containsKey(
303 PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS)) {
304
305 DefaultControlPanelEntryFactory.setInstance(null);
306 }
307
308 if (portalProperties.containsKey(PropsKeys.DL_HOOK_IMPL)) {
309 com.liferay.documentlibrary.util.HookFactory.setInstance(null);
310 }
311
312 if (portalProperties.containsKey(PropsKeys.IMAGE_HOOK_IMPL)) {
313 com.liferay.portal.image.HookFactory.setInstance(null);
314 }
315
316 if (portalProperties.containsKey(
317 PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL)) {
318
319 AttributesTransformerFactory.setInstance(null);
320 }
321
322 if (portalProperties.containsKey(PropsKeys.MAIL_HOOK_IMPL)) {
323 com.liferay.mail.util.HookFactory.setInstance(null);
324 }
325
326 if (portalProperties.containsKey(PropsKeys.SANITIZER_IMPL)) {
327 SanitizerWrapper sanitizerWrapper =
328 (SanitizerWrapper)SanitizerUtil.getSanitizer();
329
330 sanitizerWrapper.setSanitizer(null);
331 }
332
333 if (portalProperties.containsKey(
334 PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR)) {
335
336 EmailAddressGeneratorFactory.setInstance(null);
337 }
338
339 if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_GENERATOR)) {
340 FullNameGeneratorFactory.setInstance(null);
341 }
342
343 if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_VALIDATOR)) {
344 FullNameValidatorFactory.setInstance(null);
345 }
346
347 if (portalProperties.containsKey(
348 PropsKeys.USERS_SCREEN_NAME_GENERATOR)) {
349
350 ScreenNameGeneratorFactory.setInstance(null);
351 }
352
353 if (portalProperties.containsKey(
354 PropsKeys.USERS_SCREEN_NAME_VALIDATOR)) {
355
356 ScreenNameValidatorFactory.setInstance(null);
357 }
358 }
359
360 protected void destroyServices(String servletContextName) throws Exception {
361 List<ServiceBag> serviceBags =
362 _servicesContainer.findByServletContextName(servletContextName);
363
364 for (ServiceBag serviceBag : serviceBags) {
365 Object serviceProxy = PortalBeanLocatorUtil.locate(
366 serviceBag.getServiceType());
367
368 AdvisedSupport advisedSupport = getAdvisedSupport(serviceProxy);
369
370 TargetSource originalTargetSource = new SingletonTargetSource(
371 serviceBag.getOriginalService());
372
373 advisedSupport.setTargetSource(originalTargetSource);
374 }
375
376 _servicesContainer.removeByServletContextName(servletContextName);
377 }
378
379 protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
380 ServletContext servletContext = event.getServletContext();
381
382 String servletContextName = servletContext.getServletContextName();
383
384 if (_log.isDebugEnabled()) {
385 _log.debug("Invoking deploy for " + servletContextName);
386 }
387
388 String xml = HttpUtil.URLtoString(
389 servletContext.getResource("/WEB-INF/liferay-hook.xml"));
390
391 if (xml == null) {
392 return;
393 }
394
395 if (_log.isInfoEnabled()) {
396 _log.info("Registering hook for " + servletContextName);
397 }
398
399 _servletContextNames.add(servletContextName);
400
401 ClassLoader portletClassLoader = event.getContextClassLoader();
402
403 Document doc = SAXReaderUtil.read(xml, true);
404
405 Element root = doc.getRootElement();
406
407 String portalPropertiesLocation = root.elementText("portal-properties");
408
409 if (Validator.isNotNull(portalPropertiesLocation)) {
410 Configuration portalPropertiesConfiguration = null;
411
412 try {
413 String name = portalPropertiesLocation;
414
415 int pos = name.lastIndexOf(".properties");
416
417 if (pos != -1) {
418 name = name.substring(0, pos);
419 }
420
421 portalPropertiesConfiguration =
422 ConfigurationFactoryUtil.getConfiguration(
423 portletClassLoader, name);
424 }
425 catch (Exception e) {
426 _log.error("Unable to read " + portalPropertiesLocation, e);
427 }
428
429 if (portalPropertiesConfiguration != null) {
430 Properties portalProperties =
431 portalPropertiesConfiguration.getProperties();
432
433 if (portalProperties.size() > 0) {
434 _portalPropertiesMap.put(
435 servletContextName, portalProperties);
436
437
442 initPortalProperties(
443 servletContextName, portletClassLoader,
444 portalProperties);
445 initAuthFailures(
446 servletContextName, portletClassLoader,
447 portalProperties);
448 initAutoDeployListeners(
449 servletContextName, portletClassLoader,
450 portalProperties);
451 initAutoLogins(
452 servletContextName, portletClassLoader,
453 portalProperties);
454 initAuthenticators(
455 servletContextName, portletClassLoader,
456 portalProperties);
457 initHotDeployListeners(
458 servletContextName, portletClassLoader,
459 portalProperties);
460 initModelListeners(
461 servletContextName, portletClassLoader,
462 portalProperties);
463 initEvents(
464 servletContextName, portletClassLoader,
465 portalProperties);
466 }
467 }
468 }
469
470 LanguagesContainer languagesContainer = new LanguagesContainer();
471
472 _languagesContainerMap.put(servletContextName, languagesContainer);
473
474 List<Element> languagePropertiesEls = root.elements(
475 "language-properties");
476
477 for (Element languagePropertiesEl : languagePropertiesEls) {
478 String languagePropertiesLocation = languagePropertiesEl.getText();
479
480 try {
481 URL url = portletClassLoader.getResource(
482 languagePropertiesLocation);
483
484 if (url == null) {
485 continue;
486 }
487
488 InputStream is = url.openStream();
489
490 Properties properties = new Properties();
491
492 properties.load(is);
493
494 is.close();
495
496 Map<String, String> languageMap = new HashMap<String, String>();
497
498 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
499 String key = (String)entry.getKey();
500 String value = (String)entry.getValue();
501
502 languageMap.put(key, value);
503 }
504
505 Locale locale = getLocale(languagePropertiesLocation);
506
507 if (locale != null) {
508 languagesContainer.addLanguage(locale, languageMap);
509 }
510 }
511 catch (Exception e) {
512 _log.error("Unable to read " + languagePropertiesLocation, e);
513 }
514 }
515
516 String customJspDir = root.elementText("custom-jsp-dir");
517
518 if (Validator.isNotNull(customJspDir)) {
519 if (_log.isDebugEnabled()) {
520 _log.debug("Custom JSP directory: " + customJspDir);
521 }
522
523 List<String> customJsps = new ArrayList<String>();
524
525 String webDir = servletContext.getRealPath(StringPool.SLASH);
526
527 getCustomJsps(servletContext, webDir, customJspDir, customJsps);
528
529 if (customJsps.size() > 0) {
530 CustomJspBag customJspBag = new CustomJspBag(
531 customJspDir, customJsps);
532
533 if (_log.isDebugEnabled()) {
534 StringBundler sb = new StringBundler(customJsps.size() * 2);
535
536 sb.append("Custom JSP files:\n");
537
538 Iterator<String> itr = customJsps.iterator();
539
540 while (itr.hasNext()) {
541 String customJsp = itr.next();
542
543 sb.append(customJsp);
544
545 if (itr.hasNext()) {
546 sb.append(StringPool.NEW_LINE);
547 }
548 }
549
550 _log.debug(sb.toString());
551 }
552
553 _customJspBagsMap.put(servletContextName, customJspBag);
554
555 initCustomJspBag(customJspBag);
556 }
557 }
558
559 List<Element> serviceEls = root.elements("service");
560
561 for (Element serviceEl : serviceEls) {
562 String serviceType = serviceEl.elementText("service-type");
563 String serviceImpl = serviceEl.elementText("service-impl");
564
565 Class<?> serviceTypeClass = portletClassLoader.loadClass(
566 serviceType);
567 Class<?> serviceImplClass = portletClassLoader.loadClass(
568 serviceImpl);
569
570 Constructor<?> serviceImplConstructor =
571 serviceImplClass.getConstructor(
572 new Class<?>[] {serviceTypeClass});
573
574 Object serviceProxy = PortalBeanLocatorUtil.locate(serviceType);
575
576 if (Proxy.isProxyClass(serviceProxy.getClass())) {
577 initServices(
578 servletContextName, portletClassLoader, serviceType,
579 serviceTypeClass, serviceImplConstructor, serviceProxy);
580 }
581 else {
582 _log.error(
583 "Service hooks require Spring to be configured to use " +
584 "JdkDynamicProxy and will not work with CGLIB");
585 }
586 }
587
588
590 ModelListenersContainer modelListenersContainer =
591 _modelListenersContainerMap.get(servletContextName);
592
593 if (modelListenersContainer == null) {
594 modelListenersContainer = new ModelListenersContainer();
595
596 _modelListenersContainerMap.put(
597 servletContextName, modelListenersContainer);
598 }
599
600 List<Element> modelListenerEls = root.elements("model-listener");
601
602 for (Element modelListenerEl : modelListenerEls) {
603 String modelName = modelListenerEl.elementText("model-name");
604 String modelListenerClassName = modelListenerEl.elementText(
605 "model-listener-class");
606
607 ModelListener<BaseModel<?>> modelListener = initModelListener(
608 modelName, modelListenerClassName, portletClassLoader);
609
610 if (modelListener != null) {
611 modelListenersContainer.registerModelListener(
612 modelName, modelListener);
613 }
614 }
615
616 EventsContainer eventsContainer = _eventsContainerMap.get(
617 servletContextName);
618
619 if (eventsContainer == null) {
620 eventsContainer = new EventsContainer();
621
622 _eventsContainerMap.put(servletContextName, eventsContainer);
623 }
624
625 List<Element> eventEls = root.elements("event");
626
627 for (Element eventEl : eventEls) {
628 String eventName = eventEl.elementText("event-type");
629 String eventClassName = eventEl.elementText("event-class");
630
631 Object obj = initEvent(
632 eventName, eventClassName, portletClassLoader);
633
634 if (obj != null) {
635 eventsContainer.registerEvent(eventName, obj);
636 }
637 }
638
639
641 registerClpMessageListeners(servletContext, portletClassLoader);
642
643 if (_log.isInfoEnabled()) {
644 _log.info(
645 "Hook for " + servletContextName + " is available for use");
646 }
647 }
648
649 protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
650 ServletContext servletContext = event.getServletContext();
651
652 String servletContextName = servletContext.getServletContextName();
653
654 if (_log.isDebugEnabled()) {
655 _log.debug("Invoking undeploy for " + servletContextName);
656 }
657
658 if (!_servletContextNames.remove(servletContextName)) {
659 return;
660 }
661
662 AuthenticatorsContainer authenticatorsContainer =
663 _authenticatorsContainerMap.remove(servletContextName);
664
665 if (authenticatorsContainer != null) {
666 authenticatorsContainer.unregisterAuthenticators();
667 }
668
669 AuthFailuresContainer authFailuresContainer =
670 _authFailuresContainerMap.remove(servletContextName);
671
672 if (authFailuresContainer != null) {
673 authFailuresContainer.unregisterAuthFailures();
674 }
675
676 AutoDeployListenersContainer autoDeployListenersContainer =
677 _autoDeployListenersContainerMap.remove(servletContextName);
678
679 if (autoDeployListenersContainer != null) {
680 autoDeployListenersContainer.unregisterAutoDeployListeners();
681 }
682
683 AutoLoginsContainer autoLoginsContainer =
684 _autoLoginsContainerMap.remove(servletContextName);
685
686 if (autoLoginsContainer != null) {
687 autoLoginsContainer.unregisterAutoLogins();
688 }
689
690 CustomJspBag customJspBag = _customJspBagsMap.remove(
691 servletContextName);
692
693 if (customJspBag != null) {
694 destroyCustomJspBag(customJspBag);
695 }
696
697 EventsContainer eventsContainer = _eventsContainerMap.remove(
698 servletContextName);
699
700 if (eventsContainer != null) {
701 eventsContainer.unregisterEvents();
702 }
703
704 HotDeployListenersContainer hotDeployListenersContainer =
705 _hotDeployListenersContainerMap.remove(servletContextName);
706
707 if (hotDeployListenersContainer != null) {
708 hotDeployListenersContainer.unregisterHotDeployListeners();
709 }
710
711 LanguagesContainer languagesContainer = _languagesContainerMap.remove(
712 servletContextName);
713
714 if (languagesContainer != null) {
715 languagesContainer.unregisterLanguages();
716 }
717
718 ModelListenersContainer modelListenersContainer =
719 _modelListenersContainerMap.remove(servletContextName);
720
721 if (modelListenersContainer != null) {
722 modelListenersContainer.unregisterModelListeners();
723 }
724
725 Properties portalProperties = _portalPropertiesMap.remove(
726 servletContextName);
727
728 if (portalProperties != null) {
729 destroyPortalProperties(servletContextName, portalProperties);
730 }
731
732 destroyServices(servletContextName);
733
734 unregisterClpMessageListeners(servletContext);
735
736 if (_log.isInfoEnabled()) {
737 _log.info("Hook for " + servletContextName + " was unregistered");
738 }
739 }
740
741 protected AdvisedSupport getAdvisedSupport(Object serviceProxy)
742 throws Exception {
743
744 InvocationHandler invocationHandler = Proxy.getInvocationHandler(
745 serviceProxy);
746
747 Class<?> invocationHandlerClass = invocationHandler.getClass();
748
749 Field advisedField = invocationHandlerClass.getDeclaredField("advised");
750
751 advisedField.setAccessible(true);
752
753 return (AdvisedSupport)advisedField.get(invocationHandler);
754 }
755
756 protected void getCustomJsps(
757 ServletContext servletContext, String webDir, String resourcePath,
758 List<String> customJsps) {
759
760 Set<String> resourcePaths = servletContext.getResourcePaths(
761 resourcePath);
762
763 for (String curResourcePath : resourcePaths) {
764 if (curResourcePath.endsWith(StringPool.SLASH)) {
765 getCustomJsps(
766 servletContext, webDir, curResourcePath, customJsps);
767 }
768 else {
769 String customJsp = webDir + curResourcePath;
770
771 customJsp = StringUtil.replace(
772 customJsp, StringPool.DOUBLE_SLASH, StringPool.SLASH);
773
774 customJsps.add(customJsp);
775 }
776 }
777 }
778
779 protected Locale getLocale(String languagePropertiesLocation) {
780 int x = languagePropertiesLocation.indexOf(StringPool.UNDERLINE);
781 int y = languagePropertiesLocation.indexOf(".properties");
782
783 Locale locale = null;
784
785 if ((x != -1) && (y != 1)) {
786 String localeKey = languagePropertiesLocation.substring(x + 1, y);
787
788 locale = LocaleUtil.fromLanguageId(localeKey);
789
790 locale = LanguageUtil.getLocale(locale.getLanguage());
791 }
792
793 return locale;
794 }
795
796 protected BasePersistence<?> getPersistence(String modelName) {
797 int pos = modelName.lastIndexOf(StringPool.PERIOD);
798
799 String entityName = modelName.substring(pos + 1);
800
801 pos = modelName.lastIndexOf(".model.");
802
803 String packagePath = modelName.substring(0, pos);
804
805 return (BasePersistence<?>)PortalBeanLocatorUtil.locate(
806 packagePath + ".service.persistence." + entityName + "Persistence");
807 }
808
809 protected File getPortalJspBackupFile(File portalJspFile) {
810 String fileName = portalJspFile.getName();
811 String filePath = portalJspFile.toString();
812
813 int fileNameIndex = fileName.lastIndexOf(StringPool.PERIOD);
814
815 if (fileNameIndex > 0) {
816 int filePathIndex = filePath.lastIndexOf(fileName);
817
818 fileName =
819 fileName.substring(0, fileNameIndex) + ".portal" +
820 fileName.substring(fileNameIndex);
821
822 filePath = filePath.substring(0, filePathIndex) + fileName;
823 }
824 else {
825 filePath += ".portal";
826 }
827
828 return new File(filePath);
829 }
830
831 protected void initAuthenticators(
832 ClassLoader portletClassLoader, Properties portalProperties,
833 String key, AuthenticatorsContainer authenticatorsContainer)
834 throws Exception {
835
836 String[] authenticatorClassNames = StringUtil.split(
837 portalProperties.getProperty(key));
838
839 for (String authenticatorClassName : authenticatorClassNames) {
840 Authenticator authenticator = (Authenticator)newInstance(
841 portletClassLoader, Authenticator.class,
842 authenticatorClassName);
843
844 authenticatorsContainer.registerAuthenticator(
845 key, authenticator);
846 }
847 }
848
849 protected void initAuthenticators(
850 String servletContextName, ClassLoader portletClassLoader,
851 Properties portalProperties)
852 throws Exception {
853
854 AuthenticatorsContainer authenticatorsContainer =
855 new AuthenticatorsContainer();
856
857 _authenticatorsContainerMap.put(
858 servletContextName, authenticatorsContainer);
859
860 initAuthenticators(
861 portletClassLoader, portalProperties, AUTH_PIPELINE_PRE,
862 authenticatorsContainer);
863 initAuthenticators(
864 portletClassLoader, portalProperties, AUTH_PIPELINE_POST,
865 authenticatorsContainer);
866 }
867
868 protected void initAuthFailures(
869 ClassLoader portletClassLoader, Properties portalProperties,
870 String key, AuthFailuresContainer authFailuresContainer)
871 throws Exception {
872
873 String[] authFailureClassNames = StringUtil.split(
874 portalProperties.getProperty(key));
875
876 for (String authFailureClassName : authFailureClassNames) {
877 AuthFailure authFailure = (AuthFailure)newInstance(
878 portletClassLoader, AuthFailure.class, authFailureClassName);
879
880 authFailuresContainer.registerAuthFailure(key, authFailure);
881 }
882 }
883
884 protected void initAuthFailures(
885 String servletContextName, ClassLoader portletClassLoader,
886 Properties portalProperties)
887 throws Exception {
888
889 AuthFailuresContainer authFailuresContainer =
890 new AuthFailuresContainer();
891
892 _authFailuresContainerMap.put(
893 servletContextName, authFailuresContainer);
894
895 initAuthFailures(
896 portletClassLoader, portalProperties, AUTH_FAILURE,
897 authFailuresContainer);
898 initAuthFailures(
899 portletClassLoader, portalProperties, AUTH_MAX_FAILURES,
900 authFailuresContainer);
901 }
902
903 protected void initAutoDeployListeners(
904 String servletContextName, ClassLoader portletClassLoader,
905 Properties portalProperties)
906 throws Exception {
907
908 String[] autoDeployListenerClassNames = StringUtil.split(
909 portalProperties.getProperty(PropsKeys.AUTO_DEPLOY_LISTENERS));
910
911 if (autoDeployListenerClassNames.length == 0) {
912 return;
913 }
914
915 AutoDeployListenersContainer autoDeployListenersContainer =
916 new AutoDeployListenersContainer();
917
918 _autoDeployListenersContainerMap.put(
919 servletContextName, autoDeployListenersContainer);
920
921 for (String autoDeployListenerClassName :
922 autoDeployListenerClassNames) {
923
924 AutoDeployListener autoDeployListener =
925 (AutoDeployListener)newInstance(
926 portletClassLoader, AutoDeployListener.class,
927 autoDeployListenerClassName);
928
929 autoDeployListenersContainer.registerAutoDeployListener(
930 autoDeployListener);
931 }
932 }
933
934 protected void initAutoLogins(
935 String servletContextName, ClassLoader portletClassLoader,
936 Properties portalProperties)
937 throws Exception {
938
939 AutoLoginsContainer autoLoginsContainer = new AutoLoginsContainer();
940
941 _autoLoginsContainerMap.put(servletContextName, autoLoginsContainer);
942
943 String[] autoLoginClassNames = StringUtil.split(
944 portalProperties.getProperty(AUTO_LOGIN_HOOKS));
945
946 for (String autoLoginClassName : autoLoginClassNames) {
947 AutoLogin autoLogin = (AutoLogin)newInstance(
948 portletClassLoader, AutoLogin.class, autoLoginClassName);
949
950 autoLoginsContainer.registerAutoLogin(autoLogin);
951 }
952 }
953
954 protected void initCustomJspBag(CustomJspBag customJspBag)
955 throws Exception {
956
957 String customJspDir = customJspBag.getCustomJspDir();
958 List<String> customJsps = customJspBag.getCustomJsps();
959
961 String portalWebDir = PortalUtil.getPortalWebDir();
962
963 for (String customJsp : customJsps) {
964 int pos = customJsp.indexOf(customJspDir);
965
966 String portalJsp = customJsp.substring(
967 pos + customJspDir.length(), customJsp.length());
968
969 File portalJspFile = new File(portalWebDir + portalJsp);
970 File portalJspBackupFile = getPortalJspBackupFile(portalJspFile);
971
972 if (portalJspFile.exists() && !portalJspBackupFile.exists()) {
973 FileUtil.copyFile(portalJspFile, portalJspBackupFile);
974 }
975
976 FileUtil.copyFile(customJsp, portalWebDir + portalJsp);
977 }
978 }
979
980 protected Object initEvent(
981 String eventName, String eventClassName,
982 ClassLoader portletClassLoader)
983 throws Exception {
984
985 if (eventName.equals(APPLICATION_STARTUP_EVENTS)) {
986 SimpleAction simpleAction =
987 (SimpleAction)portletClassLoader.loadClass(
988 eventClassName).newInstance();
989
990 simpleAction = new InvokerSimpleAction(
991 simpleAction, portletClassLoader);
992
993 long companyId = CompanyThreadLocal.getCompanyId();
994
995 long[] companyIds = PortalInstances.getCompanyIds();
996
997 for (long curCompanyId : companyIds) {
998 CompanyThreadLocal.setCompanyId(curCompanyId);
999
1000 simpleAction.run(new String[] {String.valueOf(curCompanyId)});
1001 }
1002
1003 CompanyThreadLocal.setCompanyId(companyId);
1004
1005 return null;
1006 }
1007
1008 if (ArrayUtil.contains(_PROPS_KEYS_EVENTS, eventName)) {
1009 Action action = (Action)portletClassLoader.loadClass(
1010 eventClassName).newInstance();
1011
1012 action = new InvokerAction(action, portletClassLoader);
1013
1014 EventsProcessorUtil.registerEvent(eventName, action);
1015
1016 return action;
1017 }
1018
1019 if (ArrayUtil.contains(_PROPS_KEYS_SESSION_EVENTS, eventName)) {
1020 SessionAction sessionAction =
1021 (SessionAction)portletClassLoader.loadClass(
1022 eventClassName).newInstance();
1023
1024 sessionAction = new InvokerSessionAction(
1025 sessionAction, portletClassLoader);
1026
1027 EventsProcessorUtil.registerEvent(eventName, sessionAction);
1028
1029 return sessionAction;
1030 }
1031
1032 return null;
1033 }
1034
1035 protected void initEvents(
1036 String servletContextName, ClassLoader portletClassLoader,
1037 Properties portalProperties)
1038 throws Exception {
1039
1040 EventsContainer eventsContainer = new EventsContainer();
1041
1042 _eventsContainerMap.put(servletContextName, eventsContainer);
1043
1044 Iterator<Object> itr = portalProperties.keySet().iterator();
1045
1046 while (itr.hasNext()) {
1047 String key = (String)itr.next();
1048
1049 if (!key.equals(APPLICATION_STARTUP_EVENTS) &&
1050 !ArrayUtil.contains(_PROPS_KEYS_EVENTS, key) &&
1051 !ArrayUtil.contains(_PROPS_KEYS_SESSION_EVENTS, key)) {
1052
1053 continue;
1054 }
1055
1056 String eventName = key;
1057 String[] eventClassNames = StringUtil.split(
1058 portalProperties.getProperty(key));
1059
1060 for (String eventClassName : eventClassNames) {
1061 Object obj = initEvent(
1062 eventName, eventClassName, portletClassLoader);
1063
1064 if (obj == null) {
1065 continue;
1066 }
1067
1068 eventsContainer.registerEvent(eventName, obj);
1069 }
1070 }
1071 }
1072
1073 protected void initHotDeployListeners(
1074 String servletContextName, ClassLoader portletClassLoader,
1075 Properties portalProperties)
1076 throws Exception {
1077
1078 String[] hotDeployListenerClassNames = StringUtil.split(
1079 portalProperties.getProperty(PropsKeys.HOT_DEPLOY_LISTENERS));
1080
1081 if (hotDeployListenerClassNames.length == 0) {
1082 return;
1083 }
1084
1085 HotDeployListenersContainer hotDeployListenersContainer =
1086 new HotDeployListenersContainer();
1087
1088 _hotDeployListenersContainerMap.put(
1089 servletContextName, hotDeployListenersContainer);
1090
1091 for (String hotDeployListenerClassName : hotDeployListenerClassNames) {
1092 HotDeployListener hotDeployListener =
1093 (HotDeployListener)newInstance(
1094 portletClassLoader, HotDeployListener.class,
1095 hotDeployListenerClassName);
1096
1097 hotDeployListenersContainer.registerHotDeployListener(
1098 hotDeployListener);
1099 }
1100 }
1101
1102 @SuppressWarnings("unchecked")
1103 protected ModelListener<BaseModel<?>> initModelListener(
1104 String modelName, String modelListenerClassName,
1105 ClassLoader portletClassLoader)
1106 throws Exception {
1107
1108 ModelListener<BaseModel<?>> modelListener =
1109 (ModelListener<BaseModel<?>>)newInstance(
1110 portletClassLoader, ModelListener.class,
1111 modelListenerClassName);
1112
1113 BasePersistence persistence = getPersistence(modelName);
1114
1115 persistence.registerListener(modelListener);
1116
1117 return modelListener;
1118 }
1119
1120 protected void initModelListeners(
1121 String servletContextName, ClassLoader portletClassLoader,
1122 Properties portalProperties)
1123 throws Exception {
1124
1125 ModelListenersContainer modelListenersContainer =
1126 new ModelListenersContainer();
1127
1128 _modelListenersContainerMap.put(
1129 servletContextName, modelListenersContainer);
1130
1131 Iterator<Object> itr = portalProperties.keySet().iterator();
1132
1133 while (itr.hasNext()) {
1134 String key = (String)itr.next();
1135
1136 if (!key.startsWith(VALUE_OBJECT_LISTENER)) {
1137 continue;
1138 }
1139
1140 String modelName = key.substring(VALUE_OBJECT_LISTENER.length());
1141
1142 String[] modelListenerClassNames = StringUtil.split(
1143 portalProperties.getProperty(key));
1144
1145 for (String modelListenerClassName : modelListenerClassNames) {
1146 ModelListener<BaseModel<?>> modelListener = initModelListener(
1147 modelName, modelListenerClassName, portletClassLoader);
1148
1149 if (modelListener != null) {
1150 modelListenersContainer.registerModelListener(
1151 modelName, modelListener);
1152 }
1153 }
1154 }
1155 }
1156
1157 protected void initPortalProperties(
1158 String servletContextName, ClassLoader portletClassLoader,
1159 Properties portalProperties)
1160 throws Exception {
1161
1162 PropsUtil.addProperties(portalProperties);
1163
1164 if (_log.isDebugEnabled() && portalProperties.containsKey(LOCALES)) {
1165 _log.debug(
1166 "Portlet locales " + portalProperties.getProperty(LOCALES));
1167 _log.debug("Merged locales " + PropsUtil.get(LOCALES));
1168 _log.debug(
1169 "Merged locales array length " +
1170 PropsUtil.getArray(LOCALES).length);
1171 }
1172
1173 resetPortalProperties(servletContextName, portalProperties, true);
1174
1175 if (portalProperties.containsKey(PropsKeys.AUTH_TOKEN_IMPL)) {
1176 String authTokenClassName = portalProperties.getProperty(
1177 PropsKeys.AUTH_TOKEN_IMPL);
1178
1179 AuthToken authToken = (AuthToken)newInstance(
1180 portletClassLoader, AuthToken.class, authTokenClassName);
1181
1182 AuthTokenWrapper authTokenWrapper =
1183 (AuthTokenWrapper)AuthTokenUtil.getAuthToken();
1184
1185 authTokenWrapper.setAuthToken(authToken);
1186 }
1187
1188 if (portalProperties.containsKey(PropsKeys.CAPTCHA_ENGINE_IMPL)) {
1189 String captchaClassName = portalProperties.getProperty(
1190 PropsKeys.CAPTCHA_ENGINE_IMPL);
1191
1192 Captcha captcha = (Captcha)newInstance(
1193 portletClassLoader, Captcha.class, captchaClassName);
1194
1195 CaptchaWrapper captchaWrapper =
1196 (CaptchaWrapper)CaptchaUtil.getCaptcha();
1197
1198 captchaWrapper.setCaptcha(captcha);
1199 }
1200
1201 if (portalProperties.containsKey(
1202 PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS)) {
1203
1204 String controlPanelEntryClassName = portalProperties.getProperty(
1205 PropsKeys.CONTROL_PANEL_DEFAULT_ENTRY_CLASS);
1206
1207 ControlPanelEntry controlPanelEntry =
1208 (ControlPanelEntry)newInstance(
1209 portletClassLoader, ControlPanelEntry.class,
1210 controlPanelEntryClassName);
1211
1212 DefaultControlPanelEntryFactory.setInstance(controlPanelEntry);
1213 }
1214
1215 if (portalProperties.containsKey(PropsKeys.DL_HOOK_IMPL)) {
1216 String dlHookClassName = portalProperties.getProperty(
1217 PropsKeys.DL_HOOK_IMPL);
1218
1219 com.liferay.documentlibrary.util.Hook dlHook =
1220 (com.liferay.documentlibrary.util.Hook)newInstance(
1221 portletClassLoader,
1222 com.liferay.documentlibrary.util.Hook.class,
1223 dlHookClassName);
1224
1225 com.liferay.documentlibrary.util.HookFactory.setInstance(dlHook);
1226 }
1227
1228 if (portalProperties.containsKey(PropsKeys.IMAGE_HOOK_IMPL)) {
1229 String imageHookClassName = portalProperties.getProperty(
1230 PropsKeys.IMAGE_HOOK_IMPL);
1231
1232 com.liferay.portal.kernel.image.Hook imageHook =
1233 (com.liferay.portal.kernel.image.Hook)newInstance(
1234 portletClassLoader,
1235 com.liferay.portal.kernel.image.Hook.class,
1236 imageHookClassName);
1237
1238 com.liferay.portal.image.HookFactory.setInstance(imageHook);
1239 }
1240
1241 if (portalProperties.containsKey(
1242 PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL)) {
1243
1244 String attributesTransformerClassName =
1245 portalProperties.getProperty(
1246 PropsKeys.LDAP_ATTRS_TRANSFORMER_IMPL);
1247
1248 AttributesTransformer attributesTransformer =
1249 (AttributesTransformer)newInstance(
1250 portletClassLoader, AttributesTransformer.class,
1251 attributesTransformerClassName);
1252
1253 AttributesTransformerFactory.setInstance(attributesTransformer);
1254 }
1255
1256 if (portalProperties.containsKey(PropsKeys.MAIL_HOOK_IMPL)) {
1257 String mailHookClassName = portalProperties.getProperty(
1258 PropsKeys.MAIL_HOOK_IMPL);
1259
1260 com.liferay.mail.util.Hook mailHook =
1261 (com.liferay.mail.util.Hook)newInstance(
1262 portletClassLoader, com.liferay.mail.util.Hook.class,
1263 mailHookClassName);
1264
1265 com.liferay.mail.util.HookFactory.setInstance(mailHook);
1266 }
1267
1268 if (portalProperties.containsKey(PropsKeys.SANITIZER_IMPL)) {
1269 String sanitizerClassName = portalProperties.getProperty(
1270 PropsKeys.SANITIZER_IMPL);
1271
1272 Sanitizer sanitizer = (Sanitizer)newInstance(
1273 portletClassLoader, Sanitizer.class, sanitizerClassName);
1274
1275 SanitizerWrapper sanitizerWrapper =
1276 (SanitizerWrapper)SanitizerUtil.getSanitizer();
1277
1278 sanitizerWrapper.setSanitizer(sanitizer);
1279 }
1280
1281 if (portalProperties.containsKey(
1282 PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR)) {
1283
1284 String emailAddressGeneratorClassName =
1285 portalProperties.getProperty(
1286 PropsKeys.USERS_EMAIL_ADDRESS_GENERATOR);
1287
1288 EmailAddressGenerator emailAddressGenerator =
1289 (EmailAddressGenerator)newInstance(
1290 portletClassLoader, EmailAddressGenerator.class,
1291 emailAddressGeneratorClassName);
1292
1293 EmailAddressGeneratorFactory.setInstance(emailAddressGenerator);
1294 }
1295
1296 if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_GENERATOR)) {
1297 String fullNameGeneratorClassName = portalProperties.getProperty(
1298 PropsKeys.USERS_FULL_NAME_GENERATOR);
1299
1300 FullNameGenerator fullNameGenerator =
1301 (FullNameGenerator)newInstance(
1302 portletClassLoader, FullNameGenerator.class,
1303 fullNameGeneratorClassName);
1304
1305 FullNameGeneratorFactory.setInstance(fullNameGenerator);
1306 }
1307
1308 if (portalProperties.containsKey(PropsKeys.USERS_FULL_NAME_VALIDATOR)) {
1309 String fullNameValidatorClassName = portalProperties.getProperty(
1310 PropsKeys.USERS_FULL_NAME_VALIDATOR);
1311
1312 FullNameValidator fullNameValidator =
1313 (FullNameValidator)newInstance(
1314 portletClassLoader, FullNameValidator.class,
1315 fullNameValidatorClassName);
1316
1317 FullNameValidatorFactory.setInstance(fullNameValidator);
1318 }
1319
1320 if (portalProperties.containsKey(
1321 PropsKeys.USERS_SCREEN_NAME_GENERATOR)) {
1322
1323 String screenNameGeneratorClassName = portalProperties.getProperty(
1324 PropsKeys.USERS_SCREEN_NAME_GENERATOR);
1325
1326 ScreenNameGenerator screenNameGenerator =
1327 (ScreenNameGenerator)newInstance(
1328 portletClassLoader, ScreenNameGenerator.class,
1329 screenNameGeneratorClassName);
1330
1331 ScreenNameGeneratorFactory.setInstance(screenNameGenerator);
1332 }
1333
1334 if (portalProperties.containsKey(
1335 PropsKeys.USERS_SCREEN_NAME_VALIDATOR)) {
1336
1337 String screenNameValidatorClassName = portalProperties.getProperty(
1338 PropsKeys.USERS_SCREEN_NAME_VALIDATOR);
1339
1340 ScreenNameValidator screenNameValidator =
1341 (ScreenNameValidator)newInstance(
1342 portletClassLoader, ScreenNameValidator.class,
1343 screenNameValidatorClassName);
1344
1345 ScreenNameValidatorFactory.setInstance(screenNameValidator);
1346 }
1347
1348 if (portalProperties.containsKey(PropsKeys.RELEASE_INFO_BUILD_NUMBER) ||
1349 portalProperties.containsKey(PropsKeys.UPGRADE_PROCESSES)) {
1350
1351 updateRelease(
1352 servletContextName, portletClassLoader, portalProperties);
1353 }
1354 }
1355
1356 protected void initServices(
1357 String servletContextName, ClassLoader portletClassLoader,
1358 String serviceType, Class<?> serviceTypeClass,
1359 Constructor<?> serviceImplConstructor, Object serviceProxy)
1360 throws Exception {
1361
1362 ServiceBag serviceBag = _servicesContainer.findByServiceType(
1363 serviceType);
1364
1365 if (serviceBag != null) {
1366 throw new IllegalStateException(
1367 serviceType + " is already overridden by " +
1368 serviceBag.getServletContextName());
1369 }
1370
1371 AdvisedSupport advisedSupport = getAdvisedSupport(serviceProxy);
1372
1373 TargetSource targetSource = advisedSupport.getTargetSource();
1374
1375 Object originalService = targetSource.getTarget();
1376
1377 if (Proxy.isProxyClass(originalService.getClass())) {
1378 InvocationHandler invocationHandler =
1379 Proxy.getInvocationHandler(originalService);
1380
1381 if (invocationHandler instanceof ClassLoaderBeanHandler) {
1382 ClassLoaderBeanHandler classLoaderBeanHandler =
1383 (ClassLoaderBeanHandler)invocationHandler;
1384
1385 originalService = classLoaderBeanHandler.getBean();
1386 }
1387 }
1388
1389 Object customService = serviceImplConstructor.newInstance(
1390 originalService);
1391
1392 Object customTarget = Proxy.newProxyInstance(
1393 portletClassLoader, new Class<?>[] {serviceTypeClass},
1394 new ClassLoaderBeanHandler(customService, portletClassLoader));
1395
1396 TargetSource customTargetSource = new SingletonTargetSource(
1397 customTarget);
1398
1399 advisedSupport.setTargetSource(customTargetSource);
1400
1401 _servicesContainer.addServiceBag(
1402 servletContextName, serviceType, originalService);
1403 }
1404
1405 protected void resetPortalProperties(
1406 String servletContextName, Properties portalProperties,
1407 boolean initPhase)
1408 throws Exception {
1409
1410 for (String key : _PROPS_VALUES_BOOLEAN) {
1411 String fieldName = StringUtil.replace(
1412 key.toUpperCase(), StringPool.PERIOD, StringPool.UNDERLINE);
1413
1414 if (!containsKey(portalProperties, key)) {
1415 continue;
1416 }
1417
1418 try {
1419 Field field = PropsValues.class.getField(fieldName);
1420
1421 Boolean value = Boolean.valueOf(GetterUtil.getBoolean(
1422 PropsUtil.get(key)));
1423
1424 field.setBoolean(null, value);
1425 }
1426 catch (Exception e) {
1427 _log.error(
1428 "Error setting field " + fieldName + ": " + e.getMessage());
1429 }
1430 }
1431
1432 for (String key : _PROPS_VALUES_INTEGER) {
1433 String fieldName = StringUtil.replace(
1434 key.toUpperCase(), StringPool.PERIOD, StringPool.UNDERLINE);
1435
1436 if (!containsKey(portalProperties, key)) {
1437 continue;
1438 }
1439
1440 try {
1441 Field field = PropsValues.class.getField(fieldName);
1442
1443 Integer value = Integer.valueOf(GetterUtil.getInteger(
1444 PropsUtil.get(key)));
1445
1446 field.setInt(null, value);
1447 }
1448 catch (Exception e) {
1449 _log.error(
1450 "Error setting field " + fieldName + ": " + e.getMessage());
1451 }
1452 }
1453
1454 for (String key : _PROPS_VALUES_LONG) {
1455 String fieldName = StringUtil.replace(
1456 key.toUpperCase(), StringPool.PERIOD, StringPool.UNDERLINE);
1457
1458 if (!containsKey(portalProperties, key)) {
1459 continue;
1460 }
1461
1462 try {
1463 Field field = PropsValues.class.getField(fieldName);
1464
1465 Long value = Long.valueOf(GetterUtil.getLong(
1466 PropsUtil.get(key)));
1467
1468 field.setLong(null, value);
1469 }
1470 catch (Exception e) {
1471 _log.error(
1472 "Error setting field " + fieldName + ": " + e.getMessage());
1473 }
1474 }
1475
1476 for (String key : _PROPS_VALUES_STRING) {
1477 String fieldName = StringUtil.replace(
1478 key.toUpperCase(), StringPool.PERIOD, StringPool.UNDERLINE);
1479
1480 if (!containsKey(portalProperties, key)) {
1481 continue;
1482 }
1483
1484 try {
1485 Field field = PropsValues.class.getField(fieldName);
1486
1487 String value = GetterUtil.getString(PropsUtil.get(key));
1488
1489 field.set(null, value);
1490 }
1491 catch (Exception e) {
1492 _log.error(
1493 "Error setting field " + fieldName + ": " + e.getMessage());
1494 }
1495 }
1496
1497 for (String key : _PROPS_VALUES_STRING_ARRAY) {
1498 String fieldName = StringUtil.replace(
1499 key.toUpperCase(), StringPool.PERIOD, StringPool.UNDERLINE);
1500
1501 if (!containsKey(portalProperties, key)) {
1502 continue;
1503 }
1504
1505 try {
1506 Field field = PropsValues.class.getField(fieldName);
1507
1508 StringArraysContainer stringArraysContainer =
1509 _stringArraysContainerMap.get(key);
1510
1511 String[] value = null;
1512
1513 if (initPhase) {
1514 value = PropsUtil.getArray(key);
1515 }
1516
1517 stringArraysContainer.setPluginStringArray(
1518 servletContextName, value);
1519
1520 value = stringArraysContainer.getMergedStringArray();
1521
1522 field.set(null, value);
1523 }
1524 catch (Exception e) {
1525 _log.error(
1526 "Error setting field " + fieldName + ": " + e.getMessage());
1527 }
1528 }
1529
1530 if (containsKey(portalProperties, LOCALES)) {
1531 PropsValues.LOCALES = PropsUtil.getArray(LOCALES);
1532
1533 LanguageUtil.init();
1534 }
1535
1536 CacheUtil.clearCache();
1537
1538 JavaScriptBundleUtil.clearCache();
1539 }
1540
1541 protected void updateRelease(
1542 String servletContextName, ClassLoader portletClassLoader,
1543 Properties portalProperties)
1544 throws Exception {
1545
1546 int buildNumber = GetterUtil.getInteger(
1547 portalProperties.getProperty(PropsKeys.RELEASE_INFO_BUILD_NUMBER));
1548
1549 if (buildNumber <= 0) {
1550 _log.error(
1551 "Skipping upgrade processes for " + servletContextName +
1552 " because \"release.info.build.number\" is not specified");
1553
1554 return;
1555 }
1556
1557 Release release = null;
1558
1559 try {
1560 release = ReleaseLocalServiceUtil.getRelease(
1561 servletContextName, buildNumber);
1562 }
1563 catch (PortalException pe) {
1564 int previousBuildNumber = GetterUtil.getInteger(
1565 portalProperties.getProperty(
1566 PropsKeys.RELEASE_INFO_PREVIOUS_BUILD_NUMBER),
1567 buildNumber);
1568
1569 release = ReleaseLocalServiceUtil.addRelease(
1570 servletContextName, previousBuildNumber);
1571 }
1572
1573 if (buildNumber == release.getBuildNumber()) {
1574 if (_log.isDebugEnabled()) {
1575 _log.debug(
1576 "Skipping upgrade processes for " + servletContextName +
1577 " because it is already up to date");
1578 }
1579 }
1580 else if (buildNumber < release.getBuildNumber()) {
1581 throw new UpgradeException(
1582 "Skipping upgrade processes for " + servletContextName +
1583 " because you are trying to upgrade with an older version");
1584 }
1585 else {
1586 String[] upgradeProcessClassNames = StringUtil.split(
1587 portalProperties.getProperty(PropsKeys.UPGRADE_PROCESSES));
1588
1589 UpgradeProcessUtil.upgradeProcess(
1590 release.getBuildNumber(), upgradeProcessClassNames,
1591 portletClassLoader);
1592 }
1593
1594 ReleaseLocalServiceUtil.updateRelease(
1595 release.getReleaseId(), buildNumber, null, true);
1596 }
1597
1598 private static final String[] _PROPS_KEYS_EVENTS = new String[] {
1599 LOGIN_EVENTS_POST,
1600 LOGIN_EVENTS_PRE,
1601 LOGOUT_EVENTS_POST,
1602 LOGOUT_EVENTS_PRE,
1603 SERVLET_SERVICE_EVENTS_POST,
1604 SERVLET_SERVICE_EVENTS_PRE
1605 };
1606
1607 private static final String[] _PROPS_KEYS_SESSION_EVENTS = new String[] {
1608 SERVLET_SESSION_CREATE_EVENTS,
1609 SERVLET_SESSION_DESTROY_EVENTS
1610 };
1611
1612 private static final String[] _PROPS_VALUES_BOOLEAN = new String[] {
1613 "auth.forward.by.last.path",
1614 "captcha.check.portal.create_account",
1615 "dl.webdav.hold.lock",
1616 "dl.webdav.save.to.single.version",
1617 "field.enable.com.liferay.portal.model.Contact.birthday",
1618 "field.enable.com.liferay.portal.model.Contact.male",
1619 "field.enable.com.liferay.portal.model.Organization.status",
1620 "javascript.fast.load",
1621 "layout.template.cache.enabled",
1622 "layout.user.private.layouts.auto.create",
1623 "layout.user.private.layouts.enabled",
1624 "layout.user.private.layouts.modifiable",
1625 "layout.user.public.layouts.auto.create",
1626 "layout.user.public.layouts.enabled",
1627 "layout.user.public.layouts.modifiable",
1628 "login.create.account.allow.custom.password",
1629 "my.places.show.community.private.sites.with.no.layouts",
1630 "my.places.show.community.public.sites.with.no.layouts",
1631 "my.places.show.organization.private.sites.with.no.layouts",
1632 "my.places.show.organization.public.sites.with.no.layouts",
1633 "my.places.show.user.private.sites.with.no.layouts",
1634 "my.places.show.user.public.sites.with.no.layouts",
1635 "portlet.add.default.resource.check.enabled",
1636 "terms.of.use.required",
1637 "theme.css.fast.load",
1638 "theme.images.fast.load",
1639 "theme.loader.new.theme.id.on.import",
1640 "theme.portlet.decorate.default",
1641 "theme.portlet.sharing.default",
1642 "users.email.address.required",
1643 "users.screen.name.always.autogenerate"
1644 };
1645
1646 private static final String[] _PROPS_VALUES_INTEGER = new String[] {
1647 };
1648
1649 private static final String[] _PROPS_VALUES_LONG = new String[] {
1650 };
1651
1652 private static final String[] _PROPS_VALUES_STRING = new String[] {
1653 "default.landing.page.path",
1654 "passwords.passwordpolicytoolkit.generator",
1655 "passwords.passwordpolicytoolkit.static",
1656 "theme.shortcut.icon"
1657 };
1658
1659 private static final String[] _PROPS_VALUES_STRING_ARRAY = new String[] {
1660 "admin.default.group.names",
1661 "admin.default.role.names",
1662 "admin.default.user.group.names",
1663 "convert.processes",
1664 "layout.static.portlets.all",
1665 "layout.types",
1666 "session.phishing.protected.attributes"
1667 };
1668
1669 private static Log _log = LogFactoryUtil.getLog(
1670 HookHotDeployListener.class);
1671
1672 private Map<String, AuthenticatorsContainer> _authenticatorsContainerMap =
1673 new HashMap<String, AuthenticatorsContainer>();
1674 private Map<String, AuthFailuresContainer> _authFailuresContainerMap =
1675 new HashMap<String, AuthFailuresContainer>();
1676 private Map<String, AutoDeployListenersContainer>
1677 _autoDeployListenersContainerMap =
1678 new HashMap<String, AutoDeployListenersContainer>();
1679 private Map<String, AutoLoginsContainer> _autoLoginsContainerMap =
1680 new HashMap<String, AutoLoginsContainer>();
1681 private Map<String, CustomJspBag> _customJspBagsMap =
1682 new HashMap<String, CustomJspBag>();
1683 private Map<String, EventsContainer> _eventsContainerMap =
1684 new HashMap<String, EventsContainer>();
1685 private Map<String, HotDeployListenersContainer>
1686 _hotDeployListenersContainerMap =
1687 new HashMap<String, HotDeployListenersContainer>();
1688 private Map<String, LanguagesContainer> _languagesContainerMap =
1689 new HashMap<String, LanguagesContainer>();
1690 private Map<String, ModelListenersContainer> _modelListenersContainerMap =
1691 new HashMap<String, ModelListenersContainer>();
1692 private Map<String, Properties> _portalPropertiesMap =
1693 new HashMap<String, Properties>();
1694 private ServicesContainer _servicesContainer = new ServicesContainer();
1695 private Set<String> _servletContextNames = new HashSet<String>();
1696 private Map<String, StringArraysContainer> _stringArraysContainerMap =
1697 new HashMap<String, StringArraysContainer>();
1698
1699 private class AuthenticatorsContainer {
1700
1701 public void registerAuthenticator(
1702 String key, Authenticator authenticator) {
1703
1704 List<Authenticator> authenticators = _authenticators.get(key);
1705
1706 if (authenticators == null) {
1707 authenticators = new ArrayList<Authenticator>();
1708
1709 _authenticators.put(key, authenticators);
1710 }
1711
1712 AuthPipeline.registerAuthenticator(key, authenticator);
1713
1714 authenticators.add(authenticator);
1715 }
1716
1717 public void unregisterAuthenticators() {
1718 for (Map.Entry<String, List<Authenticator>> entry :
1719 _authenticators.entrySet()) {
1720
1721 String key = entry.getKey();
1722 List<Authenticator> authenticators = entry.getValue();
1723
1724 for (Authenticator authenticator : authenticators) {
1725 AuthPipeline.unregisterAuthenticator(key, authenticator);
1726 }
1727 }
1728 }
1729
1730 Map<String, List<Authenticator>> _authenticators =
1731 new HashMap<String, List<Authenticator>>();
1732
1733 }
1734
1735 private class AuthFailuresContainer {
1736
1737 public void registerAuthFailure(String key, AuthFailure authFailure) {
1738 List<AuthFailure> authFailures = _authFailures.get(key);
1739
1740 if (authFailures == null) {
1741 authFailures = new ArrayList<AuthFailure>();
1742
1743 _authFailures.put(key, authFailures);
1744 }
1745
1746 AuthPipeline.registerAuthFailure(key, authFailure);
1747
1748 authFailures.add(authFailure);
1749 }
1750
1751 public void unregisterAuthFailures() {
1752 for (Map.Entry<String, List<AuthFailure>> entry :
1753 _authFailures.entrySet()) {
1754
1755 String key = entry.getKey();
1756 List<AuthFailure> authFailures = entry.getValue();
1757
1758 for (AuthFailure authFailure : authFailures) {
1759 AuthPipeline.unregisterAuthFailure(key, authFailure);
1760 }
1761 }
1762 }
1763
1764 Map<String, List<AuthFailure>> _authFailures =
1765 new HashMap<String, List<AuthFailure>>();
1766
1767 }
1768
1769 private class AutoDeployListenersContainer {
1770
1771 public void registerAutoDeployListener(
1772 AutoDeployListener autoDeployListener) {
1773
1774 AutoDeployDir autoDeployDir = AutoDeployUtil.getDir(
1775 AutoDeployDir.DEFAULT_NAME);
1776
1777 if (autoDeployDir == null) {
1778 return;
1779 }
1780
1781 autoDeployDir.registerListener(autoDeployListener);
1782
1783 _autoDeployListeners.add(autoDeployListener);
1784 }
1785
1786 public void unregisterAutoDeployListeners() {
1787 AutoDeployDir autoDeployDir = AutoDeployUtil.getDir(
1788 AutoDeployDir.DEFAULT_NAME);
1789
1790 if (autoDeployDir == null) {
1791 return;
1792 }
1793
1794 for (AutoDeployListener autoDeployListener : _autoDeployListeners) {
1795 autoDeployDir.unregisterListener(autoDeployListener);
1796 }
1797 }
1798
1799 private List<AutoDeployListener> _autoDeployListeners =
1800 new ArrayList<AutoDeployListener>();
1801
1802 }
1803
1804 private class AutoLoginsContainer {
1805
1806 public void registerAutoLogin(AutoLogin autoLogin) {
1807 AutoLoginFilter.registerAutoLogin(autoLogin);
1808
1809 _autoLogins.add(autoLogin);
1810 }
1811
1812 public void unregisterAutoLogins() {
1813 for (AutoLogin autoLogin : _autoLogins) {
1814 AutoLoginFilter.unregisterAutoLogin(autoLogin);
1815 }
1816 }
1817
1818 List<AutoLogin> _autoLogins = new ArrayList<AutoLogin>();
1819
1820 }
1821
1822 private class CustomJspBag {
1823
1824 public CustomJspBag(String customJspDir, List<String> customJsps) {
1825 _customJspDir = customJspDir;
1826 _customJsps = customJsps;
1827 }
1828
1829 public String getCustomJspDir() {
1830 return _customJspDir;
1831 }
1832
1833 public List<String> getCustomJsps() {
1834 return _customJsps;
1835 }
1836
1837 private String _customJspDir;
1838 private List<String> _customJsps;
1839
1840 }
1841
1842 private class EventsContainer {
1843
1844 public void registerEvent(String eventName, Object event) {
1845 List<Object> events = _eventsMap.get(eventName);
1846
1847 if (events == null) {
1848 events = new ArrayList<Object>();
1849
1850 _eventsMap.put(eventName, events);
1851 }
1852
1853 events.add(event);
1854 }
1855
1856 public void unregisterEvents() {
1857 for (Map.Entry<String, List<Object>> entry :
1858 _eventsMap.entrySet()) {
1859
1860 String eventName = entry.getKey();
1861 List<Object> events = entry.getValue();
1862
1863 for (Object event : events) {
1864 EventsProcessorUtil.unregisterEvent(eventName, event);
1865 }
1866 }
1867 }
1868
1869 private Map<String, List<Object>> _eventsMap =
1870 new HashMap<String, List<Object>>();
1871
1872 }
1873
1874 private class HotDeployListenersContainer {
1875
1876 public void registerHotDeployListener(
1877 HotDeployListener hotDeployListener) {
1878
1879 HotDeployUtil.registerListener(hotDeployListener);
1880
1881 _hotDeployListeners.add(hotDeployListener);
1882 }
1883
1884 public void unregisterHotDeployListeners() {
1885 for (HotDeployListener hotDeployListener : _hotDeployListeners) {
1886 HotDeployUtil.unregisterListener(hotDeployListener);
1887 }
1888 }
1889
1890 private List<HotDeployListener> _hotDeployListeners =
1891 new ArrayList<HotDeployListener>();
1892
1893 }
1894
1895 private class LanguagesContainer {
1896
1897 public void addLanguage(
1898 Locale locale, Map<String, String> languageMap) {
1899
1900 Map<String, String> oldLanguageMap =
1901 LanguageResources.putLanguageMap(locale, languageMap);
1902
1903 _languagesMap.put(locale, oldLanguageMap);
1904 }
1905
1906 public void unregisterLanguages() {
1907 for (Map.Entry<Locale, Map<String, String>> entry :
1908 _languagesMap.entrySet()) {
1909
1910 Locale locale = entry.getKey();
1911 Map<String, String> languageMap = entry.getValue();
1912
1913 LanguageResources.putLanguageMap(locale, languageMap);
1914 }
1915 }
1916
1917 private Map<Locale, Map<String, String>> _languagesMap =
1918 new HashMap<Locale, Map<String, String>>();
1919
1920 }
1921
1922 private class ModelListenersContainer {
1923
1924 public void registerModelListener(
1925 String modelName, ModelListener<BaseModel<?>> modelListener) {
1926
1927 List<ModelListener<BaseModel<?>>> modelListeners =
1928 _modelListenersMap.get(modelName);
1929
1930 if (modelListeners == null) {
1931 modelListeners = new ArrayList<ModelListener<BaseModel<?>>>();
1932
1933 _modelListenersMap.put(modelName, modelListeners);
1934 }
1935
1936 modelListeners.add(modelListener);
1937 }
1938
1939 @SuppressWarnings("unchecked")
1940 public void unregisterModelListeners() {
1941 for (Map.Entry<String, List<ModelListener<BaseModel<?>>>> entry :
1942 _modelListenersMap.entrySet()) {
1943
1944 String modelName = entry.getKey();
1945 List<ModelListener<BaseModel<?>>> modelListeners =
1946 entry.getValue();
1947
1948 BasePersistence persistence = getPersistence(modelName);
1949
1950 for (ModelListener<BaseModel<?>> modelListener :
1951 modelListeners) {
1952
1953 persistence.unregisterListener(modelListener);
1954 }
1955 }
1956 }
1957
1958 private Map<String, List<ModelListener<BaseModel<?>>>>
1959 _modelListenersMap =
1960 new HashMap<String, List<ModelListener<BaseModel<?>>>>();
1961
1962 }
1963
1964 private class ServiceBag {
1965
1966 public ServiceBag(
1967 String servletContextName, String serviceType,
1968 Object originalService) {
1969
1970 _servletContextName = servletContextName;
1971 _serviceType = serviceType;
1972 _originalService = originalService;
1973 }
1974
1975 public Object getOriginalService() {
1976 return _originalService;
1977 }
1978
1979 public String getServiceType() {
1980 return _serviceType;
1981 }
1982
1983 public String getServletContextName() {
1984 return _servletContextName;
1985 }
1986
1987 private Object _originalService;
1988 private String _serviceType;
1989 private String _servletContextName;
1990
1991 }
1992
1993 private class ServicesContainer {
1994
1995 public void addServiceBag(
1996 String servletContextName, String serviceType,
1997 Object originalService) {
1998
1999 ServiceBag serviceBag = new ServiceBag(
2000 servletContextName, serviceType, originalService);
2001
2002 _serviceBags.add(serviceBag);
2003 }
2004
2005 public ServiceBag findByServiceType(String serviceType) {
2006 for (ServiceBag serviceBag : _serviceBags) {
2007 if (serviceBag.getServiceType().equals(serviceType)) {
2008 return serviceBag;
2009 }
2010 }
2011
2012 return null;
2013 }
2014
2015 public List<ServiceBag> findByServletContextName(
2016 String servletContextName) {
2017
2018 List<ServiceBag> serviceBags = new ArrayList<ServiceBag>();
2019
2020 for (ServiceBag serviceBag : _serviceBags) {
2021 if (serviceBag.getServletContextName().equals(
2022 servletContextName)) {
2023
2024 serviceBags.add(serviceBag);
2025 }
2026 }
2027
2028 return serviceBags;
2029 }
2030
2031 public void removeByServletContextName(
2032 String servletContextName) {
2033
2034 Iterator<ServiceBag> itr = _serviceBags.iterator();
2035
2036 while (itr.hasNext()) {
2037 ServiceBag serviceBag = itr.next();
2038
2039 if (serviceBag.getServletContextName().equals(
2040 servletContextName)) {
2041
2042 itr.remove();
2043 }
2044 }
2045 }
2046
2047 private List<ServiceBag> _serviceBags = new ArrayList<ServiceBag>();
2048
2049 }
2050
2051 private class StringArraysContainer {
2052
2053 private StringArraysContainer(String key) {
2054 _portalStringArray = PropsUtil.getArray(key);
2055 }
2056
2057 public String[] getMergedStringArray() {
2058 List<String> mergedStringList = new UniqueList<String>();
2059
2060 mergedStringList.addAll(ListUtil.fromArray(_portalStringArray));
2061
2062 for (Map.Entry<String, String[]> entry :
2063 _pluginStringArrayMap.entrySet()) {
2064
2065 String[] pluginStringArray = entry.getValue();
2066
2067 mergedStringList.addAll(ListUtil.fromArray(pluginStringArray));
2068 }
2069
2070 return mergedStringList.toArray(
2071 new String[mergedStringList.size()]);
2072 }
2073
2074 public void setPluginStringArray(
2075 String servletContextName, String[] pluginStringArray) {
2076
2077 if (pluginStringArray != null) {
2078 _pluginStringArrayMap.put(
2079 servletContextName, pluginStringArray);
2080 }
2081 else {
2082 _pluginStringArrayMap.remove(servletContextName);
2083 }
2084 }
2085
2086 private String[] _portalStringArray;
2087 private Map<String, String[]> _pluginStringArrayMap =
2088 new HashMap<String, String[]>();
2089
2090 }
2091
2092}