/* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.pluto.container.driver; | |
import java.io.InputStream; | |
import java.util.EnumSet; | |
import java.util.Set; | |
import javax.portlet.annotations.PortletApplication; | |
import javax.portlet.annotations.PortletConfiguration; | |
import javax.portlet.annotations.PortletConfigurations; | |
import javax.portlet.annotations.PortletLifecycleFilter; | |
import javax.portlet.annotations.PortletListener; | |
import javax.portlet.annotations.PortletPreferencesValidator; | |
import javax.servlet.DispatcherType; | |
import javax.servlet.FilterRegistration; | |
import javax.servlet.MultipartConfigElement; | |
import javax.servlet.ServletContainerInitializer; | |
import javax.servlet.ServletContext; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRegistration; | |
import javax.servlet.annotation.HandlesTypes; | |
import org.apache.pluto.container.PortletInvokerService; | |
import org.apache.pluto.container.bean.processor.AnnotatedConfigBean; | |
import org.apache.pluto.container.bean.processor.AnnotatedMethodStore; | |
import org.apache.pluto.container.bean.processor.ConfigSummary; | |
import org.apache.pluto.container.bean.processor.PortletCDIExtension; | |
import org.apache.pluto.container.om.portlet.PortletDefinition; | |
import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
/** | |
* Servlet container initializer that reads the configuration and adds the | |
* portlet servlets for any portlets contained in the application. | |
* | |
* @author Scott Nicklous | |
* | |
*/ | |
@HandlesTypes({PortletApplication.class, PortletConfiguration.class, | |
PortletLifecycleFilter.class, PortletConfigurations.class, | |
PortletListener.class, PortletPreferencesValidator.class}) | |
public class PortletContainerInitializer implements ServletContainerInitializer { | |
private static final String WEB_XML = "/WEB-INF/web.xml"; | |
private static final String PORTLET_XML = "/WEB-INF/portlet.xml"; | |
/** Logger. */ | |
private static final Logger LOG = LoggerFactory | |
.getLogger(PortletContainerInitializer.class); | |
private static boolean isDebug = LOG.isDebugEnabled(); | |
/* | |
* (non-Javadoc) | |
* | |
* @see javax.servlet.ServletContainerInitializer#onStartup(java.util.Set, | |
* javax.servlet.ServletContext) | |
*/ | |
@Override | |
public void onStartup(Set<Class<?>> classes, ServletContext ctx) | |
throws ServletException { | |
try { | |
// Get the bean configuration from the CDI extension | |
ConfigurationHolder holder = new ConfigurationHolder(); | |
AnnotatedConfigBean acb = PortletCDIExtension.getConfig(); | |
if (acb == null) { | |
holder.setMethodStore(new AnnotatedMethodStore(new ConfigSummary())); | |
if (isDebug) { | |
StringBuilder txt = new StringBuilder(); | |
txt.append("CDI not available. Created new method store."); | |
LOG.debug(txt.toString()); | |
} | |
} else { | |
holder.setMethodStore(acb.getMethodStore()); | |
} | |
// Read the annotated configuration | |
if (classes != null) { | |
holder.processConfigAnnotations(classes); | |
} | |
// set up for reading the XML files | |
InputStream win = ctx.getResourceAsStream(WEB_XML); | |
InputStream pin = ctx.getResourceAsStream(PORTLET_XML); | |
if (isDebug) { | |
StringBuilder txt = new StringBuilder(128); | |
txt.append("ยงยงยง ServletContainerInitializer. ctx path: ").append( | |
ctx.getContextPath()); | |
txt.append(", servlet ctx name: ").append(ctx.getServletContextName()); | |
txt.append(", # portlet annotations: ").append( | |
(classes != null) ? classes.size() : "null"); | |
txt.append(", found web.xml: ").append(win != null); | |
txt.append(", found portlet.xml: ").append(pin != null); | |
LOG.debug(txt.toString()); | |
} | |
// Now read the XML configuration and validate the resulting explicit config | |
if (pin != null) { | |
// parse the portlet deployment descriptor | |
holder.processPortletDD(pin); | |
} | |
if (win != null) { | |
// parse the web app deployment descriptor | |
holder.processWebDD(win); | |
} | |
holder.validate(); | |
// Reconcile the bean config with the explicitly declared portlet configuration. | |
holder.reconcileBeanConfig(); | |
// If portlets have been found in this servlet context, launch the portlet servlets | |
if (holder.getPad().getPortlets().size() > 0) { | |
ctx.setAttribute(ConfigurationHolder.ATTRIB_NAME, holder); | |
// dynamically deploy the portlet servlets | |
for (PortletDefinition pd : holder.getPad().getPortlets()) { | |
String pn = pd.getPortletName(); | |
String mapping = PortletInvokerService.URIPREFIX + pn; | |
String servletName = pn + "_PS3"; | |
if (isDebug) { | |
StringBuilder txt = new StringBuilder(); | |
txt.append("Adding PortletServlet3. Portlet name: "); | |
txt.append(pn); | |
txt.append(", servlet name: ").append(servletName); | |
txt.append(", mapping: ").append(mapping); | |
LOG.debug(txt.toString()); | |
} | |
ServletRegistration.Dynamic sr = ctx.addServlet(servletName, PortletServlet3.class); | |
sr.addMapping(mapping); | |
sr.setInitParameter(PortletServlet3.PORTLET_NAME, pn); | |
sr.setAsyncSupported(pd.isAsyncSupported()); | |
if (pd.isMultipartSupported()) { | |
MultipartConfigElement mce = new MultipartConfigElement(pd.getLocation(), | |
pd.getMaxFileSize(), pd.getMaxRequestSize(), pd.getFileSizeThreshold()); | |
sr.setMultipartConfig(mce); | |
} | |
sr.setLoadOnStartup(100); | |
} | |
// Add the cross-context filter & terminal listener | |
FilterRegistration.Dynamic fr = ctx.addFilter("WeldCrossContextFilter", "org.jboss.weld.servlet.WeldCrossContextFilter"); | |
EnumSet<DispatcherType> dt = EnumSet.noneOf(DispatcherType.class); | |
dt.add(DispatcherType.FORWARD); | |
dt.add(DispatcherType.INCLUDE); | |
dt.add(DispatcherType.ERROR); | |
fr.addMappingForUrlPatterns(dt, false, "/*"); | |
ctx.addListener("org.jboss.weld.servlet.WeldTerminalListener"); | |
LOG.debug("Completed deployment of servlets & filters for context: " + ctx.getContextPath()); | |
} else { | |
LOG.debug("No portlet definitions for context: " + ctx.getServletContextName()); | |
} | |
} catch (Exception e) { | |
StringBuilder txt = new StringBuilder(128); | |
txt.append("Exception processing portlet application configuration"); | |
txt.append(", Servlet ctx name: ").append( | |
ctx.getServletContextName()); | |
txt.append(", Exception: ").append(e.toString()); | |
LOG.info(txt.toString()); | |
} | |
} | |
} |