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, "Error registering portlets for ", t);
129                    }
130            }
131    
132            @Override
133            public void invokeUndeploy(HotDeployEvent hotDeployEvent)
134                    throws HotDeployException {
135    
136                    try {
137                            doInvokeUndeploy(hotDeployEvent);
138                    }
139                    catch (Throwable t) {
140                            throwHotDeployException(
141                                    hotDeployEvent, "Error unregistering portlets for ", t);
142                    }
143            }
144    
145            protected void bindDataSource(String servletContextName) throws Exception {
146                    if (ServerDetector.isGlassfish() || ServerDetector.isJOnAS()) {
147                            return;
148                    }
149    
150                    if (_log.isDebugEnabled()) {
151                            _log.debug("Dynamically binding the Liferay data source");
152                    }
153    
154                    DataSource dataSource = InfrastructureUtil.getDataSource();
155    
156                    if (dataSource == null) {
157                            if (_log.isDebugEnabled()) {
158                                    _log.debug(
159                                            "Abort dynamically binding the Liferay data source " +
160                                                    "because it is not available");
161                            }
162    
163                            return;
164                    }
165    
166                    Context context = new InitialContext();
167    
168                    try {
169                            try {
170                                    context.lookup(_JNDI_JDBC);
171                            }
172                            catch (NamingException ne) {
173                                    context.createSubcontext(_JNDI_JDBC);
174                            }
175    
176                            try {
177                                    context.lookup(_JNDI_JDBC_LIFERAY_POOL);
178                            }
179                            catch (NamingException ne) {
180                                    context.bind(_JNDI_JDBC_LIFERAY_POOL, dataSource);
181                            }
182    
183                            _dataSourceBindStates.put(servletContextName, true);
184                    }
185                    catch (Exception e) {
186                            if (_log.isWarnEnabled()) {
187                                    _log.warn(
188                                            "Unable to dynamically bind the Liferay data source: " +
189                                                    e.getMessage());
190                            }
191                    }
192            }
193    
194            protected void destroyPortlet(Portlet portlet, Set<String> portletIds)
195                    throws Exception {
196    
197                    PortletApp portletApp = portlet.getPortletApp();
198    
199                    Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
200    
201                    for (PortletFilter portletFilter : portletFilters) {
202                            PortletFilterFactory.destroy(portletFilter);
203                    }
204    
205                    Set<PortletURLListener> portletURLListeners =
206                            portletApp.getPortletURLListeners();
207    
208                    for (PortletURLListener portletURLListener : portletURLListeners) {
209                            PortletURLListenerFactory.destroy(portletURLListener);
210                    }
211    
212                    List<Indexer> indexers = portlet.getIndexerInstances();
213    
214                    for (Indexer indexer : indexers) {
215                            IndexerRegistryUtil.unregister(indexer);
216                    }
217    
218                    if (PropsValues.SCHEDULER_ENABLED) {
219                            List<SchedulerEntry> schedulerEntries =
220                                    portlet.getSchedulerEntries();
221    
222                            if ((schedulerEntries != null) && !schedulerEntries.isEmpty()) {
223                                    for (SchedulerEntry schedulerEntry : schedulerEntries) {
224                                            SchedulerEngineHelperUtil.unschedule(
225                                                    schedulerEntry, StorageType.MEMORY_CLUSTERED);
226                                    }
227                            }
228                    }
229    
230                    List<StagedModelDataHandler<?>> stagedModelDataHandlers =
231                            portlet.getStagedModelDataHandlerInstances();
232    
233                    if (stagedModelDataHandlers != null) {
234                            StagedModelDataHandlerRegistryUtil.unregister(
235                                    stagedModelDataHandlers);
236                    }
237    
238                    PollerProcessorUtil.deletePollerProcessor(portlet.getPortletId());
239    
240                    POPServerUtil.deleteListener(portlet.getPopMessageListenerInstance());
241    
242                    List<SocialActivityInterpreter> socialActivityInterpreters =
243                            portlet.getSocialActivityInterpreterInstances();
244    
245                    if (socialActivityInterpreters != null) {
246                            for (SocialActivityInterpreter socialActivityInterpreter :
247                                            socialActivityInterpreters) {
248    
249                                    SocialActivityInterpreterLocalServiceUtil.
250                                            deleteActivityInterpreter(socialActivityInterpreter);
251                            }
252                    }
253    
254                    SocialRequestInterpreterLocalServiceUtil.deleteRequestInterpreter(
255                            portlet.getSocialRequestInterpreterInstance());
256    
257                    UserNotificationManagerUtil.deleteUserNotificationDefinitions(
258                            portlet.getPortletId());
259    
260                    List<UserNotificationHandler> userNotificationHandlers =
261                            portlet.getUserNotificationHandlerInstances();
262    
263                    if (userNotificationHandlers != null) {
264                            for (UserNotificationHandler userNotificationHandler :
265                                            userNotificationHandlers) {
266    
267                                    UserNotificationManagerUtil.deleteUserNotificationHandler(
268                                            userNotificationHandler);
269                            }
270                    }
271    
272                    WebDAVUtil.deleteStorage(portlet.getWebDAVStorageInstance());
273    
274                    XmlRpcServlet.unregisterMethod(portlet.getXmlRpcMethodInstance());
275    
276                    List<AssetRendererFactory> assetRendererFactories =
277                            portlet.getAssetRendererFactoryInstances();
278    
279                    if (assetRendererFactories != null) {
280                            AssetRendererFactoryRegistryUtil.unregister(assetRendererFactories);
281                    }
282    
283                    List<AtomCollectionAdapter<?>> atomCollectionAdapters =
284                            portlet.getAtomCollectionAdapterInstances();
285    
286                    if (atomCollectionAdapters != null) {
287                            AtomCollectionAdapterRegistryUtil.unregister(
288                                    atomCollectionAdapters);
289                    }
290    
291                    List<TrashHandler> trashHandlers = portlet.getTrashHandlerInstances();
292    
293                    if (trashHandlers != null) {
294                            TrashHandlerRegistryUtil.unregister(trashHandlers);
295                    }
296    
297                    List<WorkflowHandler> workflowHandlers =
298                            portlet.getWorkflowHandlerInstances();
299    
300                    if (workflowHandlers != null) {
301                            WorkflowHandlerRegistryUtil.unregister(workflowHandlers);
302                    }
303    
304                    PortletInstanceFactoryUtil.destroy(portlet);
305    
306                    portletIds.add(portlet.getPortletId());
307            }
308    
309            protected void doInvokeDeploy(HotDeployEvent hotDeployEvent)
310                    throws Exception {
311    
312                    ServletContext servletContext = hotDeployEvent.getServletContext();
313    
314                    String servletContextName = servletContext.getServletContextName();
315    
316                    if (_log.isDebugEnabled()) {
317                            _log.debug("Invoking deploy for " + servletContextName);
318                    }
319    
320                    String[] xmls = new String[] {
321                            HttpUtil.URLtoString(
322                                    servletContext.getResource(
323                                            "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_STANDARD)),
324                            HttpUtil.URLtoString(
325                                    servletContext.getResource(
326                                            "/WEB-INF/" + Portal.PORTLET_XML_FILE_NAME_CUSTOM)),
327                            HttpUtil.URLtoString(
328                                    servletContext.getResource("/WEB-INF/liferay-portlet.xml")),
329                            HttpUtil.URLtoString(servletContext.getResource("/WEB-INF/web.xml"))
330                    };
331    
332                    if ((xmls[0] == null) && (xmls[1] == null)) {
333                            return;
334                    }
335    
336                    if (_log.isInfoEnabled()) {
337                            _log.info("Registering portlets for " + servletContextName);
338                    }
339    
340                    List<Portlet> portlets = PortletLocalServiceUtil.initWAR(
341                            servletContextName, servletContext, xmls,
342                            hotDeployEvent.getPluginPackage());
343    
344                    boolean portletAppInitialized = false;
345    
346                    boolean phpPortlet = false;
347                    boolean strutsBridges = false;
348    
349                    PortletBagFactory portletBagFactory = new PortletBagFactory();
350    
351                    ClassLoader classLoader = hotDeployEvent.getContextClassLoader();
352    
353                    portletBagFactory.setClassLoader(classLoader);
354    
355                    portletBagFactory.setServletContext(servletContext);
356                    portletBagFactory.setWARFile(true);
357    
358                    Iterator<Portlet> itr = portlets.iterator();
359    
360                    while (itr.hasNext()) {
361                            Portlet portlet = itr.next();
362    
363                            PortletBag portletBag = portletBagFactory.create(portlet);
364    
365                            if (portletBag == null) {
366                                    itr.remove();
367                            }
368                            else {
369                                    if (!portletAppInitialized) {
370                                            initPortletApp(
371                                                    servletContextName, servletContext, classLoader,
372                                                    portlet);
373    
374                                            portletAppInitialized = true;
375                                    }
376    
377                                    javax.portlet.Portlet portletInstance =
378                                            portletBag.getPortletInstance();
379    
380                                    if (ClassUtil.isSubclass(
381                                                    portletInstance.getClass(),
382                                                    PHPPortlet.class.getName())) {
383    
384                                            phpPortlet = true;
385                                    }
386    
387                                    if (ClassUtil.isSubclass(
388                                                    portletInstance.getClass(),
389                                                    StrutsPortlet.class.getName())) {
390    
391                                            strutsBridges = true;
392                                    }
393                            }
394                    }
395    
396                    if (phpPortlet) {
397                            bindDataSource(servletContextName);
398                    }
399    
400                    if (!strutsBridges) {
401                            strutsBridges = GetterUtil.getBoolean(
402                                    servletContext.getInitParameter(
403                                            "struts-bridges-context-provider"));
404                    }
405    
406                    if (strutsBridges) {
407                            servletContext.setAttribute(
408                                    ServletContextProvider.STRUTS_BRIDGES_CONTEXT_PROVIDER,
409                                    new LiferayServletContextProvider());
410                    }
411    
412                    String xml = HttpUtil.URLtoString(
413                            servletContext.getResource("/WEB-INF/liferay-display.xml"));
414    
415                    PortletCategory newPortletCategory =
416                            PortletLocalServiceUtil.getWARDisplay(servletContextName, xml);
417    
418                    long[] companyIds = PortalInstances.getCompanyIds();
419    
420                    for (long companyId : companyIds) {
421                            PortletCategory portletCategory = (PortletCategory)WebAppPool.get(
422                                    companyId, WebKeys.PORTLET_CATEGORY);
423    
424                            if (portletCategory != null) {
425                                    portletCategory.merge(newPortletCategory);
426                            }
427                            else {
428                                    _log.error(
429                                            "Unable to register portlet for company " + companyId +
430                                                    " because it does not exist");
431                            }
432                    }
433    
434                    processPortletProperties(servletContextName, classLoader);
435    
436                    for (Portlet portlet : portlets) {
437                            List<String> modelNames =
438                                    ResourceActionsUtil.getPortletModelResources(
439                                            portlet.getPortletId());
440    
441                            List<String> portletActions =
442                                    ResourceActionsUtil.getPortletResourceActions(
443                                            portlet.getPortletId());
444    
445                            ResourceActionLocalServiceUtil.checkResourceActions(
446                                    portlet.getPortletId(), portletActions);
447    
448                            for (String modelName : modelNames) {
449                                    List<String> modelActions =
450                                            ResourceActionsUtil.getModelResourceActions(modelName);
451    
452                                    ResourceActionLocalServiceUtil.checkResourceActions(
453                                            modelName, modelActions);
454                            }
455    
456                            for (long companyId : companyIds) {
457                                    Portlet curPortlet = PortletLocalServiceUtil.getPortletById(
458                                            companyId, portlet.getPortletId());
459    
460                                    PortletLocalServiceUtil.checkPortlet(curPortlet);
461                            }
462                    }
463    
464                    for (Portlet portlet : portlets) {
465                            boolean ready = GetterUtil.getBoolean(
466                                    servletContext.getInitParameter(
467                                            "portlets-ready-by-default"), true);
468    
469                            portlet.setReady(ready);
470                    }
471    
472                    registerClpMessageListeners(servletContext, classLoader);
473    
474                    JavadocManagerUtil.load(servletContextName, classLoader);
475    
476                    DirectServletRegistryUtil.clearServlets();
477    
478                    _portlets.put(servletContextName, portlets);
479    
480                    servletContext.setAttribute(WebKeys.PLUGIN_PORTLETS, portlets);
481    
482                    if (_log.isInfoEnabled()) {
483                            if (portlets.size() == 1) {
484                                    _log.info(
485                                            "1 portlet for " + servletContextName +
486                                                    " is available for use");
487                            }
488                            else {
489                                    _log.info(
490                                            portlets.size() + " portlets for " + servletContextName +
491                                                    " are available for use");
492                            }
493                    }
494            }
495    
496            protected void doInvokeUndeploy(HotDeployEvent hotDeployEvent)
497                    throws Exception {
498    
499                    ServletContext servletContext = hotDeployEvent.getServletContext();
500    
501                    String servletContextName = servletContext.getServletContextName();
502    
503                    if (_log.isDebugEnabled()) {
504                            _log.debug("Invoking undeploy for " + servletContextName);
505                    }
506    
507                    List<Portlet> portlets = _portlets.remove(servletContextName);
508    
509                    if (portlets == null) {
510                            return;
511                    }
512    
513                    Set<String> portletIds = new HashSet<String>();
514    
515                    if (portlets != null) {
516                            if (_log.isInfoEnabled()) {
517                                    _log.info("Unregistering portlets for " + servletContextName);
518                            }
519    
520                            for (Portlet portlet : portlets) {
521                                    destroyPortlet(portlet, portletIds);
522                            }
523                    }
524    
525                    ServletContextPool.remove(servletContextName);
526    
527                    if (!portletIds.isEmpty()) {
528                            long[] companyIds = PortalInstances.getCompanyIds();
529    
530                            for (long companyId : companyIds) {
531                                    PortletCategory portletCategory =
532                                            (PortletCategory)WebAppPool.get(
533                                                    companyId, WebKeys.PORTLET_CATEGORY);
534    
535                                    portletCategory.separate(portletIds);
536                            }
537                    }
538    
539                    PortletContextBagPool.remove(servletContextName);
540                    PortletResourceBundles.remove(servletContextName);
541    
542                    unbindDataSource(servletContextName);
543    
544                    unregisterClpMessageListeners(servletContext);
545    
546                    JavadocManagerUtil.unload(servletContextName);
547    
548                    DirectServletRegistryUtil.clearServlets();
549    
550                    if (_log.isInfoEnabled()) {
551                            if (portlets.size() == 1) {
552                                    _log.info(
553                                            "1 portlet for " + servletContextName +
554                                                    " was unregistered");
555                            }
556                            else {
557                                    _log.info(
558                                            portlets.size() + " portlets for " + servletContextName +
559                                                    " were unregistered");
560                            }
561                    }
562            }
563    
564            protected void initPortletApp(
565                            String servletContextName, ServletContext servletContext,
566                            ClassLoader classLoader, Portlet portlet)
567                    throws Exception {
568    
569                    PortletContextBag portletContextBag = new PortletContextBag(
570                            servletContextName);
571    
572                    PortletContextBagPool.put(servletContextName, portletContextBag);
573    
574                    PortletApp portletApp = portlet.getPortletApp();
575    
576                    servletContext.setAttribute(PortletServlet.PORTLET_APP, portletApp);
577    
578                    Map<String, String> customUserAttributes =
579                            portletApp.getCustomUserAttributes();
580    
581                    for (Map.Entry<String, String> entry :
582                                    customUserAttributes.entrySet()) {
583    
584                            String attrCustomClass = entry.getValue();
585    
586                            CustomUserAttributes customUserAttributesInstance =
587                                    (CustomUserAttributes)classLoader.loadClass(
588                                            attrCustomClass).newInstance();
589    
590                            portletContextBag.getCustomUserAttributes().put(
591                                    attrCustomClass, customUserAttributesInstance);
592                    }
593    
594                    Set<PortletFilter> portletFilters = portletApp.getPortletFilters();
595    
596                    for (PortletFilter portletFilter : portletFilters) {
597                            javax.portlet.filter.PortletFilter portletFilterInstance =
598                                    (javax.portlet.filter.PortletFilter)newInstance(
599                                            classLoader,
600                                            new Class<?>[] {
601                                                    javax.portlet.filter.ActionFilter.class,
602                                                    javax.portlet.filter.EventFilter.class,
603                                                    javax.portlet.filter.PortletFilter.class,
604                                                    javax.portlet.filter.RenderFilter.class,
605                                                    javax.portlet.filter.ResourceFilter.class
606                                            },
607                                            portletFilter.getFilterClass());
608    
609                            portletContextBag.getPortletFilters().put(
610                                    portletFilter.getFilterName(), portletFilterInstance);
611                    }
612    
613                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
614                            portlet, servletContext);
615    
616                    invokerPortlet.setPortletFilters();
617    
618                    Set<PortletURLListener> portletURLListeners =
619                            portletApp.getPortletURLListeners();
620    
621                    for (PortletURLListener portletURLListener : portletURLListeners) {
622                            PortletURLGenerationListener portletURLListenerInstance =
623                                    (PortletURLGenerationListener)newInstance(
624                                            classLoader, PortletURLGenerationListener.class,
625                                            portletURLListener.getListenerClass());
626    
627                            portletContextBag.getPortletURLListeners().put(
628                                    portletURLListener.getListenerClass(),
629                                    portletURLListenerInstance);
630    
631                            PortletURLListenerFactory.create(portletURLListener);
632                    }
633            }
634    
635            protected void processPortletProperties(
636                            String servletContextName, ClassLoader classLoader)
637                    throws Exception {
638    
639                    Configuration portletPropertiesConfiguration = null;
640    
641                    try {
642                            portletPropertiesConfiguration =
643                                    ConfigurationFactoryUtil.getConfiguration(
644                                            classLoader, "portlet");
645                    }
646                    catch (Exception e) {
647                            if (_log.isDebugEnabled()) {
648                                    _log.debug("Unable to read portlet.properties");
649                            }
650    
651                            return;
652                    }
653    
654                    Properties portletProperties =
655                            portletPropertiesConfiguration.getProperties();
656    
657                    if (portletProperties.size() == 0) {
658                            return;
659                    }
660    
661                    String languageBundleName = portletProperties.getProperty(
662                            "language.bundle");
663    
664                    if (Validator.isNotNull(languageBundleName)) {
665                            Locale[] locales = LanguageUtil.getAvailableLocales();
666    
667                            for (Locale locale : locales) {
668                                    ResourceBundle resourceBundle = ResourceBundle.getBundle(
669                                            languageBundleName, locale, classLoader);
670    
671                                    PortletResourceBundles.put(
672                                            servletContextName, LocaleUtil.toLanguageId(locale),
673                                            resourceBundle);
674                            }
675                    }
676    
677                    String[] resourceActionConfigs = StringUtil.split(
678                            portletProperties.getProperty(PropsKeys.RESOURCE_ACTIONS_CONFIGS));
679    
680                    for (String resourceActionConfig : resourceActionConfigs) {
681                            ResourceActionsUtil.read(
682                                    servletContextName, classLoader, resourceActionConfig);
683                    }
684            }
685    
686            protected void unbindDataSource(String servletContextName) {
687                    Boolean dataSourceBindState = _dataSourceBindStates.remove(
688                            servletContextName);
689    
690                    if (dataSourceBindState == null) {
691                            return;
692                    }
693    
694                    try {
695                            if (_log.isDebugEnabled()) {
696                                    _log.debug("Dynamically unbinding the Liferay data source");
697                            }
698    
699                            Context context = new InitialContext();
700    
701                            try {
702                                    context.lookup(_JNDI_JDBC_LIFERAY_POOL);
703    
704                                    context.unbind(_JNDI_JDBC_LIFERAY_POOL);
705                            }
706                            catch (NamingException ne) {
707                            }
708    
709                            try {
710                                    context.lookup(_JNDI_JDBC);
711    
712                                    context.destroySubcontext(_JNDI_JDBC);
713                            }
714                            catch (NamingException ne) {
715                            }
716                    }
717                    catch (Exception e) {
718                            if (_log.isWarnEnabled()) {
719                                    _log.warn(
720                                            "Unable to dynamically unbind the Liferay data source: " +
721                                                    e.getMessage());
722                            }
723                    }
724            }
725    
726            private static final String _JNDI_JDBC = "java_liferay:jdbc";
727    
728            private static final String _JNDI_JDBC_LIFERAY_POOL =
729                    _JNDI_JDBC + "/LiferayPool";
730    
731            private static Log _log = LogFactoryUtil.getLog(
732                    PortletHotDeployListener.class);
733    
734            private static Map<String, Boolean> _dataSourceBindStates =
735                    new HashMap<String, Boolean>();
736            private static Map<String, List<Portlet>> _portlets =
737                    new HashMap<String, List<Portlet>>();
738    
739    }