KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > xs > opti > SchemaDOM


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 2001, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.impl.xs.opti;
59
60 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
61 import com.sun.org.apache.xerces.internal.xni.QName;
62 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
63 import com.sun.org.apache.xerces.internal.xni.XMLString;
64 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
65 import org.w3c.dom.Attr JavaDoc;
66 import org.w3c.dom.Element JavaDoc;
67 import org.w3c.dom.NamedNodeMap JavaDoc;
68 import org.w3c.dom.Node JavaDoc;
69
70 import java.util.Vector JavaDoc;
71 import java.util.Enumeration JavaDoc;
72
73 /**
74  * @author Rahul Srivastava, Sun Microsystems Inc.
75  * @author Sandy Gao, IBM
76  *
77  * @version $Id: SchemaDOM.java,v 1.4 2003/07/03 15:15:58 neilg Exp $
78  */

79 public class SchemaDOM extends DefaultDocument {
80
81     static final int relationsRowResizeFactor = 15;
82     static final int relationsColResizeFactor = 10;
83
84     NodeImpl[][] relations;
85     // parent must be an element in this scheme
86
ElementImpl parent;
87     int currLoc;
88     int nextFreeLoc;
89     boolean hidden;
90
91     // for annotation support:
92
StringBuffer JavaDoc fAnnotationBuffer = null;
93
94     public SchemaDOM() {
95         reset();
96     }
97     
98
99     public void startElement(QName element, XMLAttributes attributes,
100                              int line, int column) {
101         ElementImpl node = new ElementImpl(line, column);
102         processElement(element, attributes, node);
103         // now the current node added, becomes the parent
104
parent = node;
105     }
106     
107     
108     public void emptyElement(QName element, XMLAttributes attributes,
109                              int line, int column) {
110         ElementImpl node = new ElementImpl(line, column);
111         processElement(element, attributes, node);
112     }
113     
114     
115     private void processElement(QName element, XMLAttributes attributes, ElementImpl node) {
116
117         // populate node
118
node.prefix = element.prefix;
119         node.localpart = element.localpart;
120         node.rawname = element.rawname;
121         node.uri = element.uri;
122         node.schemaDOM = this;
123         
124         // set the attributes
125
Attr JavaDoc[] attrs = new Attr JavaDoc[attributes.getLength()];
126         for (int i=0; i<attributes.getLength(); i++) {
127             attrs[i] = new AttrImpl(null,
128                                     attributes.getPrefix(i),
129                                     attributes.getLocalName(i),
130                                     attributes.getQName(i),
131                                     attributes.getURI(i),
132                                     attributes.getValue(i));
133         }
134         node.attrs = attrs;
135         
136         // check if array needs to be resized
137
if (nextFreeLoc == relations.length) {
138             resizeRelations();
139         }
140         
141         // store the current parent
142
//if (relations[currLoc][0] == null || relations[currLoc][0] != parent) {
143
if (relations[currLoc][0] != parent) {
144             relations[nextFreeLoc][0] = parent;
145             currLoc = nextFreeLoc++;
146         }
147         
148         // add the current node as child of parent
149
boolean foundPlace = false;
150         int i = 1;
151         for (i = 1; i<relations[currLoc].length; i++) {
152             if (relations[currLoc][i] == null) {
153                 foundPlace = true;
154                 break;
155             }
156         }
157         
158         if (!foundPlace) {
159             resizeRelations(currLoc);
160         }
161         relations[currLoc][i] = node;
162         
163         parent.parentRow = currLoc;
164         node.row = currLoc;
165         node.col = i;
166     }
167     
168     
169     public void endElement() {
170         // the parent of current parent node becomes the parent
171
// for the next node.
172
currLoc = parent.row;
173         parent = (ElementImpl)relations[currLoc][0];
174     }
175     
176     // note that this will only be called within appinfo/documentation
177
void comment(XMLString text) {
178         fAnnotationBuffer.append("<!--").append(text.toString()).append("-->");
179     }
180
181     // note that this will only be called within appinfo/documentation
182
void processingInstruction(String JavaDoc target, String JavaDoc data) {
183         fAnnotationBuffer.append("<?").append(target).append(" ").append(data).append("?>");
184     }
185     
186     // note that this will only be called within appinfo/documentation
187
void characters(XMLString text ) {
188         // need to handle &s and <s
189
for(int i=text.offset; i<text.offset+text.length; i++ ) {
190             if(text.ch[i] == '&') {
191                 fAnnotationBuffer.append("&amp;");
192             } else if (text.ch[i] == '<') {
193                 fAnnotationBuffer.append("&lt;");
194             } else {
195                 fAnnotationBuffer.append(text.ch[i]);
196             }
197         }
198     }
199
200     void endAnnotationElement(QName elemName, boolean complete) {
201         if(complete) {
202             fAnnotationBuffer.append("\n</").append(elemName.rawname).append(">");
203             // note that this is always called after endElement on <annotation>'s
204
// child and before endElement on annotation.
205
// hence, we must make this the child of the current
206
// parent's only child.
207
ElementImpl child = (ElementImpl)relations[currLoc][1];
208
209             // check if array needs to be resized
210
if (nextFreeLoc == relations.length) {
211                 resizeRelations();
212             }
213             int newRow = child.parentRow = nextFreeLoc++;
214         
215             // now find the place to insert this node
216
boolean foundPlace = false;
217             int i = 1;
218             for (; i<relations[newRow].length; i++) {
219                 if (relations[newRow][i] == null) {
220                     foundPlace = true;
221                     break;
222                 }
223             }
224         
225             if (!foundPlace) {
226                 resizeRelations(newRow);
227             }
228             relations[newRow][i] = new TextImpl(fAnnotationBuffer, this, newRow, i);
229             // apparently, there is no sensible way of resetting
230
// these things
231
fAnnotationBuffer = null;
232         } else //capturing character calls
233
fAnnotationBuffer.append("</").append(elemName.rawname).append(">");
234     }
235
236     void startAnnotationCDATA() {
237         fAnnotationBuffer.append("<![CDATA[");
238     }
239     
240     void endAnnotationCDATA() {
241         fAnnotationBuffer.append("]]>");
242     }
243     
244     private void resizeRelations() {
245         NodeImpl[][] temp = new NodeImpl[relations.length+relationsRowResizeFactor][];
246         System.arraycopy(relations, 0, temp, 0, relations.length);
247         for (int i = relations.length ; i < temp.length ; i++) {
248             temp[i] = new NodeImpl[relationsColResizeFactor];
249         }
250         relations = temp;
251     }
252     
253     private void resizeRelations(int i) {
254         NodeImpl[] temp = new NodeImpl[relations[i].length+relationsColResizeFactor];
255         System.arraycopy(relations[i], 0, temp, 0, relations[i].length);
256         relations[i] = temp;
257     }
258     
259     
260     public void reset() {
261         
262         // help out the garbage collector
263
if(relations != null)
264             for(int i=0; i<relations.length; i++)
265                 for(int j=0; j<relations[i].length; j++)
266                     relations[i][j] = null;
267         relations = new NodeImpl[relationsRowResizeFactor][];
268         parent = new ElementImpl(0, 0);
269         parent.rawname = "DOCUMENT_NODE";
270         currLoc = 0;
271         nextFreeLoc = 1;
272         for (int i=0; i<relationsRowResizeFactor; i++) {
273             relations[i] = new NodeImpl[relationsColResizeFactor];
274         }
275         relations[currLoc][0] = parent;
276     }
277     
278     
279     public void printDOM() {
280         /*
281         for (int i=0; i<relations.length; i++) {
282             if (relations[i][0] != null) {
283             for (int j=0; j<relations[i].length; j++) {
284                 if (relations[i][j] != null) {
285                     System.out.print(relations[i][j].nodeType+"-"+relations[i][j].parentRow+" ");
286                 }
287             }
288             System.out.println("");
289             }
290         }
291         */

292         //traverse(getDocumentElement(), 0);
293
}
294     
295     
296     // debug methods
297

298     public static void traverse(Node JavaDoc node, int depth) {
299         indent(depth);
300         System.out.print("<"+node.getNodeName());
301         
302         if (node.hasAttributes()) {
303             NamedNodeMap JavaDoc attrs = node.getAttributes();
304             for (int i=0; i<attrs.getLength(); i++) {
305                 System.out.print(" "+((Attr JavaDoc)attrs.item(i)).getName()+"=\""+((Attr JavaDoc)attrs.item(i)).getValue()+"\"");
306             }
307         }
308         
309         if (node.hasChildNodes()) {
310             System.out.println(">");
311             depth+=4;
312             for (Node JavaDoc child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
313                 traverse(child, depth);
314             }
315             depth-=4;
316             indent(depth);
317             System.out.println("</"+node.getNodeName()+">");
318         }
319         else {
320             System.out.println("/>");
321         }
322     }
323     
324     public static void indent(int amount) {
325         for (int i = 0; i < amount; i++) {
326             System.out.print(' ');
327         }
328     }
329     
330     // org.w3c.dom methods
331
public Element JavaDoc getDocumentElement() {
332         // this returns a parent node, known to be an ElementImpl
333
return (ElementImpl)relations[0][1];
334     }
335     
336     // commence the serialization of an annotation
337
void startAnnotation(QName elemName, XMLAttributes attributes,
338                 NamespaceContext namespaceContext) {
339         if(fAnnotationBuffer == null) fAnnotationBuffer = new StringBuffer JavaDoc(256);
340         fAnnotationBuffer.append("<").append(elemName.rawname).append(" ");
341
342         // attributes are a bit of a pain. To get this right, we have to keep track
343
// of the namespaces we've seen declared, then examine the namespace context
344
// for other namespaces so that we can also include them.
345
// optimized for simplicity and the case that not many
346
// namespaces are declared on this annotation...
347
Vector JavaDoc namespaces = new Vector JavaDoc();
348         for(int i=0; i<attributes.getLength(); i++) {
349             String JavaDoc aValue = attributes.getValue(i);
350             String JavaDoc aPrefix = attributes.getPrefix(i);
351             // if it's xmlns, must be a namespace decl
352
namespaces.addElement(aValue);
353             fAnnotationBuffer.append(attributes.getQName(i)).append("=\"").append(aValue).append("\" ");
354         }
355         // now we have to look through currently in-scope namespaces to see what
356
// wasn't declared here
357
Enumeration JavaDoc currPrefixes = namespaceContext.getAllPrefixes();
358         while(currPrefixes.hasMoreElements()) {
359             String JavaDoc prefix = (String JavaDoc)currPrefixes.nextElement();
360             String JavaDoc uri = namespaceContext.getURI(prefix);
361             if(!namespaces.contains(uri)) {
362                 // have to declare this one
363
if(prefix == XMLSymbols.EMPTY_STRING)
364                     fAnnotationBuffer.append("xmlns").append("=\"").append(uri).append("\" ");
365                 else
366                     fAnnotationBuffer.append("xmlns:").append(prefix).append("=\"").append(uri).append("\" ");
367             }
368         }
369         fAnnotationBuffer.append(">\n");
370     }
371     void startAnnotationElement(QName elemName, XMLAttributes attributes) {
372         fAnnotationBuffer.append("<").append(elemName.rawname).append(" ");
373         for(int i=0; i<attributes.getLength(); i++) {
374             String JavaDoc aValue = attributes.getValue(i);
375             fAnnotationBuffer.append(" ").append(attributes.getQName(i)).append("=\"").append(processAttValue(aValue)).append("\" ");
376         }
377         fAnnotationBuffer.append(">");
378     }
379     
380     private static String JavaDoc processAttValue(String JavaDoc original) {
381         // normally, nothing will happen
382
StringBuffer JavaDoc newVal = new StringBuffer JavaDoc(original.length());
383         for(int i=0; i<original.length(); i++) {
384             char currChar = original.charAt(i);
385             if(currChar == '"') {
386                 newVal.append("&quot;");
387             } else if (currChar == '>') {
388                 newVal.append("&gt;");
389             } else if (currChar == '&') {
390                 newVal.append("&amp;");
391             } else {
392                 newVal.append(currChar);
393             }
394         }
395         return newVal.toString();
396     }
397 }
398
Popular Tags