KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > text > html > parser > ContentModel


1 /*
2  * @(#)ContentModel.java 1.11 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing.text.html.parser;
9
10 import java.util.Vector JavaDoc;
11 import java.util.Enumeration JavaDoc;
12 import java.io.*;
13
14
15 /**
16  * A representation of a content model. A content model is
17  * basically a restricted BNF expression. It is restricted in
18  * the sense that it must be deterministic. This means that you
19  * don't have to represent it as a finite state automata.<p>
20  * See Annex H on page 556 of the SGML handbook for more information.
21  *
22  * @author Arthur van Hoff
23  * @version 1.11,05/05/04
24  *
25  */

26 public final class ContentModel implements Serializable {
27     /**
28      * Type. Either '*', '?', '+', ',', '|', '&'.
29      */

30     public int type;
31
32     /**
33      * The content. Either an Element or a ContentModel.
34      */

35     public Object JavaDoc content;
36
37     /**
38      * The next content model (in a ',', '|' or '&' expression).
39      */

40     public ContentModel JavaDoc next;
41
42     public ContentModel() {
43     }
44
45     /**
46      * Create a content model for an element.
47      */

48     public ContentModel(Element JavaDoc content) {
49     this(0, content, null);
50     }
51
52     /**
53      * Create a content model of a particular type.
54      */

55     public ContentModel(int type, ContentModel JavaDoc content) {
56     this(type, content, null);
57     }
58
59     /**
60      * Create a content model of a particular type.
61      */

62     public ContentModel(int type, Object JavaDoc content, ContentModel JavaDoc next) {
63     this.type = type;
64     this.content = content;
65     this.next = next;
66     }
67
68     /**
69      * Return true if the content model could
70      * match an empty input stream.
71      */

72     public boolean empty() {
73     switch (type) {
74       case '*':
75       case '?':
76         return true;
77
78       case '+':
79       case '|':
80         for (ContentModel JavaDoc m = (ContentModel JavaDoc)content ; m != null ; m = m.next) {
81         if (m.empty()) {
82             return true;
83         }
84         }
85         return false;
86
87       case ',':
88       case '&':
89         for (ContentModel JavaDoc m = (ContentModel JavaDoc)content ; m != null ; m = m.next) {
90         if (!m.empty()) {
91             return false;
92         }
93         }
94         return true;
95
96       default:
97         return false;
98     }
99     }
100
101     /**
102      * Update elemVec with the list of elements that are
103      * part of the this contentModel.
104      */

105      public void getElements(Vector JavaDoc<Element JavaDoc> elemVec) {
106      switch (type) {
107      case '*':
108      case '?':
109      case '+':
110          ((ContentModel JavaDoc)content).getElements(elemVec);
111          break;
112      case ',':
113      case '|':
114      case '&':
115          for (ContentModel JavaDoc m=(ContentModel JavaDoc)content; m != null; m=m.next){
116          m.getElements(elemVec);
117          }
118          break;
119      default:
120          elemVec.addElement((Element JavaDoc)content);
121      }
122      }
123
124      private boolean valSet[];
125      private boolean val[];
126      // A cache used by first(). This cache was found to speed parsing
127
// by about 10% (based on measurements of the 4-12 code base after
128
// buffering was fixed).
129

130     /**
131      * Return true if the token could potentially be the
132      * first token in the input stream.
133      */

134     public boolean first(Object JavaDoc token) {
135     switch (type) {
136       case '*':
137       case '?':
138       case '+':
139         return ((ContentModel JavaDoc)content).first(token);
140
141       case ',':
142         for (ContentModel JavaDoc m = (ContentModel JavaDoc)content ; m != null ; m = m.next) {
143         if (m.first(token)) {
144             return true;
145         }
146         if (!m.empty()) {
147             return false;
148         }
149         }
150         return false;
151
152       case '|':
153       case '&': {
154         Element JavaDoc e = (Element JavaDoc) token;
155         if (valSet == null) {
156         valSet = new boolean[Element.maxIndex + 1];
157         val = new boolean[Element.maxIndex + 1];
158         // All Element instances are created before this ever executes
159
}
160         if (valSet[e.index]) {
161         return val[e.index];
162         }
163         for (ContentModel JavaDoc m = (ContentModel JavaDoc)content ; m != null ; m = m.next) {
164         if (m.first(token)) {
165             val[e.index] = true;
166             break;
167         }
168         }
169         valSet[e.index] = true;
170         return val[e.index];
171       }
172
173       default:
174         return (content == token);
175             // PENDING: refer to comment in ContentModelState
176
/*
177               if (content == token) {
178                   return true;
179               }
180               Element e = (Element)content;
181               if (e.omitStart() && e.content != null) {
182                   return e.content.first(token);
183               }
184               return false;
185 */

186     }
187     }
188
189     /**
190      * Return the element that must be next.
191      */

192     public Element JavaDoc first() {
193     switch (type) {
194       case '&':
195       case '|':
196       case '*':
197       case '?':
198         return null;
199
200       case '+':
201       case ',':
202         return ((ContentModel JavaDoc)content).first();
203
204       default:
205         return (Element JavaDoc)content;
206     }
207     }
208
209     /**
210      * Convert to a string.
211      */

212     public String JavaDoc toString() {
213     switch (type) {
214       case '*':
215         return content + "*";
216       case '?':
217         return content + "?";
218       case '+':
219         return content + "+";
220
221       case ',':
222       case '|':
223       case '&':
224         char data[] = {' ', (char)type, ' '};
225         String JavaDoc str = "";
226         for (ContentModel JavaDoc m = (ContentModel JavaDoc)content ; m != null ; m = m.next) {
227         str = str + m;
228         if (m.next != null) {
229             str += new String JavaDoc(data);
230         }
231         }
232         return "(" + str + ")";
233
234       default:
235         return content.toString();
236     }
237     }
238 }
239
Popular Tags