/* * @param uri The uri of the TLD @param ctxt The compilation context * * @return String array whose first element denotes the path to the TLD. If * the path to the TLD points to a jar file, then the second element denotes * the name of the TLD entry in the jar file, which is hardcoded to * META-INF/taglib.tld. */ private String[] generateTLDLocation(String uri, JspCompilationContext ctxt) throws JasperException { int uriType = TldLocationsCache.uriType(uri); if (uriType == TldLocationsCache.ABS_URI) { err.jspError("jsp.error.taglibDirective.absUriCannotBeResolved", uri); } else if (uriType == TldLocationsCache.NOROOT_REL_URI) { uri = ctxt.resolveRelativeUri(uri); } String[] location = new String[2]; location[0] = uri; if (location[0].endsWith("jar")) { URL url = null; try { url = ctxt.getResource(location[0]); } catch (Exception ex) { err.jspError("jsp.error.tld.unable_to_get_jar", location[0], ex.toString()); } if (url == null) { err.jspError("jsp.error.tld.missing_jar", location[0]); } location[0] = url.toString(); location[1] = "META-INF/taglib.tld"; } return location; }
/* * buffer */ public void setBufferValue(String value, Node n, ErrorDispatcher err) throws JasperException { if ("none".equalsIgnoreCase(value)) buffer = 0; else { if (value == null || !value.endsWith("kb")) { if (n == null) { err.jspError("jsp.error.page.invalid.buffer"); } else { err.jspError(n, "jsp.error.page.invalid.buffer"); } } try { @SuppressWarnings("null") // value can't be null here int k = Integer.parseInt(value.substring(0, value.length() - 2)); buffer = k * 1024; } catch (NumberFormatException e) { if (n == null) { err.jspError("jsp.error.page.invalid.buffer"); } else { err.jspError(n, "jsp.error.page.invalid.buffer"); } } } bufferValue = value; }
/* * language */ public void setLanguage(String value, Node n, ErrorDispatcher err, boolean pagedir) throws JasperException { if (!"java".equalsIgnoreCase(value)) { if (pagedir) err.jspError(n, "jsp.error.page.language.nonjava"); else err.jspError(n, "jsp.error.tag.language.nonjava"); } language = value; }
/* * trimDirectiveWhitespaces */ public void setTrimDirectiveWhitespaces( String value, Node n, ErrorDispatcher err, boolean pagedir) throws JasperException { if ("true".equalsIgnoreCase(value)) trimDirectiveWhitespaces = true; else if ("false".equalsIgnoreCase(value)) trimDirectiveWhitespaces = false; else { if (pagedir) err.jspError(n, "jsp.error.page.invalid.trimdirectivewhitespaces"); else err.jspError(n, "jsp.error.tag.invalid.trimdirectivewhitespaces"); } trimDirectiveWhitespacesValue = value; }
/* * deferredSyntaxAllowedAsLiteral */ public void setDeferredSyntaxAllowedAsLiteral( String value, Node n, ErrorDispatcher err, boolean pagedir) throws JasperException { if ("true".equalsIgnoreCase(value)) deferredSyntaxAllowedAsLiteral = true; else if ("false".equalsIgnoreCase(value)) deferredSyntaxAllowedAsLiteral = false; else { if (pagedir) err.jspError(n, "jsp.error.page.invalid.deferredsyntaxallowedasliteral"); else err.jspError(n, "jsp.error.tag.invalid.deferredsyntaxallowedasliteral"); } deferredSyntaxAllowedAsLiteralValue = value; }
/* * isELIgnored */ public void setIsELIgnored(String value, Node n, ErrorDispatcher err, boolean pagedir) throws JasperException { if ("true".equalsIgnoreCase(value)) isELIgnored = true; else if ("false".equalsIgnoreCase(value)) isELIgnored = false; else { if (pagedir) err.jspError(n, "jsp.error.page.invalid.iselignored"); else err.jspError(n, "jsp.error.tag.invalid.iselignored"); } isELIgnoredValue = value; }
public Writer getJavaWriter(String javaFileName, String javaEncoding) throws JasperException { this.javaFileName = javaFileName; this.javaEncoding = javaEncoding; Writer writer = null; try { writer = new OutputStreamWriter(new FileOutputStream(javaFileName), javaEncoding); } catch (UnsupportedEncodingException ex) { errDispatcher.jspError("jsp.error.needAlternateJavaEncoding", javaEncoding); } catch (IOException ex) { errDispatcher.jspError("jsp.error.unableToCreateOutputWriter", javaFileName, ex); } return writer; }
/* * buffer */ public void setBufferValue(String value, Node n, ErrorDispatcher err) throws JasperException { if ("none".equalsIgnoreCase(value)) buffer = 0; else { if (value == null || !value.endsWith("kb")) err.jspError(n, "jsp.error.page.invalid.buffer"); try { Integer k = new Integer(value.substring(0, value.length() - 2)); buffer = k.intValue() * 1024; } catch (NumberFormatException e) { err.jspError(n, "jsp.error.page.invalid.buffer"); } } bufferValue = value; }
private void setScriptingVars(Node.CustomTag n, int scope) throws JasperException { TagVariableInfo[] tagVarInfos = n.getTagVariableInfos(); VariableInfo[] varInfos = n.getVariableInfos(); if (tagVarInfos.length == 0 && varInfos.length == 0) { return; } Vector vec = new Vector(); Integer ownRange = null; if (scope == VariableInfo.AT_BEGIN || scope == VariableInfo.AT_END) { Node.CustomTag parent = n.getCustomTagParent(); if (parent == null) ownRange = MAX_SCOPE; else ownRange = parent.getNumCount(); } else { // NESTED ownRange = n.getNumCount(); } if (varInfos.length > 0) { for (int i = 0; i < varInfos.length; i++) { if (varInfos[i].getScope() != scope || !varInfos[i].getDeclare()) { continue; } String varName = varInfos[i].getVarName(); Integer currentRange = scriptVars.get(varName); if (currentRange == null || ownRange.compareTo(currentRange) > 0) { scriptVars.put(varName, ownRange); vec.add(varInfos[i]); } } } else { for (int i = 0; i < tagVarInfos.length; i++) { if (tagVarInfos[i].getScope() != scope || !tagVarInfos[i].getDeclare()) { continue; } String varName = tagVarInfos[i].getNameGiven(); if (varName == null) { varName = n.getTagData().getAttributeString(tagVarInfos[i].getNameFromAttribute()); if (varName == null) { err.jspError( n, "jsp.error.scripting.variable.missing_name", tagVarInfos[i].getNameFromAttribute()); } } Integer currentRange = scriptVars.get(varName); if (currentRange == null || ownRange.compareTo(currentRange) > 0) { scriptVars.put(varName, ownRange); vec.add(tagVarInfos[i]); } } } n.setScriptingVars(vec, scope); }
/* * session */ public void setSession(String value, Node n, ErrorDispatcher err) throws JasperException { if ("true".equalsIgnoreCase(value)) isSession = true; else if ("false".equalsIgnoreCase(value)) isSession = false; else err.jspError(n, "jsp.error.page.invalid.session"); session = value; }
/* * autoFlush */ public void setAutoFlush(String value, Node n, ErrorDispatcher err) throws JasperException { if ("true".equalsIgnoreCase(value)) isAutoFlush = true; else if ("false".equalsIgnoreCase(value)) isAutoFlush = false; else err.jspError(n, "jsp.error.autoFlush.invalid"); autoFlush = value; }
/* * isErrorPage */ public void setIsErrorPage(String value, Node n, ErrorDispatcher err) throws JasperException { if ("true".equalsIgnoreCase(value)) isErrorPage = true; else if ("false".equalsIgnoreCase(value)) isErrorPage = false; else err.jspError(n, "jsp.error.page.invalid.iserrorpage"); isErrorPageValue = value; }
/** * Get an instance of JavaCompiler. If Running with JDK 6, use a Jsr199JavaCompiler that supports * JSR199, else if eclipse's JDT compiler is available, use that. The default is to use javac from * ant. */ private void initJavaCompiler() throws JasperException { if (options.getCompilerClassName() != null) { Class c = getClassFor(options.getCompilerClassName()); try { javaCompiler = (JavaCompiler) c.newInstance(); } catch (Exception ex) { } } if (javaCompiler == null) { boolean disablejsr199 = Boolean.TRUE .toString() .equals(System.getProperty("org.apache.jasper.compiler.disablejsr199")); Double version = Double.valueOf(System.getProperty("java.specification.version")); if (!disablejsr199 && (version >= 1.6 || getClassFor("javax.tools.Tool") != null)) { // JDK 6 or bundled with jsr199 compiler javaCompiler = new Jsr199JavaCompiler(); } else { Class c = getClassFor("org.eclipse.jdt.internal.compiler.Compiler"); if (c != null) { c = getClassFor("org.apache.jasper.compiler.JDTJavaCompiler"); if (c != null) { try { javaCompiler = (JavaCompiler) c.newInstance(); } catch (Exception ex) { } } } } } if (javaCompiler == null) { Class c = getClassFor("org.apache.tools.ant.taskdefs.Javac"); if (c != null) { c = getClassFor("org.apache.jasper.compiler.AntJavaCompiler"); if (c != null) { try { javaCompiler = (JavaCompiler) c.newInstance(); } catch (Exception ex) { } } } } if (javaCompiler == null) { errDispatcher.jspError("jsp.error.nojavac"); } javaCompiler.init(ctxt, errDispatcher, jspcMode); }
private void init(ErrorDispatcher err) throws JasperException { if (initialized) return; InputStream is = ctxt.getResourceAsStream(TAG_PLUGINS_XML); if (is == null) return; TreeNode root = (new ParserUtils()).parseXMLDocument(TAG_PLUGINS_XML, is); if (root == null) { return; } if (!TAG_PLUGINS_ROOT_ELEM.equals(root.getName())) { err.jspError("jsp.error.plugin.wrongRootElement", TAG_PLUGINS_XML, TAG_PLUGINS_ROOT_ELEM); } tagPlugins = new HashMap(); Iterator pluginList = root.findChildren("tag-plugin"); while (pluginList.hasNext()) { TreeNode pluginNode = (TreeNode) pluginList.next(); TreeNode tagClassNode = pluginNode.findChild("tag-class"); if (tagClassNode == null) { // Error return; } String tagClass = tagClassNode.getBody().trim(); TreeNode pluginClassNode = pluginNode.findChild("plugin-class"); if (pluginClassNode == null) { // Error return; } String pluginClassStr = pluginClassNode.getBody(); TagPlugin tagPlugin = null; try { Class pluginClass = Class.forName(pluginClassStr); tagPlugin = (TagPlugin) pluginClass.newInstance(); } catch (Exception e) { throw new JasperException(e); } if (tagPlugin == null) { return; } tagPlugins.put(tagClass, tagPlugin); } initialized = true; }
private ServletWriter setupContextWriter(String javaFileName) throws FileNotFoundException, JasperException { ServletWriter writer; // Setup the ServletWriter String javaEncoding = ctxt.getOptions().getJavaEncoding(); OutputStreamWriter osw = null; try { osw = new OutputStreamWriter(new FileOutputStream(javaFileName), javaEncoding); } catch (UnsupportedEncodingException ex) { errDispatcher.jspError("jsp.error.needAlternateJavaEncoding", javaEncoding); } writer = new ServletWriter(new PrintWriter(osw)); ctxt.setWriter(writer); return writer; }
/* * Parses the tag file directives of the given TagFile and turns them into a * TagInfo. * * @param elem The <tag-file> element in the TLD @param uri The location of * the TLD, in case the tag file is specified relative to it @param jarFile * The JAR file, in case the tag file is packaged in a JAR * * @return TagInfo correspoding to tag file directives */ private TagFileInfo createTagFileInfo(TreeNode elem, String uri, URL jarFileUrl) throws JasperException { String name = null; String path = null; Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode child = (TreeNode) list.next(); String tname = child.getName(); if ("name".equals(tname)) { name = child.getBody(); } else if ("path".equals(tname)) { path = child.getBody(); } else if ("example".equals(tname)) { // Ignore <example> element: Bugzilla 33538 } else if ("tag-extension".equals(tname)) { // Ignore <tag-extension> element: Bugzilla 33538 } else if ("icon".equals(tname) || "display-name".equals(tname) || "description".equals(tname)) { // Ignore these elements: Bugzilla 38015 } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.tagfile", tname)); } } } if (path.startsWith("/META-INF/tags")) { // Tag file packaged in JAR // See https://issues.apache.org/bugzilla/show_bug.cgi?id=46471 // This needs to be removed once all the broken code that depends on // it has been removed ctxt.setTagFileJarUrl(path, jarFileUrl); } else if (!path.startsWith("/WEB-INF/tags")) { err.jspError("jsp.error.tagfile.illegalPath", path); } TagInfo tagInfo = TagFileProcessor.parseTagFileDirectives(parserController, name, path, jarFileUrl, this); return new TagFileInfo(name, path, tagInfo); }
private TagLibraryValidator createValidator(TreeNode elem) throws JasperException { String validatorClass = null; Map initParams = new Hashtable(); Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("validator-class".equals(tname)) validatorClass = element.getBody(); else if ("init-param".equals(tname)) { String[] initParam = createInitParam(element); initParams.put(initParam[0], initParam[1]); } else if ("description".equals(tname) || // Ignored elements false) { } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.validator", tname)); } } } TagLibraryValidator tlv = null; if (validatorClass != null && !validatorClass.equals("")) { try { Class tlvClass = ctxt.getClassLoader().loadClass(validatorClass); tlv = (TagLibraryValidator) tlvClass.newInstance(); } catch (Exception e) { err.jspError("jsp.error.tlvclass.instantiation", validatorClass, e); } } if (tlv != null) { tlv.setInitParameters(initParams); } return tlv; }
/** Compile the servlet from .java file to .class file */ protected void generateClass(String[] smap) throws FileNotFoundException, JasperException, Exception { long t1 = 0; if (log.isDebugEnabled()) t1 = System.currentTimeMillis(); List<String> parameters = new ArrayList<String>(20); parameters.add("-encoding"); parameters.add(ctxt.getOptions().getJavaEncoding()); String javaFileName = new File(ctxt.getServletJavaFileName()).getPath(); String classpath = ctxt.getClassPath(); String sep = File.pathSeparator; // System.getProperty("path.separator"); StringBuffer errorReport = new StringBuffer(); StringBuffer info = new StringBuffer(); info.append("Compile: javaFileName=" + javaFileName + "\n"); // Start capturing the System.err output for this thread SystemLogHandler.setThread(); // Initializing classpath String path = System.getProperty("java.class.path"); info.append(" cmd cp=" + path + "\n"); info.append(" ctx cp=" + classpath + "\n"); path += sep; path += classpath; if (log.isDebugEnabled()) log.debug("Using classpath: " + path); parameters.add("-classpath"); parameters.add(path); // Initializing sourcepath parameters.add("-sourcepath"); parameters.add(options.getScratchDir().getPath()); info.append(" work dir=" + options.getScratchDir() + "\n"); // Initialize and set java extensions String extdirs = System.getProperty("java.ext.dirs"); if (extdirs != null) { parameters.add("-extdirs"); parameters.add(extdirs); info.append(" extension dir=" + extdirs + "\n"); } if (ctxt.getOptions().getFork()) { String endorsed = System.getProperty("java.endorsed.dirs"); if (endorsed != null) { parameters.add("-endorseddirs"); // "-J-Djava.endorsed.dirs="+endorsed parameters.add(endorsed); info.append(" endorsed dir=" + endorsed + "\n"); } else { info.append(" no endorsed dirs specified\n"); } } if (ctxt.getOptions().getClassDebugInfo()) parameters.add("-g"); Exception ie = null; // Set the Java compiler to use if (javaCompiler == null) { // assumption, there is no dynamic changing Java compiler String compiler = options.getCompiler(); if (compiler == null) compiler = "com.sun.tools.javac.Main"; // verify compiler try { javaCompiler = Class.forName(compiler); } catch (ClassNotFoundException cnfe) { // try to figure out class path to compiler String compileClassPath = System.getProperty("java.home"); if (compileClassPath == null) try { compileClassPath = System.getenv("JAVA_HOME"); if (compileClassPath == null) compileClassPath = System.getenv("java_home"); } catch (SecurityException se) { } if (compileClassPath != null) { // HACK for now compileClassPath = compileClassPath.replace("jre", "jdk"); compileClassPath += "/lib/tools.jar"; info.append(" checking default compiler in " + compileClassPath + "\n"); try { javaCompiler = Class.forName( compiler, true, new URLClassLoader(new URL[] {new URL("file", "localhost", compileClassPath)})); } catch (Error er) { log.error("Setting up Java compiler error ", er); } catch (Exception ex) { log.error("Setting up Java compiler exception ", ex); } } else info.append(" no Java home path specified\n"); } info.append(" compiler=" + compiler + "\n"); } if (options.getCompilerTargetVM() != null) { parameters.add("-target"); parameters.add(options.getCompilerTargetVM()); info.append(" compilerTargetVM=" + options.getCompilerTargetVM() + "\n"); } if (options.getCompilerSourceVM() != null) { parameters.add("-source"); parameters.add(options.getCompilerSourceVM()); info.append(" compilerSourceVM=" + options.getCompilerSourceVM() + "\n"); } info.append(" JavaPath=" + ctxt.getJavaPath() + "\n"); parameters.add(javaFileName); boolean compilationErrors = false; String errorCapture = null; if (javaCompiler != null) try { Integer success; Method cm = javaCompiler.getMethod("compile", new Class[] {String[].class}); if (ctxt.getOptions().getFork()) { success = (Integer) cm.invoke(null, new Object[] {parameters.toArray(new String[parameters.size()])}); } else { synchronized (javacLock) { success = (Integer) cm.invoke( null, new Object[] {parameters.toArray(new String[parameters.size()])}); } } if (success.intValue() != 0) compilationErrors = true; } catch (Throwable t) { if (t instanceof ThreadDeath) throw (ThreadDeath) t; if (t instanceof InvocationTargetException) t = t.getCause(); if (t instanceof Exception) ie = (Exception) t; else ie = new Exception(t); log.error("Javac exception ", t); log.error("Env: " + info.toString()); } finally { // Stop capturing the System.err output for this thread errorCapture = SystemLogHandler.unsetThread(); } if (compilationErrors && errorCapture != null) { errorReport.append(System.getProperty("line.separator")); errorReport.append(errorCapture); } if (!ctxt.keepGenerated()) { if (new File(javaFileName).delete() == false) log.error("Couldn't delete source: " + javaFileName); } if (compilationErrors || ie != null) { String errorReportString = errorReport.toString(); log.error("Error compiling file: " + javaFileName + " " + errorReportString); JavacErrorDetail[] javacErrors = ErrorDispatcher.parseJavacErrors(errorReportString, javaFileName, pageNodes); if (javacErrors != null) { errDispatcher.javacError(javacErrors); } else { errDispatcher.javacError(errorReportString, ie); } } if (log.isDebugEnabled()) { long t2 = System.currentTimeMillis(); log.debug("Compiled " + ctxt.getServletJavaFileName() + " " + (t2 - t1) + "ms"); } if (ctxt.isPrototypeMode()) { return; } // JSR45 Support if (!options.isSmapSuppressed()) { log.debug("Install Smap " + (smap == null ? "null" : Arrays.toString(smap))); SmapUtil.installSmap(smap); } }
/** * Compile the jsp file into equivalent servlet in .java file * * @return a smap for the current JSP page, if one is generated, null otherwise */ protected String[] generateJava() throws Exception { String[] smapStr = null; long t1, t2, t3, t4; t1 = t2 = t3 = t4 = 0; if (log.isDebugEnabled()) { t1 = System.currentTimeMillis(); } // Setup page info area pageInfo = new PageInfo(new BeanRepository(ctxt.getClassLoader(), errDispatcher), ctxt.getJspFile()); JspConfig jspConfig = options.getJspConfig(); JspConfig.JspProperty jspProperty = jspConfig.findJspProperty(ctxt.getJspFile()); /* * If the current uri is matched by a pattern specified in a * jsp-property-group in web.xml, initialize pageInfo with those * properties. */ if (jspProperty.isELIgnored() != null) { pageInfo.setELIgnored(JspUtil.booleanValue(jspProperty.isELIgnored())); } if (jspProperty.isScriptingInvalid() != null) { pageInfo.setScriptingInvalid(JspUtil.booleanValue(jspProperty.isScriptingInvalid())); } if (jspProperty.getIncludePrelude() != null) { pageInfo.setIncludePrelude(jspProperty.getIncludePrelude()); } if (jspProperty.getIncludeCoda() != null) { pageInfo.setIncludeCoda(jspProperty.getIncludeCoda()); } if (jspProperty.isDeferedSyntaxAllowedAsLiteral() != null) { pageInfo.setDeferredSyntaxAllowedAsLiteral( JspUtil.booleanValue(jspProperty.isDeferedSyntaxAllowedAsLiteral())); } if (jspProperty.isTrimDirectiveWhitespaces() != null) { pageInfo.setTrimDirectiveWhitespaces( JspUtil.booleanValue(jspProperty.isTrimDirectiveWhitespaces())); } // Default ContentType processing is deferred until after the page has // been parsed if (jspProperty.getBuffer() != null) { pageInfo.setBufferValue(jspProperty.getBuffer(), null, errDispatcher); } if (jspProperty.isErrorOnUndeclaredNamespace() != null) { pageInfo.setErrorOnUndeclaredNamespace( JspUtil.booleanValue(jspProperty.isErrorOnUndeclaredNamespace())); } if (ctxt.isTagFile()) { try { double libraryVersion = Double.parseDouble(ctxt.getTagInfo().getTagLibrary().getRequiredVersion()); if (libraryVersion < 2.0) { pageInfo.setIsELIgnored("true", null, errDispatcher, true); } if (libraryVersion < 2.1) { pageInfo.setDeferredSyntaxAllowedAsLiteral("true", null, errDispatcher, true); } } catch (NumberFormatException ex) { errDispatcher.jspError(ex); } } ctxt.checkOutputDir(); String javaFileName = ctxt.getServletJavaFileName(); ServletWriter writer = null; try { /* * The setting of isELIgnored changes the behaviour of the parser * in subtle ways. To add to the 'fun', isELIgnored can be set in * any file that forms part of the translation unit so setting it * in a file included towards the end of the translation unit can * change how the parser should have behaved when parsing content * up to the point where isELIgnored was set. Arghh! * Previous attempts to hack around this have only provided partial * solutions. We now use two passes to parse the translation unit. * The first just parses the directives and the second parses the * whole translation unit once we know how isELIgnored has been set. * TODO There are some possible optimisations of this process. */ // Parse the file ParserController parserCtl = new ParserController(ctxt, this); // Pass 1 - the directives Node.Nodes directives = parserCtl.parseDirectives(ctxt.getJspFile()); Validator.validateDirectives(this, directives); // Pass 2 - the whole translation unit pageNodes = parserCtl.parse(ctxt.getJspFile()); // Leave this until now since it can only be set once - bug 49726 if (pageInfo.getContentType() == null && jspProperty.getDefaultContentType() != null) { pageInfo.setContentType(jspProperty.getDefaultContentType()); } if (ctxt.isPrototypeMode()) { // generate prototype .java file for the tag file writer = setupContextWriter(javaFileName); Generator.generate(writer, this, pageNodes); writer.close(); writer = null; return null; } // Validate and process attributes - don't re-validate the // directives we validated in pass 1 Validator.validateExDirectives(this, pageNodes); if (log.isDebugEnabled()) { t2 = System.currentTimeMillis(); } // Collect page info Collector.collect(this, pageNodes); // Compile (if necessary) and load the tag files referenced in // this compilation unit. tfp = new TagFileProcessor(); tfp.loadTagFiles(this, pageNodes); if (log.isDebugEnabled()) { t3 = System.currentTimeMillis(); } // Determine which custom tag needs to declare which scripting vars ScriptingVariabler.set(pageNodes, errDispatcher); // Optimizations by Tag Plugins TagPluginManager tagPluginManager = options.getTagPluginManager(); tagPluginManager.apply(pageNodes, errDispatcher, pageInfo); // Optimization: concatenate contiguous template texts. TextOptimizer.concatenate(this, pageNodes); // Generate static function mapper codes. ELFunctionMapper.map(pageNodes); // generate servlet .java file writer = setupContextWriter(javaFileName); Generator.generate(writer, this, pageNodes); writer.close(); writer = null; // The writer is only used during the compile, dereference // it in the JspCompilationContext when done to allow it // to be GC'd and save memory. ctxt.setWriter(null); if (log.isDebugEnabled()) { t4 = System.currentTimeMillis(); log.debug( "Generated " + javaFileName + " total=" + (t4 - t1) + " generate=" + (t4 - t3) + " validate=" + (t2 - t1)); } } catch (Exception e) { if (writer != null) { try { writer.close(); writer = null; } catch (Exception e1) { // do nothing } } // Remove the generated .java file File file = new File(javaFileName); if (file.exists()) { if (!file.delete()) { log.warn( Localizer.getMessage( "jsp.warning.compiler.javafile.delete.fail", file.getAbsolutePath())); } } throw e; } finally { if (writer != null) { try { writer.close(); } catch (Exception e2) { // do nothing } } } // JSR45 Support if (!options.isSmapSuppressed()) { smapStr = SmapUtil.generateSmap(ctxt, pageNodes); } // If any proto type .java and .class files was generated, // the prototype .java may have been replaced by the current // compilation (if the tag file is self referencing), but the // .class file need to be removed, to make sure that javac would // generate .class again from the new .java file just generated. tfp.removeProtoTypeFiles(ctxt.getClassFileName()); return smapStr; }
private TagInfo createTagInfo(TreeNode elem, String jspVersion) throws JasperException { String tagName = null; String tagClassName = null; String teiClassName = null; /* * Default body content for JSP 1.2 tag handlers (<body-content> has * become mandatory in JSP 2.0, because the default would be invalid for * simple tag handlers) */ String bodycontent = "JSP"; String info = null; String displayName = null; String smallIcon = null; String largeIcon = null; boolean dynamicAttributes = false; Vector attributeVector = new Vector(); Vector variableVector = new Vector(); Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("name".equals(tname)) { tagName = element.getBody(); } else if ("tagclass".equals(tname) || "tag-class".equals(tname)) { tagClassName = element.getBody(); } else if ("teiclass".equals(tname) || "tei-class".equals(tname)) { teiClassName = element.getBody(); } else if ("bodycontent".equals(tname) || "body-content".equals(tname)) { bodycontent = element.getBody(); } else if ("display-name".equals(tname)) { displayName = element.getBody(); } else if ("small-icon".equals(tname)) { smallIcon = element.getBody(); } else if ("large-icon".equals(tname)) { largeIcon = element.getBody(); } else if ("icon".equals(tname)) { TreeNode icon = element.findChild("small-icon"); if (icon != null) { smallIcon = icon.getBody(); } icon = element.findChild("large-icon"); if (icon != null) { largeIcon = icon.getBody(); } } else if ("info".equals(tname) || "description".equals(tname)) { info = element.getBody(); } else if ("variable".equals(tname)) { variableVector.addElement(createVariable(element)); } else if ("attribute".equals(tname)) { attributeVector.addElement(createAttribute(element, jspVersion)); } else if ("dynamic-attributes".equals(tname)) { dynamicAttributes = JspUtil.booleanValue(element.getBody()); } else if ("example".equals(tname)) { // Ignored elements } else if ("tag-extension".equals(tname)) { // Ignored } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.tag", tname)); } } } TagExtraInfo tei = null; if (teiClassName != null && !teiClassName.equals("")) { try { Class teiClass = ctxt.getClassLoader().loadClass(teiClassName); tei = (TagExtraInfo) teiClass.newInstance(); } catch (Exception e) { err.jspError("jsp.error.teiclass.instantiation", teiClassName, e); } } TagAttributeInfo[] tagAttributeInfo = new TagAttributeInfo[attributeVector.size()]; attributeVector.copyInto(tagAttributeInfo); TagVariableInfo[] tagVariableInfos = new TagVariableInfo[variableVector.size()]; variableVector.copyInto(tagVariableInfos); TagInfo taginfo = new TagInfo( tagName, tagClassName, bodycontent, info, this, tei, tagAttributeInfo, displayName, smallIcon, largeIcon, tagVariableInfos, dynamicAttributes); return taginfo; }
/** Compile the servlet from .java file to .class file */ private void generateClass() throws FileNotFoundException, JasperException, Exception { long t1 = 0; if (log.isLoggable(Level.FINE)) { t1 = System.currentTimeMillis(); } String javaFileName = ctxt.getServletJavaFileName(); String classpath = ctxt.getClassPath(); String sep = System.getProperty("path.separator"); // Initializing classpath ArrayList<File> cpath = new ArrayList<File>(); HashSet<String> paths = new HashSet<String>(); // Process classpath, which includes system classpath from compiler // options, plus the context classpath from the classloader String sysClassPath = options.getSystemClassPath(); if (sysClassPath != null) { StringTokenizer tokenizer = new StringTokenizer(sysClassPath, sep); while (tokenizer.hasMoreElements()) { String path = tokenizer.nextToken(); if (!paths.contains(path) && !systemJarInWebinf(path)) { paths.add(path); cpath.add(new File(path)); } } } if (classpath != null) { StringTokenizer tokenizer = new StringTokenizer(classpath, sep); while (tokenizer.hasMoreElements()) { String path = tokenizer.nextToken(); if (!paths.contains(path) && !systemJarInWebinf(path)) { paths.add(path); cpath.add(new File(path)); } } } if (log.isLoggable(Level.FINE)) { log.fine("Using classpath: " + sysClassPath + sep + classpath); } javaCompiler.setClassPath(cpath); // Set debug info javaCompiler.setDebug(options.getClassDebugInfo()); // Initialize and set java extensions String exts = System.getProperty("java.ext.dirs"); if (exts != null) { javaCompiler.setExtdirs(exts); } if (options.getCompilerTargetVM() != null) { javaCompiler.setTargetVM(options.getCompilerTargetVM()); } if (options.getCompilerSourceVM() != null) { javaCompiler.setSourceVM(options.getCompilerSourceVM()); } // Start java compilation JavacErrorDetail[] javacErrors = javaCompiler.compile(ctxt.getFullClassName(), pageNodes); if (javacErrors != null) { // If there are errors, always generate java files to disk. javaCompiler.doJavaFile(true); log.severe("Error compiling file: " + javaFileName); errDispatcher.javacError(javacErrors); } if (log.isLoggable(Level.FINE)) { long t2 = System.currentTimeMillis(); log.fine("Compiled " + javaFileName + " " + (t2 - t1) + "ms"); } // Save or delete the generated Java files, depending on the // value of "keepgenerated" attribute javaCompiler.doJavaFile(ctxt.keepGenerated()); // JSR45 Support if (!ctxt.isPrototypeMode() && !options.isSmapSuppressed()) { smapUtil.installSmap(); } // START CR 6373479 if (jsw != null && jsw.getServletClassLastModifiedTime() <= 0) { jsw.setServletClassLastModifiedTime(javaCompiler.getClassLastModified()); } // END CR 6373479 if (options.getSaveBytecode()) { javaCompiler.saveClassFile(ctxt.getFullClassName(), ctxt.getClassFileName()); } // On some systems, due to file caching, the time stamp for the updated // JSP file may actually be greater than that of the newly created byte // codes in the cache. In such cases, adjust the cache time stamp to // JSP page time, to avoid unnecessary recompilations. ctxt.getRuntimeContext().adjustBytecodeTime(ctxt.getFullClassName(), jspModTime); }
/* * @param ctxt The JSP compilation context @param uri The TLD's uri @param * in The TLD's input stream @param jarFileUrl The JAR file containing the * TLD, or null if the tag library is not packaged in a JAR */ private void parseTLD(JspCompilationContext ctxt, String uri, InputStream in, URL jarFileUrl) throws JasperException { Vector tagVector = new Vector(); Vector tagFileVector = new Vector(); Hashtable functionTable = new Hashtable(); // Create an iterator over the child elements of our <taglib> element ParserUtils pu = new ParserUtils(); TreeNode tld = pu.parseXMLDocument(uri, in); // Check to see if the <taglib> root element contains a 'version' // attribute, which was added in JSP 2.0 to replace the <jsp-version> // subelement this.jspversion = tld.findAttribute("version"); // Process each child element of our <taglib> element Iterator list = tld.findChildren(); while (list.hasNext()) { TreeNode element = (TreeNode) list.next(); String tname = element.getName(); if ("tlibversion".equals(tname) // JSP 1.1 || "tlib-version".equals(tname)) { // JSP 1.2 this.tlibversion = element.getBody(); } else if ("jspversion".equals(tname) || "jsp-version".equals(tname)) { this.jspversion = element.getBody(); } else if ("shortname".equals(tname) || "short-name".equals(tname)) this.shortname = element.getBody(); else if ("uri".equals(tname)) this.urn = element.getBody(); else if ("info".equals(tname) || "description".equals(tname)) this.info = element.getBody(); else if ("validator".equals(tname)) this.tagLibraryValidator = createValidator(element); else if ("tag".equals(tname)) tagVector.addElement(createTagInfo(element, jspversion)); else if ("tag-file".equals(tname)) { TagFileInfo tagFileInfo = createTagFileInfo(element, uri, jarFileUrl); tagFileVector.addElement(tagFileInfo); } else if ("function".equals(tname)) { // JSP2.0 FunctionInfo funcInfo = createFunctionInfo(element); String funcName = funcInfo.getName(); if (functionTable.containsKey(funcName)) { err.jspError("jsp.error.tld.fn.duplicate.name", funcName, uri); } functionTable.put(funcName, funcInfo); } else if ("display-name".equals(tname) || // Ignored elements "small-icon".equals(tname) || "large-icon".equals(tname) || "listener".equals(tname)) {; } else if ("taglib-extension".equals(tname)) { // Recognized but ignored } else { if (log.isWarnEnabled()) { log.warn(Localizer.getMessage("jsp.warning.unknown.element.in.taglib", tname)); } } } if (tlibversion == null) { err.jspError("jsp.error.tld.mandatory.element.missing", "tlib-version", uri); } if (jspversion == null) { err.jspError("jsp.error.tld.mandatory.element.missing", "jsp-version", uri); } this.tags = new TagInfo[tagVector.size()]; tagVector.copyInto(this.tags); this.tagFiles = new TagFileInfo[tagFileVector.size()]; tagFileVector.copyInto(this.tagFiles); this.functions = new FunctionInfo[functionTable.size()]; int i = 0; Enumeration enumeration = functionTable.elements(); while (enumeration.hasMoreElements()) { this.functions[i++] = (FunctionInfo) enumeration.nextElement(); } }
/** Compile the servlet from .java file to .class file */ @Override protected void generateClass(String[] smap) throws FileNotFoundException, JasperException, Exception { long t1 = 0; if (log.isDebugEnabled()) { t1 = System.currentTimeMillis(); } String javaEncoding = ctxt.getOptions().getJavaEncoding(); String javaFileName = ctxt.getServletJavaFileName(); String classpath = ctxt.getClassPath(); String sep = System.getProperty("path.separator"); StringBuilder errorReport = new StringBuilder(); StringBuilder info = new StringBuilder(); info.append("Compile: javaFileName=" + javaFileName + "\n"); info.append(" classpath=" + classpath + "\n"); // Start capturing the System.err output for this thread SystemLogHandler.setThread(); // Initializing javac task getProject(); Javac javac = (Javac) project.createTask("javac"); // Initializing classpath Path path = new Path(project); path.setPath(System.getProperty("java.class.path")); info.append(" cp=" + System.getProperty("java.class.path") + "\n"); StringTokenizer tokenizer = new StringTokenizer(classpath, sep); while (tokenizer.hasMoreElements()) { String pathElement = tokenizer.nextToken(); File repository = new File(pathElement); path.setLocation(repository); info.append(" cp=" + repository + "\n"); } if (log.isDebugEnabled()) log.debug("Using classpath: " + System.getProperty("java.class.path") + sep + classpath); // Initializing sourcepath Path srcPath = new Path(project); srcPath.setLocation(options.getScratchDir()); info.append(" work dir=" + options.getScratchDir() + "\n"); // Initialize and set java extensions String exts = System.getProperty("java.ext.dirs"); if (exts != null) { Path extdirs = new Path(project); extdirs.setPath(exts); javac.setExtdirs(extdirs); info.append(" extension dir=" + exts + "\n"); } // Add endorsed directories if any are specified and we're forking // See Bugzilla 31257 if (ctxt.getOptions().getFork()) { String endorsed = System.getProperty("java.endorsed.dirs"); if (endorsed != null) { Javac.ImplementationSpecificArgument endorsedArg = javac.createCompilerArg(); endorsedArg.setLine("-J-Djava.endorsed.dirs=" + quotePathList(endorsed)); info.append(" endorsed dir=" + quotePathList(endorsed) + "\n"); } else { info.append(" no endorsed dirs specified\n"); } } // Configure the compiler object javac.setEncoding(javaEncoding); javac.setClasspath(path); javac.setDebug(ctxt.getOptions().getClassDebugInfo()); javac.setSrcdir(srcPath); javac.setTempdir(options.getScratchDir()); javac.setOptimize(!ctxt.getOptions().getClassDebugInfo()); javac.setFork(ctxt.getOptions().getFork()); info.append(" srcDir=" + srcPath + "\n"); // Set the Java compiler to use if (options.getCompiler() != null) { javac.setCompiler(options.getCompiler()); info.append(" compiler=" + options.getCompiler() + "\n"); } if (options.getCompilerTargetVM() != null) { javac.setTarget(options.getCompilerTargetVM()); info.append(" compilerTargetVM=" + options.getCompilerTargetVM() + "\n"); } if (options.getCompilerSourceVM() != null) { javac.setSource(options.getCompilerSourceVM()); info.append(" compilerSourceVM=" + options.getCompilerSourceVM() + "\n"); } // Build includes path PatternSet.NameEntry includes = javac.createInclude(); includes.setName(ctxt.getJavaPath()); info.append(" include=" + ctxt.getJavaPath() + "\n"); BuildException be = null; try { if (ctxt.getOptions().getFork()) { javac.execute(); } else { synchronized (javacLock) { javac.execute(); } } } catch (BuildException e) { be = e; log.error(Localizer.getMessage("jsp.error.javac"), e); log.error(Localizer.getMessage("jsp.error.javac.env") + info.toString()); } errorReport.append(logger.getReport()); // Stop capturing the System.err output for this thread String errorCapture = SystemLogHandler.unsetThread(); if (errorCapture != null) { errorReport.append(Constants.NEWLINE); errorReport.append(errorCapture); } if (!ctxt.keepGenerated()) { File javaFile = new File(javaFileName); javaFile.delete(); } if (be != null) { String errorReportString = errorReport.toString(); log.error(Localizer.getMessage("jsp.error.compilation", javaFileName, errorReportString)); JavacErrorDetail[] javacErrors = ErrorDispatcher.parseJavacErrors(errorReportString, javaFileName, pageNodes); if (javacErrors != null) { errDispatcher.javacError(javacErrors); } else { errDispatcher.javacError(errorReportString, be); } } if (log.isDebugEnabled()) { long t2 = System.currentTimeMillis(); log.debug("Compiled " + ctxt.getServletJavaFileName() + " " + (t2 - t1) + "ms"); } logger = null; project = null; if (ctxt.isPrototypeMode()) { return; } // JSR45 Support if (!options.isSmapSuppressed()) { SmapUtil.installSmap(smap); } }
/** Constructor. */ public TagLibraryInfoImpl( JspCompilationContext ctxt, ParserController pc, PageInfo pi, String prefix, String uriIn, String[] location, ErrorDispatcher err) throws JasperException { super(prefix, uriIn); this.ctxt = ctxt; this.parserController = pc; this.pi = pi; this.err = err; InputStream in = null; JarFile jarFile = null; if (location == null) { // The URI points to the TLD itself or to a JAR file in which the // TLD is stored location = generateTLDLocation(uri, ctxt); } try { if (!location[0].endsWith("jar")) { // Location points to TLD file try { in = getResourceAsStream(location[0]); if (in == null) { throw new FileNotFoundException(location[0]); } } catch (FileNotFoundException ex) { err.jspError("jsp.error.file.not.found", location[0]); } parseTLD(ctxt, location[0], in, null); // Add TLD to dependency list PageInfo pageInfo = ctxt.createCompiler().getPageInfo(); if (pageInfo != null) { pageInfo.addDependant(location[0]); } } else { // Tag library is packaged in JAR file try { URL jarFileUrl = new URL("jar:" + location[0] + "!/"); JarURLConnection conn = (JarURLConnection) jarFileUrl.openConnection(); conn.setUseCaches(false); conn.connect(); jarFile = conn.getJarFile(); ZipEntry jarEntry = jarFile.getEntry(location[1]); in = jarFile.getInputStream(jarEntry); parseTLD(ctxt, location[0], in, jarFileUrl); } catch (Exception ex) { err.jspError("jsp.error.tld.unable_to_read", location[0], location[1], ex.toString()); } } } finally { if (in != null) { try { in.close(); } catch (Throwable t) { } } if (jarFile != null) { try { jarFile.close(); } catch (Throwable t) { } } } }