All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.khubla.pragmatach.plugin.jsp.JSPCompiler Maven / Gradle / Ivy

package com.khubla.pragmatach.plugin.jsp;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.jasper.EmbeddedServletOptions;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.Options;
import org.apache.jasper.compiler.Compiler;
import org.apache.jasper.compiler.JspRuntimeContext;
import org.apache.jasper.runtime.HttpJspBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.khubla.pragmatach.framework.api.PragmatachException;

/**
 * Simple JSP compiler
 * 

* http://javasourcecode.org/html/open-source/tomcat/tomcat-7.0.29/org/apache/jasper/JspCompilationContext.java.html *

*

* http://javasourcecode.org/html/open-source/tomcat/tomcat-6.0.32/org/apache/jasper/JspC.java.html *

*

* http://javasourcecode.org/html/open-source/tomcat/tomcat-7.0.29/org/apache/jasper/JspC.java.html *

* * @author tome */ public class JSPCompiler { /** * class cache */ private static JSPClassCache jspClassCache = new JSPClassCache(); /** * namespace */ private static final String JSP_NAMESPACE = "com.khubla.pragmatach.jsp"; /** * servlet context */ private final ServletContext servletContext; /** * servlet config */ private final ServletConfig servletConfig; /** * logger */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * classloader */ private URLClassLoader compilerClassLoader; /** * options */ private final Options options; /** * file */ private final String jspFile; /** * the classname */ final String className; /** * the class package */ final String packageName; /** * the fully qualified classname */ final String fullyQualifiedClassName; /** * the path to the classfile */ final String classFilePath; /** * ctor */ public JSPCompiler(String jspFile, ServletConfig servletConfig, ServletContext servletContext) { this.servletContext = servletContext; this.servletConfig = servletConfig; options = new EmbeddedServletOptions(servletConfig, servletContext); this.jspFile = jspFile; compilerClassLoader = createCompilerClassLoader(jspFile); className = makeClassName(); packageName = getPackage(); fullyQualifiedClassName = getFullyQualifiedClassName(); classFilePath = getClassFilePath(); } /** * compile a jspFile and return the class type */ private void compile() throws PragmatachException { ClassLoader originalClassLoader = null; try { /* * get description of the class we want to create */ final String className = makeClassName(); final String packageName = getPackage(); final String fullyQualifiedClassName = getFullyQualifiedClassName(); /* * log */ logger.info("Compiling '" + jspFile + "' to '" + fullyQualifiedClassName + "' in directory '" + getPackageDir(packageName) + "'"); /* * options */ final Options options = new EmbeddedServletOptions(servletConfig, servletContext); /* * runtime context */ final JspRuntimeContext jspRuntimeContext = new JspRuntimeContext(servletContext, options); /* * set up class compilation context */ final String jspUri = jspFile.replace('\\', '/'); final JspCompilationContext jspCompilationContext = new JspCompilationContext(jspUri, false, options, servletContext, null, jspRuntimeContext); jspCompilationContext.setServletClassName(className); jspCompilationContext.setServletPackageName(packageName); /* * save the class loader and set new class loader */ originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(compilerClassLoader); jspCompilationContext.setClassLoader(compilerClassLoader); /* * compile */ final Compiler compiler = jspCompilationContext.createCompiler(); if (null != compiler) { compiler.compile(); } else { throw new Exception("Unable to create compiler"); } /* * refresh the classloader */ compilerClassLoader = createCompilerClassLoader(jspUri); } catch (final Exception e) { throw new PragmatachException("Exception in compile", e); } finally { if (originalClassLoader != null) { Thread.currentThread().setContextClassLoader(originalClassLoader); } } } /** * set up the class loader for the JSP compiler */ private URLClassLoader createCompilerClassLoader(String jspFile) { try { /* * the urls */ final List urls = new ArrayList(); /* * find the files in /WEB-INF/classes/ */ final String rootURI = servletContext.getRealPath(File.separator); final File classesDir = new File(rootURI + "/WEB-INF/classes/"); if (classesDir.exists()) { final Collection jars = FileUtils.listFiles(classesDir, new String[] { "jar" }, true); for (final File jar : jars) { urls.add(new URL("file://" + jar.getAbsolutePath())); } } /* * find the files in /WEB-INF/lib/ */ final File libsDir = new File(rootURI + "/WEB-INF/lib/"); if (libsDir.exists()) { final Collection jars = FileUtils.listFiles(libsDir, new String[] { "jar" }, true); for (final File jar : jars) { urls.add(new URL("file://" + jar.getAbsolutePath())); } } /* * show all urls */ for (final URL url : urls) { logger.debug(url.getPath()); } /* * done */ final URL[] u = new URL[urls.size()]; urls.toArray(u); return new URLClassLoader(u); } catch (final Exception e) { logger.error("Exception in createCompilerClassLoader", e); return null; } } private URLClassLoader createJSPClassLoader() { try { return new URLClassLoader(new URL[] { new URL("file://" + options.getScratchDir().getAbsolutePath() + "/") }, Thread.currentThread().getContextClassLoader()); } catch (final Exception e) { logger.error("Exception in createJSPClassLoader", e); return null; } } private final String getClassFilePath() { return getPackageDir(getPackage()) + "/" + makeClassName() + ".class"; } /** * get a Class for the jspFile */ private Class getClazz() throws PragmatachException { try { /* * get from cache */ Class ret = jspClassCache.find(fullyQualifiedClassName); if (null == ret) { /* * compile */ compile(); /* * get it */ final URLClassLoader jspClassLoader = createJSPClassLoader(); if (null != jspClassLoader) { ret = jspClassLoader.loadClass(fullyQualifiedClassName); /* * cache it */ jspClassCache.add(ret, fullyQualifiedClassName); } } /* * done */ return ret; } catch (final Exception e) { throw new PragmatachException("Exception in getClazz", e); } } /** * get jspFile fully qualified name */ private String getFullyQualifiedClassName() { return getPackage() + "." + makeClassName(); } /** * get jspFile package */ private String getPackage() { final String classPart = jspFile.replaceAll(File.separator, "."); final int i = classPart.lastIndexOf(File.separator); if (-1 != i) { return JSP_NAMESPACE + "." + classPart.substring(0, i); } else { return JSP_NAMESPACE; } } /** * get the absolute dir that files in a specific package will end up in */ private String getPackageDir(String packageName) { return options.getScratchDir().getAbsolutePath() + File.separator + StringUtils.replace(packageName, ".", File.separator); } /** * given a JSP file relative path, return a Servlet */ public HttpJspBase getServlet() throws PragmatachException { try { final Class clazz = getClazz(); if (null != clazz) { final Object o = clazz.newInstance(); return (HttpJspBase) o; } else { return null; } } catch (final Exception e) { throw new PragmatachException("Exception in getServlet", e); } } /** * create classname from jspFile */ private String makeClassName() { /* * get the part after the last dot */ String ret = jspFile.substring(0, jspFile.indexOf(".")); final int i = ret.lastIndexOf(File.separator); if (-1 != i) { ret = ret.substring(i + 1); } /* * capitalize first letter */ ret = ret.substring(0, 1).toUpperCase() + ret.substring(1); /* * done */ return ret; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy