KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > xml > Policy


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.xml;
30
31 import com.caucho.util.CharBuffer;
32 import com.caucho.util.L10N;
33 import com.caucho.vfs.ReadStream;
34
35 import java.util.HashMap JavaDoc;
36
37 /**
38  * The Policy class defines the parsing policy. It configures the parser
39  * between HTML, XML, and loose versions of HTML and XML.
40  */

41 class Policy {
42   static L10N L = new L10N(Policy.class);
43   
44   final static int ERROR = 0;
45   final static int IGNORE = ERROR + 1;
46   final static int PUSH = IGNORE + 1;
47   final static int PUSH_EMPTY = PUSH + 1;
48   final static int PUSH_OPT = PUSH_EMPTY + 1;
49   final static int PUSH_VERBATIM = PUSH_OPT + 1;
50   final static int POP = PUSH_VERBATIM + 1;
51   final static int POP_AND_LOOP = POP + 1;
52
53   private NamespaceMap namespaces;
54   private HashMap JavaDoc nameCache = new HashMap JavaDoc();
55   private HashMap JavaDoc _attrCache = new HashMap JavaDoc();
56   protected QName opt;
57   protected ReadStream is;
58
59   boolean expandReferences = true;
60   boolean optionalTags = true;
61   boolean skipWhitespace;
62   boolean skipComments;
63   boolean strictComments;
64   boolean strictAttributes;
65   boolean entitiesAsText = false;
66   boolean expandEntities = true;
67   boolean strictCharacters;
68   boolean strictXml;
69   boolean singleTopElement;
70   boolean normalizeWhitespace = false;
71   boolean forgiving;
72   boolean _isNamespaceAware = false;
73
74   /**
75    * Initialize the policy.
76    */

77   void init()
78   {
79     namespaces = null;
80     nameCache.clear();
81     _attrCache.clear();
82     opt = null;
83     is = null;
84     
85     expandReferences = true;
86     optionalTags = true;
87     skipWhitespace = false;
88     skipComments = false;
89     strictComments = false;
90     strictAttributes = false;
91     entitiesAsText = false;
92     expandEntities = true;
93     strictCharacters = false;
94     strictXml = false;
95     singleTopElement = false;
96     normalizeWhitespace = false;
97     forgiving = false;
98     _isNamespaceAware = false;
99   }
100
101   /**
102    * Sets the current read stream.
103    */

104   void setStream(ReadStream is)
105   {
106     this.is = is;
107   }
108
109   QName getOpt()
110   {
111     return opt;
112   }
113
114   /**
115    * Sets the new namespace binding.
116    *
117    * @param ns the namespace
118    */

119   void setNamespace(NamespaceMap ns)
120   {
121     if (namespaces != ns) {
122       nameCache.clear();
123       _attrCache.clear();
124     }
125
126     namespaces = ns;
127   }
128
129   /**
130    * Set true for namespace aware.
131    */

132   void setNamespaceAware(boolean isNamespaceAware)
133   {
134     _isNamespaceAware = isNamespaceAware;
135   }
136
137   /**
138    * Clears the namespace cache when the namespace changes.
139    */

140   void clearNamespaceCache()
141   {
142     namespaces = null;
143     nameCache.clear();
144     _attrCache.clear();
145   }
146
147   QName getAttributeName(CharBuffer eltName, CharBuffer source)
148   {
149     return getAttributeName(eltName, source, false);
150   }
151   
152   /**
153    * Returns the qname for the named attribute.
154    *
155    * @param eltName the current node
156    * @param source the name of the attribute
157    *
158    * @param the QName including namespace for the attribute name.
159    */

160   QName getAttributeName(CharBuffer eltName, CharBuffer source, boolean nsNull)
161   {
162     QName qname = (QName) _attrCache.get(source);
163     if (qname != null)
164       return qname;
165
166     int i = source.lastIndexOf(':');
167     String JavaDoc fullName = source.toString();
168     String JavaDoc prefix = null;
169     String JavaDoc localName = null;
170     String JavaDoc ns = null;;
171
172     if (! _isNamespaceAware) {
173     }
174     else if (i < 0) {
175       localName = fullName;
176     }
177     else {
178       prefix = source.substring(0, i);
179       
180       ns = NamespaceMap.get(namespaces, prefix);
181
182       if (ns != null) {
183     localName = source.substring(i + 1);
184       }
185       else if ("xml".equals(prefix)) {
186     ns = XmlParser.XML;
187     localName = source.substring(i + 1);
188       }
189       else {
190     prefix = null;
191     localName = source.toString();
192       }
193     }
194
195     qname = new QName(fullName, prefix, localName, ns);
196
197     _attrCache.put(source.clone(), qname);
198
199     return qname;
200   }
201
202   /**
203    * Returns the fully qualified name, including namespaces, for the
204    * new qname.
205    *
206    * @param node the current parent node
207    * @param source the qname string needing resolving.
208    *
209    * @return the QName including namespace for the source.
210    */

211   QName getName(CharBuffer source)
212   {
213     QName qname = (QName) nameCache.get(source);
214     if (qname != null)
215       return qname;
216
217     int i = source.lastIndexOf(':');
218     String JavaDoc fullName = source.toString();
219     String JavaDoc prefix = null;
220     String JavaDoc localName = null;
221     String JavaDoc ns = null;;
222
223     if (! _isNamespaceAware) {
224     }
225     else if (i < 0) {
226       ns = NamespaceMap.get(namespaces, "");
227       localName = source.toString();
228     }
229     else {
230       prefix = source.substring(0, i);
231       
232       ns = NamespaceMap.get(namespaces, prefix);
233
234       if (ns != null) {
235     localName = source.substring(i + 1);
236       }
237       else {
238     prefix = null;
239     localName = source.toString();
240       }
241     }
242
243     qname = new QName(fullName, prefix, localName, ns);
244
245     nameCache.put(source.clone(), qname);
246
247     return qname;
248   }
249
250   /**
251    * Returns the fully qualified name, including namespaces, for the
252    * new qname.
253    *
254    * @param source the qname string needing resolving.
255    *
256    * @return the QName including namespace for the source.
257    */

258   QName getNamespaceName(CharBuffer source)
259   {
260     QName qname = (QName) nameCache.get(source);
261     if (qname != null)
262       return qname;
263
264     int i = source.lastIndexOf(':');
265     String JavaDoc prefix;
266     String JavaDoc localName;
267
268     // xml/01ek
269
if (true) {
270       prefix = null;
271       localName = source.toString();
272     }
273     else if (i < 0) {
274       prefix = null;
275       localName = source.toString();
276     }
277     else {
278       prefix = source.substring(0, i);
279       localName = source.substring(i + 1);
280     }
281
282     // xml/01ek vs xml/01eg
283
qname = new QName(prefix, localName, null); // XmlParser.XMLNS
284

285     nameCache.put(source.clone(), qname);
286
287     return qname;
288   }
289
290   /**
291    * Returns true if the string contains only whitespace.
292    *
293    * @param s string to test
294    * @return true if the string is completely whitespace
295    */

296   boolean isWhitespaceOnly(String JavaDoc s)
297   {
298     for (int i = s.length() - 1; i >= 0; i--)
299       if (! XmlChar.isWhitespace(s.charAt(i)))
300     return false;
301
302     return true;
303   }
304
305   /**
306    * Returns the action to be performed with the next node on an open
307    * tag. In general, for XML, the next node is just pushed into the tree.
308    *
309    * @param parser the current XML parser
310    * @param node the current node
311    * @param next the node that needs an action
312    *
313    * @return the action code for the next node
314    */

315   int openAction(XmlParser parser, QName node, QName next)
316     throws XmlParseException
317   {
318     String JavaDoc nodeName = node.getName();
319     /*
320     if (nodeName.equals("#document")) {
321       QDocument document = (QDocument) node;
322
323       switch (next.getNodeType()) {
324       case Node.TEXT_NODE:
325     if (isWhitespaceOnly(next.getNodeValue()))
326       return PUSH; // XXX: ignore
327     break;
328
329       case Node.COMMENT_NODE:
330       case Node.PROCESSING_INSTRUCTION_NODE:
331     return PUSH;
332       }
333
334       if (document.getDocumentElement() == null &&
335       next.getNodeType() == Node.ELEMENT_NODE) {
336     document.setDocumentElement((Element) next);
337     return PUSH;
338       }
339
340       Element elt = document.getDocumentElement();
341       return PUSH;
342     } else
343       return PUSH;
344     */

345     return PUSH;
346   }
347
348   /**
349    * Returns the action to be performed with the next node on a close
350    * tag. In general, for XML, the current node is changed to its parent
351    *
352    * @param parser the current XML parser
353    * @param node the current node
354    * @param tagEnd the name of the close tag
355    *
356    * @return the action code for the next node
357    */

358   int elementCloseAction(XmlParser parser, QName node, String JavaDoc tagEnd)
359     throws XmlParseException
360   {
361     String JavaDoc nodeName = node.getName();
362
363     if (nodeName.equals("#document") && tagEnd.equals(""))
364       return POP;
365     else if (nodeName.equals(tagEnd))
366       return POP;
367     else {
368       String JavaDoc expect = nodeName;
369       if (expect.equals("#document"))
370     expect = L.l("end of document");
371       else
372     expect = "`</" + expect + ">'";
373       if (tagEnd.equals(""))
374     tagEnd = L.l("end of file");
375       else
376     tagEnd = "`</" + tagEnd + ">'";
377
378       throw parser.error(L.l("expected {0} at {1}", expect, tagEnd));
379     }
380   }
381 }
382
Popular Tags