package org.anodyneos.xpImpl.runtime; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.anodyneos.commons.net.ClassLoaderURIHandler; import org.anodyneos.commons.xml.UnifiedResolver; import org.anodyneos.servlet.net.ServletContextURIHandler; import org.anodyneos.xp.XpException; import org.anodyneos.xp.XpFactory; import org.anodyneos.xp.XpFileNotFoundException; import org.anodyneos.xp.XpPage; import org.anodyneos.xp.http.HttpXpContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class XpServlet extends HttpServlet{ private static final Log logger = LogFactory.getLog(XpServlet.class); private static final long serialVersionUID = 3258132440416794419L; public static final String IP_XP_REGISTRY = "xpRegistry"; public static final String IP_XP_CACHE_AUTOLOAD = "xpCacheAutoload"; public static final String IP_XSLT_CACHE = "xsltCache"; public static final String XP_FACTORY_SERVLET_CONTEXT_ATTRIBUTE = "org.anodyneos.xp.xpFactory"; private static final String TMP_DIR_ATTRIBUTE = "javax.servlet.context.tempdir"; private XpFactory xpFactory; public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); ////////////////////////////////////////// // XP Setup ////////////////////////////////////////// // determine work directory for compiling XP pages File scratchDir = (File) getServletContext().getAttribute(TMP_DIR_ATTRIBUTE); if (!(scratchDir.exists() && scratchDir.canRead() && scratchDir.canWrite())){ throw new ServletException("Work directory is invalid. Check for existance and Read/Write settings."); } if (logger.isInfoEnabled()) { logger.info("xpClassRoot and xpJavaRoot: " + scratchDir.getPath()); } // configure URI resolvers UnifiedResolver resolver = new UnifiedResolver(); resolver.setDefaultLookupEnabled(false); resolver.addProtocolHandler("classpath", new ClassLoaderURIHandler()); resolver.addProtocolHandler("webapp", new ServletContextURIHandler(servletConfig.getServletContext())); // determine xpRegistry configuration file String xpRegistry = servletConfig.getInitParameter(IP_XP_REGISTRY); URI xpRegistryURI; try { if (xpRegistry == null){ xpRegistry = "webapp:///WEB-INF/registry.xpreg"; } if (logger.isInfoEnabled()) { logger.info("xpRegistry URI: " + xpRegistry); } xpRegistryURI = new URI(xpRegistry); } catch (URISyntaxException e) { throw new ServletException("Cannot create URI for xpRegistry '" + xpRegistry + "';", e); } // determine autoLoad setting boolean xpCacheAutoload = true; // default true String xpCacheAutoloadParam = servletConfig.getInitParameter(IP_XP_CACHE_AUTOLOAD); if (null != xpCacheAutoloadParam){ xpCacheAutoload = Boolean.getBoolean(xpCacheAutoloadParam); } if (logger.isInfoEnabled()) { logger.info("xpCacheAutoload: " + xpCacheAutoload); } // configure the XpCachingLoader try { xpFactory = XpFactory.newInstance(); } catch (XpException e) { throw new ServletException("Could not create xpFactory.", e); } xpFactory.setXpRegistryURI(xpRegistryURI); xpFactory.setAutoLoad(xpCacheAutoload); xpFactory.setResolver(resolver); xpFactory.setJavaGenDirectory(scratchDir); xpFactory.setClassGenDirectory(scratchDir); ////////////////////////////////////////// // XSLT Setup ////////////////////////////////////////// // determine xsltCache setting boolean xsltCache = true; // default String xsltCacheParam = servletConfig.getInitParameter(IP_XSLT_CACHE); if (null != xsltCacheParam) { xsltCache = Boolean.getBoolean(xsltCacheParam); } if (logger.isInfoEnabled()) { logger.info("xsltCacheEnabled: " + xsltCache); } // configure the xslt templates cache xpFactory.getTemplatesCache().setCacheEnabled(xsltCache); servletConfig.getServletContext().setAttribute(XP_FACTORY_SERVLET_CONTEXT_ATTRIBUTE, xpFactory); } public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpXpContext xpContext = null; try { // get XpPage URI xpURI = getXpURIFromRequest(req.getServletPath()); XpPage xpPage = xpFactory.newXpPage(xpURI); if (xpPage == null) { // TODO replace with smarter error page res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } // configure userAgent for xhtml auto method xpPage.configureForUserAgent(req.getHeader("User-Agent")); // set mimetype and encoding on the servlet response res.setContentType(genContentType(xpPage.getMediaType(), xpPage.getEncoding())); // setup xpContext xpContext = xpFactory.getHttpXpContext(this,req,res); // do it OutputStream out = res.getOutputStream(); xpPage.service(xpContext, out); out.close(); } catch (XpFileNotFoundException fnf) { res.sendError(HttpServletResponse.SC_NOT_FOUND,req.getServletPath()); } catch (XpException e) { if (logger.isInfoEnabled()) { logger.info("XpServlet.service - 500 " ); } res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); e.printStackTrace(); } catch (Exception e) { if (logger.isInfoEnabled()) { logger.info("XpServlet.service - " + e.getMessage(),e); } throw new ServletException(e); } finally { if (null != xpContext) { xpContext.release(); } } } private URI getXpURIFromRequest(String servletPath){ try { // there will already be a leading / in the servletPath URI uri = new URI("webapp://" + servletPath); return uri; } catch (Exception e) { logger.error("XpServlet.getXpURIFromRequest - Unable to create URI from servletPath" + e.getMessage(),e); return null; } } private String genContentType(String media, String encoding) { if (encoding != null) { return media + "; charset=" + encoding; } else { return media; } } }