KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)DTD.java 1.20 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.io.PrintStream JavaDoc;
11 import java.io.File JavaDoc;
12 import java.io.FileInputStream JavaDoc;
13 import java.io.InputStream JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.FileNotFoundException JavaDoc;
16 import java.io.BufferedInputStream JavaDoc;
17 import java.io.DataInputStream JavaDoc;
18 import java.util.Hashtable JavaDoc;
19 import java.util.Vector JavaDoc;
20 import java.util.BitSet JavaDoc;
21 import java.util.StringTokenizer JavaDoc;
22 import java.util.Enumeration JavaDoc;
23 import java.util.Properties JavaDoc;
24 import java.net.URL JavaDoc;
25
26 /**
27  * The representation of an SGML DTD. DTD describes a document
28  * syntax and is used in parsing of HTML documents. It contains
29  * a list of elements and their attributes as well as a list of
30  * entities defined in the DTD.
31  *
32  * @see Element
33  * @see AttributeList
34  * @see ContentModel
35  * @see Parser
36  * @author Arthur van Hoff
37  * @version 1.20 05/05/04
38  */

39 public
40 class DTD implements DTDConstants JavaDoc {
41     public String JavaDoc name;
42     public Vector JavaDoc<Element JavaDoc> elements = new Vector JavaDoc<Element JavaDoc>();
43     public Hashtable JavaDoc<String JavaDoc,Element JavaDoc> elementHash
44     = new Hashtable JavaDoc<String JavaDoc,Element JavaDoc>();
45     public Hashtable JavaDoc<Object JavaDoc,Entity JavaDoc> entityHash
46     = new Hashtable JavaDoc<Object JavaDoc,Entity JavaDoc>();
47     public final Element JavaDoc pcdata = getElement("#pcdata");
48     public final Element JavaDoc html = getElement("html");
49     public final Element JavaDoc meta = getElement("meta");
50     public final Element JavaDoc base = getElement("base");
51     public final Element JavaDoc isindex = getElement("isindex");
52     public final Element JavaDoc head = getElement("head");
53     public final Element JavaDoc body = getElement("body");
54     public final Element JavaDoc applet = getElement("applet");
55     public final Element JavaDoc param = getElement("param");
56     public final Element JavaDoc p = getElement("p");
57     public final Element JavaDoc title = getElement("title");
58     final Element JavaDoc style = getElement("style");
59     final Element JavaDoc link = getElement("link");
60     final Element JavaDoc script = getElement("script");
61
62     public static final int FILE_VERSION = 1;
63
64     /**
65      * Creates a new DTD with the specified name.
66      * @param name the name, as a <code>String</code> of the new DTD
67      */

68     protected DTD(String JavaDoc name) {
69     this.name = name;
70     defEntity("#RE", GENERAL, '\r');
71     defEntity("#RS", GENERAL, '\n');
72     defEntity("#SPACE", GENERAL, ' ');
73     defineElement("unknown", EMPTY, false, true, null, null, null, null);
74     }
75
76     /**
77      * Gets the name of the DTD.
78      * @return the name of the DTD
79      */

80     public String JavaDoc getName() {
81     return name;
82     }
83
84     /**
85      * Gets an entity by name.
86      * @return the <code>Entity</code> corresponding to the
87      * <code>name</code> <code>String</code>
88      */

89     public Entity JavaDoc getEntity(String JavaDoc name) {
90     return (Entity JavaDoc)entityHash.get(name);
91     }
92
93     /**
94      * Gets a character entity.
95      * @return the <code>Entity</code> corresponding to the
96      * <code>ch</code> character
97      */

98     public Entity JavaDoc getEntity(int ch) {
99     return (Entity JavaDoc)entityHash.get(new Integer JavaDoc(ch));
100     }
101
102     /**
103      * Returns <code>true</code> if the element is part of the DTD,
104      * otherwise returns <code>false</code>.
105      *
106      * @param name the requested <code>String</code>
107      * @return <code>true</code> if <code>name</code> exists as
108      * part of the DTD, otherwise returns <code>false</code>
109      */

110     boolean elementExists(String JavaDoc name) {
111     Element JavaDoc e = (Element JavaDoc)elementHash.get(name);
112     return ((e == null) ? false : true);
113     }
114
115     /**
116      * Gets an element by name. A new element is
117      * created if the element doesn't exist.
118      *
119      * @param name the requested <code>String</code>
120      * @return the <code>Element</code> corresponding to
121      * <code>name</code>, which may be newly created
122      */

123     public Element JavaDoc getElement(String JavaDoc name) {
124     Element JavaDoc e = (Element JavaDoc)elementHash.get(name);
125     if (e == null) {
126         e = new Element JavaDoc(name, elements.size());
127         elements.addElement(e);
128         elementHash.put(name, e);
129     }
130     return e;
131     }
132
133     /**
134      * Gets an element by index.
135      *
136      * @param index the requested index
137      * @return the <code>Element</code> corresponding to
138      * <code>index</code>
139      */

140     public Element JavaDoc getElement(int index) {
141     return (Element JavaDoc)elements.elementAt(index);
142     }
143
144     /**
145      * Defines an entity. If the <code>Entity</code> specified
146      * by <code>name</code>, <code>type</code>, and <code>data</code>
147      * exists, it is returned; otherwise a new <code>Entity</code>
148      * is created and is returned.
149      *
150      * @param name the name of the <code>Entity</code> as a <code>String</code>
151      * @param type the type of the <code>Entity</code>
152      * @param data the <code>Entity</code>'s data
153      * @return the <code>Entity</code> requested or a new <code>Entity</code>
154      * if not found
155      */

156     public Entity JavaDoc defineEntity(String JavaDoc name, int type, char data[]) {
157     Entity JavaDoc ent = (Entity JavaDoc)entityHash.get(name);
158     if (ent == null) {
159         ent = new Entity JavaDoc(name, type, data);
160         entityHash.put(name, ent);
161         if (((type & GENERAL) != 0) && (data.length == 1)) {
162         switch (type & ~GENERAL) {
163           case CDATA:
164           case SDATA:
165             entityHash.put(new Integer JavaDoc(data[0]), ent);
166             break;
167         }
168         }
169     }
170     return ent;
171     }
172
173     /**
174      * Returns the <code>Element</code> which matches the
175      * specified parameters. If one doesn't exist, a new
176      * one is created and returned.
177      *
178      * @param name the name of the <code>Element</code>
179      * @param type the type of the <code>Element</code>
180      * @param omitStart <code>true</code if start should be omitted
181      * @param omitEnd <code>true</code> if end should be omitted
182      * @param content the <code>ContentModel</code>
183      * @param atts the <code>AttributeList</code> specifying the
184      * <code>Element</code>
185      * @return the <code>Element</code> specified
186      */

187     public Element JavaDoc defineElement(String JavaDoc name, int type,
188                boolean omitStart, boolean omitEnd, ContentModel JavaDoc content,
189                BitSet JavaDoc exclusions, BitSet JavaDoc inclusions, AttributeList JavaDoc atts) {
190     Element JavaDoc e = getElement(name);
191     e.type = type;
192     e.oStart = omitStart;
193     e.oEnd = omitEnd;
194     e.content = content;
195     e.exclusions = exclusions;
196     e.inclusions = inclusions;
197     e.atts = atts;
198     return e;
199     }
200
201     /**
202      * Returns the <code>Element</code> which matches the
203      * specified <code>AttributeList</code>.
204      * If one doesn't exist, a new one is created and returned.
205      *
206      * @param name the name of the <code>Element</code>
207      * @param atts the <code>AttributeList</code> specifying the
208      * <code>Element</code>
209      * @return the <code>Element</code> specified
210      */

211     public void defineAttributes(String JavaDoc name, AttributeList JavaDoc atts) {
212     Element JavaDoc e = getElement(name);
213     e.atts = atts;
214     }
215
216     /**
217      * Creates and returns a character <code>Entity</code>.
218      * @param name the entity's name
219      * @return the new character <code>Entity</code>
220      */

221     public Entity JavaDoc defEntity(String JavaDoc name, int type, int ch) {
222     char data[] = {(char)ch};
223     return defineEntity(name, type, data);
224     }
225
226     /**
227      * Creates and returns an <code>Entity</code>.
228      * @param name the entity's name
229      * @return the new <code>Entity</code>
230      */

231     protected Entity JavaDoc defEntity(String JavaDoc name, int type, String JavaDoc str) {
232     int len = str.length();
233     char data[] = new char[len];
234     str.getChars(0, len, data, 0);
235     return defineEntity(name, type, data);
236     }
237
238     /**
239      * Creates and returns an <code>Element</code>.
240      * @param name the element's name
241      * @return the new <code>Element</code>
242      */

243     protected Element JavaDoc defElement(String JavaDoc name, int type,
244                boolean omitStart, boolean omitEnd, ContentModel JavaDoc content,
245                String JavaDoc[] exclusions, String JavaDoc[] inclusions, AttributeList JavaDoc atts) {
246     BitSet JavaDoc excl = null;
247     if (exclusions != null && exclusions.length > 0) {
248         excl = new BitSet JavaDoc();
249         for (int i = 0; i < exclusions.length; i++) {
250         String JavaDoc str = exclusions[i];
251         if (str.length() > 0) {
252             excl.set(getElement(str).getIndex());
253         }
254         }
255     }
256     BitSet JavaDoc incl = null;
257     if (inclusions != null && inclusions.length > 0) {
258         incl = new BitSet JavaDoc();
259         for (int i = 0; i < inclusions.length; i++) {
260         String JavaDoc str = inclusions[i];
261         if (str.length() > 0) {
262             incl.set(getElement(str).getIndex());
263         }
264         }
265     }
266     return defineElement(name, type, omitStart, omitEnd, content, excl, incl, atts);
267     }
268
269     /**
270      * Creates and returns an <code>AttributeList</code>.
271      * @param name the attribute list's name
272      * @return the new <code>AttributeList</code>
273      */

274     protected AttributeList JavaDoc defAttributeList(String JavaDoc name, int type, int modifier, String JavaDoc value, String JavaDoc values, AttributeList JavaDoc atts) {
275     Vector JavaDoc vals = null;
276     if (values != null) {
277         vals = new Vector JavaDoc();
278         for (StringTokenizer JavaDoc s = new StringTokenizer JavaDoc(values, "|") ; s.hasMoreTokens() ;) {
279         String JavaDoc str = s.nextToken();
280         if (str.length() > 0) {
281             vals.addElement(str);
282         }
283         }
284     }
285     return new AttributeList JavaDoc(name, type, modifier, value, vals, atts);
286     }
287
288     /**
289      * Creates and returns a new content model.
290      * @param type the type of the new content model
291      * @return the new <code>ContentModel</code>
292      */

293     protected ContentModel JavaDoc defContentModel(int type, Object JavaDoc obj, ContentModel JavaDoc next) {
294     return new ContentModel JavaDoc(type, obj, next);
295     }
296
297     /**
298      * Returns a string representation of this DTD.
299      * @return the string representation of this DTD
300      */

301     public String JavaDoc toString() {
302     return name;
303     }
304
305     /**
306      * The hashtable of DTDs.
307      */

308     static Hashtable JavaDoc dtdHash = new Hashtable JavaDoc();
309
310   public static void putDTDHash(String JavaDoc name, DTD JavaDoc dtd) {
311     dtdHash.put(name, dtd);
312   }
313     /**
314      * Returns a DTD with the specified <code>name</code>. If
315      * a DTD with that name doesn't exist, one is created
316      * and returned. Any uppercase characters in the name
317      * are converted to lowercase.
318      *
319      * @param name the name of the DTD
320      * @return the DTD which corresponds to <code>name</code>
321      */

322     public static DTD JavaDoc getDTD(String JavaDoc name) throws IOException JavaDoc {
323     name = name.toLowerCase();
324     DTD JavaDoc dtd = (DTD JavaDoc)dtdHash.get(name);
325     if (dtd == null)
326       dtd = new DTD JavaDoc(name);
327
328     return dtd;
329     }
330
331     /**
332      * Recreates a DTD from an archived format.
333      * @param in the <code>DataInputStream</code> to read from
334      */

335     public void read(DataInputStream JavaDoc in) throws IOException JavaDoc {
336     if (in.readInt() != FILE_VERSION) {
337     }
338
339     //
340
// Read the list of names
341
//
342
String JavaDoc[] names = new String JavaDoc[in.readShort()];
343     for (int i = 0; i < names.length; i++) {
344         names[i] = in.readUTF();
345     }
346
347
348     //
349
// Read the entities
350
//
351
int num = in.readShort();
352     for (int i = 0; i < num; i++) {
353         short nameId = in.readShort();
354         int type = in.readByte();
355         String JavaDoc name = in.readUTF();
356         defEntity(names[nameId], type | GENERAL, name);
357     }
358
359     // Read the elements
360
//
361
num = in.readShort();
362     for (int i = 0; i < num; i++) {
363         short nameId = in.readShort();
364         int type = in.readByte();
365         byte flags = in.readByte();
366         ContentModel JavaDoc m = readContentModel(in, names);
367         String JavaDoc[] exclusions = readNameArray(in, names);
368         String JavaDoc[] inclusions = readNameArray(in, names);
369         AttributeList JavaDoc atts = readAttributeList(in, names);
370         defElement(names[nameId], type,
371                ((flags & 0x01) != 0), ((flags & 0x02) != 0),
372                m, exclusions, inclusions, atts);
373     }
374     }
375
376     private ContentModel JavaDoc readContentModel(DataInputStream JavaDoc in, String JavaDoc[] names)
377         throws IOException JavaDoc {
378     byte flag = in.readByte();
379     switch(flag) {
380         case 0: // null
381
return null;
382         case 1: { // content_c
383
int type = in.readByte();
384         ContentModel JavaDoc m = readContentModel(in, names);
385         ContentModel JavaDoc next = readContentModel(in, names);
386         return defContentModel(type, m, next);
387         }
388         case 2: { // content_e
389
int type = in.readByte();
390         Element JavaDoc el = getElement(names[in.readShort()]);
391         ContentModel JavaDoc next = readContentModel(in, names);
392         return defContentModel(type, el, next);
393         }
394     default:
395         throw new IOException JavaDoc("bad bdtd");
396     }
397     }
398
399     private String JavaDoc[] readNameArray(DataInputStream JavaDoc in, String JavaDoc[] names)
400         throws IOException JavaDoc {
401     int num = in.readShort();
402     if (num == 0) {
403         return null;
404     }
405     String JavaDoc[] result = new String JavaDoc[num];
406     for (int i = 0; i < num; i++) {
407         result[i] = names[in.readShort()];
408     }
409     return result;
410     }
411
412
413     private AttributeList JavaDoc readAttributeList(DataInputStream JavaDoc in, String JavaDoc[] names)
414         throws IOException JavaDoc {
415     AttributeList JavaDoc result = null;
416     for (int num = in.readByte(); num > 0; --num) {
417         short nameId = in.readShort();
418         int type = in.readByte();
419         int modifier = in.readByte();
420         short valueId = in.readShort();
421         String JavaDoc value = (valueId == -1) ? null : names[valueId];
422         Vector JavaDoc values = null;
423         short numValues = in.readShort();
424         if (numValues > 0) {
425         values = new Vector JavaDoc(numValues);
426         for (int i = 0; i < numValues; i++) {
427             values.addElement(names[in.readShort()]);
428         }
429         }
430 result = new AttributeList JavaDoc(names[nameId], type, modifier, value,
431                        values, result);
432         // We reverse the order of the linked list by doing this, but
433
// that order isn't important.
434
}
435     return result;
436     }
437
438 }
439
Popular Tags