You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2009/09/28 02:43:39 UTC
svn commit: r819435 [6/23] - in
/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper:
./ compiler/ compiler/tagplugin/ el/ runtime/ security/ servlet/
tagplugins/ tagplugins/jstl/ tagplugins/jstl/core/ util/ xmlparser/
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/ImplicitTagLibraryInfo.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/ImplicitTagLibraryInfo.java?rev=819435&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/ImplicitTagLibraryInfo.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/ImplicitTagLibraryInfo.java Mon Sep 28 00:43:34 2009
@@ -0,0 +1,218 @@
+/*
+ * 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.jasper.compiler;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.servlet.jsp.tagext.FunctionInfo;
+import javax.servlet.jsp.tagext.TagFileInfo;
+import javax.servlet.jsp.tagext.TagInfo;
+import javax.servlet.jsp.tagext.TagLibraryInfo;
+
+import org.apache.jasper.JasperException;
+import org.apache.jasper.JspCompilationContext;
+import org.apache.jasper.xmlparser.ParserUtils;
+import org.apache.jasper.xmlparser.TreeNode;
+
+/**
+ * Class responsible for generating an implicit tag library containing tag
+ * handlers corresponding to the tag files in "/WEB-INF/tags/" or a
+ * subdirectory of it.
+ *
+ * @author Jan Luehe
+ */
+class ImplicitTagLibraryInfo extends TagLibraryInfo {
+
+ private static final String WEB_INF_TAGS = "/WEB-INF/tags";
+ private static final String TAG_FILE_SUFFIX = ".tag";
+ private static final String TAGX_FILE_SUFFIX = ".tagx";
+ private static final String TAGS_SHORTNAME = "tags";
+ private static final String TLIB_VERSION = "1.0";
+ private static final String JSP_VERSION = "2.0";
+ private static final String IMPLICIT_TLD = "implicit.tld";
+
+ // Maps tag names to tag file paths
+ private Hashtable tagFileMap;
+
+ private ParserController pc;
+ private PageInfo pi;
+ private Vector vec;
+
+ /**
+ * Constructor.
+ */
+ public ImplicitTagLibraryInfo(JspCompilationContext ctxt,
+ ParserController pc,
+ PageInfo pi,
+ String prefix,
+ String tagdir,
+ ErrorDispatcher err) throws JasperException {
+ super(prefix, null);
+ this.pc = pc;
+ this.pi = pi;
+ this.tagFileMap = new Hashtable();
+ this.vec = new Vector();
+
+ // Implicit tag libraries have no functions:
+ this.functions = new FunctionInfo[0];
+
+ tlibversion = TLIB_VERSION;
+ jspversion = JSP_VERSION;
+
+ if (!tagdir.startsWith(WEB_INF_TAGS)) {
+ err.jspError("jsp.error.invalid.tagdir", tagdir);
+ }
+
+ // Determine the value of the <short-name> subelement of the
+ // "imaginary" <taglib> element
+ if (tagdir.equals(WEB_INF_TAGS)
+ || tagdir.equals( WEB_INF_TAGS + "/")) {
+ shortname = TAGS_SHORTNAME;
+ } else {
+ shortname = tagdir.substring(WEB_INF_TAGS.length());
+ shortname = shortname.replace('/', '-');
+ }
+
+ // Populate mapping of tag names to tag file paths
+ Set dirList = ctxt.getResourcePaths(tagdir);
+ if (dirList != null) {
+ Iterator it = dirList.iterator();
+ while (it.hasNext()) {
+ String path = (String) it.next();
+ if (path.endsWith(TAG_FILE_SUFFIX)
+ || path.endsWith(TAGX_FILE_SUFFIX)) {
+ /*
+ * Use the filename of the tag file, without the .tag or
+ * .tagx extension, respectively, as the <name> subelement
+ * of the "imaginary" <tag-file> element
+ */
+ String suffix = path.endsWith(TAG_FILE_SUFFIX) ?
+ TAG_FILE_SUFFIX : TAGX_FILE_SUFFIX;
+ String tagName = path.substring(path.lastIndexOf("/") + 1);
+ tagName = tagName.substring(0,
+ tagName.lastIndexOf(suffix));
+ tagFileMap.put(tagName, path);
+ } else if (path.endsWith(IMPLICIT_TLD)) {
+ InputStream in = null;
+ try {
+ in = ctxt.getResourceAsStream(path);
+ if (in != null) {
+
+ // Add implicit TLD to dependency list
+ if (pi != null) {
+ pi.addDependant(path);
+ }
+
+ ParserUtils pu = new ParserUtils();
+ TreeNode tld = pu.parseXMLDocument(uri, in);
+
+ if (tld.findAttribute("version") != null) {
+ 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)) {
+ // Ignore
+ } else {
+ // All other elements are invalid
+ err.jspError("jsp.error.invalid.implicit", path);
+ }
+ }
+ try {
+ double version = Double.parseDouble(this.jspversion);
+ if (version < 2.0) {
+ err.jspError("jsp.error.invalid.implicit.version", path);
+ }
+ } catch (NumberFormatException e) {
+ err.jspError("jsp.error.invalid.implicit.version", path);
+ }
+ }
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (Throwable t) {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Checks to see if the given tag name maps to a tag file path,
+ * and if so, parses the corresponding tag file.
+ *
+ * @return The TagFileInfo corresponding to the given tag name, or null if
+ * the given tag name is not implemented as a tag file
+ */
+ public TagFileInfo getTagFile(String shortName) {
+
+ TagFileInfo tagFile = super.getTagFile(shortName);
+ if (tagFile == null) {
+ String path = (String) tagFileMap.get(shortName);
+ if (path == null) {
+ return null;
+ }
+
+ TagInfo tagInfo = null;
+ try {
+ tagInfo = TagFileProcessor.parseTagFileDirectives(pc,
+ shortName,
+ path,
+ pc.getJspCompilationContext().getTagFileJarUrl(path),
+ this);
+ } catch (JasperException je) {
+ throw new RuntimeException(je.toString(), je);
+ }
+
+ tagFile = new TagFileInfo(shortName, path, tagInfo);
+ vec.addElement(tagFile);
+
+ this.tagFiles = new TagFileInfo[vec.size()];
+ vec.copyInto(this.tagFiles);
+ }
+
+ return tagFile;
+ }
+
+ public TagLibraryInfo[] getTagLibraryInfos() {
+ Collection coll = pi.getTaglibs();
+ return (TagLibraryInfo[]) coll.toArray(new TagLibraryInfo[0]);
+ }
+
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JDTCompiler.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JDTCompiler.java?rev=819435&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JDTCompiler.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JDTCompiler.java Mon Sep 28 00:43:34 2009
@@ -0,0 +1,460 @@
+/*
+ * 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.jasper.compiler;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.jasper.JasperException;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.CompilationResult;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
+import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
+import org.eclipse.jdt.internal.compiler.IProblemFactory;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+
+/**
+ * JDT class compiler. This compiler will load source dependencies from the
+ * context classloader, reducing dramatically disk access during
+ * the compilation process.
+ *
+ * @author Cocoon2
+ * @author Remy Maucherat
+ */
+public class JDTCompiler extends org.apache.jasper.compiler.Compiler {
+
+
+ /**
+ * 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();
+ }
+
+ final String sourceFile = ctxt.getServletJavaFileName();
+ final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
+ String packageName = ctxt.getServletPackageName();
+ final String targetClassName =
+ ((packageName.length() != 0) ? (packageName + ".") : "")
+ + ctxt.getServletClassName();
+ final ClassLoader classLoader = ctxt.getJspLoader();
+ String[] fileNames = new String[] {sourceFile};
+ String[] classNames = new String[] {targetClassName};
+ final ArrayList problemList = new ArrayList();
+
+ class CompilationUnit implements ICompilationUnit {
+
+ String className;
+ String sourceFile;
+
+ CompilationUnit(String sourceFile, String className) {
+ this.className = className;
+ this.sourceFile = sourceFile;
+ }
+
+ public char[] getFileName() {
+ return sourceFile.toCharArray();
+ }
+
+ public char[] getContents() {
+ char[] result = null;
+ FileInputStream is = null;
+ try {
+ is = new FileInputStream(sourceFile);
+ Reader reader =
+ new BufferedReader(new InputStreamReader(is, ctxt.getOptions().getJavaEncoding()));
+ if (reader != null) {
+ char[] chars = new char[8192];
+ StringBuffer buf = new StringBuffer();
+ int count;
+ while ((count = reader.read(chars, 0,
+ chars.length)) > 0) {
+ buf.append(chars, 0, count);
+ }
+ result = new char[buf.length()];
+ buf.getChars(0, result.length, result, 0);
+ }
+ } catch (IOException e) {
+ log.error("Compilation error", e);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException exc) {
+ // Ignore
+ }
+ }
+ }
+ return result;
+ }
+
+ public char[] getMainTypeName() {
+ int dot = className.lastIndexOf('.');
+ if (dot > 0) {
+ return className.substring(dot + 1).toCharArray();
+ }
+ return className.toCharArray();
+ }
+
+ public char[][] getPackageName() {
+ StringTokenizer izer =
+ new StringTokenizer(className, ".");
+ char[][] result = new char[izer.countTokens()-1][];
+ for (int i = 0; i < result.length; i++) {
+ String tok = izer.nextToken();
+ result[i] = tok.toCharArray();
+ }
+ return result;
+ }
+ }
+
+ final INameEnvironment env = new INameEnvironment() {
+
+ public NameEnvironmentAnswer
+ findType(char[][] compoundTypeName) {
+ String result = "";
+ String sep = "";
+ for (int i = 0; i < compoundTypeName.length; i++) {
+ result += sep;
+ result += new String(compoundTypeName[i]);
+ sep = ".";
+ }
+ return findType(result);
+ }
+
+ public NameEnvironmentAnswer
+ findType(char[] typeName,
+ char[][] packageName) {
+ String result = "";
+ String sep = "";
+ for (int i = 0; i < packageName.length; i++) {
+ result += sep;
+ result += new String(packageName[i]);
+ sep = ".";
+ }
+ result += sep;
+ result += new String(typeName);
+ return findType(result);
+ }
+
+ private NameEnvironmentAnswer findType(String className) {
+
+ InputStream is = null;
+ try {
+ if (className.equals(targetClassName)) {
+ ICompilationUnit compilationUnit =
+ new CompilationUnit(sourceFile, className);
+ return
+ new NameEnvironmentAnswer(compilationUnit, null);
+ }
+ String resourceName =
+ className.replace('.', '/') + ".class";
+ is = classLoader.getResourceAsStream(resourceName);
+ if (is != null) {
+ byte[] classBytes;
+ byte[] buf = new byte[8192];
+ ByteArrayOutputStream baos =
+ new ByteArrayOutputStream(buf.length);
+ int count;
+ while ((count = is.read(buf, 0, buf.length)) > 0) {
+ baos.write(buf, 0, count);
+ }
+ baos.flush();
+ classBytes = baos.toByteArray();
+ char[] fileName = className.toCharArray();
+ ClassFileReader classFileReader =
+ new ClassFileReader(classBytes, fileName,
+ true);
+ return
+ new NameEnvironmentAnswer(classFileReader, null);
+ }
+ } catch (IOException exc) {
+ log.error("Compilation error", exc);
+ } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException exc) {
+ log.error("Compilation error", exc);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException exc) {
+ // Ignore
+ }
+ }
+ }
+ return null;
+ }
+
+ private boolean isPackage(String result) {
+ if (result.equals(targetClassName)) {
+ return false;
+ }
+ String resourceName = result.replace('.', '/') + ".class";
+ InputStream is =
+ classLoader.getResourceAsStream(resourceName);
+ return is == null;
+ }
+
+ public boolean isPackage(char[][] parentPackageName,
+ char[] packageName) {
+ String result = "";
+ String sep = "";
+ if (parentPackageName != null) {
+ for (int i = 0; i < parentPackageName.length; i++) {
+ result += sep;
+ String str = new String(parentPackageName[i]);
+ result += str;
+ sep = ".";
+ }
+ }
+ String str = new String(packageName);
+ if (Character.isUpperCase(str.charAt(0))) {
+ if (!isPackage(result)) {
+ return false;
+ }
+ }
+ result += sep;
+ result += str;
+ return isPackage(result);
+ }
+
+ public void cleanup() {
+ }
+
+ };
+
+ final IErrorHandlingPolicy policy =
+ DefaultErrorHandlingPolicies.proceedWithAllProblems();
+
+ final Map settings = new HashMap();
+ settings.put(CompilerOptions.OPTION_LineNumberAttribute,
+ CompilerOptions.GENERATE);
+ settings.put(CompilerOptions.OPTION_SourceFileAttribute,
+ CompilerOptions.GENERATE);
+ settings.put(CompilerOptions.OPTION_ReportDeprecation,
+ CompilerOptions.IGNORE);
+ if (ctxt.getOptions().getJavaEncoding() != null) {
+ settings.put(CompilerOptions.OPTION_Encoding,
+ ctxt.getOptions().getJavaEncoding());
+ }
+ if (ctxt.getOptions().getClassDebugInfo()) {
+ settings.put(CompilerOptions.OPTION_LocalVariableAttribute,
+ CompilerOptions.GENERATE);
+ }
+
+ // Source JVM
+ if(ctxt.getOptions().getCompilerSourceVM() != null) {
+ String opt = ctxt.getOptions().getCompilerSourceVM();
+ if(opt.equals("1.1")) {
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_1);
+ } else if(opt.equals("1.2")) {
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_2);
+ } else if(opt.equals("1.3")) {
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_3);
+ } else if(opt.equals("1.4")) {
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_4);
+ } else if(opt.equals("1.5")) {
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_5);
+ } else if(opt.equals("1.6")) {
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_6);
+ } else if(opt.equals("1.7")) {
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_7);
+ } else {
+ log.warn("Unknown source VM " + opt + " ignored.");
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_5);
+ }
+ } else {
+ // Default to 1.5
+ settings.put(CompilerOptions.OPTION_Source,
+ CompilerOptions.VERSION_1_5);
+ }
+
+ // Target JVM
+ if(ctxt.getOptions().getCompilerTargetVM() != null) {
+ String opt = ctxt.getOptions().getCompilerTargetVM();
+ if(opt.equals("1.1")) {
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_1);
+ } else if(opt.equals("1.2")) {
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_2);
+ } else if(opt.equals("1.3")) {
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_3);
+ } else if(opt.equals("1.4")) {
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_4);
+ } else if(opt.equals("1.5")) {
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_5);
+ settings.put(CompilerOptions.OPTION_Compliance,
+ CompilerOptions.VERSION_1_5);
+ } else if(opt.equals("1.6")) {
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_6);
+ settings.put(CompilerOptions.OPTION_Compliance,
+ CompilerOptions.VERSION_1_6);
+ } else if(opt.equals("1.7")) {
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_7);
+ settings.put(CompilerOptions.OPTION_Compliance,
+ CompilerOptions.VERSION_1_7);
+ } else {
+ log.warn("Unknown target VM " + opt + " ignored.");
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_5);
+ }
+ } else {
+ // Default to 1.5
+ settings.put(CompilerOptions.OPTION_TargetPlatform,
+ CompilerOptions.VERSION_1_5);
+ settings.put(CompilerOptions.OPTION_Compliance,
+ CompilerOptions.VERSION_1_5);
+ }
+
+ final IProblemFactory problemFactory =
+ new DefaultProblemFactory(Locale.getDefault());
+
+ final ICompilerRequestor requestor = new ICompilerRequestor() {
+ public void acceptResult(CompilationResult result) {
+ try {
+ if (result.hasProblems()) {
+ IProblem[] problems = result.getProblems();
+ for (int i = 0; i < problems.length; i++) {
+ IProblem problem = problems[i];
+ if (problem.isError()) {
+ String name =
+ new String(problems[i].getOriginatingFileName());
+ try {
+ problemList.add(ErrorDispatcher.createJavacError
+ (name, pageNodes, new StringBuffer(problem.getMessage()),
+ problem.getSourceLineNumber(), ctxt));
+ } catch (JasperException e) {
+ log.error("Error visiting node", e);
+ }
+ }
+ }
+ }
+ if (problemList.isEmpty()) {
+ ClassFile[] classFiles = result.getClassFiles();
+ for (int i = 0; i < classFiles.length; i++) {
+ ClassFile classFile = classFiles[i];
+ char[][] compoundName =
+ classFile.getCompoundName();
+ String className = "";
+ String sep = "";
+ for (int j = 0;
+ j < compoundName.length; j++) {
+ className += sep;
+ className += new String(compoundName[j]);
+ sep = ".";
+ }
+ byte[] bytes = classFile.getBytes();
+ String outFile = outputDir + "/" +
+ className.replace('.', '/') + ".class";
+ FileOutputStream fout =
+ new FileOutputStream(outFile);
+ BufferedOutputStream bos =
+ new BufferedOutputStream(fout);
+ bos.write(bytes);
+ bos.close();
+ }
+ }
+ } catch (IOException exc) {
+ log.error("Compilation error", exc);
+ }
+ }
+ };
+
+ ICompilationUnit[] compilationUnits =
+ new ICompilationUnit[classNames.length];
+ for (int i = 0; i < compilationUnits.length; i++) {
+ String className = classNames[i];
+ compilationUnits[i] = new CompilationUnit(fileNames[i], className);
+ }
+ Compiler compiler = new Compiler(env,
+ policy,
+ settings,
+ requestor,
+ problemFactory,
+ true);
+ compiler.compile(compilationUnits);
+
+ if (!ctxt.keepGenerated()) {
+ File javaFile = new File(ctxt.getServletJavaFileName());
+ javaFile.delete();
+ }
+
+ if (!problemList.isEmpty()) {
+ JavacErrorDetail[] jeds =
+ (JavacErrorDetail[]) problemList.toArray(new JavacErrorDetail[0]);
+ errDispatcher.javacError(jeds);
+ }
+
+ if( log.isDebugEnabled() ) {
+ long t2=System.currentTimeMillis();
+ log.debug("Compiled " + ctxt.getServletJavaFileName() + " "
+ + (t2-t1) + "ms");
+ }
+
+ if (ctxt.isPrototypeMode()) {
+ return;
+ }
+
+ // JSR45 Support
+ if (! options.isSmapSuppressed()) {
+ SmapUtil.installSmap(smap);
+ }
+
+ }
+
+
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JasperTagInfo.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JasperTagInfo.java?rev=819435&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JasperTagInfo.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JasperTagInfo.java Mon Sep 28 00:43:34 2009
@@ -0,0 +1,58 @@
+/*
+ * 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.jasper.compiler;
+
+import javax.servlet.jsp.tagext.*;
+
+/**
+ * TagInfo extension used by tag handlers that are implemented via tag files.
+ * This class provides access to the name of the Map used to store the
+ * dynamic attribute names and values passed to the custom action invocation.
+ * This information is used by the code generator.
+ */
+class JasperTagInfo extends TagInfo {
+
+ private String dynamicAttrsMapName;
+
+ public JasperTagInfo(String tagName,
+ String tagClassName,
+ String bodyContent,
+ String infoString,
+ TagLibraryInfo taglib,
+ TagExtraInfo tagExtraInfo,
+ TagAttributeInfo[] attributeInfo,
+ String displayName,
+ String smallIcon,
+ String largeIcon,
+ TagVariableInfo[] tvi,
+ String mapName) {
+
+ super(tagName, tagClassName, bodyContent, infoString, taglib,
+ tagExtraInfo, attributeInfo, displayName, smallIcon, largeIcon,
+ tvi);
+ this.dynamicAttrsMapName = mapName;
+ }
+
+ public String getDynamicAttributesMapName() {
+ return dynamicAttrsMapName;
+ }
+
+ public boolean hasDynamicAttributes() {
+ return dynamicAttrsMapName != null;
+ }
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JavacErrorDetail.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JavacErrorDetail.java?rev=819435&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JavacErrorDetail.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JavacErrorDetail.java Mon Sep 28 00:43:34 2009
@@ -0,0 +1,232 @@
+/*
+ * 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.jasper.compiler;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jasper.JspCompilationContext;
+
+/**
+ * Class providing details about a javac compilation error.
+ *
+ * @author Jan Luehe
+ * @author Kin-man Chung
+ */
+public class JavacErrorDetail {
+
+ private String javaFileName;
+ private int javaLineNum;
+ private String jspFileName;
+ private int jspBeginLineNum;
+ private StringBuffer errMsg;
+ private String jspExtract = null;
+
+ /**
+ * Constructor.
+ *
+ * @param javaFileName The name of the Java file in which the
+ * compilation error occurred
+ * @param javaLineNum The compilation error line number
+ * @param errMsg The compilation error message
+ */
+ public JavacErrorDetail(String javaFileName,
+ int javaLineNum,
+ StringBuffer errMsg) {
+
+ this.javaFileName = javaFileName;
+ this.javaLineNum = javaLineNum;
+ this.errMsg = errMsg;
+ this.jspBeginLineNum = -1;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param javaFileName The name of the Java file in which the
+ * compilation error occurred
+ * @param javaLineNum The compilation error line number
+ * @param jspFileName The name of the JSP file from which the Java source
+ * file was generated
+ * @param jspBeginLineNum The start line number of the JSP element
+ * responsible for the compilation error
+ * @param errMsg The compilation error message
+ */
+ public JavacErrorDetail(String javaFileName,
+ int javaLineNum,
+ String jspFileName,
+ int jspBeginLineNum,
+ StringBuffer errMsg) {
+
+ this(javaFileName, javaLineNum, jspFileName, jspBeginLineNum, errMsg,
+ null);
+ }
+
+ public JavacErrorDetail(String javaFileName,
+ int javaLineNum,
+ String jspFileName,
+ int jspBeginLineNum,
+ StringBuffer errMsg,
+ JspCompilationContext ctxt) {
+
+ this(javaFileName, javaLineNum, errMsg);
+ this.jspFileName = jspFileName;
+ this.jspBeginLineNum = jspBeginLineNum;
+
+ if (jspBeginLineNum > 0 && ctxt != null) {
+ InputStream is = null;
+ FileInputStream fis = null;
+
+ try {
+ // Read both files in, so we can inspect them
+ is = ctxt.getResourceAsStream(jspFileName);
+ String[] jspLines = readFile(is);
+
+ fis = new FileInputStream(ctxt.getServletJavaFileName());
+ String[] javaLines = readFile(fis);
+
+ // If the line contains the opening of a multi-line scriptlet
+ // block, then the JSP line number we got back is probably
+ // faulty. Scan forward to match the java line...
+ if (jspLines[jspBeginLineNum-1].lastIndexOf("<%") >
+ jspLines[jspBeginLineNum-1].lastIndexOf("%>")) {
+ String javaLine = javaLines[javaLineNum-1].trim();
+
+ for (int i=jspBeginLineNum-1; i<jspLines.length; i++) {
+ if (jspLines[i].indexOf(javaLine) != -1) {
+ // Update jsp line number
+ this.jspBeginLineNum = i+1;
+ break;
+ }
+ }
+ }
+
+ // copy out a fragment of JSP to display to the user
+ StringBuffer fragment = new StringBuffer(1024);
+ int startIndex = Math.max(0, this.jspBeginLineNum-1-3);
+ int endIndex = Math.min(
+ jspLines.length-1, this.jspBeginLineNum-1+3);
+
+ for (int i=startIndex;i<=endIndex; ++i) {
+ fragment.append(i+1);
+ fragment.append(": ");
+ fragment.append(jspLines[i]);
+ fragment.append("\n");
+ }
+ jspExtract = fragment.toString();
+
+ } catch (IOException ioe) {
+ // Can't read files - ignore
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ioe) {
+ // Ignore
+ }
+ }
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException ioe) {
+ // Ignore
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the name of the Java source file in which the compilation error
+ * occurred.
+ *
+ * @return Java source file name
+ */
+ public String getJavaFileName() {
+ return this.javaFileName;
+ }
+
+ /**
+ * Gets the compilation error line number.
+ *
+ * @return Compilation error line number
+ */
+ public int getJavaLineNumber() {
+ return this.javaLineNum;
+ }
+
+ /**
+ * Gets the name of the JSP file from which the Java source file was
+ * generated.
+ *
+ * @return JSP file from which the Java source file was generated.
+ */
+ public String getJspFileName() {
+ return this.jspFileName;
+ }
+
+ /**
+ * Gets the start line number (in the JSP file) of the JSP element
+ * responsible for the compilation error.
+ *
+ * @return Start line number of the JSP element responsible for the
+ * compilation error
+ */
+ public int getJspBeginLineNumber() {
+ return this.jspBeginLineNum;
+ }
+
+ /**
+ * Gets the compilation error message.
+ *
+ * @return Compilation error message
+ */
+ public String getErrorMessage() {
+ return this.errMsg.toString();
+ }
+
+ /**
+ * Gets the extract of the JSP that corresponds to this message.
+ *
+ * @return Extract of JSP where error occurred
+ */
+ public String getJspExtract() {
+ return this.jspExtract;
+ }
+
+ /**
+ * Reads a text file from an input stream into a String[]. Used to read in
+ * the JSP and generated Java file when generating error messages.
+ */
+ private String[] readFile(InputStream s) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(s));
+ List lines = new ArrayList();
+ String line;
+
+ while ( (line = reader.readLine()) != null ) {
+ lines.add(line);
+ }
+
+ return (String[]) lines.toArray( new String[lines.size()] );
+ }
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspConfig.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspConfig.java?rev=819435&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspConfig.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/compiler/JspConfig.java Mon Sep 28 00:43:34 2009
@@ -0,0 +1,531 @@
+/*
+ * 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.jasper.compiler;
+
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Vector;
+import java.net.URL;
+
+import javax.servlet.ServletContext;
+
+import org.apache.jasper.JasperException;
+import org.apache.jasper.xmlparser.ParserUtils;
+import org.apache.jasper.xmlparser.TreeNode;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.xml.sax.InputSource;
+
+/**
+ * Handles the jsp-config element in WEB_INF/web.xml. This is used
+ * for specifying the JSP configuration information on a JSP page
+ *
+ * @author Kin-man Chung
+ * @author Remy Maucherat
+ */
+
+public class JspConfig {
+
+ private static final String WEB_XML = "/WEB-INF/web.xml";
+
+ // Logger
+ private Log log = LogFactory.getLog(JspConfig.class);
+
+ private Vector jspProperties = null;
+ private ServletContext ctxt;
+ private boolean initialized = false;
+
+ private String defaultIsXml = null; // unspecified
+ private String defaultIsELIgnored = null; // unspecified
+ private String defaultIsScriptingInvalid = null;
+ private String defaultDeferedSyntaxAllowedAsLiteral = null;
+ private String defaultTrimDirectiveWhitespaces = null;
+ private JspProperty defaultJspProperty;
+
+ public JspConfig(ServletContext ctxt) {
+ this.ctxt = ctxt;
+ }
+
+ private double getVersion(TreeNode webApp) {
+ String v = webApp.findAttribute("version");
+ if (v != null) {
+ try {
+ return Double.parseDouble(v);
+ } catch (NumberFormatException e) {
+ }
+ }
+ return 2.3;
+ }
+
+ private void processWebDotXml(ServletContext ctxt) throws JasperException {
+
+ InputStream is = null;
+
+ try {
+ URL uri = ctxt.getResource(WEB_XML);
+ if (uri == null) {
+ // no web.xml
+ return;
+ }
+
+ is = uri.openStream();
+ InputSource ip = new InputSource(is);
+ ip.setSystemId(uri.toExternalForm());
+
+ ParserUtils pu = new ParserUtils();
+ TreeNode webApp = pu.parseXMLDocument(WEB_XML, ip);
+
+ if (webApp == null
+ || getVersion(webApp) < 2.4) {
+ defaultIsELIgnored = "true";
+ return;
+ }
+ TreeNode jspConfig = webApp.findChild("jsp-config");
+ if (jspConfig == null) {
+ return;
+ }
+
+ jspProperties = new Vector();
+ Iterator jspPropertyList = jspConfig.findChildren("jsp-property-group");
+ while (jspPropertyList.hasNext()) {
+
+ TreeNode element = (TreeNode) jspPropertyList.next();
+ Iterator list = element.findChildren();
+
+ Vector urlPatterns = new Vector();
+ String pageEncoding = null;
+ String scriptingInvalid = null;
+ String elIgnored = null;
+ String isXml = null;
+ Vector includePrelude = new Vector();
+ Vector includeCoda = new Vector();
+ String deferredSyntaxAllowedAsLiteral = null;
+ String trimDirectiveWhitespaces = null;
+
+ while (list.hasNext()) {
+
+ element = (TreeNode) list.next();
+ String tname = element.getName();
+
+ if ("url-pattern".equals(tname))
+ urlPatterns.addElement( element.getBody() );
+ else if ("page-encoding".equals(tname))
+ pageEncoding = element.getBody();
+ else if ("is-xml".equals(tname))
+ isXml = element.getBody();
+ else if ("el-ignored".equals(tname))
+ elIgnored = element.getBody();
+ else if ("scripting-invalid".equals(tname))
+ scriptingInvalid = element.getBody();
+ else if ("include-prelude".equals(tname))
+ includePrelude.addElement(element.getBody());
+ else if ("include-coda".equals(tname))
+ includeCoda.addElement(element.getBody());
+ else if ("deferred-syntax-allowed-as-literal".equals(tname))
+ deferredSyntaxAllowedAsLiteral = element.getBody();
+ else if ("trim-directive-whitespaces".equals(tname))
+ trimDirectiveWhitespaces = element.getBody();
+ }
+
+ if (urlPatterns.size() == 0) {
+ continue;
+ }
+
+ // Add one JspPropertyGroup for each URL Pattern. This makes
+ // the matching logic easier.
+ for( int p = 0; p < urlPatterns.size(); p++ ) {
+ String urlPattern = (String)urlPatterns.elementAt( p );
+ String path = null;
+ String extension = null;
+
+ if (urlPattern.indexOf('*') < 0) {
+ // Exact match
+ path = urlPattern;
+ } else {
+ int i = urlPattern.lastIndexOf('/');
+ String file;
+ if (i >= 0) {
+ path = urlPattern.substring(0,i+1);
+ file = urlPattern.substring(i+1);
+ } else {
+ file = urlPattern;
+ }
+
+ // pattern must be "*", or of the form "*.jsp"
+ if (file.equals("*")) {
+ extension = "*";
+ } else if (file.startsWith("*.")) {
+ extension = file.substring(file.indexOf('.')+1);
+ }
+
+ // The url patterns are reconstructed as the follwoing:
+ // path != null, extension == null: / or /foo/bar.ext
+ // path == null, extension != null: *.ext
+ // path != null, extension == "*": /foo/*
+ boolean isStar = "*".equals(extension);
+ if ((path == null && (extension == null || isStar))
+ || (path != null && !isStar)) {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage(
+ "jsp.warning.bad.urlpattern.propertygroup",
+ urlPattern));
+ }
+ continue;
+ }
+ }
+
+ JspProperty property = new JspProperty(isXml,
+ elIgnored,
+ scriptingInvalid,
+ pageEncoding,
+ includePrelude,
+ includeCoda,
+ deferredSyntaxAllowedAsLiteral,
+ trimDirectiveWhitespaces);
+ JspPropertyGroup propertyGroup =
+ new JspPropertyGroup(path, extension, property);
+
+ jspProperties.addElement(propertyGroup);
+ }
+ }
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (Throwable t) {}
+ }
+ }
+ }
+
+ private void init() throws JasperException {
+
+ if (!initialized) {
+ processWebDotXml(ctxt);
+ defaultJspProperty = new JspProperty(defaultIsXml,
+ defaultIsELIgnored,
+ defaultIsScriptingInvalid,
+ null, null, null, defaultDeferedSyntaxAllowedAsLiteral,
+ defaultTrimDirectiveWhitespaces);
+ initialized = true;
+ }
+ }
+
+ /**
+ * Select the property group that has more restrictive url-pattern.
+ * In case of tie, select the first.
+ */
+ private JspPropertyGroup selectProperty(JspPropertyGroup prev,
+ JspPropertyGroup curr) {
+ if (prev == null) {
+ return curr;
+ }
+ if (prev.getExtension() == null) {
+ // exact match
+ return prev;
+ }
+ if (curr.getExtension() == null) {
+ // exact match
+ return curr;
+ }
+ String prevPath = prev.getPath();
+ String currPath = curr.getPath();
+ if (prevPath == null && currPath == null) {
+ // Both specifies a *.ext, keep the first one
+ return prev;
+ }
+ if (prevPath == null && currPath != null) {
+ return curr;
+ }
+ if (prevPath != null && currPath == null) {
+ return prev;
+ }
+ if (prevPath.length() >= currPath.length()) {
+ return prev;
+ }
+ return curr;
+ }
+
+
+ /**
+ * Find a property that best matches the supplied resource.
+ * @param uri the resource supplied.
+ * @return a JspProperty indicating the best match, or some default.
+ */
+ public JspProperty findJspProperty(String uri) throws JasperException {
+
+ init();
+
+ // JSP Configuration settings do not apply to tag files
+ if (jspProperties == null || uri.endsWith(".tag")
+ || uri.endsWith(".tagx")) {
+ return defaultJspProperty;
+ }
+
+ String uriPath = null;
+ int index = uri.lastIndexOf('/');
+ if (index >=0 ) {
+ uriPath = uri.substring(0, index+1);
+ }
+ String uriExtension = null;
+ index = uri.lastIndexOf('.');
+ if (index >=0) {
+ uriExtension = uri.substring(index+1);
+ }
+
+ Vector includePreludes = new Vector();
+ Vector includeCodas = new Vector();
+
+ JspPropertyGroup isXmlMatch = null;
+ JspPropertyGroup elIgnoredMatch = null;
+ JspPropertyGroup scriptingInvalidMatch = null;
+ JspPropertyGroup pageEncodingMatch = null;
+ JspPropertyGroup deferedSyntaxAllowedAsLiteralMatch = null;
+ JspPropertyGroup trimDirectiveWhitespacesMatch = null;
+
+ Iterator iter = jspProperties.iterator();
+ while (iter.hasNext()) {
+
+ JspPropertyGroup jpg = (JspPropertyGroup) iter.next();
+ JspProperty jp = jpg.getJspProperty();
+
+ // (arrays will be the same length)
+ String extension = jpg.getExtension();
+ String path = jpg.getPath();
+
+ if (extension == null) {
+ // exact match pattern: /a/foo.jsp
+ if (!uri.equals(path)) {
+ // not matched;
+ continue;
+ }
+ } else {
+ // Matching patterns *.ext or /p/*
+ if (path != null && uriPath != null &&
+ ! uriPath.startsWith(path)) {
+ // not matched
+ continue;
+ }
+ if (!extension.equals("*") &&
+ !extension.equals(uriExtension)) {
+ // not matched
+ continue;
+ }
+ }
+ // We have a match
+ // Add include-preludes and include-codas
+ if (jp.getIncludePrelude() != null) {
+ includePreludes.addAll(jp.getIncludePrelude());
+ }
+ if (jp.getIncludeCoda() != null) {
+ includeCodas.addAll(jp.getIncludeCoda());
+ }
+
+ // If there is a previous match for the same property, remember
+ // the one that is more restrictive.
+ if (jp.isXml() != null) {
+ isXmlMatch = selectProperty(isXmlMatch, jpg);
+ }
+ if (jp.isELIgnored() != null) {
+ elIgnoredMatch = selectProperty(elIgnoredMatch, jpg);
+ }
+ if (jp.isScriptingInvalid() != null) {
+ scriptingInvalidMatch =
+ selectProperty(scriptingInvalidMatch, jpg);
+ }
+ if (jp.getPageEncoding() != null) {
+ pageEncodingMatch = selectProperty(pageEncodingMatch, jpg);
+ }
+ if (jp.isDeferedSyntaxAllowedAsLiteral() != null) {
+ deferedSyntaxAllowedAsLiteralMatch =
+ selectProperty(deferedSyntaxAllowedAsLiteralMatch, jpg);
+ }
+ if (jp.isTrimDirectiveWhitespaces() != null) {
+ trimDirectiveWhitespacesMatch =
+ selectProperty(trimDirectiveWhitespacesMatch, jpg);
+ }
+ }
+
+
+ String isXml = defaultIsXml;
+ String isELIgnored = defaultIsELIgnored;
+ String isScriptingInvalid = defaultIsScriptingInvalid;
+ String pageEncoding = null;
+ String isDeferedSyntaxAllowedAsLiteral = defaultDeferedSyntaxAllowedAsLiteral;
+ String isTrimDirectiveWhitespaces = defaultTrimDirectiveWhitespaces;
+
+ if (isXmlMatch != null) {
+ isXml = isXmlMatch.getJspProperty().isXml();
+ }
+ if (elIgnoredMatch != null) {
+ isELIgnored = elIgnoredMatch.getJspProperty().isELIgnored();
+ }
+ if (scriptingInvalidMatch != null) {
+ isScriptingInvalid =
+ scriptingInvalidMatch.getJspProperty().isScriptingInvalid();
+ }
+ if (pageEncodingMatch != null) {
+ pageEncoding = pageEncodingMatch.getJspProperty().getPageEncoding();
+ }
+ if (deferedSyntaxAllowedAsLiteralMatch != null) {
+ isDeferedSyntaxAllowedAsLiteral =
+ deferedSyntaxAllowedAsLiteralMatch.getJspProperty().isDeferedSyntaxAllowedAsLiteral();
+ }
+ if (trimDirectiveWhitespacesMatch != null) {
+ isTrimDirectiveWhitespaces =
+ trimDirectiveWhitespacesMatch.getJspProperty().isTrimDirectiveWhitespaces();
+ }
+
+ return new JspProperty(isXml, isELIgnored, isScriptingInvalid,
+ pageEncoding, includePreludes, includeCodas,
+ isDeferedSyntaxAllowedAsLiteral, isTrimDirectiveWhitespaces);
+ }
+
+ /**
+ * To find out if an uri matches an url pattern in jsp config. If so,
+ * then the uri is a JSP page. This is used primarily for jspc.
+ */
+ public boolean isJspPage(String uri) throws JasperException {
+
+ init();
+ if (jspProperties == null) {
+ return false;
+ }
+
+ String uriPath = null;
+ int index = uri.lastIndexOf('/');
+ if (index >=0 ) {
+ uriPath = uri.substring(0, index+1);
+ }
+ String uriExtension = null;
+ index = uri.lastIndexOf('.');
+ if (index >=0) {
+ uriExtension = uri.substring(index+1);
+ }
+
+ Iterator iter = jspProperties.iterator();
+ while (iter.hasNext()) {
+
+ JspPropertyGroup jpg = (JspPropertyGroup) iter.next();
+ JspProperty jp = jpg.getJspProperty();
+
+ String extension = jpg.getExtension();
+ String path = jpg.getPath();
+
+ if (extension == null) {
+ if (uri.equals(path)) {
+ // There is an exact match
+ return true;
+ }
+ } else {
+ if ((path == null || path.equals(uriPath)) &&
+ (extension.equals("*") || extension.equals(uriExtension))) {
+ // Matches *, *.ext, /p/*, or /p/*.ext
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ static class JspPropertyGroup {
+ private String path;
+ private String extension;
+ private JspProperty jspProperty;
+
+ JspPropertyGroup(String path, String extension,
+ JspProperty jspProperty) {
+ this.path = path;
+ this.extension = extension;
+ this.jspProperty = jspProperty;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String getExtension() {
+ return extension;
+ }
+
+ public JspProperty getJspProperty() {
+ return jspProperty;
+ }
+ }
+
+ static public class JspProperty {
+
+ private String isXml;
+ private String elIgnored;
+ private String scriptingInvalid;
+ private String pageEncoding;
+ private Vector includePrelude;
+ private Vector includeCoda;
+ private String deferedSyntaxAllowedAsLiteral;
+ private String trimDirectiveWhitespaces;
+
+ public JspProperty(String isXml, String elIgnored,
+ String scriptingInvalid, String pageEncoding,
+ Vector includePrelude, Vector includeCoda,
+ String deferedSyntaxAllowedAsLiteral,
+ String trimDirectiveWhitespaces) {
+
+ this.isXml = isXml;
+ this.elIgnored = elIgnored;
+ this.scriptingInvalid = scriptingInvalid;
+ this.pageEncoding = pageEncoding;
+ this.includePrelude = includePrelude;
+ this.includeCoda = includeCoda;
+ this.deferedSyntaxAllowedAsLiteral = deferedSyntaxAllowedAsLiteral;
+ this.trimDirectiveWhitespaces = trimDirectiveWhitespaces;
+ }
+
+ public String isXml() {
+ return isXml;
+ }
+
+ public String isELIgnored() {
+ return elIgnored;
+ }
+
+ public String isScriptingInvalid() {
+ return scriptingInvalid;
+ }
+
+ public String getPageEncoding() {
+ return pageEncoding;
+ }
+
+ public Vector getIncludePrelude() {
+ return includePrelude;
+ }
+
+ public Vector getIncludeCoda() {
+ return includeCoda;
+ }
+
+ public String isDeferedSyntaxAllowedAsLiteral() {
+ return deferedSyntaxAllowedAsLiteral;
+ }
+
+ public String isTrimDirectiveWhitespaces() {
+ return trimDirectiveWhitespaces;
+ }
+ }
+}