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