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