1   /**
2    * Copyright (c) 2000-2009 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   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.deploy.hot;
21  
22  import com.liferay.portal.apache.bridges.struts.LiferayServletContextProvider;
23  import com.liferay.portal.kernel.configuration.Configuration;
24  import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
25  import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
26  import com.liferay.portal.kernel.deploy.hot.HotDeployException;
27  import com.liferay.portal.kernel.job.Scheduler;
28  import com.liferay.portal.kernel.language.LanguageUtil;
29  import com.liferay.portal.kernel.log.Log;
30  import com.liferay.portal.kernel.log.LogFactoryUtil;
31  import com.liferay.portal.kernel.pop.MessageListener;
32  import com.liferay.portal.kernel.portlet.ConfigurationAction;
33  import com.liferay.portal.kernel.portlet.FriendlyURLMapper;
34  import com.liferay.portal.kernel.portlet.PortletBag;
35  import com.liferay.portal.kernel.portlet.PortletBagPool;
36  import com.liferay.portal.kernel.portlet.PortletLayoutListener;
37  import com.liferay.portal.kernel.search.Indexer;
38  import com.liferay.portal.kernel.search.IndexerWrapper;
39  import com.liferay.portal.kernel.search.OpenSearch;
40  import com.liferay.portal.kernel.servlet.PortletServlet;
41  import com.liferay.portal.kernel.servlet.ServletContextProvider;
42  import com.liferay.portal.kernel.servlet.URLEncoder;
43  import com.liferay.portal.kernel.util.ClassUtil;
44  import com.liferay.portal.kernel.util.GetterUtil;
45  import com.liferay.portal.kernel.util.HttpUtil;
46  import com.liferay.portal.kernel.util.LocaleUtil;
47  import com.liferay.portal.kernel.util.ObjectValuePair;
48  import com.liferay.portal.kernel.util.StringUtil;
49  import com.liferay.portal.kernel.util.Validator;
50  import com.liferay.portal.lar.PortletDataHandler;
51  import com.liferay.portal.model.Portlet;
52  import com.liferay.portal.model.PortletApp;
53  import com.liferay.portal.model.PortletCategory;
54  import com.liferay.portal.model.PortletFilter;
55  import com.liferay.portal.model.PortletURLListener;
56  import com.liferay.portal.pop.POPServerUtil;
57  import com.liferay.portal.security.permission.ResourceActionsUtil;
58  import com.liferay.portal.service.PortletLocalServiceUtil;
59  import com.liferay.portal.util.Portal;
60  import com.liferay.portal.util.PortalInstances;
61  import com.liferay.portal.util.PropsValues;
62  import com.liferay.portal.util.WebAppPool;
63  import com.liferay.portal.util.WebKeys;
64  import com.liferay.portlet.CustomUserAttributes;
65  import com.liferay.portlet.PortletBagImpl;
66  import com.liferay.portlet.PortletConfigFactory;
67  import com.liferay.portlet.PortletContextBag;
68  import com.liferay.portlet.PortletContextBagPool;
69  import com.liferay.portlet.PortletFilterFactory;
70  import com.liferay.portlet.PortletInstanceFactory;
71  import com.liferay.portlet.PortletPreferencesSerializer;
72  import com.liferay.portlet.PortletResourceBundles;
73  import com.liferay.portlet.PortletURLListenerFactory;
74  import com.liferay.portlet.social.model.SocialActivityInterpreter;
75  import com.liferay.portlet.social.model.SocialRequestInterpreter;
76  import com.liferay.portlet.social.model.impl.SocialActivityInterpreterImpl;
77  import com.liferay.portlet.social.model.impl.SocialRequestInterpreterImpl;
78  import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
79  import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
80  
81  import java.util.HashMap;
82  import java.util.HashSet;
83  import java.util.Iterator;
84  import java.util.List;
85  import java.util.Locale;
86  import java.util.Map;
87  import java.util.MissingResourceException;
88  import java.util.Properties;
89  import java.util.ResourceBundle;
90  import java.util.Set;
91  
92  import javax.portlet.PortletConfig;
93  import javax.portlet.PortletContext;
94  import javax.portlet.PortletURLGenerationListener;
95  import javax.portlet.PreferencesValidator;
96  
97  import javax.servlet.ServletContext;
98  
99  import org.apache.portals.bridges.struts.StrutsPortlet;
100 
101 /**
102  * <a href="PortletHotDeployListener.java.html"><b><i>View Source</i></b></a>
103  *
104  * @author Brian Wing Shun Chan
105  * @author Brian Myunghun Kim
106  * @author Ivica Cardic
107  *
108  */
109 public class PortletHotDeployListener extends BaseHotDeployListener {
110 
111     public void invokeDeploy(HotDeployEvent event) throws HotDeployException {
112         try {
113             doInvokeDeploy(event);
114         }
115         catch (Throwable t) {
116             throwHotDeployException(
117                 event, "Error registering portlets for ", t);
118         }
119     }
120 
121     public void invokeUndeploy(HotDeployEvent event) throws HotDeployException {
122         try {
123             doInvokeUndeploy(event);
124         }
125         catch (Throwable t) {
126             throwHotDeployException(
127                 event, "Error unregistering portlets for ", t);
128         }
129     }
130 
131     protected void destroyPortlet(Portlet portlet, Set<String> portletIds)
132         throws Exception {
133 
134         PortletApp portletApp = portlet.getPortletApp();
135 
136         Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
137 
138         for (PortletFilter portletFilter : portletFilters) {
139             PortletFilterFactory.destroy(portletFilter);
140         }
141 
142         Set<PortletURLListener> portletURLListeners =
143             portletApp.getPortletURLListeners();
144 
145         for (PortletURLListener portletURLListener : portletURLListeners) {
146             PortletURLListenerFactory.destroy(portletURLListener);
147         }
148 
149         Scheduler scheduler = portlet.getSchedulerInstance();
150 
151         if (scheduler != null) {
152             scheduler.unschedule();
153         }
154 
155         POPServerUtil.deleteListener(portlet.getPopMessageListenerInstance());
156 
157         SocialActivityInterpreterLocalServiceUtil.deleteActivityInterpreter(
158             portlet.getSocialActivityInterpreterInstance());
159 
160         SocialRequestInterpreterLocalServiceUtil.deleteRequestInterpreter(
161             portlet.getSocialRequestInterpreterInstance());
162 
163         PortletInstanceFactory.destroy(portlet);
164 
165         portletIds.add(portlet.getPortletId());
166     }
167 
168     protected void doInvokeDeploy(HotDeployEvent event) throws Exception {
169 
170         // Servlet context
171 
172         ServletContext servletContext = event.getServletContext();
173 
174         String servletContextName = servletContext.getServletContextName();
175 
176         if (_log.isDebugEnabled()) {
177             _log.debug("Invoking deploy for " + servletContextName);
178         }
179 
180         // Company ids
181 
182         long[] companyIds = PortalInstances.getCompanyIds();
183 
184         // Initialize portlets
185 
186         String[] xmls = new String[] {
187             HttpUtil.URLtoString(servletContext.getResource(
188                 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD)),
189             HttpUtil.URLtoString(servletContext.getResource(
190                 "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
191             HttpUtil.URLtoString(servletContext.getResource(
192                 "/WEB-INF/liferay-portlet.xml")),
193             HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"))
194         };
195 
196         if (xmls[0] == null) {
197             return;
198         }
199 
200         if (_log.isInfoEnabled()) {
201             _log.info("Registering portlets for " + servletContextName);
202         }
203 
204         List<Portlet> portlets = PortletLocalServiceUtil.initWAR(
205             servletContextName, servletContext, xmls, event.getPluginPackage());
206 
207         // Class loader
208 
209         ClassLoader portletClassLoader = event.getContextClassLoader();
210 
211         servletContext.setAttribute(
212             PortletServlet.PORTLET_CLASS_LOADER, portletClassLoader);
213 
214         // Portlet context wrapper
215 
216         _portletAppInitialized = false;
217         _strutsBridges = false;
218 
219         Iterator<Portlet> portletsItr = portlets.iterator();
220 
221         while (portletsItr.hasNext()) {
222             Portlet portlet = portletsItr.next();
223 
224             initPortlet(
225                 portlet, servletContext, portletClassLoader, portletsItr);
226         }
227 
228         // Struts bridges
229 
230         if (!_strutsBridges) {
231             _strutsBridges = GetterUtil.getBoolean(
232                 servletContext.getInitParameter(
233                     "struts-bridges-context-provider"));
234         }
235 
236         if (_strutsBridges) {
237             servletContext.setAttribute(
238                 ServletContextProvider.STRUTS_BRIDGES_CONTEXT_PROVIDER,
239                 new LiferayServletContextProvider());
240         }
241 
242         // Portlet display
243 
244         String xml = HttpUtil.URLtoString(servletContext.getResource(
245             "/WEB-INF/liferay-display.xml"));
246 
247         PortletCategory newPortletCategory =
248             PortletLocalServiceUtil.getWARDisplay(servletContextName, xml);
249 
250         for (int i = 0; i < companyIds.length; i++) {
251             long companyId = companyIds[i];
252 
253             PortletCategory portletCategory =
254                 (PortletCategory)WebAppPool.get(
255                     String.valueOf(companyId), WebKeys.PORTLET_CATEGORY);
256 
257             if (portletCategory != null) {
258                 portletCategory.merge(newPortletCategory);
259             }
260             else {
261                 _log.error(
262                     "Unable to register portlet for company " + companyId +
263                         " because it does not exist");
264             }
265         }
266 
267         // Portlet properties
268 
269         processPortletProperties(servletContextName, portletClassLoader);
270 
271         // Variables
272 
273         _vars.put(
274             servletContextName,
275             new ObjectValuePair<long[], List<Portlet>>(
276                 companyIds, portlets));
277 
278         if (_log.isInfoEnabled()) {
279             if (portlets.size() == 1) {
280                 _log.info(
281                     "1 portlet for " + servletContextName +
282                         " is available for use");
283             }
284             else {
285                 _log.info(
286                     portlets.size() + " portlets for " + servletContextName +
287                         " are available for use");
288             }
289         }
290     }
291 
292     protected void doInvokeUndeploy(HotDeployEvent event) throws Exception {
293         ServletContext servletContext = event.getServletContext();
294 
295         String servletContextName = servletContext.getServletContextName();
296 
297         if (_log.isDebugEnabled()) {
298             _log.debug("Invoking undeploy for " + servletContextName);
299         }
300 
301         ObjectValuePair<long[], List<Portlet>> ovp =
302             _vars.remove(servletContextName);
303 
304         if (ovp == null) {
305             return;
306         }
307 
308         long[] companyIds = ovp.getKey();
309         List<Portlet> portlets = ovp.getValue();
310 
311         Set<String> portletIds = new HashSet<String>();
312 
313         if (portlets != null) {
314             if (_log.isInfoEnabled()) {
315                 _log.info(
316                     "Unregistering portlets for " + servletContextName);
317             }
318 
319             Iterator<Portlet> itr = portlets.iterator();
320 
321             while (itr.hasNext()) {
322                 Portlet portlet = itr.next();
323 
324                 destroyPortlet(portlet, portletIds);
325             }
326         }
327 
328         if (portletIds.size() > 0) {
329             for (int i = 0; i < companyIds.length; i++) {
330                 long companyId = companyIds[i];
331 
332                 PortletCategory portletCategory =
333                     (PortletCategory)WebAppPool.get(
334                         String.valueOf(companyId), WebKeys.PORTLET_CATEGORY);
335 
336                 portletCategory.separate(portletIds);
337             }
338         }
339 
340         PortletResourceBundles.remove(servletContextName);
341 
342         if (_log.isInfoEnabled()) {
343             if (portlets.size() == 1) {
344                 _log.info(
345                     "1 portlet for " + servletContextName +
346                         " was unregistered");
347             }
348             else {
349                 _log.info(
350                     portlets.size() + " portlets for " + servletContextName +
351                         " was unregistered");
352             }
353         }
354     }
355 
356     protected void initPortlet(
357             Portlet portlet, ServletContext servletContext,
358             ClassLoader portletClassLoader, Iterator<Portlet> portletsItr)
359         throws Exception {
360 
361         Class<?> portletClass = null;
362 
363         try {
364             portletClass = portletClassLoader.loadClass(
365                 portlet.getPortletClass());
366         }
367         catch (Exception e) {
368             _log.error(e, e);
369 
370             portletsItr.remove();
371 
372             PortletLocalServiceUtil.destroyPortlet(portlet);
373 
374             return;
375         }
376 
377         javax.portlet.Portlet portletInstance =
378             (javax.portlet.Portlet)portletClass.newInstance();
379 
380         if (ClassUtil.isSubclass(portletClass, StrutsPortlet.class.getName())) {
381             _strutsBridges = true;
382         }
383 
384         ConfigurationAction configurationActionInstance = null;
385 
386         if (Validator.isNotNull(portlet.getConfigurationActionClass())) {
387             configurationActionInstance =
388                 (ConfigurationAction)portletClassLoader.loadClass(
389                     portlet.getConfigurationActionClass()).newInstance();
390         }
391 
392         Indexer indexerInstance = null;
393 
394         if (Validator.isNotNull(portlet.getIndexerClass())) {
395             indexerInstance = (Indexer)portletClassLoader.loadClass(
396                 portlet.getIndexerClass()).newInstance();
397 
398             indexerInstance = new IndexerWrapper(
399                 indexerInstance, portletClassLoader);
400         }
401 
402         OpenSearch openSearchInstance = null;
403 
404         if (Validator.isNotNull(portlet.getOpenSearchClass())) {
405             openSearchInstance = (OpenSearch)portletClassLoader.loadClass(
406                 portlet.getOpenSearchClass()).newInstance();
407         }
408 
409         Scheduler schedulerInstance = null;
410 
411         if (PropsValues.SCHEDULER_ENABLED &&
412             Validator.isNotNull(portlet.getSchedulerClass())) {
413 
414             schedulerInstance = (Scheduler)portletClassLoader.loadClass(
415                 portlet.getSchedulerClass()).newInstance();
416 
417             schedulerInstance.schedule();
418         }
419 
420         FriendlyURLMapper friendlyURLMapperInstance = null;
421 
422         if (Validator.isNotNull(portlet.getFriendlyURLMapperClass())) {
423             friendlyURLMapperInstance =
424                 (FriendlyURLMapper)portletClassLoader.loadClass(
425                     portlet.getFriendlyURLMapperClass()).newInstance();
426         }
427 
428         URLEncoder urlEncoderInstance = null;
429 
430         if (Validator.isNotNull(portlet.getURLEncoderClass())) {
431             urlEncoderInstance = (URLEncoder)portletClassLoader.loadClass(
432                 portlet.getURLEncoderClass()).newInstance();
433         }
434 
435         PortletDataHandler portletDataHandlerInstance = null;
436 
437         if (Validator.isNotNull(portlet.getPortletDataHandlerClass())) {
438             portletDataHandlerInstance =
439                 (PortletDataHandler)portletClassLoader.loadClass(
440                     portlet.getPortletDataHandlerClass()).newInstance();
441         }
442 
443         PortletLayoutListener portletLayoutListenerInstance = null;
444 
445         if (Validator.isNotNull(portlet.getPortletLayoutListenerClass())) {
446             portletLayoutListenerInstance =
447                 (PortletLayoutListener)portletClassLoader.loadClass(
448                     portlet.getPortletLayoutListenerClass()).newInstance();
449         }
450 
451         MessageListener popMessageListenerInstance = null;
452 
453         if (Validator.isNotNull(portlet.getPopMessageListenerClass())) {
454             popMessageListenerInstance =
455                 (MessageListener)portletClassLoader.loadClass(
456                     portlet.getPopMessageListenerClass()).newInstance();
457 
458             POPServerUtil.addListener(popMessageListenerInstance);
459         }
460 
461         SocialActivityInterpreter socialActivityInterpreterInstance = null;
462 
463         if (Validator.isNotNull(portlet.getSocialActivityInterpreterClass())) {
464             socialActivityInterpreterInstance =
465                 (SocialActivityInterpreter)portletClassLoader.loadClass(
466                     portlet.getSocialActivityInterpreterClass()).newInstance();
467 
468             socialActivityInterpreterInstance =
469                 new SocialActivityInterpreterImpl(
470                     portlet.getPortletId(), socialActivityInterpreterInstance);
471 
472             SocialActivityInterpreterLocalServiceUtil.addActivityInterpreter(
473                 socialActivityInterpreterInstance);
474         }
475 
476         SocialRequestInterpreter socialRequestInterpreterInstance = null;
477 
478         if (Validator.isNotNull(portlet.getSocialRequestInterpreterClass())) {
479             socialRequestInterpreterInstance =
480                 (SocialRequestInterpreter)portletClassLoader.loadClass(
481                     portlet.getSocialRequestInterpreterClass()).newInstance();
482 
483             socialRequestInterpreterInstance = new SocialRequestInterpreterImpl(
484                 portlet.getPortletId(), socialRequestInterpreterInstance);
485 
486             SocialRequestInterpreterLocalServiceUtil.addRequestInterpreter(
487                 socialRequestInterpreterInstance);
488         }
489 
490         PreferencesValidator prefsValidatorInstance = null;
491 
492         if (Validator.isNotNull(portlet.getPreferencesValidator())) {
493             prefsValidatorInstance =
494                 (PreferencesValidator)portletClassLoader.loadClass(
495                     portlet.getPreferencesValidator()).newInstance();
496 
497             try {
498                 if (PropsValues.PREFERENCE_VALIDATE_ON_STARTUP) {
499                     prefsValidatorInstance.validate(
500                         PortletPreferencesSerializer.fromDefaultXML(
501                             portlet.getDefaultPreferences()));
502                 }
503             }
504             catch (Exception e) {
505                 _log.warn(
506                     "Portlet with the name " + portlet.getPortletId() +
507                         " does not have valid default preferences");
508             }
509         }
510 
511         Map<String, ResourceBundle> resourceBundles = null;
512 
513         if (Validator.isNotNull(portlet.getResourceBundle())) {
514             resourceBundles = new HashMap<String, ResourceBundle>();
515 
516             initResourceBundle(
517                 resourceBundles, portlet, portletClassLoader,
518                 LocaleUtil.getDefault());
519 
520             Iterator<String> supportLocalesItr =
521                 portlet.getSupportedLocales().iterator();
522 
523             while (supportLocalesItr.hasNext()) {
524                 String supportedLocale = supportLocalesItr.next();
525 
526                 Locale locale = LocaleUtil.fromLanguageId(supportedLocale);
527 
528                 initResourceBundle(
529                     resourceBundles, portlet, portletClassLoader, locale);
530             }
531         }
532 
533         PortletBag portletBag = new PortletBagImpl(
534             portlet.getPortletId(), servletContext, portletInstance,
535             configurationActionInstance, indexerInstance, openSearchInstance,
536             schedulerInstance, friendlyURLMapperInstance, urlEncoderInstance,
537             portletDataHandlerInstance, portletLayoutListenerInstance,
538             popMessageListenerInstance, socialActivityInterpreterInstance,
539             socialRequestInterpreterInstance, prefsValidatorInstance,
540             resourceBundles);
541 
542         PortletBagPool.put(portlet.getPortletId(), portletBag);
543 
544         if (!_portletAppInitialized) {
545             initPortletApp(portlet, servletContext, portletClassLoader);
546 
547             _portletAppInitialized = true;
548         }
549 
550         try {
551             PortletInstanceFactory.create(portlet, servletContext);
552         }
553         catch (Exception e) {
554             _log.error(e, e);
555         }
556     }
557 
558     protected void initPortletApp(
559             Portlet portlet, ServletContext servletContext,
560             ClassLoader portletClassLoader)
561         throws Exception {
562 
563         String servletContextName = servletContext.getServletContextName();
564 
565         PortletConfig portletConfig = PortletConfigFactory.create(
566             portlet, servletContext);
567 
568         PortletContext portletContext = portletConfig.getPortletContext();
569 
570         PortletContextBag portletContextBag = new PortletContextBag(
571             servletContextName);
572 
573         PortletContextBagPool.put(servletContextName, portletContextBag);
574 
575         PortletApp portletApp = portlet.getPortletApp();
576 
577         Map<String, String> customUserAttributes =
578             portletApp.getCustomUserAttributes();
579 
580         for (Map.Entry<String, String> entry :
581                 customUserAttributes.entrySet()) {
582 
583             String attrCustomClass = entry.getValue();
584 
585             CustomUserAttributes customUserAttributesInstance =
586                 (CustomUserAttributes)portletClassLoader.loadClass(
587                     attrCustomClass).newInstance();
588 
589             portletContextBag.getCustomUserAttributes().put(
590                 attrCustomClass, customUserAttributesInstance);
591         }
592 
593         Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
594 
595         for (PortletFilter portletFilter : portletFilters) {
596             javax.portlet.filter.PortletFilter portletFilterInstance =
597                 (javax.portlet.filter.PortletFilter)
598                     portletClassLoader.loadClass(
599                         portletFilter.getFilterClass()).newInstance();
600 
601             portletContextBag.getPortletFilters().put(
602                 portletFilter.getFilterName(), portletFilterInstance);
603 
604             PortletFilterFactory.create(portletFilter, portletContext);
605         }
606 
607         Set<PortletURLListener> portletURLListeners =
608             portletApp.getPortletURLListeners();
609 
610         for (PortletURLListener portletURLListener : portletURLListeners) {
611             PortletURLGenerationListener portletURLListenerInstance =
612                 (PortletURLGenerationListener)portletClassLoader.loadClass(
613                     portletURLListener.getListenerClass()).newInstance();
614 
615             portletContextBag.getPortletURLListeners().put(
616                 portletURLListener.getListenerClass(),
617                 portletURLListenerInstance);
618 
619             PortletURLListenerFactory.create(portletURLListener);
620         }
621     }
622 
623     protected void initResourceBundle(
624         Map<String, ResourceBundle> resourceBundles, Portlet portlet,
625         ClassLoader portletClassLoader, Locale locale) {
626 
627         try {
628             ResourceBundle resourceBundle = ResourceBundle.getBundle(
629                 portlet.getResourceBundle(), locale, portletClassLoader);
630 
631             resourceBundles.put(
632                 LocaleUtil.toLanguageId(locale), resourceBundle);
633         }
634         catch (MissingResourceException mre) {
635             _log.warn(mre.getMessage());
636         }
637     }
638 
639     protected void processPortletProperties(
640             String servletContextName, ClassLoader portletClassLoader)
641         throws Exception {
642 
643         Configuration portletPropertiesConfiguration = null;
644 
645         try {
646             portletPropertiesConfiguration =
647                 ConfigurationFactoryUtil.getConfiguration(
648                     portletClassLoader, "portlet");
649         }
650         catch (Exception e) {
651             if (_log.isDebugEnabled()) {
652                 _log.debug("Unable to read portlet.properties");
653             }
654 
655             return;
656         }
657 
658         Properties portletProperties =
659             portletPropertiesConfiguration.getProperties();
660 
661         if (portletProperties.size() == 0) {
662             return;
663         }
664 
665         String languageBundleName = portletProperties.getProperty(
666             "language.bundle");
667 
668         if (Validator.isNotNull(languageBundleName)) {
669             Locale[] locales = LanguageUtil.getAvailableLocales();
670 
671             for (int i = 0; i < locales.length; i++) {
672                 ResourceBundle bundle = ResourceBundle.getBundle(
673                     languageBundleName, locales[i], portletClassLoader);
674 
675                 PortletResourceBundles.put(
676                     servletContextName, LocaleUtil.toLanguageId(locales[i]),
677                     bundle);
678             }
679         }
680 
681         String[] resourceActionConfigs = StringUtil.split(
682             portletProperties.getProperty("resource.actions.configs"));
683 
684         for (int i = 0; i < resourceActionConfigs.length; i++) {
685             ResourceActionsUtil.read(
686                 servletContextName, portletClassLoader,
687                 resourceActionConfigs[i]);
688         }
689     }
690 
691     private static Log _log =
692          LogFactoryUtil.getLog(PortletHotDeployListener.class);
693 
694     private static Map<String, ObjectValuePair<long[], List<Portlet>>> _vars =
695         new HashMap<String, ObjectValuePair<long[], List<Portlet>>>();
696 
697     private boolean _portletAppInitialized;
698     private boolean _strutsBridges;
699 
700 }