View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript-XML: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2005 Kevin Rogers
4   //
5   // This file is part of MillScript-XML.
6   //
7   // MillScript-XML is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript-XML is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript-XML; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
20  ////////////////////////////////////////////////////////////////////////////////
21  package org.millscript.commons.xml.tokenizer.wellformed;
22  
23  import org.millscript.commons.xml.alerts.XmlWellFormednessAlert;
24  import org.millscript.commons.xml.api.token.CharDataToken;
25  import org.millscript.commons.xml.api.token.CommentToken;
26  import org.millscript.commons.xml.api.token.DTDToken;
27  import org.millscript.commons.xml.api.token.EmptyElementToken;
28  import org.millscript.commons.xml.api.token.EndTagToken;
29  import org.millscript.commons.xml.api.token.PIToken;
30  import org.millscript.commons.xml.api.token.StartTagToken;
31  import org.millscript.commons.xml.api.token.TokenVisitor;
32  
33  /**
34   * This class provides a token visitor the for <code>content</code> part of an
35   * XML document. This is the a sub token visitor of the <code>element</code>
36   * token visitor, in the chain that provides the well formedness checks
37   * required of an XML processor.
38   */
39  public class ContentTokenVisitor extends AbsTokenVisitor {
40  
41      /**
42       * The start tag token that begins this content section.
43       */
44      private final StartTagToken startTagToken;
45  
46      /**
47       * Constructs a new <code>content</code> section token visitor, with the
48       * specified tokenizer, next-in-the-chain token visitor and start tag.
49       *
50       * @param xt    the well-formed XML tokenizer our tokens come from
51       * @param p the next token visitor in the well-formedness chain
52       * @param stToken   the start tag token for the tag that began this content
53       * section
54       */
55      public ContentTokenVisitor( final WellFormedXmlTokenizer xt, final TokenVisitor p, final StartTagToken stToken ) {
56          // We set the "next" token visitor to the parent one, i.e. the one that
57          // we should return to when we find the end tag for this content
58          super( xt, p );
59          this.startTagToken = stToken;
60      }
61  
62      /**
63       * @see org.millscript.commons.xml.api.token.TokenVisitor#visit(org.millscript.commons.xml.api.token.CharDataToken)
64       */
65      public void visit( final CharDataToken token ) {
66          // this token is valid in this section
67          this.wellFormed.nextToken = token;
68      }
69  
70      /**
71       * @see org.millscript.commons.xml.api.token.TokenVisitor#visit(org.millscript.commons.xml.api.token.CommentToken)
72       */
73      public void visit( final CommentToken token ) {
74          // this token is valid in this section
75          this.wellFormed.nextToken = token;
76      }
77  
78      /**
79       * @see org.millscript.commons.xml.api.token.TokenVisitor#visit(org.millscript.commons.xml.api.token.DTDToken)
80       */
81      public void visit( final DTDToken token ) {
82          throw new XmlWellFormednessAlert(
83              "Only one document type declaration can be used in a single XML document"
84          ).decorate( token ).mishap();
85      }
86  
87      /**
88       * @see org.millscript.commons.xml.api.token.TokenVisitor#visit(org.millscript.commons.xml.api.token.EmptyElementToken)
89       */
90      public void visit( final EmptyElementToken token ) {
91          // this token is valid in this section
92          this.wellFormed.nextToken = token;
93      }
94  
95      /**
96       * @see org.millscript.commons.xml.api.token.TokenVisitor#visit(org.millscript.commons.xml.api.token.EndTagToken)
97       */
98      public void visit( final EndTagToken token ) {
99          // To be valid, this token must match the start tags
100         if ( this.startTagToken.getName().equals( token.getName() ) ) {
101             // this token is valid in this section
102             this.wellFormed.nextToken = token;
103             // but next time round we are in the "previous" visitor
104             this.wellFormed.tokenVisitor = this.nextTokenVisitor;
105             // reset the namespace scope to what it was just before this element
106             // was read
107             this.wellFormed.setNamespaces(
108                 this.startTagToken.getPreviousNamespaceScope()
109             );
110         } else {
111             throw new XmlWellFormednessAlert(
112                 "Mismatched start/end tags"
113             ).decorate( this.startTagToken ).decorate( token ).mishap();
114         }
115     }
116 
117     /**
118      * @see org.millscript.commons.xml.api.token.TokenVisitor#visit(org.millscript.commons.xml.api.token.PIToken)
119      */
120     public void visit( final PIToken token ) {
121         // this token is valid in this section
122         this.wellFormed.nextToken = token;
123     }
124 
125     /**
126      * @see org.millscript.commons.xml.api.token.TokenVisitor#visit(org.millscript.commons.xml.api.token.StartTagToken)
127      */
128     public void visit( final StartTagToken token ) {
129         // this token is valid in this section
130         this.wellFormed.nextToken = token;
131         // but we override the visitor for the next section
132         // when we finish this content, we must return to this visitor
133         this.wellFormed.tokenVisitor = new ContentTokenVisitor( this.wellFormed, this, token );
134     }
135 
136 }