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