blob: f5729d322ae51141877c10f23eac2973adbc8f69 [file] [log] [blame]
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;
}
}