1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.deploy.hot;
16  
17  import com.liferay.portal.apache.bridges.struts.LiferayServletContextProvider;
18  import com.liferay.portal.kernel.configuration.Configuration;
19  import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
20  import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
21  import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
22  import com.liferay.portal.kernel.deploy.hot.HotDeployException;
23  import com.liferay.portal.kernel.job.Scheduler;
24  import com.liferay.portal.kernel.language.LanguageUtil;
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  import com.liferay.portal.kernel.messaging.DestinationNames;
28  import com.liferay.portal.kernel.messaging.MessageBusUtil;
29  import com.liferay.portal.kernel.messaging.MessageListener;
30  import com.liferay.portal.kernel.poller.PollerProcessor;
31  import com.liferay.portal.kernel.portlet.ConfigurationAction;
32  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
33  import com.liferay.portal.kernel.portlet.PortletBag;
34  import com.liferay.portal.kernel.portlet.PortletBagPool;
35  import com.liferay.portal.kernel.portlet.PortletLayoutListener;
36  import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
37  import com.liferay.portal.kernel.scheduler.SchedulerEntry;
38  import com.liferay.portal.kernel.scheduler.messaging.SchedulerEventMessageListenerWrapper;
39  import com.liferay.portal.kernel.search.Indexer;
40  import com.liferay.portal.kernel.search.IndexerRegistryUtil;
41  import com.liferay.portal.kernel.search.OpenSearch;
42  import com.liferay.portal.kernel.servlet.PortletServlet;
43  import com.liferay.portal.kernel.servlet.ServletContextProvider;
44  import com.liferay.portal.kernel.servlet.URLEncoder;
45  import com.liferay.portal.kernel.util.ClassUtil;
46  import com.liferay.portal.kernel.util.GetterUtil;
47  import com.liferay.portal.kernel.util.HttpUtil;
48  import com.liferay.portal.kernel.util.LocaleUtil;
49  import com.liferay.portal.kernel.util.ObjectValuePair;
50  import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
51  import com.liferay.portal.kernel.util.StringUtil;
52  import com.liferay.portal.kernel.util.Validator;
53  import com.liferay.portal.kernel.workflow.WorkflowHandler;
54  import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
55  import com.liferay.portal.kernel.xmlrpc.Method;
56  import com.liferay.portal.lar.PortletDataHandler;
57  import com.liferay.portal.model.Portlet;
58  import com.liferay.portal.model.PortletApp;
59  import com.liferay.portal.model.PortletCategory;
60  import com.liferay.portal.model.PortletFilter;
61  import com.liferay.portal.model.PortletURLListener;
62  import com.liferay.portal.poller.PollerProcessorUtil;
63  import com.liferay.portal.pop.POPServerUtil;
64  import com.liferay.portal.security.permission.ResourceActionsUtil;
65  import com.liferay.portal.service.PortletLocalServiceUtil;
66  import com.liferay.portal.service.ResourceActionLocalServiceUtil;
67  import com.liferay.portal.service.ResourceCodeLocalServiceUtil;
68  import com.liferay.portal.util.Portal;
69  import com.liferay.portal.util.PortalInstances;
70  import com.liferay.portal.util.PortalUtil;
71  import com.liferay.portal.util.PropsValues;
72  import com.liferay.portal.util.WebAppPool;
73  import com.liferay.portal.util.WebKeys;
74  import com.liferay.portal.velocity.VelocityContextPool;
75  import com.liferay.portal.webdav.WebDAVStorage;
76  import com.liferay.portal.webdav.WebDAVUtil;
77  import com.liferay.portal.xmlrpc.XmlRpcServlet;
78  import com.liferay.portlet.ControlPanelEntry;
79  import com.liferay.portlet.CustomUserAttributes;
80  import com.liferay.portlet.PortletBagImpl;
81  import com.liferay.portlet.PortletConfigFactory;
82  import com.liferay.portlet.PortletContextBag;
83  import com.liferay.portlet.PortletContextBagPool;
84  import com.liferay.portlet.PortletFilterFactory;
85  import com.liferay.portlet.PortletInstanceFactoryUtil;
86  import com.liferay.portlet.PortletPreferencesSerializer;
87  import com.liferay.portlet.PortletResourceBundles;
88  import com.liferay.portlet.PortletURLListenerFactory;
89  import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
90  import com.liferay.portlet.asset.model.AssetRendererFactory;
91  import com.liferay.portlet.expando.model.CustomAttributesDisplay;
92  import com.liferay.portlet.social.model.SocialActivityInterpreter;
93  import com.liferay.portlet.social.model.SocialRequestInterpreter;
94  import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
95  import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
96  import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
97  import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
98  
99  import java.util.ArrayList;
100 import java.util.HashMap;
101 import java.util.HashSet;
102 import java.util.Iterator;
103 import java.util.List;
104 import java.util.Locale;
105 import java.util.Map;
106 import java.util.MissingResourceException;
107 import java.util.Properties;
108 import java.util.ResourceBundle;
109 import java.util.Set;
110 
111 import javax.portlet.PortletConfig;
112 import javax.portlet.PortletContext;
113 import javax.portlet.PortletURLGenerationListener;
114 import javax.portlet.PreferencesValidator;
115 
116 import javax.servlet.ServletContext;
117 
118 import org.apache.portals.bridges.struts.StrutsPortlet;
119 
120 /**
121  * <a href="PortletHotDeployListener.java.html"><b><i>View Source</i></b></a>
122  *
123  * @author Brian Wing Shun Chan
124  * @author Brian Myunghun Kim
125  * @author Ivica Cardic
126  * @author Raymond Augé
127  */
128 public class PortletHotDeployListener extends BaseHotDeployListener {
129 
130     public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
131         try {
132             doInvokeDeploy(event);
133         }
134         catch (Throwable t) {
135             throwHotDeployException(
136                 event, "Error registering portlets for ", t);
137         }
138     }
139 
140     public void invokeUndeploy(HotDeployEvent event) throws HotDeployException {
141         try {
142             doInvokeUndeploy(event);
143         }
144         catch (Throwable t) {
145             throwHotDeployException(
146                 event, "Error unregistering portlets for ", t);
147         }
148     }
149 
150     protected void destroySchedulerEntry(SchedulerEntry schedulerEntry)
151         throws Exception {
152 
153         MessageListener schedulerEventListener =
154             schedulerEntry.getEventListener();
155 
156         MessageBusUtil.unregisterMessageListener(
157             DestinationNames.SCHEDULER_DISPATCH, schedulerEventListener);
158 
159         SchedulerEngineUtil.unschedule(schedulerEntry.getTrigger());
160     }
161 
162     protected void destroyPortlet(Portlet portlet, Set<String> portletIds)
163         throws Exception {
164 
165         PortletApp portletApp = portlet.getPortletApp();
166 
167         Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
168 
169         for (PortletFilter portletFilter : portletFilters) {
170             PortletFilterFactory.destroy(portletFilter);
171         }
172 
173         Set<PortletURLListener> portletURLListeners =
174             portletApp.getPortletURLListeners();
175 
176         for (PortletURLListener portletURLListener : portletURLListeners) {
177             PortletURLListenerFactory.destroy(portletURLListener);
178         }
179 
180         Indexer indexer = portlet.getIndexerInstance();
181 
182         if (indexer != null) {
183             IndexerRegistryUtil.unregister(indexer);
184         }
185 
186         if (PropsValues.SCHEDULER_ENABLED){
187             Scheduler scheduler = portlet.getSchedulerInstance();
188 
189             if (scheduler != null) {
190                 scheduler.unschedule();
191             }
192 
193             List<SchedulerEntry> schedulerEntries =
194                 portlet.getSchedulerEntries();
195 
196             if ((schedulerEntries != null) && !schedulerEntries.isEmpty()) {
197                 for (SchedulerEntry schedulerEntry : schedulerEntries) {
198                     destroySchedulerEntry(schedulerEntry);
199                 }
200             }
201         }
202 
203         PollerProcessorUtil.deletePollerProcessor(portlet.getPortletId());
204 
205         POPServerUtil.deleteListener(portlet.getPopMessageListenerInstance());
206 
207         SocialActivityInterpreterLocalServiceUtil.deleteActivityInterpreter(
208             portlet.getSocialActivityInterpreterInstance());
209 
210         SocialRequestInterpreterLocalServiceUtil.deleteRequestInterpreter(
211             portlet.getSocialRequestInterpreterInstance());
212 
213         WebDAVUtil.deleteStorage(portlet.getWebDAVStorageInstance());
214 
215         XmlRpcServlet.unregisterMethod(portlet.getXmlRpcMethodInstance());
216 
217         List<AssetRendererFactory> assetRendererFactories =
218             portlet.getAssetRendererFactoryInstances();
219 
220         if (assetRendererFactories != null) {
221             AssetRendererFactoryRegistryUtil.unregister(assetRendererFactories);
222         }
223 
224         List<WorkflowHandler> workflowHandlers =
225             portlet.getWorkflowHandlerInstances();
226 
227         if (workflowHandlers != null) {
228             WorkflowHandlerRegistryUtil.unregister(workflowHandlers);
229         }
230 
231         PortletInstanceFactoryUtil.destroy(portlet);
232 
233         portletIds.add(portlet.getPortletId());
234     }
235 
236     protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
237 
238         // Servlet context
239 
240         ServletContext servletContext = event.getServletContext();
241 
242         String servletContextName = servletContext.getServletContextName();
243 
244         if (_log.isDebugEnabled()) {
245             _log.debug("Invoking deploy for " + servletContextName);
246         }
247 
248         // Company ids
249 
250         long[] companyIds = PortalInstances.getCompanyIds();
251 
252         // Initialize portlets
253 
254         String[] xmls = new String[] {
255             HttpUtil.URLtoString(servletContext.getResource(
256                 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD)),
257             HttpUtil.URLtoString(servletContext.getResource(
258                 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
259             HttpUtil.URLtoString(servletContext.getResource(
260                 "/WEB-INF/liferay-portlet.xml")),
261             HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"))
262         };
263 
264         if (xmls[0] == null) {
265             return;
266         }
267 
268         if (_log.isInfoEnabled()) {
269             _log.info("Registering portlets for " + servletContextName);
270         }
271 
272         List<Portlet> portlets = PortletLocalServiceUtil.initWAR(
273             servletContextName, servletContext, xmls, event.getPluginPackage());
274 
275         // Class loader
276 
277         ClassLoader portletClassLoader = event.getContextClassLoader();
278 
279         servletContext.setAttribute(
280             PortletServlet.PORTLET_CLASS_LOADER, portletClassLoader);
281 
282         // Portlet context wrapper
283 
284         _portletAppInitialized = false;
285         _strutsBridges = false;
286 
287         Iterator<Portlet> itr = portlets.iterator();
288 
289         while (itr.hasNext()) {
290             Portlet portlet = itr.next();
291 
292             initPortlet(portlet, servletContext, portletClassLoader, itr);
293         }
294 
295         // Struts bridges
296 
297         if (!_strutsBridges) {
298             _strutsBridges = GetterUtil.getBoolean(
299                 servletContext.getInitParameter(
300                     "struts-bridges-context-provider"));
301         }
302 
303         if (_strutsBridges) {
304             servletContext.setAttribute(
305                 ServletContextProvider.STRUTS_BRIDGES_CONTEXT_PROVIDER,
306                 new LiferayServletContextProvider());
307         }
308 
309         // Portlet display
310 
311         String xml = HttpUtil.URLtoString(servletContext.getResource(
312             "/WEB-INF/liferay-display.xml"));
313 
314         PortletCategory newPortletCategory =
315             PortletLocalServiceUtil.getWARDisplay(servletContextName, xml);
316 
317         for (int i = 0; i < companyIds.length; i++) {
318             long companyId = companyIds[i];
319 
320             PortletCategory portletCategory =
321                 (PortletCategory)WebAppPool.get(
322                     String.valueOf(companyId), WebKeys.PORTLET_CATEGORY);
323 
324             if (portletCategory != null) {
325                 portletCategory.merge(newPortletCategory);
326             }
327             else {
328                 _log.error(
329                     "Unable to register portlet for company " + companyId +
330                         " because it does not exist");
331             }
332         }
333 
334         // Portlet properties
335 
336         processPortletProperties(servletContextName, portletClassLoader);
337 
338         // Resource actions, resource codes, and check
339 
340         itr = portlets.iterator();
341 
342         while (itr.hasNext()) {
343             Portlet portlet = itr.next();
344 
345             List<String> modelNames =
346                 ResourceActionsUtil.getPortletModelResources(
347                     portlet.getPortletId());
348 
349             for (long companyId : companyIds) {
350                 ResourceCodeLocalServiceUtil.checkResourceCodes(
351                     companyId, portlet.getPortletId());
352 
353                 for (String modelName : modelNames) {
354                     ResourceCodeLocalServiceUtil.checkResourceCodes(
355                         companyId, modelName);
356                 }
357             }
358 
359             List<String> portletActions =
360                 ResourceActionsUtil.getPortletResourceActions(
361                     portlet.getPortletId());
362 
363             ResourceActionLocalServiceUtil.checkResourceActions(
364                 portlet.getPortletId(), portletActions);
365 
366             for (String modelName : modelNames) {
367                 List<String> modelActions =
368                     ResourceActionsUtil.getModelResourceActions(modelName);
369 
370                 ResourceActionLocalServiceUtil.checkResourceActions(
371                     modelName, modelActions);
372             }
373 
374             for (long companyId : companyIds) {
375                 Portlet curPortlet = PortletLocalServiceUtil.getPortletById(
376                     companyId, portlet.getPortletId());
377 
378                 PortletLocalServiceUtil.checkPortlet(curPortlet);
379             }
380         }
381 
382         // ClpMessageListener
383 
384         registerClpMessageListeners(servletContext, portletClassLoader);
385 
386         // Variables
387 
388         _vars.put(
389             servletContextName,
390             new ObjectValuePair<long[], List<Portlet>>(
391                 companyIds, portlets));
392 
393         if (_log.isInfoEnabled()) {
394             if (portlets.size() == 1) {
395                 _log.info(
396                     "1 portlet for " + servletContextName +
397                         " is available for use");
398             }
399             else {
400                 _log.info(
401                     portlets.size() + " portlets for " + servletContextName +
402                         " are available for use");
403             }
404         }
405     }
406 
407     protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
408         ServletContext servletContext = event.getServletContext();
409 
410         String servletContextName = servletContext.getServletContextName();
411 
412         if (_log.isDebugEnabled()) {
413             _log.debug("Invoking undeploy for " + servletContextName);
414         }
415 
416         ObjectValuePair<long[], List<Portlet>> ovp =
417             _vars.remove(servletContextName);
418 
419         if (ovp == null) {
420             return;
421         }
422 
423         long[] companyIds = ovp.getKey();
424         List<Portlet> portlets = ovp.getValue();
425 
426         Set<String> portletIds = new HashSet<String>();
427 
428         if (portlets != null) {
429             if (_log.isInfoEnabled()) {
430                 _log.info(
431                     "Unregistering portlets for " + servletContextName);
432             }
433 
434             Iterator<Portlet> itr = portlets.iterator();
435 
436             while (itr.hasNext()) {
437                 Portlet portlet = itr.next();
438 
439                 destroyPortlet(portlet, portletIds);
440             }
441         }
442 
443         if (portletIds.size() > 0) {
444             for (int i = 0; i < companyIds.length; i++) {
445                 long companyId = companyIds[i];
446 
447                 PortletCategory portletCategory =
448                     (PortletCategory)WebAppPool.get(
449                         String.valueOf(companyId), WebKeys.PORTLET_CATEGORY);
450 
451                 portletCategory.separate(portletIds);
452             }
453         }
454 
455         PortletResourceBundles.remove(servletContextName);
456 
457         unregisterClpMessageListeners(servletContext);
458 
459         if (_log.isInfoEnabled()) {
460             if (portlets.size() == 1) {
461                 _log.info(
462                     "1 portlet for " + servletContextName +
463                         " was unregistered");
464             }
465             else {
466                 _log.info(
467                     portlets.size() + " portlets for " + servletContextName +
468                         " was unregistered");
469             }
470         }
471     }
472 
473     protected void initPortlet(
474             Portlet portlet, ServletContext servletContext,
475             ClassLoader portletClassLoader, Iterator<Portlet> portletsItr)
476         throws Exception {
477 
478         String servletContextName = servletContext.getServletContextName();
479 
480         PortletApp portletApp = portlet.getPortletApp();
481 
482         if (!portletApp.isWARFile()) {
483             String contextPath = PortalUtil.getPathContext();
484 
485             servletContext = VelocityContextPool.get(contextPath);
486 
487             portletClassLoader = PortalClassLoaderUtil.getClassLoader();
488         }
489 
490         Class<?> portletClass = null;
491 
492         try {
493             portletClass = portletClassLoader.loadClass(
494                 portlet.getPortletClass());
495         }
496         catch (Throwable e) {
497             _log.error(e, e);
498 
499             portletsItr.remove();
500 
501             PortletLocalServiceUtil.destroyPortlet(portlet);
502 
503             return;
504         }
505 
506         javax.portlet.Portlet portletInstance =
507             (javax.portlet.Portlet)portletClass.newInstance();
508 
509         if (ClassUtil.isSubclass(portletClass, StrutsPortlet.class.getName())) {
510             _strutsBridges = true;
511         }
512 
513         ConfigurationAction configurationActionInstance = null;
514 
515         if (Validator.isNotNull(portlet.getConfigurationActionClass())) {
516             configurationActionInstance = (ConfigurationAction)newInstance(
517                 portletClassLoader, ConfigurationAction.class,
518                 portlet.getConfigurationActionClass());
519         }
520 
521         Indexer indexerInstance = null;
522 
523         if (Validator.isNotNull(portlet.getIndexerClass())) {
524             indexerInstance = (Indexer)newInstance(
525                 portletClassLoader, Indexer.class, portlet.getIndexerClass());
526 
527             IndexerRegistryUtil.register(indexerInstance);
528         }
529 
530         OpenSearch openSearchInstance = null;
531 
532         if (Validator.isNotNull(portlet.getOpenSearchClass())) {
533             openSearchInstance = (OpenSearch)newInstance(
534                 portletClassLoader, OpenSearch.class,
535                 portlet.getOpenSearchClass());
536         }
537 
538         Scheduler schedulerInstance = null;
539 
540         if (PropsValues.SCHEDULER_ENABLED &&
541             Validator.isNotNull(portlet.getSchedulerClass())) {
542 
543             schedulerInstance = (Scheduler)newInstance(
544                 portletClassLoader, Scheduler.class,
545                 portlet.getSchedulerClass());
546 
547             schedulerInstance.schedule();
548         }
549 
550         if (PropsValues.SCHEDULER_ENABLED){
551             List<SchedulerEntry> schedulerEntries =
552                 portlet.getSchedulerEntries();
553 
554             if ((schedulerEntries != null) && !schedulerEntries.isEmpty()) {
555                 for (SchedulerEntry schedulerEntry : schedulerEntries) {
556                     initSchedulerEntry(schedulerEntry, portletClassLoader);
557                 }
558             }
559         }
560 
561         FriendlyURLMapper friendlyURLMapperInstance = null;
562 
563         if (Validator.isNotNull(portlet.getFriendlyURLMapperClass())) {
564             friendlyURLMapperInstance = (FriendlyURLMapper)newInstance(
565                 portletClassLoader, FriendlyURLMapper.class,
566                 portlet.getFriendlyURLMapperClass());
567         }
568 
569         URLEncoder urlEncoderInstance = null;
570 
571         if (Validator.isNotNull(portlet.getURLEncoderClass())) {
572             urlEncoderInstance = (URLEncoder)newInstance(
573                 portletClassLoader, URLEncoder.class,
574                 portlet.getURLEncoderClass());
575         }
576 
577         PortletDataHandler portletDataHandlerInstance = null;
578 
579         if (Validator.isNotNull(portlet.getPortletDataHandlerClass())) {
580             portletDataHandlerInstance = (PortletDataHandler)newInstance(
581                 portletClassLoader, PortletDataHandler.class,
582                 portlet.getPortletDataHandlerClass());
583         }
584 
585         PortletLayoutListener portletLayoutListenerInstance = null;
586 
587         if (Validator.isNotNull(portlet.getPortletLayoutListenerClass())) {
588             portletLayoutListenerInstance = (PortletLayoutListener)newInstance(
589                 portletClassLoader, PortletLayoutListener.class,
590                 portlet.getPortletLayoutListenerClass());
591         }
592 
593         PollerProcessor pollerProcessorInstance = null;
594 
595         if (Validator.isNotNull(portlet.getPollerProcessorClass())) {
596             pollerProcessorInstance = (PollerProcessor)newInstance(
597                 portletClassLoader, PollerProcessor.class,
598                 portlet.getPollerProcessorClass());
599 
600             PollerProcessorUtil.addPollerProcessor(
601                 portlet.getPortletId(), pollerProcessorInstance);
602         }
603 
604         com.liferay.portal.kernel.pop.MessageListener
605             popMessageListenerInstance = null;
606 
607         if (Validator.isNotNull(portlet.getPopMessageListenerClass())) {
608             popMessageListenerInstance =
609                 (com.liferay.portal.kernel.pop.MessageListener)newInstance(
610                     portletClassLoader,
611                     com.liferay.portal.kernel.pop.MessageListener.class,
612                     portlet.getPopMessageListenerClass());
613 
614             POPServerUtil.addListener(popMessageListenerInstance);
615         }
616 
617         SocialActivityInterpreter socialActivityInterpreterInstance = null;
618 
619         if (Validator.isNotNull(portlet.getSocialActivityInterpreterClass())) {
620             socialActivityInterpreterInstance =
621                 (SocialActivityInterpreter)newInstance(
622                     portletClassLoader, SocialActivityInterpreter.class,
623                     portlet.getSocialActivityInterpreterClass());
624 
625             socialActivityInterpreterInstance =
626                 new SocialActivityInterpreterImpl(
627                     portlet.getPortletId(), socialActivityInterpreterInstance);
628 
629             SocialActivityInterpreterLocalServiceUtil.addActivityInterpreter(
630                 socialActivityInterpreterInstance);
631         }
632 
633         SocialRequestInterpreter socialRequestInterpreterInstance = null;
634 
635         if (Validator.isNotNull(portlet.getSocialRequestInterpreterClass())) {
636             socialRequestInterpreterInstance =
637                 (SocialRequestInterpreter)newInstance(
638                     portletClassLoader, SocialRequestInterpreter.class,
639                     portlet.getSocialRequestInterpreterClass());
640 
641             socialRequestInterpreterInstance = new SocialRequestInterpreterImpl(
642                 portlet.getPortletId(), socialRequestInterpreterInstance);
643 
644             SocialRequestInterpreterLocalServiceUtil.addRequestInterpreter(
645                 socialRequestInterpreterInstance);
646         }
647 
648         WebDAVStorage webDAVStorageInstance = null;
649 
650         if (Validator.isNotNull(portlet.getWebDAVStorageClass())) {
651             webDAVStorageInstance = (WebDAVStorage)newInstance(
652                 portletClassLoader, WebDAVStorage.class,
653                 portlet.getWebDAVStorageClass());
654 
655             webDAVStorageInstance.setToken(portlet.getWebDAVStorageToken());
656 
657             WebDAVUtil.addStorage(webDAVStorageInstance);
658         }
659 
660         Method xmlRpcMethodInstance = null;
661 
662         if (Validator.isNotNull(portlet.getXmlRpcMethodClass())) {
663             xmlRpcMethodInstance = (Method)newInstance(
664                 portletClassLoader, Method.class,
665                 portlet.getXmlRpcMethodClass());
666 
667             XmlRpcServlet.registerMethod(xmlRpcMethodInstance);
668         }
669 
670         ControlPanelEntry controlPanelEntryInstance = null;
671 
672         if (Validator.isNotNull(portlet.getControlPanelEntryClass())) {
673             controlPanelEntryInstance = (ControlPanelEntry)newInstance(
674                 portletClassLoader, ControlPanelEntry.class,
675                 portlet.getControlPanelEntryClass());
676         }
677 
678         List<AssetRendererFactory> assetRendererFactoryInstances =
679             new ArrayList<AssetRendererFactory>();
680 
681         for (String assetRendererFactoryClass :
682                 portlet.getAssetRendererFactoryClasses()) {
683 
684             AssetRendererFactory assetRendererFactoryInstance =
685                 (AssetRendererFactory)newInstance(
686                     portletClassLoader, AssetRendererFactory.class,
687                     assetRendererFactoryClass);
688 
689             assetRendererFactoryInstance.setClassNameId(
690                 PortalUtil.getClassNameId(
691                     assetRendererFactoryInstance.getClassName()));
692             assetRendererFactoryInstance.setPortletId(portlet.getPortletId());
693 
694             assetRendererFactoryInstances.add(assetRendererFactoryInstance);
695 
696             AssetRendererFactoryRegistryUtil.register(
697                 assetRendererFactoryInstance);
698         }
699 
700         List<CustomAttributesDisplay> customAttributesDisplayInstances =
701             new ArrayList<CustomAttributesDisplay>();
702 
703         for (String customAttributesDisplayClass :
704                 portlet.getCustomAttributesDisplayClasses()) {
705 
706             CustomAttributesDisplay customAttributesDisplayInstance =
707                 (CustomAttributesDisplay)newInstance(
708                     portletClassLoader, CustomAttributesDisplay.class,
709                     customAttributesDisplayClass);
710 
711             customAttributesDisplayInstance.setClassNameId(
712                 PortalUtil.getClassNameId(
713                     customAttributesDisplayInstance.getClassName()));
714             customAttributesDisplayInstance.setPortletId(
715                 portlet.getPortletId());
716 
717             customAttributesDisplayInstances.add(
718                 customAttributesDisplayInstance);
719         }
720 
721         List<WorkflowHandler> workflowHandlerInstances =
722             new ArrayList<WorkflowHandler>();
723 
724         for (String workflowHandlerClass :
725                 portlet.getWorkflowHandlerClasses()) {
726 
727             WorkflowHandler workflowHandlerInstance =
728                 (WorkflowHandler)newInstance(
729                     portletClassLoader, WorkflowHandler.class,
730                     workflowHandlerClass);
731 
732             workflowHandlerInstances.add(workflowHandlerInstance);
733 
734             WorkflowHandlerRegistryUtil.register(workflowHandlerInstance);
735         }
736 
737         PreferencesValidator preferencesValidatorInstance = null;
738 
739         if (Validator.isNotNull(portlet.getPreferencesValidator())) {
740             preferencesValidatorInstance = (PreferencesValidator)newInstance(
741                 portletClassLoader, PreferencesValidator.class,
742                 portlet.getPreferencesValidator());
743 
744             try {
745                 if (PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
746                     preferencesValidatorInstance.validate(
747                         PortletPreferencesSerializer.fromDefaultXML(
748                             portlet.getDefaultPreferences()));
749                 }
750             }
751             catch (Exception e) {
752                 _log.warn(
753                     "Portlet with the name " + portlet.getPortletId() +
754                         " does not have valid default preferences");
755             }
756         }
757 
758         Map<String, ResourceBundle> resourceBundles = null;
759 
760         if (Validator.isNotNull(portlet.getResourceBundle())) {
761             resourceBundles = new HashMap<String, ResourceBundle>();
762 
763             initResourceBundle(
764                 resourceBundles, portlet, portletClassLoader,
765                 LocaleUtil.getDefault());
766 
767             Iterator<String> supportLocalesItr =
768                 portlet.getSupportedLocales().iterator();
769 
770             while (supportLocalesItr.hasNext()) {
771                 String supportedLocale = supportLocalesItr.next();
772 
773                 Locale locale = LocaleUtil.fromLanguageId(supportedLocale);
774 
775                 initResourceBundle(
776                     resourceBundles, portlet, portletClassLoader, locale);
777             }
778         }
779 
780         PortletBag portletBag = new PortletBagImpl(
781             portlet.getPortletId(), servletContext, portletInstance,
782             configurationActionInstance, indexerInstance, openSearchInstance,
783             schedulerInstance, friendlyURLMapperInstance, urlEncoderInstance,
784             portletDataHandlerInstance, portletLayoutListenerInstance,
785             pollerProcessorInstance, popMessageListenerInstance,
786             socialActivityInterpreterInstance, socialRequestInterpreterInstance,
787             webDAVStorageInstance, xmlRpcMethodInstance,
788             controlPanelEntryInstance, assetRendererFactoryInstances,
789             customAttributesDisplayInstances, workflowHandlerInstances,
790             preferencesValidatorInstance, resourceBundles);
791 
792         PortletBagPool.put(portlet.getPortletId(), portletBag);
793 
794         if (!_portletAppInitialized) {
795             initPortletApp(
796                 portlet, servletContextName, servletContext,
797                 portletClassLoader);
798 
799             _portletAppInitialized = true;
800         }
801 
802         try {
803             PortletInstanceFactoryUtil.create(portlet, servletContext);
804         }
805         catch (Exception e) {
806             _log.error(e, e);
807         }
808     }
809 
810     protected void initSchedulerEntry(
811             SchedulerEntry schedulerEntry, ClassLoader portletClassLoader)
812         throws Exception {
813 
814         MessageListener schedulerEventListener = (MessageListener)newInstance(
815             portletClassLoader, MessageListener.class,
816             schedulerEntry.getEventListenerClass());
817 
818         schedulerEventListener = new SchedulerEventMessageListenerWrapper(
819             schedulerEventListener);
820 
821         schedulerEntry.setEventListener(schedulerEventListener);
822 
823         MessageBusUtil.registerMessageListener(
824             DestinationNames.SCHEDULER_DISPATCH, schedulerEventListener);
825 
826         SchedulerEngineUtil.schedule(
827             schedulerEntry.getTrigger(), schedulerEntry.getDescription(),
828             DestinationNames.SCHEDULER_DISPATCH, null);
829     }
830 
831     protected void initPortletApp(
832             Portlet portlet, String servletContextName,
833             ServletContext servletContext, ClassLoader portletClassLoader)
834         throws Exception {
835 
836         PortletConfig portletConfig = PortletConfigFactory.create(
837             portlet, servletContext);
838 
839         PortletContext portletContext = portletConfig.getPortletContext();
840 
841         PortletContextBag portletContextBag = new PortletContextBag(
842             servletContextName);
843 
844         PortletContextBagPool.put(servletContextName, portletContextBag);
845 
846         PortletApp portletApp = portlet.getPortletApp();
847 
848         Map<String, String> customUserAttributes =
849             portletApp.getCustomUserAttributes();
850 
851         for (Map.Entry<String, String> entry :
852                 customUserAttributes.entrySet()) {
853 
854             String attrCustomClass = entry.getValue();
855 
856             CustomUserAttributes customUserAttributesInstance =
857                 (CustomUserAttributes)portletClassLoader.loadClass(
858                     attrCustomClass).newInstance();
859 
860             portletContextBag.getCustomUserAttributes().put(
861                 attrCustomClass, customUserAttributesInstance);
862         }
863 
864         Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
865 
866         for (PortletFilter portletFilter : portletFilters) {
867             javax.portlet.filter.PortletFilter portletFilterInstance =
868                 (javax.portlet.filter.PortletFilter)newInstance(
869                     portletClassLoader,
870                     new Class<?>[] {
871                         javax.portlet.filter.ActionFilter.class,
872                         javax.portlet.filter.EventFilter.class,
873                         javax.portlet.filter.PortletFilter.class,
874                         javax.portlet.filter.RenderFilter.class,
875                         javax.portlet.filter.ResourceFilter.class
876                     },
877                     portletFilter.getFilterClass());
878 
879             portletContextBag.getPortletFilters().put(
880                 portletFilter.getFilterName(), portletFilterInstance);
881 
882             PortletFilterFactory.create(portletFilter, portletContext);
883         }
884 
885         Set<PortletURLListener> portletURLListeners =
886             portletApp.getPortletURLListeners();
887 
888         for (PortletURLListener portletURLListener : portletURLListeners) {
889             PortletURLGenerationListener portletURLListenerInstance =
890                 (PortletURLGenerationListener)newInstance(
891                     portletClassLoader, PortletURLGenerationListener.class,
892                     portletURLListener.getListenerClass());
893 
894             portletContextBag.getPortletURLListeners().put(
895                 portletURLListener.getListenerClass(),
896                 portletURLListenerInstance);
897 
898             PortletURLListenerFactory.create(portletURLListener);
899         }
900     }
901 
902     protected void initResourceBundle(
903         Map<String, ResourceBundle> resourceBundles, Portlet portlet,
904         ClassLoader portletClassLoader, Locale locale) {
905 
906         try {
907             ResourceBundle resourceBundle = ResourceBundle.getBundle(
908                 portlet.getResourceBundle(), locale, portletClassLoader);
909 
910             resourceBundles.put(
911                 LocaleUtil.toLanguageId(locale), resourceBundle);
912         }
913         catch (MissingResourceException mre) {
914             _log.warn(mre.getMessage());
915         }
916     }
917 
918     protected void processPortletProperties(
919             String servletContextName, ClassLoader portletClassLoader)
920         throws Exception {
921 
922         Configuration portletPropertiesConfiguration = null;
923 
924         try {
925             portletPropertiesConfiguration =
926                 ConfigurationFactoryUtil.getConfiguration(
927                     portletClassLoader, "portlet");
928         }
929         catch (Exception e) {
930             if (_log.isDebugEnabled()) {
931                 _log.debug("Unable to read portlet.properties");
932             }
933 
934             return;
935         }
936 
937         Properties portletProperties =
938             portletPropertiesConfiguration.getProperties();
939 
940         if (portletProperties.size() == 0) {
941             return;
942         }
943 
944         String languageBundleName = portletProperties.getProperty(
945             "language.bundle");
946 
947         if (Validator.isNotNull(languageBundleName)) {
948             Locale[] locales = LanguageUtil.getAvailableLocales();
949 
950             for (int i = 0; i < locales.length; i++) {
951                 ResourceBundle bundle = ResourceBundle.getBundle(
952                     languageBundleName, locales[i], portletClassLoader);
953 
954                 PortletResourceBundles.put(
955                     servletContextName, LocaleUtil.toLanguageId(locales[i]),
956                     bundle);
957             }
958         }
959 
960         String[] resourceActionConfigs = StringUtil.split(
961             portletProperties.getProperty("resource.actions.configs"));
962 
963         for (int i = 0; i < resourceActionConfigs.length; i++) {
964             ResourceActionsUtil.read(
965                 servletContextName, portletClassLoader,
966                 resourceActionConfigs[i]);
967         }
968     }
969 
970     private static Log _log = LogFactoryUtil.getLog(
971         PortletHotDeployListener.class);
972 
973     private static Map<String, ObjectValuePair<long[], List<Portlet>>> _vars =
974         new HashMap<String, ObjectValuePair<long[], List<Portlet>>>();
975 
976     private boolean _portletAppInitialized;
977     private boolean _strutsBridges;
978 
979 }