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