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 = "&lt;%@ page";
            if (isTagFile) {
                err.jspError(reader.mark(), "jsp.error.directive.istagfile",
                                            directive);
            }
            parsePageDirective(parent);
        } else if (reader.matches("include")) {
  -         directive = "<%@ include";
  +         directive = "&lt;%@ include";
            parseIncludeDirective(parent);
        } else if (reader.matches("taglib")) {
  -         directive = "<%@ taglib";
  +         directive = "&lt;%@ taglib";
            parseTaglibDirective(parent);
        } else if (reader.matches("tag")) {
  -         directive = "<%@ tag";
  +         directive = "&lt;%@ tag";
            if (!isTagFile) {
                err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
                                            directive);
            }
            parseTagDirective(parent);
        } else if (reader.matches("attribute")) {
  -         directive = "<%@ attribute";
  +         directive = "&lt;%@ attribute";
            if (!isTagFile) {
                err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
                                            directive);
            }
            parseAttributeDirective(parent);
        } else if (reader.matches("variable")) {
  -         directive = "<%@ variable";
  +         directive = "&lt;%@ variable";
            if (!isTagFile) {
                err.jspError(reader.mark(), "jsp.error.directive.isnottagfile",
                                            directive);
            }
            parseVariableDirective(parent);
        } else if (reader.matches("fragment-input")) {
  -         directive = "<%@ fragment-input";
  +         directive = "&lt;%@ 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", "&lt;%--");
        }
   
        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", "&lt;%!");
        }
   
        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", "&lt;%=");
        }
   
        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", "&lt;%");
        }
   
        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 );
  +                        "&lt;" + tag );
                   }
               }
               else {
                   err.jspError(reader.mark(), "jsp.error.jspbody.emptybody.only",
  -                    "<" + tag );
  +                    "&lt;" + tag );
               }
           }
           else {
            err.jspError(reader.mark(), "jsp.error.unterminated",
  -                "<" + tag );
  +                "&lt;" + tag );
           }
       }
   
  @@ -782,7 +783,7 @@
   
        if (!reader.matches(">")) {
            err.jspError(reader.mark(), "jsp.error.unterminated",
  -                      "<" + tag );
  +                      "&lt;" + tag );
        }
           
           if( reader.matchesETag( tag ) ) {
  @@ -829,7 +830,7 @@
               reader.skipSpaces();
               if( !reader.matchesETag( tag ) ) {
                   err.jspError(reader.mark(), "jsp.error.unterminated", 
  -                    "<" + tag );
  +                    "&lt;" + 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 );
  +                "&lt;" + tag );
           }
           
           return result;
  @@ -859,7 +860,7 @@
           }
           else {
               err.jspError(reader.mark(), "jsp.error.unterminated",
  -                "<jsp:params" );
  +                "&lt;jsp:params" );
           }
       }
   
  @@ -879,14 +880,14 @@
               Mark bodyEnd = reader.skipUntilETag("jsp:fallback");
               if (bodyEnd == null) {
                   err.jspError(start, "jsp.error.unterminated", 
  -                    "<jsp:fallback");
  +                    "&lt;jsp:fallback");
               }
               char[] text = reader.getText(bodyStart, bodyEnd);
               new Node.FallBackAction(start, text, parent);
           }
           else {
               err.jspError( reader.mark(), "jsp.error.unterminated",
  -                "<jsp:fallback" );
  +                "&lt;jsp:fallback" );
           }
       }
   
  @@ -956,14 +957,14 @@
            if (!isTagFile) {
                err.jspError(reader.mark(),
                             "jsp.error.invalid.action.isnottagfile",
  -                          "<jsp:invoke");
  +                          "&lt;jsp:invoke");
            }
            parseInvoke(parent);
        } else if (reader.matches("doBody")) {
            if (!isTagFile) {
                err.jspError(reader.mark(),
                             "jsp.error.invalid.action.isnottagfile",
  -                          "<jsp:doBody");
  +                          "&lt;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", "&lt;"+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>" );
  +                    "&lt;jsp:body&gt;" );
               }
               else {
                   parseBody( bodyNode, "jsp:body", bodyType );
  @@ -1230,7 +1244,7 @@
               {
                   err.jspError(reader.mark(), 
                       "jsp.error.jspbody.body.not.allowed.with.value",
  -                    "<jsp:body>" );
  +                    "&lt;jsp:body&gt;" );
               }
           }
       }
  @@ -1257,7 +1271,7 @@
               parsePluginTags(parent);
               if( !reader.matchesETag( tag ) ) {
                   err.jspError( reader.mark(), "jsp.error.unterminated",
  -                    "<" + tag  );
  +                    "&lt;" + 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", "&lt;"+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" );
  +                    "&lt;jsp:attribute" );
               }
               else if( !reader.matches( ">" ) ) {
                   err.jspError(reader.mark(), "jsp.error.unterminated",
  -                    "<jsp:attribute");
  +                    "&lt;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" );
  +                    "&lt;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]>

Reply via email to