blob: 9100208c150c2f9e5b70a612afc03fab48a03b87 [file] [log] [blame]
/* 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());
}
}
}