| package org.apache.pluto.driver.services.impl.resource; |
| |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.portlet.PortletMode; |
| import javax.servlet.ServletContext; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.pluto.PortletContainer; |
| import org.apache.pluto.PortletContainerException; |
| import org.apache.pluto.descriptors.portlet.PortletAppDD; |
| import org.apache.pluto.descriptors.portlet.PortletDD; |
| import org.apache.pluto.descriptors.portlet.SupportsDD; |
| import org.apache.pluto.driver.AttributeKeys; |
| import org.apache.pluto.driver.config.DriverConfigurationException; |
| import org.apache.pluto.driver.services.portal.PortletApplicationConfig; |
| import org.apache.pluto.driver.services.portal.PortletRegistryService; |
| import org.apache.pluto.driver.services.portal.PortletWindowConfig; |
| import org.apache.pluto.driver.services.portal.PropertyConfigService; |
| import org.apache.pluto.driver.services.portal.SupportedModesService; |
| |
| /** |
| * Allows clients to determine if a particular PortletMode is supported |
| * by the portal, a particular portlet, or both. |
| * |
| * This implementation depends on {@link PropertyConfigService}, |
| * {@link PortletRegistryService}, and {@link PortletContainer}. |
| * The two services are injected by Spring, and the container is obtained |
| * from the <code>ServletContext</code>. |
| * |
| * @author <a href="mailto:esm@apache.org">Elliot Metsger</a> |
| * @version $Id$ |
| * @since September 9, 2006 |
| * @todo How will hot-deploy of portlets via the admin portlet work with this impl? |
| */ |
| public class SupportedModesServiceImpl implements SupportedModesService |
| { |
| /** Logger */ |
| private static final Log LOG = LogFactory.getLog(SupportedModesServiceImpl.class); |
| |
| /** PortletApplicationConfig objects keyed by their String context path */ |
| private Map portletApps = new HashMap(); |
| |
| /** Sets containing PortletMode objects keyed by String portlet Id */ |
| private Map supportedPortletModesByPortlet = new HashMap(); |
| |
| /** PortletMode objects supported by the portal */ |
| private Set supportedPortletModesByPortal = new HashSet(); |
| |
| /** PortletContainer used to obtain Portlet Descriptors (PortletAppDD) */ |
| private PortletContainer container = null; |
| |
| /** PortletRegistryService used to obtain PortletApplicationConfig objects */ |
| private PortletRegistryService portletRegistry = null; |
| |
| /** PropertyConfig Service used to obtain supported portal modes */ |
| private PropertyConfigService propertySvc = null; |
| |
| |
| /** |
| * Constructs a SupportedModesService with its dependencies. |
| * |
| * @param portletRegistry the PortletRegistryService |
| * @param propertySvc the PropertyConfigService |
| */ |
| public SupportedModesServiceImpl(PortletRegistryService portletRegistry, PropertyConfigService propertySvc) |
| { |
| this.portletRegistry = portletRegistry; |
| this.propertySvc = propertySvc; |
| } |
| |
| // SupportedModesService Implementation ----------------- |
| |
| public boolean isPortletModeSupported(String portletId, String mode) |
| { |
| return isPortletModeSupportedByPortal(mode) && isPortletModeSupportedByPortlet(portletId, mode); |
| } |
| |
| public boolean isPortletModeSupportedByPortal(String mode) |
| { |
| LOG.debug("Is mode [" + mode + "] supported by the portal?"); |
| return supportedPortletModesByPortal.contains(new PortletMode(mode)); |
| } |
| |
| public boolean isPortletModeSupportedByPortlet(String portletId, String mode) |
| { |
| LOG.debug("Is mode [" + mode + "] for portlet [" + portletId + "] supported by the portlet?"); |
| |
| // hack? or required, can't remember? |
| if(PortletMode.EDIT.toString().equalsIgnoreCase(mode) |
| || PortletMode.HELP.toString().equalsIgnoreCase(mode) |
| || PortletMode.VIEW.toString().equalsIgnoreCase(mode)) { |
| return true; |
| } |
| |
| Set supportedModes = (Set)supportedPortletModesByPortlet.get(portletId); |
| if (supportedModes == null) |
| { |
| return false; |
| } |
| return supportedModes.contains(new PortletMode(mode)); |
| } |
| |
| // DriverConfiguration Lifecycle Implementation --------- |
| |
| public void destroy() throws DriverConfigurationException |
| { |
| LOG.debug("Destroying Supported Modes Service..."); |
| supportedPortletModesByPortlet = null; |
| supportedPortletModesByPortal = null; |
| container = null; |
| portletRegistry = null; |
| portletApps = null; |
| propertySvc = null; |
| LOG.debug("Supported Modes Service destroyed."); |
| } |
| |
| public void init(ServletContext ctx) throws DriverConfigurationException |
| { |
| LOG.debug("Initializing Supported Modes Service..."); |
| // Obtain the Portlet Container |
| this.container = (PortletContainer)ctx.getAttribute(AttributeKeys.PORTLET_CONTAINER); |
| initInternal(); |
| LOG.debug("Supported Modes Service initalized."); |
| } |
| |
| // Private Methods -------------------------------------- |
| |
| /** |
| * Initialize the data structures for supportedPortletModesByPortal, |
| * supportedPortletModesByPortlet, and portletApps. |
| * |
| * Note that the order of initalization matters. |
| */ |
| private void initInternal() |
| { |
| // portlet applications should be loaded first |
| loadPortletApplications(); |
| loadPortalModes(); |
| loadPortletModes(); |
| } |
| |
| /** |
| * Populates the portletApps map with PortletApplicationConfig objects |
| * keyed by their context path. |
| */ |
| private void loadPortletApplications() |
| { |
| LOG.debug("Loading Portlet Applications..."); |
| Iterator apps = portletRegistry.getPortletApplications().iterator(); |
| while (apps.hasNext()) |
| { |
| PortletApplicationConfig app = (PortletApplicationConfig)apps.next(); |
| LOG.debug("Loading [" + app.getContextPath() + "]"); |
| portletApps.put(app.getContextPath(), app); |
| } |
| LOG.debug("Loaded [" + portletApps.size() + "] Portlet Applications."); |
| } |
| |
| /** Populates the supportedPortletModesByPortal set. */ |
| private void loadPortalModes() |
| { |
| // Add the PortletModes supported by the portal to the |
| // supportedPortletModesByPortal set. |
| LOG.debug("Loading supported portal modes..."); |
| Iterator modes = propertySvc.getSupportedPortletModes().iterator(); |
| while (modes.hasNext()) { |
| String mode = (String) modes.next(); |
| LOG.debug("Loading mode [" + mode + "]"); |
| supportedPortletModesByPortal.add(new PortletMode(mode)); |
| } |
| LOG.debug("Loaded [" + supportedPortletModesByPortal.size() + "] supported portal modes"); |
| } |
| |
| /** |
| * Populates the supportedPortletModesByPortlet map, which contains |
| * Sets of PortletMode objects keyed by String portlet Ids. |
| */ |
| private void loadPortletModes() |
| { |
| // Add the PortletModes supported by each portlet to |
| // the supportedPortletModesByPortlet map. |
| LOG.debug("Loading modes supported by each Portlet..."); |
| Iterator apps = portletApps.values().iterator(); |
| while (apps.hasNext()) |
| { |
| PortletApplicationConfig app = (PortletApplicationConfig)apps.next(); |
| PortletAppDD portletAppDD; |
| try { |
| portletAppDD = container |
| .getOptionalContainerServices() |
| .getPortletRegistryService() |
| .getPortletApplicationDescriptor(app.getContextPath()); |
| } catch (PortletContainerException e) { |
| LOG.warn(e); |
| continue; |
| } |
| |
| if(portletAppDD == null) { |
| continue; |
| } |
| |
| // for each portletAppDD, retrieve the portletDD and the supported modes |
| Iterator portlets = portletAppDD.getPortlets().iterator(); |
| while (portlets.hasNext()) { |
| PortletDD portlet = (PortletDD)portlets.next(); |
| LOG.debug("Loading modes supported by portlet [" + app.getContextPath() + "]." + |
| "[" + portlet.getPortletName() + "]"); |
| Iterator supports = portlet.getSupports().iterator(); |
| Set pModes = new HashSet(); |
| while (supports.hasNext()) |
| { |
| SupportsDD supportsDD = (SupportsDD)supports.next(); |
| Iterator portletModes = supportsDD.getPortletModes().iterator(); |
| |
| while (portletModes.hasNext()) |
| { |
| PortletMode pMode = new PortletMode((String)portletModes.next()); |
| LOG.debug("Adding mode [" + pMode + "]"); |
| pModes.add(pMode); |
| } |
| } |
| |
| supportedPortletModesByPortlet.put( |
| PortletWindowConfig.createPortletId(app.getContextPath(), portlet.getPortletName()), |
| pModes); |
| } |
| } |
| |
| } |
| |
| /** |
| * Retrieve the PortletApplicationConfig by its context path. |
| * |
| * @param contextPath the context |
| * @return the PortletApplicationConfig, or null if it wasn't found. |
| */ |
| private PortletApplicationConfig getPortletApplication(String contextPath) |
| { |
| PortletApplicationConfig app = null; |
| // attempt to retrieve the PortletApplicationConfig from the map |
| app = (PortletApplicationConfig)portletApps.get(contextPath); |
| |
| // if it wasn't in the map, perhaps it has been added since |
| // the container was started |
| if (app == null) |
| { |
| loadPortletApplications(); |
| } |
| app = (PortletApplicationConfig)portletApps.get(contextPath); |
| return app; |
| } |
| |
| } |