001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.deploy.hot;
016    
017    import com.liferay.portal.apache.bridges.struts.LiferayServletContextProvider;
018    import com.liferay.portal.kernel.atom.AtomCollectionAdapter;
019    import com.liferay.portal.kernel.atom.AtomCollectionAdapterRegistryUtil;
020    import com.liferay.portal.kernel.configuration.Configuration;
021    import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil;
022    import com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener;
023    import com.liferay.portal.kernel.deploy.hot.HotDeployEvent;
024    import com.liferay.portal.kernel.deploy.hot.HotDeployException;
025    import com.liferay.portal.kernel.javadoc.JavadocManagerUtil;
026    import com.liferay.portal.kernel.language.LanguageUtil;
027    import com.liferay.portal.kernel.lar.StagedModelDataHandler;
028    import com.liferay.portal.kernel.lar.StagedModelDataHandlerRegistryUtil;
029    import com.liferay.portal.kernel.log.Log;
030    import com.liferay.portal.kernel.log.LogFactoryUtil;
031    import com.liferay.portal.kernel.notifications.UserNotificationHandler;
032    import com.liferay.portal.kernel.notifications.UserNotificationManagerUtil;
033    import com.liferay.portal.kernel.portlet.PortletBag;
034    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
035    import com.liferay.portal.kernel.scheduler.SchedulerEntry;
036    import com.liferay.portal.kernel.scheduler.StorageType;
037    import com.liferay.portal.kernel.search.Indexer;
038    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
039    import com.liferay.portal.kernel.servlet.DirectServletRegistryUtil;
040    import com.liferay.portal.kernel.servlet.PortletServlet;
041    import com.liferay.portal.kernel.servlet.ServletContextPool;
042    import com.liferay.portal.kernel.servlet.ServletContextProvider;
043    import com.liferay.portal.kernel.trash.TrashHandler;
044    import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
045    import com.liferay.portal.kernel.util.ClassUtil;
046    import com.liferay.portal.kernel.util.GetterUtil;
047    import com.liferay.portal.kernel.util.HttpUtil;
048    import com.liferay.portal.kernel.util.InfrastructureUtil;
049    import com.liferay.portal.kernel.util.LocaleUtil;
050    import com.liferay.portal.kernel.util.PropsKeys;
051    import com.liferay.portal.kernel.util.ServerDetector;
052    import com.liferay.portal.kernel.util.StringUtil;
053    import com.liferay.portal.kernel.util.Validator;
054    import com.liferay.portal.kernel.webdav.WebDAVUtil;
055    import com.liferay.portal.kernel.workflow.WorkflowHandler;
056    import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
057    import com.liferay.portal.model.Portlet;
058    import com.liferay.portal.model.PortletApp;
059    import com.liferay.portal.model.PortletCategory;
060    import com.liferay.portal.model.PortletFilter;
061    import com.liferay.portal.model.PortletURLListener;
062    import com.liferay.portal.poller.PollerProcessorUtil;
063    import com.liferay.portal.pop.POPServerUtil;
064    import com.liferay.portal.security.permission.ResourceActionsUtil;
065    import com.liferay.portal.service.PortletLocalServiceUtil;
066    import com.liferay.portal.service.ResourceActionLocalServiceUtil;
067    import com.liferay.portal.util.Portal;
068    import com.liferay.portal.util.PortalInstances;
069    import com.liferay.portal.util.PropsValues;
070    import com.liferay.portal.util.WebAppPool;
071    import com.liferay.portal.util.WebKeys;
072    import com.liferay.portal.xmlrpc.XmlRpcServlet;
073    import com.liferay.portlet.CustomUserAttributes;
074    import com.liferay.portlet.InvokerPortlet;
075    import com.liferay.portlet.PortletBagFactory;
076    import com.liferay.portlet.PortletContextBag;
077    import com.liferay.portlet.PortletContextBagPool;
078    import com.liferay.portlet.PortletFilterFactory;
079    import com.liferay.portlet.PortletInstanceFactoryUtil;
080    import com.liferay.portlet.PortletResourceBundles;
081    import com.liferay.portlet.PortletURLListenerFactory;
082    import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
083    import com.liferay.portlet.asset.model.AssetRendererFactory;
084    import com.liferay.portlet.social.model.SocialActivityInterpreter;
085    import com.liferay.portlet.social.service.SocialActivityInterpreterLocalServiceUtil;
086    import com.liferay.portlet.social.service.SocialRequestInterpreterLocalServiceUtil;
087    import com.liferay.util.bridges.php.PHPPortlet;
088    
089    import java.util.HashMap;
090    import java.util.HashSet;
091    import java.util.Iterator;
092    import java.util.List;
093    import java.util.Locale;
094    import java.util.Map;
095    import java.util.Properties;
096    import java.util.ResourceBundle;
097    import java.util.Set;
098    
099    import javax.naming.Context;
100    import javax.naming.InitialContext;
101    import javax.naming.NamingException;
102    
103    import javax.portlet.PortletURLGenerationListener;
104    
105    import javax.servlet.ServletContext;
106    
107    import javax.sql.DataSource;
108    
109    import org.apache.portals.bridges.struts.StrutsPortlet;
110    
111    /**
112     * @author Brian Wing Shun Chan
113     * @author Brian Myunghun Kim
114     * @author Ivica Cardic
115     * @author Raymond Aug??
116     */
117    public class PortletHotDeployListener extends BaseHotDeployListener {
118    
119            @Override
120            public void invokeDeploy(HotDeployEvent hotDeployEvent)
121                    throws HotDeployException {
122    
123                    try {
124                            doInvokeDeploy(hotDeployEvent);
125                    }
126                    catch (Throwable t) {
127                            throwHotDeployException(
128                                    hotDeployEvent,
129                                    "Error registering portlets for " +
130                                            hotDeployEvent.getServletContextName(),
131                                    t);
132                    }
133            }
134    
135            @Override
136            public void invokeUndeploy(HotDeployEvent hotDeployEvent)
137                    throws HotDeployException {
138    
139                    try {
140                            doInvokeUndeploy(hotDeployEvent);
141                    }
142                    catch (Throwable t) {
143                            throwHotDeployException(
144                                    hotDeployEvent,
145                                    "Error unregistering portlets for " +
146                                            hotDeployEvent.getServletContextName(),
147                                    t);
148                    }
149            }
150    
151            protected void bindDataSource(String servletContextName) throws Exception {
152                    if (ServerDetector.isGlassfish() || ServerDetector.isJOnAS()) {
153                            return;
154                    }
155    
156                    if (_log.isDebugEnabled()) {
157                            _log.debug("Dynamically binding the Liferay data source");
158                    }
159    
160                    DataSource dataSource = InfrastructureUtil.getDataSource();
161    
162                    if (dataSource == null) {
163                            if (_log.isDebugEnabled()) {
164                                    _log.debug(
165                                            "Abort dynamically binding the Liferay data source " +
166                                                    "because it is not available");
167                            }
168    
169                            return;
170                    }
171    
172                    Context context = new InitialContext();
173    
174                    try {
175                            try {
176                                    context.lookup(_JNDI_JDBC);
177                            }
178                            catch (NamingException ne) {
179                                    context.createSubcontext(_JNDI_JDBC);
180                            }
181    
182                            try {
183                                    context.lookup(_JNDI_JDBC_LIFERAY_POOL);
184                            }
185                            catch (NamingException ne) {
186                                    context.bind(_JNDI_JDBC_LIFERAY_POOL, dataSource);
187                            }
188    
189                            _dataSourceBindStates.put(servletContextName, true);
190                    }
191                    catch (Exception e) {
192                            if (_log.isWarnEnabled()) {
193                                    _log.warn(
194                                            "Unable to dynamically bind the Liferay data source: " +
195                                                    e.getMessage());
196                            }
197                    }
198            }
199    
200            protected void destroyPortlet(Portlet portlet, Set<String> portletIds)
201                    throws Exception {
202    
203                    PortletApp portletApp = portlet.getPortletApp();
204    
205                    Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
206    
207                    for (PortletFilter portletFilter : portletFilters) {
208                            PortletFilterFactory.destroy(portletFilter);
209                    }
210    
211                    Set<PortletURLListener> portletURLListeners =
212                            portletApp.getPortletURLListeners();
213    
214                    for (PortletURLListener portletURLListener : portletURLListeners) {
215                            PortletURLListenerFactory.destroy(portletURLListener);
216                    }
217    
218                    List<Indexer> indexers = portlet.getIndexerInstances();
219    
220                    for (Indexer indexer : indexers) {
221                            IndexerRegistryUtil.unregister(indexer);
222                    }
223    
224                    if (PropsValues.SCHEDULER_ENABLED) {
225                            List<SchedulerEntry> schedulerEntries =
226                                    portlet.getSchedulerEntries();
227    
228                            if ((schedulerEntries != null) && !schedulerEntries.isEmpty()) {
229                                    for (SchedulerEntry schedulerEntry : schedulerEntries) {
230                                            SchedulerEngineHelperUtil.unschedule(
231                                                    schedulerEntry, StorageType.MEMORY_CLUSTERED);
232                                    }
233                            }
234                    }
235    
236                    List<StagedModelDataHandler<?>> stagedModelDataHandlers =
237                            portlet.getStagedModelDataHandlerInstances();
238    
239                    if (stagedModelDataHandlers != null) {
240                            StagedModelDataHandlerRegistryUtil.unregister(
241                                    stagedModelDataHandlers);
242                    }
243    
244                    PollerProcessorUtil.deletePollerProcessor(portlet.getPortletId());
245    
246                    POPServerUtil.deleteListener(portlet.getPopMessageListenerInstance());
247    
248                    List<SocialActivityInterpreter> socialActivityInterpreters =
249                            portlet.getSocialActivityInterpreterInstances();
250    
251                    if (socialActivityInterpreters != null) {
252                            for (SocialActivityInterpreter socialActivityInterpreter :
253                                            socialActivityInterpreters) {
254    
255                                    SocialActivityInterpreterLocalServiceUtil.
256                                            deleteActivityInterpreter(socialActivityInterpreter);
257                            }
258                    }
259    
260                    SocialRequestInterpreterLocalServiceUtil.deleteRequestInterpreter(
261                            portlet.getSocialRequestInterpreterInstance());
262    
263                    UserNotificationManagerUtil.deleteUserNotificationDefinitions(
264                            portlet.getPortletId());
265    
266                    List<UserNotificationHandler> userNotificationHandlers =
267                            portlet.getUserNotificationHandlerInstances();
268    
269                    if (userNotificationHandlers != null) {
270                            for (UserNotificationHandler userNotificationHandler :
271                                            userNotificationHandlers) {
272    
273                                    UserNotificationManagerUtil.deleteUserNotificationHandler(
274                                            userNotificationHandler);
275                            }
276                    }
277    
278                    WebDAVUtil.deleteStorage(portlet.getWebDAVStorageInstance());
279    
280                    XmlRpcServlet.unregisterMethod(portlet.getXmlRpcMethodInstance());
281    
282                    List<AssetRendererFactory> assetRendererFactories =
283                            portlet.getAssetRendererFactoryInstances();
284    
285                    if (assetRendererFactories != null) {
286                            AssetRendererFactoryRegistryUtil.unregister(assetRendererFactories);
287                    }
288    
289                    List<AtomCollectionAdapter<?>> atomCollectionAdapters =
290                            portlet.getAtomCollectionAdapterInstances();
291    
292                    if (atomCollectionAdapters != null) {
293                            AtomCollectionAdapterRegistryUtil.unregister(
294                                    atomCollectionAdapters);
295                    }
296    
297                    List<TrashHandler> trashHandlers = portlet.getTrashHandlerInstances();
298    
299                    if (trashHandlers != null) {
300                            TrashHandlerRegistryUtil.unregister(trashHandlers);
301                    }
302    
303                    List<WorkflowHandler> workflowHandlers =
304                            portlet.getWorkflowHandlerInstances();
305    
306                    if (workflowHandlers != null) {
307                            WorkflowHandlerRegistryUtil.unregister(workflowHandlers);
308                    }
309    
310                    PortletInstanceFactoryUtil.destroy(portlet);
311    
312                    portletIds.add(portlet.getPortletId());
313            }
314    
315            protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
316                    throws Exception {
317    
318                    ServletContext servletContext = hotDeployEvent.getServletContext();
319    
320                    String servletContextName = servletContext.getServletContextName();
321    
322                    if (_log.isDebugEnabled()) {
323                            _log.debug("Invoking deploy for " + servletContextName);
324                    }
325    
326                    String[] xmls = new String[] {
327                            HttpUtil.URLtoString(
328                                    servletContext.getResource(
329                                            "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD)),
330                            HttpUtil.URLtoString(
331                                    servletContext.getResource(
332                                            "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
333                            HttpUtil.URLtoString(
334                                    servletContext.getResource("/WEB-INF/liferay-portlet.xml")),
335                            HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"))
336                    };
337    
338                    if ((xmls[0] == null) && (xmls[1] == null)) {
339                            return;
340                    }
341    
342                    if (_log.isInfoEnabled()) {
343                            _log.info("Registering portlets for " + servletContextName);
344                    }
345    
346                    List<Portlet> portlets = PortletLocalServiceUtil.initWAR(
347                            servletContextName, servletContext, xmls,
348                            hotDeployEvent.getPluginPackage());
349    
350                    boolean portletAppInitialized = false;
351    
352                    boolean phpPortlet = false;
353                    boolean strutsBridges = false;
354    
355                    PortletBagFactory portletBagFactory = new PortletBagFactory();
356    
357                    ClassLoader classLoader = hotDeployEvent.getContextClassLoader();
358    
359                    portletBagFactory.setClassLoader(classLoader);
360    
361                    portletBagFactory.setServletContext(servletContext);
362                    portletBagFactory.setWARFile(true);
363    
364                    Iterator<Portlet> itr = portlets.iterator();
365    
366                    while (itr.hasNext()) {
367                            Portlet portlet = itr.next();
368    
369                            PortletBag portletBag = portletBagFactory.create(portlet);
370    
371                            if (portletBag == null) {
372                                    itr.remove();
373                            }
374                            else {
375                                    if (!portletAppInitialized) {
376                                            initPortletApp(
377                                                    servletContextName, servletContext, classLoader,
378                                                    portlet);
379    
380                                            portletAppInitialized = true;
381                                    }
382    
383                                    javax.portlet.Portlet portletInstance =
384                                            portletBag.getPortletInstance();
385    
386                                    if (ClassUtil.isSubclass(
387                                                    portletInstance.getClass(),
388                                                    PHPPortlet.class.getName())) {
389    
390                                            phpPortlet = true;
391                                    }
392    
393                                    if (ClassUtil.isSubclass(
394                                                    portletInstance.getClass(),
395                                                    StrutsPortlet.class.getName())) {
396    
397                                            strutsBridges = true;
398                                    }
399                            }
400                    }
401    
402                    if (phpPortlet) {
403                            bindDataSource(servletContextName);
404                    }
405    
406                    if (!strutsBridges) {
407                            strutsBridges = GetterUtil.getBoolean(
408                                    servletContext.getInitParameter(
409                                            "struts-bridges-context-provider"));
410                    }
411    
412                    if (strutsBridges) {
413                            servletContext.setAttribute(
414                                    ServletContextProvider.STRUTS_BRIDGES_CONTEXT_PROVIDER,
415                                    new LiferayServletContextProvider());
416                    }
417    
418                    String xml = HttpUtil.URLtoString(
419                            servletContext.getResource("/WEB-INF/liferay-display.xml"));
420    
421                    PortletCategory newPortletCategory =
422                            PortletLocalServiceUtil.getWARDisplay(servletContextName, xml);
423    
424                    long[] companyIds = PortalInstances.getCompanyIds();
425    
426                    for (long companyId : companyIds) {
427                            PortletCategory portletCategory = (PortletCategory)WebAppPool.get(
428                                    companyId, WebKeys.PORTLET_CATEGORY);
429    
430                            if (portletCategory != null) {
431                                    portletCategory.merge(newPortletCategory);
432                            }
433                            else {
434                                    _log.error(
435                                            "Unable to register portlet for company " + companyId +
436                                                    " because it does not exist");
437                            }
438                    }
439    
440                    processPortletProperties(servletContextName, classLoader);
441    
442                    for (Portlet portlet : portlets) {
443                            List<String> modelNames =
444                                    ResourceActionsUtil.getPortletModelResources(
445                                            portlet.getPortletId());
446    
447                            List<String> portletActions =
448                                    ResourceActionsUtil.getPortletResourceActions(
449                                            portlet.getPortletId());
450    
451                            ResourceActionLocalServiceUtil.checkResourceActions(
452                                    portlet.getPortletId(), portletActions);
453    
454                            for (String modelName : modelNames) {
455                                    List<String> modelActions =
456                                            ResourceActionsUtil.getModelResourceActions(modelName);
457    
458                                    ResourceActionLocalServiceUtil.checkResourceActions(
459                                            modelName, modelActions);
460                            }
461    
462                            for (long companyId : companyIds) {
463                                    Portlet curPortlet = PortletLocalServiceUtil.getPortletById(
464                                            companyId, portlet.getPortletId());
465    
466                                    PortletLocalServiceUtil.checkPortlet(curPortlet);
467                            }
468                    }
469    
470                    for (Portlet portlet : portlets) {
471                            boolean ready = GetterUtil.getBoolean(
472                                    servletContext.getInitParameter(
473                                            "portlets-ready-by-default"), true);
474    
475                            portlet.setReady(ready);
476                    }
477    
478                    registerClpMessageListeners(servletContext, classLoader);
479    
480                    JavadocManagerUtil.load(servletContextName, classLoader);
481    
482                    DirectServletRegistryUtil.clearServlets();
483    
484                    _portlets.put(servletContextName, portlets);
485    
486                    servletContext.setAttribute(WebKeys.PLUGIN_PORTLETS, portlets);
487    
488                    if (_log.isInfoEnabled()) {
489                            if (portlets.size() == 1) {
490                                    _log.info(
491                                            "1 portlet for " + servletContextName +
492                                                    " is available for use");
493                            }
494                            else {
495                                    _log.info(
496                                            portlets.size() + " portlets for " + servletContextName +
497                                                    " are available for use");
498                            }
499                    }
500            }
501    
502            protected void doInvokeUndeploy(HotDeployEvent hotDeployEvent)
503                    throws Exception {
504    
505                    ServletContext servletContext = hotDeployEvent.getServletContext();
506    
507                    String servletContextName = servletContext.getServletContextName();
508    
509                    if (_log.isDebugEnabled()) {
510                            _log.debug("Invoking undeploy for " + servletContextName);
511                    }
512    
513                    List<Portlet> portlets = _portlets.remove(servletContextName);
514    
515                    if (portlets == null) {
516                            return;
517                    }
518    
519                    Set<String> portletIds = new HashSet<String>();
520    
521                    if (portlets != null) {
522                            if (_log.isInfoEnabled()) {
523                                    _log.info("Unregistering portlets for " + servletContextName);
524                            }
525    
526                            for (Portlet portlet : portlets) {
527                                    destroyPortlet(portlet, portletIds);
528                            }
529                    }
530    
531                    ServletContextPool.remove(servletContextName);
532    
533                    if (!portletIds.isEmpty()) {
534                            long[] companyIds = PortalInstances.getCompanyIds();
535    
536                            for (long companyId : companyIds) {
537                                    PortletCategory portletCategory =
538                                            (PortletCategory)WebAppPool.get(
539                                                    companyId, WebKeys.PORTLET_CATEGORY);
540    
541                                    portletCategory.separate(portletIds);
542                            }
543                    }
544    
545                    PortletContextBagPool.remove(servletContextName);
546                    PortletResourceBundles.remove(servletContextName);
547    
548                    unbindDataSource(servletContextName);
549    
550                    unregisterClpMessageListeners(servletContext);
551    
552                    JavadocManagerUtil.unload(servletContextName);
553    
554                    DirectServletRegistryUtil.clearServlets();
555    
556                    if (_log.isInfoEnabled()) {
557                            if (portlets.size() == 1) {
558                                    _log.info(
559                                            "1 portlet for " + servletContextName +
560                                                    " was unregistered");
561                            }
562                            else {
563                                    _log.info(
564                                            portlets.size() + " portlets for " + servletContextName +
565                                                    " were unregistered");
566                            }
567                    }
568            }
569    
570            protected void initPortletApp(
571                            String servletContextName, ServletContext servletContext,
572                            ClassLoader classLoader, Portlet portlet)
573                    throws Exception {
574    
575                    PortletContextBag portletContextBag = new PortletContextBag(
576                            servletContextName);
577    
578                    PortletContextBagPool.put(servletContextName, portletContextBag);
579    
580                    PortletApp portletApp = portlet.getPortletApp();
581    
582                    servletContext.setAttribute(PortletServlet.PORTLET_APP, portletApp);
583    
584                    Map<String, String> customUserAttributes =
585                            portletApp.getCustomUserAttributes();
586    
587                    for (Map.Entry<String, String> entry :
588                                    customUserAttributes.entrySet()) {
589    
590                            String attrCustomClass = entry.getValue();
591    
592                            Class<?> clazz = classLoader.loadClass(attrCustomClass);
593    
594                            CustomUserAttributes customUserAttributesInstance =
595                                    (CustomUserAttributes)clazz.newInstance();
596    
597                            portletContextBag.getCustomUserAttributes().put(
598                                    attrCustomClass, customUserAttributesInstance);
599                    }
600    
601                    Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
602    
603                    for (PortletFilter portletFilter : portletFilters) {
604                            javax.portlet.filter.PortletFilter portletFilterInstance =
605                                    (javax.portlet.filter.PortletFilter)newInstance(
606                                            classLoader,
607                                            new Class<?>[] {
608                                                    javax.portlet.filter.ActionFilter.class,
609                                                    javax.portlet.filter.EventFilter.class,
610                                                    javax.portlet.filter.PortletFilter.class,
611                                                    javax.portlet.filter.RenderFilter.class,
612                                                    javax.portlet.filter.ResourceFilter.class
613                                            },
614                                            portletFilter.getFilterClass());
615    
616                            portletContextBag.getPortletFilters().put(
617                                    portletFilter.getFilterName(), portletFilterInstance);
618                    }
619    
620                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
621                            portlet, servletContext);
622    
623                    invokerPortlet.setPortletFilters();
624    
625                    Set<PortletURLListener> portletURLListeners =
626                            portletApp.getPortletURLListeners();
627    
628                    for (PortletURLListener portletURLListener : portletURLListeners) {
629                            PortletURLGenerationListener portletURLListenerInstance =
630                                    (PortletURLGenerationListener)newInstance(
631                                            classLoader, PortletURLGenerationListener.class,
632                                            portletURLListener.getListenerClass());
633    
634                            portletContextBag.getPortletURLListeners().put(
635                                    portletURLListener.getListenerClass(),
636                                    portletURLListenerInstance);
637    
638                            PortletURLListenerFactory.create(portletURLListener);
639                    }
640            }
641    
642            protected void processPortletProperties(
643                            String servletContextName, ClassLoader classLoader)
644                    throws Exception {
645    
646                    Configuration portletPropertiesConfiguration = null;
647    
648                    try {
649                            portletPropertiesConfiguration =
650                                    ConfigurationFactoryUtil.getConfiguration(
651                                            classLoader, "portlet");
652                    }
653                    catch (Exception e) {
654                            if (_log.isDebugEnabled()) {
655                                    _log.debug("Unable to read portlet.properties");
656                            }
657    
658                            return;
659                    }
660    
661                    Properties portletProperties =
662                            portletPropertiesConfiguration.getProperties();
663    
664                    if (portletProperties.size() == 0) {
665                            return;
666                    }
667    
668                    String languageBundleName = portletProperties.getProperty(
669                            "language.bundle");
670    
671                    if (Validator.isNotNull(languageBundleName)) {
672                            Locale[] locales = LanguageUtil.getAvailableLocales();
673    
674                            for (Locale locale : locales) {
675                                    ResourceBundle resourceBundle = ResourceBundle.getBundle(
676                                            languageBundleName, locale, classLoader);
677    
678                                    PortletResourceBundles.put(
679                                            servletContextName, LocaleUtil.toLanguageId(locale),
680                                            resourceBundle);
681                            }
682                    }
683    
684                    String[] resourceActionConfigs = StringUtil.split(
685                            portletProperties.getProperty(PropsKeys.RESOURCE_ACTIONS_CONFIGS));
686    
687                    for (String resourceActionConfig : resourceActionConfigs) {
688                            ResourceActionsUtil.read(
689                                    servletContextName, classLoader, resourceActionConfig);
690                    }
691            }
692    
693            protected void unbindDataSource(String servletContextName) {
694                    Boolean dataSourceBindState = _dataSourceBindStates.remove(
695                            servletContextName);
696    
697                    if (dataSourceBindState == null) {
698                            return;
699                    }
700    
701                    try {
702                            if (_log.isDebugEnabled()) {
703                                    _log.debug("Dynamically unbinding the Liferay data source");
704                            }
705    
706                            Context context = new InitialContext();
707    
708                            try {
709                                    context.lookup(_JNDI_JDBC_LIFERAY_POOL);
710    
711                                    context.unbind(_JNDI_JDBC_LIFERAY_POOL);
712                            }
713                            catch (NamingException ne) {
714                            }
715    
716                            try {
717                                    context.lookup(_JNDI_JDBC);
718    
719                                    context.destroySubcontext(_JNDI_JDBC);
720                            }
721                            catch (NamingException ne) {
722                            }
723                    }
724                    catch (Exception e) {
725                            if (_log.isWarnEnabled()) {
726                                    _log.warn(
727                                            "Unable to dynamically unbind the Liferay data source: " +
728                                                    e.getMessage());
729                            }
730                    }
731            }
732    
733            private static final String _JNDI_JDBC = "java_liferay:jdbc";
734    
735            private static final String _JNDI_JDBC_LIFERAY_POOL =
736                    _JNDI_JDBC + "/LiferayPool";
737    
738            private static Log _log = LogFactoryUtil.getLog(
739                    PortletHotDeployListener.class);
740    
741            private static Map<String, Boolean> _dataSourceBindStates =
742                    new HashMap<String, Boolean>();
743            private static Map<String, List<Portlet>> _portlets =
744                    new HashMap<String, List<Portlet>>();
745    
746    }