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