kinman 2002/07/31 14:42:28 Modified: jasper2/src/share/org/apache/jasper JspCompilationContext.java jasper2/src/share/org/apache/jasper/compiler Compiler.java Generator.java JspDocumentParser.java Node.java Parser.java ParserController.java TagFileProcessor.java TagLibraryInfoImpl.java Validator.java jasper2/src/share/org/apache/jasper/resources messages.properties jasper2/src/share/org/apache/jasper/servlet JspServletWrapper.java Log: - First cut at triggering compilations of tag files on demand. Node: Not fully working yet. Implicit tag file library not tested. Use absolute path for tag file in TLD. Revision Changes Path 1.11 +43 -5 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspCompilationContext.java Index: JspCompilationContext.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/JspCompilationContext.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- JspCompilationContext.java 25 Jul 2002 22:28:45 -0000 1.10 +++ JspCompilationContext.java 31 Jul 2002 21:42:27 -0000 1.11 @@ -65,6 +65,8 @@ import java.net.*; import java.util.Set; import javax.servlet.ServletContext; +import javax.servlet.jsp.tagext.TagInfo; + import org.apache.jasper.compiler.JspRuntimeContext; import org.apache.jasper.compiler.JspReader; import org.apache.jasper.compiler.ServletWriter; @@ -116,6 +118,9 @@ protected URL [] outUrls = new URL[1]; protected Class servletClass; + protected boolean isTagFile; + protected TagInfo tagInfo; + // jspURI _must_ be relative to the context public JspCompilationContext(String jspUri, boolean isErrPage, Options options, ServletContext context, JspServletWrapper jsw, @@ -141,6 +146,17 @@ this.rctxt=rctxt; } + public JspCompilationContext(String tagfile, TagInfo tagInfo, + Options options, + ServletContext context, JspServletWrapper jsw, + JspRuntimeContext rctxt) { + + this(tagfile, false, options, context, jsw, rctxt); + this.isTagFile = true; + this.tagInfo = tagInfo; + return; + } + /* ==================== Methods to override ==================== */ /** ---------- Class path and loader ---------- */ @@ -304,6 +320,14 @@ this.isErrPage = isErrPage; } + public boolean isTagFile() { + return isTagFile; + } + + public TagInfo getTagInfo() { + return tagInfo; + } + /** * Package name for the generated class. */ @@ -351,6 +375,14 @@ return options; } + public ServletContext getServletContext() { + return context; + } + + public JspRuntimeContext getRuntimeContext() { + return rctxt; + } + /** * Path of the JSP relative to the work directory. */ @@ -503,8 +535,14 @@ rctxt.getPermissionCollection(), rctxt.getCodeSource()); - servletClass = jspLoader.loadClass( - getServletPackageName() + "." + getServletClassName()); + String className; + if (isTagFile()) { + className = tagInfo.getTagClassName(); + } else { + className = getServletPackageName() + "." + + getServletClassName(); + } + servletClass = jspLoader.loadClass(className); } catch (FileNotFoundException ex) { jspCompiler.removeGeneratedFiles(); throw ex; 1.22 +7 -3 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java Index: Compiler.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- Compiler.java 19 Jul 2002 01:13:46 -0000 1.21 +++ Compiler.java 31 Jul 2002 21:42:27 -0000 1.22 @@ -241,6 +241,10 @@ // Collect page info Collector.collect(this, pageNodes); + // Compile (if necessar) and load the tag files referenced in + // this compilation unit. + TagFileProcessor.loadTagFiles(this, pageNodes); + // generate servlet .java file Generator.generate(writer, this, pageNodes); writer.close(); 1.51 +13 -18 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java Index: Generator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- Generator.java 30 Jul 2002 22:53:38 -0000 1.50 +++ Generator.java 31 Jul 2002 21:42:27 -0000 1.51 @@ -2723,8 +2723,18 @@ */ public static void generate(ServletWriter out, Compiler compiler, Node.Nodes page) throws JasperException { + Generator gen = new Generator(out, compiler); + if (gen.ctxt.isTagFile()) { + TagInfo tagInfo = gen.ctxt.getTagInfo(); + gen.generateTagHandlerPreamble(tagInfo); + page.visit(gen.new GenerateVisitor(out, gen.methodsBuffer, null, + tagInfo)); + gen.generateTagHandlerPostamble(); + return; + } + if (gen.ctxt.getOptions().isPoolingEnabled()) { gen.compileTagHandlerPoolList(page); } @@ -2733,21 +2743,6 @@ page.visit(gen.new GenerateVisitor(out, gen.methodsBuffer, gen.fragmentHelperClass, null)); gen.generatePostamble(page); - } - - /** - * XXX - */ - public static void generateTagHandler(ServletWriter out, - Compiler compiler, - Node.Nodes page, - TagInfo tagInfo) - throws JasperException { - Generator gen = new Generator(out, compiler); - gen.generateTagHandlerPreamble(tagInfo); - page.visit(gen.new GenerateVisitor(out, gen.methodsBuffer, null, - tagInfo)); - gen.generateTagHandlerPostamble(); } /* 1.11 +17 -11 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspDocumentParser.java Index: JspDocumentParser.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/JspDocumentParser.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- JspDocumentParser.java 29 Jul 2002 22:29:01 -0000 1.10 +++ JspDocumentParser.java 31 Jul 2002 21:42:27 -0000 1.11 @@ -464,21 +464,27 @@ return null; } TagInfo tagInfo = tagLibInfo.getTag(shortName); - if (tagInfo == null) { + TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortName); + if (tagInfo == null && tagFileInfo == null) { throw new SAXException(err.getString("jsp.error.bad_tag", shortName, prefix)); } Class tagHandlerClass = null; - try { - tagHandlerClass - = ctxt.getClassLoader().loadClass(tagInfo.getTagClassName()); - } catch (Exception e) { - throw new SAXException(err.getString("jsp.error.unable.loadclass", + if (tagFileInfo == null) { + try { + tagHandlerClass + = ctxt.getClassLoader().loadClass(tagInfo.getTagClassName()); + } catch (Exception e) { + throw new SAXException(err.getString( + "jsp.error.unable.loadclass", shortName, prefix)); - } + } + } else { + tagInfo = tagFileInfo.getTagInfo(); + } return new Node.CustomTag(attrs, start, qName, prefix, shortName, - tagInfo, tagHandlerClass, parent); + tagInfo, tagFileInfo, tagHandlerClass, parent); } /* 1.23 +36 -14 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java Index: Node.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- Node.java 24 Jul 2002 22:38:43 -0000 1.22 +++ Node.java 31 Jul 2002 21:42:27 -0000 1.23 @@ -886,6 +886,7 @@ private TagData tagData; private String tagHandlerPoolName; private TagInfo tagInfo; + private TagFileInfo tagFileInfo; private Class tagHandlerClass; private VariableInfo[] varInfos; private VariableInfo[] nestedVarInfos; @@ -899,26 +900,39 @@ public CustomTag(Attributes attrs, Mark start, String name, String prefix, String shortName, - TagInfo tagInfo, Class tagHandlerClass, Node parent) { + TagInfo tagInfo, TagFileInfo tagFileInfo, + Class tagHandlerClass, Node parent) { super(attrs, start, parent); this.name = name; this.prefix = prefix; this.shortName = shortName; this.tagInfo = tagInfo; + this.tagFileInfo = tagFileInfo; this.tagHandlerClass = tagHandlerClass; this.customNestingLevel = computeCustomNestingLevel(); this.childInfo = new ChildInfo(); - this.implementsIterationTag = - IterationTag.class.isAssignableFrom(tagHandlerClass); - this.implementsBodyTag = - BodyTag.class.isAssignableFrom(tagHandlerClass); - this.implementsTryCatchFinally = - TryCatchFinally.class.isAssignableFrom(tagHandlerClass); - this.implementsSimpleTag = - SimpleTag.class.isAssignableFrom(tagHandlerClass); - this.implementsDynamicAttributes = - DynamicAttributes.class.isAssignableFrom(tagHandlerClass); + if (tagHandlerClass != null) { + this.implementsIterationTag = + IterationTag.class.isAssignableFrom(tagHandlerClass); + this.implementsBodyTag = + BodyTag.class.isAssignableFrom(tagHandlerClass); + this.implementsTryCatchFinally = + TryCatchFinally.class.isAssignableFrom(tagHandlerClass); + this.implementsSimpleTag = + SimpleTag.class.isAssignableFrom(tagHandlerClass); + this.implementsDynamicAttributes = + DynamicAttributes.class.isAssignableFrom(tagHandlerClass); + } + else if (tagFileInfo != null) { + // get the info from tag file + this.implementsIterationTag = false; + this.implementsBodyTag = false; + this.implementsTryCatchFinally = false; + this.implementsSimpleTag = true; + this.implementsDynamicAttributes = + tagInfo.hasDynamicAttributes(); + } } public void accept(Visitor v) throws JasperException { @@ -980,8 +994,16 @@ return tagInfo; } + public TagFileInfo getTagFileInfo() { + return tagFileInfo; + } + public Class getTagHandlerClass() { return tagHandlerClass; + } + + public void setTagHandlerClass(Class hc) { + tagHandlerClass = hc; } public boolean implementsIterationTag() { 1.17 +59 -45 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java Index: Parser.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Parser.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- Parser.java 29 Jul 2002 22:29:01 -0000 1.16 +++ Parser.java 31 Jul 2002 21:42:27 -0000 1.17 @@ -65,6 +65,7 @@ import java.util.Hashtable; import javax.servlet.jsp.tagext.TagLibraryInfo; import javax.servlet.jsp.tagext.TagInfo; +import javax.servlet.jsp.tagext.TagFileInfo; import org.xml.sax.Attributes; import org.xml.sax.helpers.AttributesImpl; import org.apache.jasper.Constants; @@ -415,41 +416,41 @@ String directive = null; if (reader.matches("page")) { - directive = "<%@ page"; + directive = "<%@ page"; if (isTagFile) { err.jspError(reader.mark(), "jsp.error.directive.istagfile", directive); } parsePageDirective(parent); } else if (reader.matches("include")) { - directive = "<%@ include"; + directive = "<%@ include"; parseIncludeDirective(parent); } else if (reader.matches("taglib")) { - directive = "<%@ taglib"; + directive = "<%@ taglib"; parseTaglibDirective(parent); } else if (reader.matches("tag")) { - directive = "<%@ tag"; + directive = "<%@ tag"; if (!isTagFile) { err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", directive); } parseTagDirective(parent); } else if (reader.matches("attribute")) { - directive = "<%@ attribute"; + directive = "<%@ attribute"; if (!isTagFile) { err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", directive); } parseAttributeDirective(parent); } else if (reader.matches("variable")) { - directive = "<%@ variable"; + directive = "<%@ variable"; if (!isTagFile) { err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", directive); } parseVariableDirective(parent); } else if (reader.matches("fragment-input")) { - directive = "<%@ fragment-input"; + directive = "<%@ fragment-input"; if (!isTagFile) { err.jspError(reader.mark(), "jsp.error.directive.isnottagfile", directive); @@ -512,7 +513,7 @@ start = reader.mark(); Mark stop = reader.skipUntil("--%>"); if (stop == null) { - err.jspError(start, "jsp.error.unterminated", "<%--"); + err.jspError(start, "jsp.error.unterminated", "<%--"); } new Node.Comment(reader.getText(start, stop), start, parent); @@ -525,7 +526,7 @@ start = reader.mark(); Mark stop = reader.skipUntil("%>"); if (stop == null) { - err.jspError(start, "jsp.error.unterminated", "<%!"); + err.jspError(start, "jsp.error.unterminated", "<%!"); } new Node.Declaration(parseScriptText(reader.getText(start, stop)), @@ -539,7 +540,7 @@ start = reader.mark(); Mark stop = reader.skipUntil("%>"); if (stop == null) { - err.jspError(start, "jsp.error.unterminated", "<%="); + err.jspError(start, "jsp.error.unterminated", "<%="); } new Node.Expression(parseScriptText(reader.getText(start, stop)), @@ -584,7 +585,7 @@ start = reader.mark(); Mark stop = reader.skipUntil("%>"); if (stop == null) { - err.jspError(start, "jsp.error.unterminated", "<%"); + err.jspError(start, "jsp.error.unterminated", "<%"); } new Node.Scriptlet(parseScriptText(reader.getText(start, stop)), @@ -596,7 +597,7 @@ */ private void parseParam(Node parent) throws JasperException { if (!reader.matches("<jsp:param")) { - err.jspError(reader.mark(), "jsp.error.paramexpectedonly"); + err.jspError(reader.mark(), "jsp.error.paramexpected"); } Attributes attrs = parseAttributes(); reader.skipSpaces(); @@ -718,17 +719,17 @@ // Body not allowed err.jspError(reader.mark(), "jsp.error.jspbody.emptybody.only", - "<" + tag ); + "<" + tag ); } } else { err.jspError(reader.mark(), "jsp.error.jspbody.emptybody.only", - "<" + tag ); + "<" + tag ); } } else { err.jspError(reader.mark(), "jsp.error.unterminated", - "<" + tag ); + "<" + tag ); } } @@ -782,7 +783,7 @@ if (!reader.matches(">")) { err.jspError(reader.mark(), "jsp.error.unterminated", - "<" + tag ); + "<" + tag ); } if( reader.matchesETag( tag ) ) { @@ -829,7 +830,7 @@ reader.skipSpaces(); if( !reader.matchesETag( tag ) ) { err.jspError(reader.mark(), "jsp.error.unterminated", - "<" + tag ); + "<" + tag ); } result = true; @@ -838,7 +839,7 @@ // If we have <jsp:attribute> but something other than // <jsp:body> or the end tag, translation error. err.jspError(reader.mark(), "jsp.error.jspbody.required", - "<" + tag ); + "<" + tag ); } return result; @@ -859,7 +860,7 @@ } else { err.jspError(reader.mark(), "jsp.error.unterminated", - "<jsp:params" ); + "<jsp:params" ); } } @@ -879,14 +880,14 @@ Mark bodyEnd = reader.skipUntilETag("jsp:fallback"); if (bodyEnd == null) { err.jspError(start, "jsp.error.unterminated", - "<jsp:fallback"); + "<jsp:fallback"); } char[] text = reader.getText(bodyStart, bodyEnd); new Node.FallBackAction(start, text, parent); } else { err.jspError( reader.mark(), "jsp.error.unterminated", - "<jsp:fallback" ); + "<jsp:fallback" ); } } @@ -956,14 +957,14 @@ if (!isTagFile) { err.jspError(reader.mark(), "jsp.error.invalid.action.isnottagfile", - "<jsp:invoke"); + "<jsp:invoke"); } parseInvoke(parent); } else if (reader.matches("doBody")) { if (!isTagFile) { err.jspError(reader.mark(), "jsp.error.invalid.action.isnottagfile", - "<jsp:doBody"); + "<jsp:doBody"); } parseDoBody(parent); } else if (reader.matches("getProperty")) { @@ -1028,16 +1029,23 @@ return false; } TagInfo tagInfo = tagLibInfo.getTag(shortTagName); - if (tagInfo == null) { + TagFileInfo tagFileInfo = tagLibInfo.getTagFile(shortTagName); + if (tagInfo == null && tagFileInfo == null) { err.jspError(start, "jsp.error.bad_tag", shortTagName, prefix); } Class tagHandlerClass = null; - try { - tagHandlerClass - = ctxt.getClassLoader().loadClass(tagInfo.getTagClassName()); - } catch (Exception e) { - err.jspError(start, "jsp.error.unable.loadclass", shortTagName, + if (tagFileInfo == null) { + // Must be a classic tag, load it here. + // tag files will be loaded later, in TagFileProcessor + try { + tagHandlerClass + = ctxt.getClassLoader().loadClass(tagInfo.getTagClassName()); + } catch (Exception e) { + err.jspError(start, "jsp.error.unable.loadclass", shortTagName, prefix); + } + } else { + tagInfo = tagFileInfo.getTagInfo(); } // Parse 'CustomActionBody' production: @@ -1051,8 +1059,7 @@ // Parse 'CustomActionEnd' production: if (reader.matches("/>")) { new Node.CustomTag(attrs, start, tagName, prefix, shortTagName, - tagInfo, tagHandlerClass, parent); - return true; + tagInfo, tagFileInfo, tagHandlerClass, parent); } // Now we parse one of 'CustomActionTagDependent', @@ -1062,11 +1069,18 @@ // Looking for a body, it still can be empty; but if there is a // a tag body, its syntax would be dependent on the type of // body content declared in TLD. - String bc = ((TagLibraryInfo)taglibs.get(prefix)).getTag( - shortTagName).getBodyContent(); + TagLibraryInfo taglib = (TagLibraryInfo)taglibs.get(prefix); + String bc; + if (taglib.getTag(shortTagName) != null) { + bc = taglib.getTag(shortTagName).getBodyContent(); + } else if (taglib.getTagFile(shortTagName) != null) { + bc = TagInfo.BODY_CONTENT_SCRIPTLESS; + } else { + bc = TagInfo.BODY_CONTENT_EMPTY; + } Node tagNode = new Node.CustomTag(attrs, start, tagName, prefix, - shortTagName, tagInfo, + shortTagName, tagInfo, tagFileInfo, tagHandlerClass, parent); parseOptionalBody( tagNode, tagName, bc ); @@ -1181,7 +1195,7 @@ Mark bodyStart = reader.mark(); Mark bodyEnd = reader.skipUntilETag(tag); if (bodyEnd == null) { - err.jspError(start, "jsp.error.unterminated", "<"+tag ); + err.jspError(start, "jsp.error.unterminated", "<"+tag ); } new Node.TemplateText(reader.getText(bodyStart, bodyEnd), bodyStart, parent); @@ -1214,7 +1228,7 @@ // Body was empty. This is illegal, according to the grammar. err.jspError(reader.mark(), "jsp.error.empty.body.not.allowed", - "<jsp:body>" ); + "<jsp:body>" ); } else { parseBody( bodyNode, "jsp:body", bodyType ); @@ -1230,7 +1244,7 @@ { err.jspError(reader.mark(), "jsp.error.jspbody.body.not.allowed.with.value", - "<jsp:body>" ); + "<jsp:body>" ); } } } @@ -1257,7 +1271,7 @@ parsePluginTags(parent); if( !reader.matchesETag( tag ) ) { err.jspError( reader.mark(), "jsp.error.unterminated", - "<" + tag ); + "<" + tag ); } } else if( bodyType.equalsIgnoreCase( TagInfo.BODY_CONTENT_JSP ) || @@ -1284,7 +1298,7 @@ parseParam( parent ); } } - err.jspError(start, "jsp.error.unterminated", "<"+tag ); + err.jspError(start, "jsp.error.unterminated", "<"+tag ); } else { err.jspError(start, "jasper.error.bad.bodycontent.type"); @@ -1311,17 +1325,17 @@ if( reader.matches( "/>" ) ) { // Body was empty. This is illegal, according to the grammar. err.jspError(reader.mark(), "jsp.error.empty.body.not.allowed", - "<jsp:attribute" ); + "<jsp:attribute" ); } else if( !reader.matches( ">" ) ) { err.jspError(reader.mark(), "jsp.error.unterminated", - "<jsp:attribute"); + "<jsp:attribute"); } if( reader.matches( "</jsp:attribute" ) ) { // Body was empty. This is illegal, according to the grammar. err.jspError(reader.mark(), "jsp.error.empty.body.not.allowed", - "<jsp:attribute" ); + "<jsp:attribute" ); } else { if( namedAttributeNode.isTrim() ) { 1.9 +4 -2 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ParserController.java Index: ParserController.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/ParserController.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- ParserController.java 29 Jul 2002 22:29:01 -0000 1.8 +++ ParserController.java 31 Jul 2002 21:42:27 -0000 1.9 @@ -247,6 +247,7 @@ } newEncoding = null; + isTagFile = false; // Figure out the encoding of the page // FIXME: We assume xml parser will take care of @@ -255,8 +256,9 @@ jspReader.reset(startMark); while (jspReader.skipUntil("<%@") != null) { jspReader.skipSpaces(); - isTagFile = jspReader.matches("tag "); - if (isTagFile || jspReader.matches("page")) { + boolean tIsTagFile = jspReader.matches("tag "); + if (tIsTagFile || jspReader.matches("page")) { + isTagFile = tIsTagFile; jspReader.skipSpaces(); Attributes attrs = Parser.parseAttributes(this, jspReader); String attribute = "pageEncoding"; 1.5 +103 -8 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/TagFileProcessor.java Index: TagFileProcessor.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/TagFileProcessor.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- TagFileProcessor.java 26 Jul 2002 01:07:14 -0000 1.4 +++ TagFileProcessor.java 31 Jul 2002 21:42:27 -0000 1.5 @@ -65,9 +65,13 @@ import java.util.*; import java.io.FileNotFoundException; +import javax.servlet.ServletException; import javax.servlet.jsp.tagext.*; +import org.apache.jasper.Constants; import org.apache.jasper.JasperException; +import org.apache.jasper.JspCompilationContext; +import org.apache.jasper.servlet.JspServletWrapper; /** * Processes and extracts the directive info in a tag file. @@ -88,7 +92,7 @@ private String name = null; private String tagclass = null; private TagExtraInfo tei = null; - private String bodycontent = "JSP"; // Default body content is JSP + private String bodycontent = null; private String description = null; private String displayName = null; private String smallIcon = null; @@ -139,6 +143,7 @@ public TagFileVisitor(Compiler compiler, TagLibraryInfo tagLibInfo) { err = compiler.getErrorDispatcher(); + this.tagLibInfo = tagLibInfo; } public void visit(Node.TagDirective n) throws JasperException { @@ -146,8 +151,18 @@ JspUtil.checkAttributes("Tag directive", n, tagDirectiveAttrs, err); - name = n.getAttributeValue("name"); + String tname = n.getAttributeValue("name"); + if (tname != null && name != null && !tname.equals(name)) { + err.jspError("jsp.error.tagfile.tld.name", name, tname); + } bodycontent = n.getAttributeValue("body-content"); + if (bodycontent != null && + !bodycontent.equals(TagInfo.BODY_CONTENT_EMPTY) && + !bodycontent.equals(TagInfo.BODY_CONTENT_TAG_DEPENDENT) && + !bodycontent.equals(TagInfo.BODY_CONTENT_SCRIPTLESS)) { + err.jspError("jsp.error.tagdirective.badbodycontent", + bodycontent); + } dynamicAttributes= JspUtil.booleanValue( n.getAttributeValue("dynamic-attributes")); smallIcon = n.getAttributeValue("small-icon"); @@ -201,7 +216,7 @@ String scopeStr = n.getAttributeValue("scope"); if (scopeStr != null) { if ("NESTED".equals(scopeStr)) { - scope = VariableInfo.NESTED; + // Already the default } else if ("AT_BEGIN".equals(scopeStr)) { scope = VariableInfo.AT_BEGIN; } else if ("AT_END".equals(scopeStr)) { @@ -225,9 +240,9 @@ boolean required = JspUtil.booleanValue(n.getAttributeValue("required")); // Find the attribute node with matching name Node.AttributeDirective attributeDirective = - (Node.AttributeDirective) fragmentAttributesMap.get(name); + (Node.AttributeDirective) fragmentAttributesMap.get(fragment); if (attributeDirective == null) { - err.jspError(n, "jsp.error.nomatching.fragment", name); + err.jspError(n, "jsp.error.nomatching.fragment", fragment); } attributeDirective.getFragmentInputs().addElement( new TagFragmentAttributeInfo.FragmentInput(name, type, @@ -236,6 +251,16 @@ public TagInfo getTagInfo() { + if (name == null) { + // XXX Get it from tag file name + } + + if (bodycontent == null) { + bodycontent = TagInfo.BODY_CONTENT_SCRIPTLESS; + } + + tagclass = Constants.JSP_PACKAGE_NAME + "." + name; + TagVariableInfo[] tagVariableInfos = new TagVariableInfo[variableVector.size()]; variableVector.copyInto(tagVariableInfos); @@ -280,10 +305,23 @@ } } - public static TagInfo parseTagFile(ParserController pc, String tagfile, + /** + * Parses the tag file, and collects information on the directives included + * in it. The method is used to obtain the info on the tag file, when the + * handler that it represents is referenced. The tag file is not compiled + * here. + * @param pc the current ParserController used in this compilation + * @param tagile the path for the tagfile + * @param tagLibInfo the TaglibraryInfo object associated with this TagInfo + * @return a TagInfo object assembled from the directives in the tag file. + */ + public static TagInfo parseTagFile(ParserController pc, + String name, + String tagfile, TagLibraryInfo tagLibInfo) throws JasperException { + Node.Nodes page = null; try { page = pc.parse(tagfile); @@ -294,9 +332,66 @@ TagFileVisitor tagFileVisitor = new TagFileVisitor(pc.getCompiler(), tagLibInfo); + tagFileVisitor.name = name; page.visit(tagFileVisitor); return tagFileVisitor.getTagInfo(); } + + /** + * Compiles and loads a tagfile. + */ + public static Class loadTagFile(JspCompilationContext ctxt, + String tagFile, TagInfo tagInfo) + throws JasperException { + + JspRuntimeContext rctxt = ctxt.getRuntimeContext(); + JspServletWrapper wrapper = + (JspServletWrapper) rctxt.getWrapper(tagFile); + if (wrapper == null) { + synchronized(rctxt) { + wrapper = (JspServletWrapper) rctxt.getWrapper(tagFile); + if (wrapper == null) { + wrapper = new JspServletWrapper(ctxt.getServletContext(), + ctxt.getOptions(), + tagFile, + tagInfo, + ctxt.getRuntimeContext()); + } + } + } + return wrapper.loadTagFile(); + } + + /* + * A visitor that scan the page, looking for tag handlers that are tag + * files and compile (if necessary) and load them. + */ + + static class TagFileLoaderVisitor extends Node.Visitor { + + private JspCompilationContext ctxt; + + TagFileLoaderVisitor(JspCompilationContext ctxt) { + this.ctxt = ctxt; + } + + public void visit(Node.CustomTag n) throws JasperException { + TagFileInfo tagFileInfo = n.getTagFileInfo(); + if (tagFileInfo != null) { + String tagFile = tagFileInfo.getPath(); + Class c = loadTagFile(ctxt, tagFile, n.getTagInfo()); + n.setTagHandlerClass(c); + } + } + } + + public static void loadTagFiles(Compiler compiler, Node.Nodes page) + throws JasperException { + + JspCompilationContext ctxt = compiler.getCompilationContext(); + page.visit(new TagFileLoaderVisitor(ctxt)); + } + } 1.8 +28 -14 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java Index: TagLibraryInfoImpl.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/TagLibraryInfoImpl.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- TagLibraryInfoImpl.java 26 Jul 2002 01:07:14 -0000 1.7 +++ TagLibraryInfoImpl.java 31 Jul 2002 21:42:27 -0000 1.8 @@ -112,6 +112,9 @@ for(int i = 0; i < tags.length; i++) out.println(tags[i].toString()); + for(int i = 0; i < tagFiles.length; i++) + out.println(tagFiles[i].toString()); + for(int i = 0; i < functions.length; i++) out.println(functions[i].toString()); @@ -249,6 +252,7 @@ throws JasperException { Vector tagVector = new Vector(); + Vector tagFileVector = new Vector(); Vector functionVector = new Vector(); // Create an iterator over the child elements of our <taglib> element @@ -282,7 +286,7 @@ else if ("tag".equals(tname)) tagVector.addElement(createTagInfo(element)); else if ("tag-file".equals(tname)) - tagVector.addElement(createTagInfoFromTagFile(element)); + tagFileVector.addElement(createTagFileInfo(element)); else if ("function".equals(tname)) // JSP2.0 functionVector.addElement(createFunctionInfo(element)); else if ("display-name".equals(tname) || // Ignored elements @@ -302,6 +306,9 @@ this.tags = new TagInfo[tagVector.size()]; tagVector.copyInto (this.tags); + this.tagFiles = new TagFileInfo[tagFileVector.size()]; + tagFileVector.copyInto (this.tagFiles); + this.functions = new FunctionInfo[functionVector.size()]; functionVector.copyInto (this.functions); } @@ -431,25 +438,32 @@ * * @return TagInfo correspoding to tag file directives */ - private TagInfo createTagInfoFromTagFile(TreeNode elem) + private TagFileInfo createTagFileInfo(TreeNode elem) throws JasperException { - TagInfo tagInfo = null; + String name = null; + String path = null; Iterator list = elem.findChildren(); while (list.hasNext()) { TreeNode child = (TreeNode) list.next(); String tname = child.getName(); - if ("path".equals(tname)) { - String tagFilePath = child.getBody(); - tagInfo = TagFileProcessor.parseTagFile(parserController, - tagFilePath, - this); - break; - } + if ("name".equals(tname)) { + name = child.getBody(); + } else if ("path".equals(tname)) { + path = child.getBody(); + } else { + Constants.message("jsp.warning.unknown.element.in.attribute", + new Object[] {tname}, + Logger.WARNING + ); + } } - return tagInfo; + TagInfo tagInfo = TagFileProcessor.parseTagFile(parserController, + name, path, + this); + return new TagFileInfo(name, path, tagInfo); } TagAttributeInfo createAttribute(TreeNode elem) { 1.16 +5 -9 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java Index: Validator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Validator.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- Validator.java 31 Jul 2002 16:04:39 -0000 1.15 +++ Validator.java 31 Jul 2002 21:42:27 -0000 1.16 @@ -580,9 +580,7 @@ } public void visit(Node.CustomTag n) throws JasperException { - TagLibraryInfo tagLibInfo = (TagLibraryInfo) - pageInfo.getTagLibraries().get(n.getPrefix()); - TagInfo tagInfo = tagLibInfo.getTag(n.getShortName()); + TagInfo tagInfo = n.getTagInfo(); if (tagInfo == null) { err.jspError(n, "jsp.error.missing.tagInfo", n.getName()); } @@ -830,9 +828,7 @@ } public void visit(Node.CustomTag n) throws JasperException { - TagLibraryInfo tagLibInfo = (TagLibraryInfo) - pageInfo.getTagLibraries().get(n.getPrefix()); - TagInfo tagInfo = tagLibInfo.getTag(n.getShortName()); + TagInfo tagInfo = n.getTagInfo(); if (tagInfo == null) { err.jspError(n, "jsp.error.missing.tagInfo", n.getName()); } 1.20 +5 -4 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/resources/messages.properties Index: messages.properties =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/resources/messages.properties,v retrieving revision 1.19 retrieving revision 1.20 diff -u -r1.19 -r1.20 --- messages.properties 31 Jul 2002 16:04:39 -0000 1.19 +++ messages.properties 31 Jul 2002 21:42:27 -0000 1.20 @@ -67,6 +67,7 @@ jsp.error.invalid.directive=Invalid directive jsp.error.directive.istagfile={0} directive cannot be used in a tag file jsp.error.directive.isnottagfile={0} directive can only be used in a tag file +jsp.error.tagfile.tld.name=The \"name\" attribute of the tag directive has a value {0} while the \"name\" tag of the \"tag-file\" element in the TLD is {1} jsp.error.action.istagfile={0} action cannot be used in a tag file jsp.error.action.isnottagfile={0} action can be used in tag files only jsp.error.unterminated=Unterminated {0} tag @@ -101,8 +102,7 @@ jsp.error.include.badflush=jsp:include page=\"...\" flush=\"true\" is the only valid combination in JSP 1.0 jsp.error.attempt_to_clear_flushed_buffer=Error: Attempt to clear a buffer that's already been flushed jsp.error.overflow=Error: JSP Buffer overflow -jsp.error.paramexpected=Expected \"param\" tag with \"name\" and \"value\" attributes after the \"params\" tag. -jsp.error.paramexpectedonly=Expected \"param\" tag with \"name\" and \"value\" attributes without the \"params\" tag. +jsp.error.paramexpected=Expected \"param\" tag with \"name\" and \"value\" attributes jsp.error.closeindividualparam=param tag needs to be closed with \"/>\" jsp.error.closeparams=param tag needs to be closed with /params jsp.error.plugin.notype=type not declared in jsp:plugin @@ -132,7 +132,7 @@ jsp.warning.unknown.element.in.attribute=Warning: Unknown element {0} in attribute jsp.error.more.than.one.taglib=More than one taglib in the TLD: {0} jsp.warning.teiclass.is.null=Could not load TagExtraInfo class {0}: {1} -jsp.warning.teiclass.is.nonnull=variable subelement defined in tld when TagExtraInfo class {0} is non-null +jsp.warning.teiclass.is.nonnull=variable subelement defined in TLD when TagExtraInfo class {0} is non-null jsp.error.parse.error.in.TLD=Parse Error in the tag library descriptor: {0} jsp.error.unable.to.open.TLD=Unable to open the tag library descriptor: {0} jsp.buffer.size.zero=Buffer size <= 0 @@ -279,3 +279,4 @@ jsp.error.attribute.noequal=equal symbol expected jsp.error.attribute.noquote=quote symbol expected jsp.error.attribute.unterminated=attribute for {0} is not properly terminated +jsp.error.missing.tagInfo=TagInfo object for {0} is missing from TLD 1.8 +46 -3 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/servlet/JspServletWrapper.java Index: JspServletWrapper.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/servlet/JspServletWrapper.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- JspServletWrapper.java 19 Jul 2002 01:13:46 -0000 1.7 +++ JspServletWrapper.java 31 Jul 2002 21:42:27 -0000 1.8 @@ -68,6 +68,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.jsp.tagext.TagInfo; import java.io.IOException; import java.io.FileNotFoundException; @@ -106,6 +107,7 @@ private Servlet theServlet; private String jspUri; private Class servletClass; + private Class tagHandlerClass; private JspCompilationContext ctxt; private long available = 0L; private ServletConfig config; @@ -125,6 +127,20 @@ ctxt.createOutdir(); } + public JspServletWrapper(ServletContext servletContext, Options options, + String tagfile, TagInfo tagInfo, JspRuntimeContext rctxt) + throws JasperException { + + this.config = null; // not used + this.options = options; + this.jspUri = tagfile; + ctxt = new JspCompilationContext( tagfile, tagInfo, + options, + servletContext, + this, rctxt); + ctxt.createOutdir(); + } + public JspCompilationContext getJspEngineContext() { return ctxt; } @@ -158,6 +174,33 @@ public ServletContext getServletContext() { return config.getServletContext(); + } + + public Class loadTagFile() throws JasperException { + + try { + if (ctxt.isRemoved()) { + throw new FileNotFoundException(jspUri); + } + if (options.getDevelopment()) { + synchronized (this) { + ctxt.compile(); + } + } + if (ctxt.isReload()) { + synchronized (this) { + if (ctxt.isReload()) { + tagHandlerClass = ctxt.load(); + } + } + } + } catch (FileNotFoundException ex) { + throw new JasperException(ex); + } catch (JasperException ex) { + throw ex; + } + + return tagHandlerClass; } public void service(HttpServletRequest request,
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>