KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xni > PSVIWriter


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package xni;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Stack JavaDoc;
23 import java.util.Vector JavaDoc;
24
25 import org.apache.xerces.dom.DocumentImpl;
26 import org.apache.xerces.impl.Constants;
27 import org.apache.xerces.impl.xs.SchemaSymbols;
28 import org.apache.xerces.util.DOMUtil;
29 import org.apache.xerces.util.NamespaceSupport;
30 import org.apache.xerces.util.XMLAttributesImpl;
31 import org.apache.xerces.util.XMLSymbols;
32 import org.apache.xerces.xni.Augmentations;
33 import org.apache.xerces.xni.NamespaceContext;
34 import org.apache.xerces.xni.QName;
35 import org.apache.xerces.xni.XMLAttributes;
36 import org.apache.xerces.xni.XMLDocumentHandler;
37 import org.apache.xerces.xni.XMLLocator;
38 import org.apache.xerces.xni.XMLResourceIdentifier;
39 import org.apache.xerces.xni.XMLString;
40 import org.apache.xerces.xni.XNIException;
41 import org.apache.xerces.xni.parser.XMLComponent;
42 import org.apache.xerces.xni.parser.XMLComponentManager;
43 import org.apache.xerces.xni.parser.XMLConfigurationException;
44 import org.apache.xerces.xni.parser.XMLDocumentFilter;
45 import org.apache.xerces.xni.parser.XMLDocumentSource;
46 import org.apache.xerces.xs.AttributePSVI;
47 import org.apache.xerces.xs.ElementPSVI;
48 import org.apache.xerces.xs.ItemPSVI;
49 import org.apache.xerces.xs.StringList;
50 import org.apache.xerces.xs.XSAnnotation;
51 import org.apache.xerces.xs.XSAttributeDeclaration;
52 import org.apache.xerces.xs.XSAttributeGroupDefinition;
53 import org.apache.xerces.xs.XSAttributeUse;
54 import org.apache.xerces.xs.XSComplexTypeDefinition;
55 import org.apache.xerces.xs.XSConstants;
56 import org.apache.xerces.xs.XSElementDeclaration;
57 import org.apache.xerces.xs.XSFacet;
58 import org.apache.xerces.xs.XSIDCDefinition;
59 import org.apache.xerces.xs.XSModel;
60 import org.apache.xerces.xs.XSModelGroup;
61 import org.apache.xerces.xs.XSModelGroupDefinition;
62 import org.apache.xerces.xs.XSMultiValueFacet;
63 import org.apache.xerces.xs.XSNamedMap;
64 import org.apache.xerces.xs.XSNamespaceItem;
65 import org.apache.xerces.xs.XSNamespaceItemList;
66 import org.apache.xerces.xs.XSNotationDeclaration;
67 import org.apache.xerces.xs.XSObject;
68 import org.apache.xerces.xs.XSObjectList;
69 import org.apache.xerces.xs.XSParticle;
70 import org.apache.xerces.xs.XSSimpleTypeDefinition;
71 import org.apache.xerces.xs.XSTypeDefinition;
72 import org.apache.xerces.xs.XSWildcard;
73 import org.w3c.dom.Attr JavaDoc;
74 import org.w3c.dom.Element JavaDoc;
75 import org.w3c.dom.Node JavaDoc;
76 import org.xml.sax.SAXNotRecognizedException JavaDoc;
77 import org.xml.sax.SAXNotSupportedException JavaDoc;
78
79 /**
80  * This class is a intersepts XNI events and serialized
81  * XML infoset and Post Schema Validation Infoset.
82  *
83  * @author Arun Yadav,Sun Miscrosystem.
84  * @author Peter McCracken, IBM
85  * @version $Id: PSVIWriter.java,v 1.30 2005/01/11 13:47:23 mrglavas Exp $
86  */

87 public class PSVIWriter implements XMLComponent, XMLDocumentFilter {
88
89     public static final String JavaDoc XERCES_PSVI_NS =
90         "http://apache.org/xml/2001/PSVInfosetExtension";
91
92     /** Feature id: augment Post-Schema-Validation-Infoset */
93     protected static final String JavaDoc PSVINFOSET =
94         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
95
96     /** Feature id: include ignorable whitespace. */
97     protected static final String JavaDoc INCLUDE_IGNORABLE_WHITESPACE =
98         "http://apache.org/xml/features/dom/include-ignorable-whitespace";
99
100     /** Include ignorable whitespace. */
101     protected boolean fIncludeIgnorableWhitespace;
102
103     /** Recognized features. */
104     private static final String JavaDoc[] RECOGNIZED_FEATURES =
105         { INCLUDE_IGNORABLE_WHITESPACE, PSVINFOSET, };
106
107     /** Feature defaults. */
108     private static final Boolean JavaDoc[] FEATURE_DEFAULTS = { null, null, };
109
110     /** Recognized properties. */
111     private static final String JavaDoc[] RECOGNIZED_PROPERTIES = {
112     };
113
114     /** Property defaults. */
115     private static final Object JavaDoc[] PROPERTY_DEFAULTS = {
116     };
117
118     /** PSVInfoset */
119     protected boolean fPSVInfoset;
120
121     /** Document handler. */
122     protected XMLDocumentHandler fDocumentHandler;
123
124     /** Document source */
125     protected XMLDocumentSource fDocumentSource;
126
127     /** The namespace context for the received event stream */
128     protected NamespaceContext fNamespaceContext;
129
130     /** The namespace context for the new event stream */
131     protected NamespaceContext fPSVINamespaceContext;
132
133     /** Document Location */
134     protected XMLLocator fDocumentLocation;
135
136     /** Attributes and Element Info is cached in stack */
137     private Stack JavaDoc _elementState = new Stack JavaDoc();
138
139     /** The number used for anonymous types */
140     protected int fAnonNum;
141
142     /** The number that stores the indent level */
143     protected int fIndent;
144
145     /** The map used to store IDs for types and elements */
146     protected HashMap JavaDoc fIDMap;
147
148     /** A list of ids for defined XSObjects */
149     protected Vector JavaDoc fDefined;
150
151     private char[] fIndentChars =
152         { '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t' };
153
154     private XMLString newLine = new XMLString(new char[] { '\n' }, 0, 1);
155
156     public PSVIWriter() {
157         /*
158         System.out.println(
159             "Generating Schema Information Set Contribution (PSVI) \n"
160                 + "which follow as a consequence of validation and/or assessment.");
161
162         System.out.println("NOTE: Requires use of -s and -v");
163         System.out.println("Output: generated in " + PSVI_OUTPUT);
164         */

165     } // <init>()
166

167     public void reset(XMLComponentManager componentManager)
168         throws XNIException {
169
170         try {
171             fPSVInfoset = componentManager.getFeature(PSVINFOSET);
172         }
173         catch (XMLConfigurationException e) {
174             fPSVInfoset = false;
175         }
176         fIncludeIgnorableWhitespace =
177             componentManager.getFeature(INCLUDE_IGNORABLE_WHITESPACE);
178
179         fAnonNum = 1000;
180         fIDMap = new HashMap JavaDoc();
181         fDefined = new Vector JavaDoc();
182         fIndent = 0;
183         fPSVINamespaceContext = new NamespaceSupport();
184     } // reset(XMLComponentManager)
185

186     /**
187      * Returns a list of feature identifiers that are recognized by
188      * this component. This method may return null if no features
189      * are recognized by this component.
190      */

191     public String JavaDoc[] getRecognizedFeatures() {
192         return RECOGNIZED_FEATURES;
193     } // getRecognizedFeatures():String[]
194

195     /**
196      * Sets the state of a feature. This method is called by the component
197      * manager any time after reset when a feature changes state.
198      * <p>
199      * <strong>Note:</strong> Components should silently ignore features
200      * that do not affect the operation of the component.
201      *
202      * @param featureId The feature identifier.
203      * @param state The state of the feature.
204      *
205      * @throws SAXNotRecognizedException The component should not throw
206      * this exception.
207      * @throws SAXNotSupportedException The component should not throw
208      * this exception.
209      */

210     public void setFeature(String JavaDoc featureId, boolean state)
211         throws XMLConfigurationException {
212     } // setFeature(String,boolean)
213

214     /**
215      * Returns a list of property identifiers that are recognized by
216      * this component. This method may return null if no properties
217      * are recognized by this component.
218      */

219     public String JavaDoc[] getRecognizedProperties() {
220         return RECOGNIZED_PROPERTIES;
221     } // getRecognizedProperties():String[]
222

223     /**
224      * Sets the value of a property. This method is called by the component
225      * manager any time after reset when a property changes value.
226      * <p>
227      * <strong>Note:</strong> Components should silently ignore properties
228      * that do not affect the operation of the component.
229      *
230      * @param propertyId The property identifier.
231      * @param value The value of the property.
232      *
233      * @throws SAXNotRecognizedException The component should not throw
234      * this exception.
235      * @throws SAXNotSupportedException The component should not throw
236      * this exception.
237      */

238     public void setProperty(String JavaDoc propertyId, Object JavaDoc value)
239         throws XMLConfigurationException {
240
241     } // setProperty(String,Object)
242

243     /**
244      * Returns the default state for a feature, or null if this
245      * component does not want to report a default value for this
246      * feature.
247      *
248      * @param featureId The feature identifier.
249      *
250      * @since Xerces 2.2.0
251      */

252     public Boolean JavaDoc getFeatureDefault(String JavaDoc featureId) {
253         for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
254             if (RECOGNIZED_FEATURES[i].equals(featureId)) {
255                 return FEATURE_DEFAULTS[i];
256             }
257         }
258         return null;
259     } // getFeatureDefault(String):Boolean
260

261     /**
262      * Returns the default state for a property, or null if this
263      * component does not want to report a default value for this
264      * property.
265      *
266      * @param propertyId The property identifier.
267      *
268      * @since Xerces 2.2.0
269      */

270     public Object JavaDoc getPropertyDefault(String JavaDoc propertyId) {
271         for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
272             if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
273                 return PROPERTY_DEFAULTS[i];
274             }
275         }
276         return null;
277     } // getPropertyDefault(String):Object
278

279     //
280
// XMLDocumentSource methods
281
//
282

283     /** Sets the document handler to receive information about the document. */
284     public void setDocumentHandler(XMLDocumentHandler documentHandler) {
285         fDocumentHandler = documentHandler;
286     } // setDocumentHandler(XMLDocumentHandler)
287

288     /** Returns the document handler */
289     public XMLDocumentHandler getDocumentHandler() {
290         return fDocumentHandler;
291     } // setDocumentHandler(XMLDocumentHandler)
292

293     //
294
// XMLDocumentHandler methods
295
//
296

297     /** Sets the document source */
298     public void setDocumentSource(XMLDocumentSource source) {
299         fDocumentSource = source;
300     } // setDocumentSource
301

302     /** Returns the document source */
303     public XMLDocumentSource getDocumentSource() {
304         return fDocumentSource;
305     } // getDocumentSource
306

307     /**
308      * This method notifies the start of an entity. General entities are just
309      * specified by their name.
310      * <p>
311      * <strong>Note:</strong> This method is not called for entity references
312      * appearing as part of attribute values.
313      *
314      * @param name The name of the entity.
315      * @param publicId The public identifier of the entity if the entity
316      * is external, null otherwise.
317      * @param systemId The system identifier of the entity if the entity
318      * is external, null otherwise.
319      * @param baseSystemId The base system identifier of the entity if
320      * the entity is external, null otherwise.
321      * @param encoding The auto-detected IANA encoding name of the entity
322      * stream. This value will be null in those situations
323      * where the entity encoding is not auto-detected (e.g.
324      * internal entities or a document entity that is
325      * parsed from a java.io.Reader).
326      * @param augs Additional information that may include infoset augmentations
327      *
328      * @throws XNIException Thrown by handler to signal an error.
329      */

330     public void startGeneralEntity(
331         String JavaDoc name,
332         XMLResourceIdentifier identifier,
333         String JavaDoc encoding,
334         Augmentations augs)
335         throws XNIException {
336     } // startEntity(String,String,String,String,String)
337

338     /**
339      * Notifies of the presence of a TextDecl line in an entity. If present,
340      * this method will be called immediately following the startEntity call.
341      * <p>
342      * <strong>Note:</strong> This method will never be called for the
343      * document entity; it is only called for external general entities
344      * referenced in document content.
345      * <p>
346      * <strong>Note:</strong> This method is not called for entity references
347      * appearing as part of attribute values.
348      *
349      * @param version The XML version, or null if not specified.
350      * @param encoding The IANA encoding name of the entity.
351      * @param augs Additional information that may include infoset augmentations
352      *
353      * @throws XNIException Thrown by handler to signal an error.
354      */

355     public void textDecl(String JavaDoc version, String JavaDoc encoding, Augmentations augs)
356         throws XNIException {
357     } // textDecl(String,String)
358

359     /**
360      * The start of the document.
361      * @throws XNIException Thrown by handler to signal an error.
362      */

363     public void startDocument(
364         XMLLocator locator,
365         String JavaDoc encoding,
366         NamespaceContext namespaceContext,
367         Augmentations augs)
368         throws XNIException {
369         fNamespaceContext = namespaceContext;
370         fDocumentLocation = locator;
371
372         fPSVINamespaceContext.declarePrefix(
373             "xsi",
374             "http://www.w3.org/2001/XMLSchema-instance");
375         fPSVINamespaceContext.declarePrefix("psv", XERCES_PSVI_NS);
376         fPSVINamespaceContext.declarePrefix(
377             "",
378             "http://www.w3.org/2001/05/XMLInfoset");
379
380         if (fDocumentHandler == null)
381             return;
382
383         fDocumentHandler.startDocument(
384             locator,
385             "UTF-8",
386             fPSVINamespaceContext,
387             null);
388
389         Vector JavaDoc attributes = new Vector JavaDoc();
390         attributes.add("xmlns:xsi");
391         attributes.add("http://www.w3.org/2001/XMLSchema-instance");
392         attributes.add(XMLSymbols.fCDATASymbol);
393         attributes.add("xmlns:psv");
394         attributes.add(XERCES_PSVI_NS);
395         attributes.add(XMLSymbols.fCDATASymbol);
396         attributes.add("xmlns");
397         attributes.add("http://www.w3.org/2001/05/XMLInfoset");
398         attributes.add(XMLSymbols.fCDATASymbol);
399         sendIndentedElement("document", attributes);
400     } // startDocument(XMLLocator,String)
401

402     /**
403      * Notifies of the presence of an XMLDecl line in the document. If
404      * present, this method will be called immediately following the
405      * startDocument call.
406      *
407      * @param version The XML version.
408      * @param encoding The IANA encoding name of the document, or null if
409      * not specified.
410      * @param standalone The standalone value, or null if not specified.
411      * @param augs Additional information that may include infoset augmentations
412      *
413      * @throws XNIException Thrown by handler to signal an error.
414      */

415     public void xmlDecl(
416         String JavaDoc version,
417         String JavaDoc encoding,
418         String JavaDoc standalone,
419         Augmentations augs)
420         throws XNIException {
421         if (fDocumentHandler == null)
422             return;
423
424         sendElementEvent("characterEncodingScheme", encoding);
425         sendElementEvent("standalone", standalone);
426         sendElementEvent("version", version);
427     } // xmlDecl(String,String,String)
428

429     /**
430      * Notifies of the presence of the DOCTYPE line in the document.
431      *
432      * @param rootElement The name of the root element.
433      * @param publicId The public identifier if an external DTD or null
434      * if the external DTD is specified using SYSTEM.
435      * @param systemId The system identifier if an external DTD, null
436      * otherwise.
437      * @param augs Additional information that may include infoset augmentations
438      *
439      * @throws XNIException Thrown by handler to signal an error.
440      */

441     public void doctypeDecl(
442         String JavaDoc rootElement,
443         String JavaDoc publicId,
444         String JavaDoc systemId,
445         Augmentations augs)
446         throws XNIException {
447         if (fDocumentHandler == null)
448             return;
449
450         checkForChildren();
451         sendIndentedElement("docTypeDeclaration");
452         if (publicId != null)
453             sendElementEvent("publicIdentifier", publicId);
454         if (systemId != null)
455             sendElementEvent("systemIdentifier", systemId);
456         sendUnIndentedElement("docTypeDeclaration");
457     } // doctypeDecl(String,String,String)
458

459     /**
460      * A comment.
461      *
462      * @param text The text in the comment.
463      * @param augs Additional information that may include infoset augmentations
464      *
465      * @throws XNIException Thrown by application to signal an error.
466      */

467     public void comment(XMLString text, Augmentations augs)
468         throws XNIException {
469         if (fDocumentHandler == null)
470             return;
471
472         checkForChildren();
473         sendIndentedElement("comment");
474         sendElementEvent("content", text);
475         sendUnIndentedElement("comment");
476     } // comment(XMLString)
477

478     /**
479      * A processing instruction. Processing instructions consist of a
480      * target name and, optionally, text data. The data is only meaningful
481      * to the application.
482      * <p>
483      * Typically, a processing instruction's data will contain a series
484      * of pseudo-attributes. These pseudo-attributes follow the form of
485      * element attributes but are <strong>not</strong> parsed or presented
486      * to the application as anything other than text. The application is
487      * responsible for parsing the data.
488      *
489      * @param target The target.
490      * @param data The data or null if none specified.
491      * @param augs Additional information that may include infoset augmentations
492      *
493      * @throws XNIException Thrown by handler to signal an error.
494      */

495     public void processingInstruction(
496         String JavaDoc target,
497         XMLString data,
498         Augmentations augs)
499         throws XNIException {
500         if (fDocumentHandler == null)
501             return;
502
503         checkForChildren();
504         sendIndentedElement("processingInstruction");
505         sendElementEvent("target", target);
506         sendElementEvent("content", data);
507         sendUnIndentedElement("processingInstruction");
508     } // processingInstruction(String,XMLString)
509

510     /**
511      * Binds the namespaces. This method will handle calling the
512      * document handler to start the prefix mappings.
513      * <p>
514      * <strong>Note:</strong> This method makes use of the
515      * fAttributeQName variable. Any contents of the variable will
516      * be destroyed. Caller should copy the values out of this
517      * temporary variable before calling this method.
518      *
519      * @param element The name of the element.
520      * @param attributes The element attributes.
521      * @param augs Additional information that may include infoset augmentations
522      *
523      * @throws XNIException Thrown by handler to signal an error.
524      */

525     public void startElement(
526         QName element,
527         XMLAttributes attributes,
528         Augmentations augs)
529         throws XNIException {
530         if (fDocumentHandler == null)
531             return;
532
533         checkForChildren();
534
535         _elementState.push(new ElementState(true));
536
537         sendIndentedElement("element");
538         sendElementEvent("namespaceName", element.uri);
539         sendElementEvent("localName", element.localpart);
540         sendElementEvent("prefix", element.prefix);
541         processAttributes(attributes);
542         processInScopeNamespaces();
543         sendElementEvent("baseURI", fDocumentLocation.getBaseSystemId());
544         if (fPSVInfoset) {
545             processPSVIStartElement(augs);
546         }
547     } // startElement(QName,XMLAttributes)
548

549     /**
550      * An empty element.
551      *
552      * @param element The name of the element.
553      * @param attributes The element attributes.
554      * @param augs Additional information that may include infoset augmentations
555      *
556      * @throws XNIException Thrown by handler to signal an error.
557      */

558     public void emptyElement(
559         QName element,
560         XMLAttributes attributes,
561         Augmentations augs)
562         throws XNIException {
563         if (fDocumentHandler == null)
564             return;
565
566         checkForChildren();
567         sendIndentedElement("element");
568         sendElementEvent("namespaceName", element.uri);
569         sendElementEvent("localName", element.localpart);
570         sendElementEvent("prefix", element.prefix);
571         processAttributes(attributes);
572         processInScopeNamespaces();
573         sendElementEvent("baseURI", fDocumentLocation.getBaseSystemId());
574         if (fPSVInfoset) {
575             processPSVIStartElement(augs);
576         }
577         sendEmptyElementEvent("children");
578         if (fPSVInfoset) {
579             processPSVIEndElement(augs);
580         }
581         sendUnIndentedElement("element");
582     } // emptyElement(QName,XMLAttributes)
583

584     /**
585      * Character content.
586      *
587      * @param text The content.
588      * @param augs Additional information that may include infoset augmentations
589      *
590      * @throws XNIException Thrown by handler to signal an error.
591      */

592     public void characters(XMLString text, Augmentations augs)
593         throws XNIException {
594         if (fDocumentHandler == null)
595             return;
596
597         checkForChildren();
598         sendIndentedElement("character");
599         sendElementEvent("textContent", text);
600         // detecting whitespace is not relevant here
601
// this is only useful if characters are output individually
602
sendUnIndentedElement("character");
603     } // characters(XMLString)
604

605     /**
606      * Ignorable whitespace. For this method to be called, the document
607      * source must have some way of determining that the text containing
608      * only whitespace characters should be considered ignorable. For
609      * example, the validator can determine if a length of whitespace
610      * characters in the document are ignorable based on the element
611      * content model.
612      *
613      * @param text The ignorable whitespace.
614      * @param augs Additional information that may include infoset augmentations
615      *
616      * @throws XNIException Thrown by handler to signal an error.
617      */

618     public void ignorableWhitespace(XMLString text, Augmentations augs)
619         throws XNIException {
620         if (fDocumentHandler == null)
621             return;
622
623         if (fIncludeIgnorableWhitespace) {
624             this.characters(text, augs);
625         }
626     } // ignorableWhitespace(XMLString)
627

628     /**
629      * The end of an element.
630      *
631      * @param element The name of the element.
632      * @param augs Additional information that may include infoset augmentations
633      *
634      * @throws XNIException Thrown by handler to signal an error.
635      */

636     public void endElement(QName element, Augmentations augs)
637         throws XNIException {
638         if (fDocumentHandler == null)
639             return;
640
641         ElementState fElementState = (ElementState)_elementState.peek();
642         if (fElementState.isEmpty) {
643             sendEmptyElementEvent("children");
644         }
645         else {
646             sendUnIndentedElement("children");
647         }
648         _elementState.pop();
649         if (fPSVInfoset) {
650             processPSVIStartElement(augs);
651             processPSVIEndElement(augs);
652         }
653         sendUnIndentedElement("element");
654     } // endElement(QName)
655

656     /**
657      * The start of a CDATA section.
658      *
659      * @param augs Additional information that may include infoset augmentations
660      *
661      * @throws XNIException Thrown by handler to signal an error.
662      */

663     public void startCDATA(Augmentations augs) throws XNIException {
664     } // startCDATA()
665

666     /**
667      * The end of a CDATA section.
668      *
669      * @param augs Additional information that may include infoset augmentations
670      *
671      * @throws XNIException Thrown by handler to signal an error.
672      */

673     public void endCDATA(Augmentations augs) throws XNIException {
674     } // endCDATA()
675

676     /**
677      * The end of the document.
678      *
679      * @param augs Additional information that may include infoset augmentations
680      *
681      * @throws XNIException Thrown by handler to signal an error.
682      */

683     public void endDocument(Augmentations augs) throws XNIException {
684         if (fDocumentHandler == null)
685             return;
686
687         sendUnIndentedElement("children");
688         sendElementEvent("documentElement");
689         // these aren't relevent for PSVI
690
sendEmptyElementEvent("notations");
691         sendEmptyElementEvent("unparsedEntities");
692
693         sendElementEvent("baseURI", fDocumentLocation.getBaseSystemId());
694
695         // do we ALWAYS process all declarations? I think so - PJM
696
// this isn't relevant to PSVI
697
sendElementEvent("allDeclarationsProcessed", "true");
698         sendUnIndentedElement("document");
699         fDocumentHandler.endDocument(null);
700     } // endDocument()
701

702     /**
703      * This method notifies the end of an entity. General entities are just
704      * specified by their name.
705      * <p>
706      * <strong>Note:</strong> This method is not called for entity references
707      * appearing as part of attribute values.
708      *
709      * @param name The name of the entity.
710      * @param augs Additional information that may include infoset augmentations
711      *
712      * @throws XNIException Thrown by handler to signal an error.
713      */

714     public void endGeneralEntity(String JavaDoc name, Augmentations augs)
715         throws XNIException {
716     } // endEntity(String)
717

718     /**
719      * Write an unordered set of attribute information items, one for each of
720      * the attributes (specified or defaulted from the DTD) of this element.
721      * Namespace declarations do not appear in this set. If the element has no
722      * attributes, this set has no members.
723      */

724     private void processAttributes(XMLAttributes attributes) {
725         boolean namespaceAttribute = false;
726         boolean attrElement = false;
727
728          int attrCount = attributes == null ? 0 : attributes.getLength();
729
730         if (attrCount == 0) {
731             sendEmptyElementEvent("attributes");
732             sendEmptyElementEvent("namespaceAttributes");
733             return;
734         }
735
736         for (int i = 0; i < attrCount; i++) {
737             String JavaDoc localpart = attributes.getLocalName(i);
738             String JavaDoc prefix = attributes.getPrefix(i);
739             if (prefix.equals(XMLSymbols.PREFIX_XMLNS)
740                 || localpart.equals(XMLSymbols.PREFIX_XMLNS)) {
741                 namespaceAttribute = true;
742                 continue;
743             }
744             if (!attrElement)
745                 sendIndentedElement("attributes");
746
747             sendIndentedElement("attribute");
748             sendElementEvent("namespaceName", attributes.getURI(i));
749             sendElementEvent("localName", attributes.getLocalName(i));
750             sendElementEvent("prefix", attributes.getPrefix(i));
751             sendElementEvent("normalizedValue", attributes.getValue(i));
752             sendElementEvent(
753                 "specified",
754                 String.valueOf(attributes.isSpecified(i)));
755             sendElementEvent("attributeType", attributes.getType(i));
756
757             // this property isn't relevent to PSVI
758
sendElementEvent("references");
759
760             if (fPSVInfoset) {
761                 processPSVIAttribute(attributes.getAugmentations(i));
762             }
763             sendUnIndentedElement("attribute");
764             attrElement = true;
765         }
766         if (attrElement) {
767             sendUnIndentedElement("attributes");
768         }
769         else {
770             sendEmptyElementEvent("attributes");
771         }
772
773         if (namespaceAttribute) {
774             processNamespaceAttributes(attributes);
775         }
776         else {
777             sendEmptyElementEvent("namespaceAttributes");
778         }
779     } //printAttributes
780

781     /**
782     * Write an unordered set of attribute information items, one for each of
783     * the namespace declarations (specified or defaulted from the DTD) of this
784     * element. A declaration of the form xmlns="", which undeclares the default
785     * namespace, counts as a namespace declaration. By definition, all
786     * namespace attributes (including those named xmlns, whose [prefix]
787     * property has no value) have a namespace URI of
788     * http://www.w3.org/2000/xmlns/. If the element has no namespace
789     * declarations, this set has no members
790     */

791     private void processNamespaceAttributes(XMLAttributes attributes) {
792
793         // we don't need to check for null, since that was checked for in processAttributes()
794
int attrCount = attributes.getLength();
795
796         sendIndentedElement("namespaceAttributes");
797         for (int i = 0; i < attrCount; i++) {
798             String JavaDoc localpart = attributes.getLocalName(i);
799             String JavaDoc prefix = attributes.getPrefix(i);
800             if (!(prefix.equals(XMLSymbols.PREFIX_XMLNS)
801                 || localpart.equals(XMLSymbols.PREFIX_XMLNS)))
802                 continue;
803             sendIndentedElement("attribute");
804             sendElementEvent("namespaceName", NamespaceContext.XMLNS_URI);
805             sendElementEvent("localName", localpart);
806             sendElementEvent("prefix", prefix);
807             sendElementEvent("normalizedValue", attributes.getValue(i));
808             sendElementEvent(
809                 "specified",
810                 String.valueOf(attributes.isSpecified(i)));
811             sendElementEvent("attributeType", attributes.getType(i));
812             // this property isn't relevent to PSVI
813
sendElementEvent("references");
814             if (fPSVInfoset) {
815                 processPSVIAttribute(attributes.getAugmentations(i));
816             }
817             sendUnIndentedElement("attribute");
818         }
819         sendUnIndentedElement("namespaceAttributes");
820
821     } //printNamespacesAttributes()
822

823     /**
824      * Write an unordered set of namespace information items, one for each of the
825      * namespaces in effect for this element. This set always contains an item
826      * with the prefix xml which is implicitly bound to the namespace name
827      * http://www.w3.org/XML/1998/namespace. It does not contain an item with the
828      * prefix xmlns (used for declaring namespaces), since an application can
829      * never encounter an element or attribute with that prefix. The set will
830      * include namespace items corresponding to all of the members of
831      * [namespace attributes], except for any representing a declaration of the
832      * form xmlns="", which does not declare a namespace but rather undeclares
833      * the default namespace
834      */

835     private void processInScopeNamespaces() {
836         sendIndentedElement("inScopeNamespaces");
837         sendIndentedElement("namespace");
838         // print 'xml' binding
839
sendElementEvent("prefix", "xml");
840         sendElementEvent("namespaceName", NamespaceContext.XML_URI);
841         sendUnIndentedElement("namespace");
842         Enumeration JavaDoc prefixes = fNamespaceContext.getAllPrefixes();
843         while (prefixes.hasMoreElements()) {
844             sendIndentedElement("namespace");
845
846             String JavaDoc prefix = (String JavaDoc)prefixes.nextElement();
847             String JavaDoc uri = fNamespaceContext.getURI(prefix);
848             sendElementEvent("prefix", prefix);
849             sendElementEvent("namespaceName", uri);
850             sendUnIndentedElement("namespace");
851
852         }
853         sendUnIndentedElement("inScopeNamespaces");
854     } //printinScopeNamespaces()
855

856     /* The following information will be available at the startElement call:
857     * name, namespace, type, notation, validation context
858     *
859     * The following information will be available at the endElement call:
860     * nil, specified, normalized value, member type, validity, error codes,
861     * default
862     */

863     private void processPSVIStartElement(Augmentations augs) {
864         if (augs == null)
865             return;
866         ElementPSVI elemPSVI =
867             (ElementPSVI)augs.getItem(Constants.ELEMENT_PSVI);
868         if (elemPSVI != null) {
869             // Should we store the values till end element call? -- AY
870
// I don't think so -- PJM
871
}
872     }
873
874     /* The following information will be available at the startElement call:
875     * name, namespace, type, notation, validation context
876     *
877     * The following information will be available at the endElement call:
878     * nil, specified, normalized value, member type, validity, error codes,
879     * default
880     */

881     private void processPSVIEndElement(Augmentations augs) {
882         if (augs == null)
883             return;
884         ElementPSVI elemPSVI =
885             (ElementPSVI)augs.getItem(Constants.ELEMENT_PSVI);
886         if (elemPSVI != null) {
887
888             processPSVISchemaInformation(elemPSVI);
889             sendElementEvent(
890                 "psv:validationAttempted",
891                 this.translateValidationAttempted(
892                     elemPSVI.getValidationAttempted()));
893             // Would rather getValidationContext() return element info item.
894
// This is non the same as XSV.
895
sendElementEvent(
896                 "psv:validationContext",
897                 elemPSVI.getValidationContext());
898
899             sendElementEvent(
900                 "psv:validity",
901                 this.translateValidity(elemPSVI.getValidity()));
902
903             processPSVISchemaErrorCode(elemPSVI.getErrorCodes());
904             sendElementEvent(
905                 "psv:schemaNormalizedValue",
906                 elemPSVI.getSchemaNormalizedValue());
907             sendElementEvent(
908                 "psv:schemaSpecified",
909                 elemPSVI.getIsSchemaSpecified() ? "schema" : "infoset");
910             sendElementEvent("psv:schemaDefault", elemPSVI.getSchemaDefault());
911
912             processPSVITypeDefinitionRef(
913                 "psv:typeDefinition",
914                 elemPSVI.getTypeDefinition());
915             processPSVITypeDefinitionRef(
916                 "psv:memberTypeDefinition",
917                 elemPSVI.getMemberTypeDefinition());
918             // A value for nil is not necessary, since we output declaration, instead.
919
// See http://www.w3.org/TR/xmlschema-1/#section-Element-Declaration-Information-Set-Contributions.
920
sendElementEvent("psv:nil");
921
922             sendIndentedElement("psv:declaration");
923             processPSVIElementRef(
924                 "psv:elementDeclaration",
925                 elemPSVI.getElementDeclaration());
926             sendUnIndentedElement("psv:declaration");
927             processPSVIElementRef("psv:notation", elemPSVI.getNotation());
928             // idref table does not have to be exposed, and is not exposed
929
sendElementEvent("psv:idIdrefTable");
930             // identity constraint table does not have to be exposed, and is not exposed
931
sendElementEvent("psv:identityConstraintTable");
932         }
933     }
934
935     private void processPSVIAttribute(Augmentations augs) {
936         if (augs == null)
937             return;
938         AttributePSVI attrPSVI =
939             (AttributePSVI)augs.getItem(Constants.ATTRIBUTE_PSVI);
940         if (attrPSVI != null) {
941             sendElementEvent(
942                 "psv:validationAttempted",
943                 this.translateValidationAttempted(
944                     attrPSVI.getValidationAttempted()));
945             // Would rather getValidationContext() return element info item.
946
// This is not the same as XSV.
947
sendElementEvent(
948                 "psv:validationContext",
949                 attrPSVI.getValidationContext());
950
951             sendElementEvent(
952                 "psv:validity",
953                 this.translateValidity(attrPSVI.getValidity()));
954
955             processPSVISchemaErrorCode(attrPSVI.getErrorCodes());
956             sendElementEvent(
957                 "psv:schemaNormalizedValue",
958                 attrPSVI.getSchemaNormalizedValue());
959             sendElementEvent(
960                 "psv:schemaSpecified",
961                 attrPSVI.getIsSchemaSpecified() ? "schema" : "infoset");
962             sendElementEvent("psv:schemaDefault", attrPSVI.getSchemaDefault());
963
964             processPSVITypeDefinitionRef(
965                 "psv:typeDefinition",
966                 attrPSVI.getTypeDefinition());
967             processPSVITypeDefinitionRef(
968                 "psv:memberTypeDefinition",
969                 attrPSVI.getMemberTypeDefinition());
970
971             if (attrPSVI.getAttributeDeclaration() == null) {
972                 sendElementEvent("psv:declaration");
973             }
974             else {
975                 sendIndentedElement("psv:declaration");
976                 processPSVIAttributeDeclarationRef(
977                     attrPSVI.getAttributeDeclaration());
978                 sendUnIndentedElement("psv:declaration");
979             }
980         }
981     }
982
983     private void processPSVISchemaErrorCode(StringList errorCodes) {
984         StringBuffer JavaDoc errorBuffer = new StringBuffer JavaDoc();
985         if (errorCodes != null && errorCodes.getLength() > 0) {
986             for (int i = 0; i < errorCodes.getLength() - 1; i++) {
987                 errorBuffer.append(errorCodes.item(i));
988                 errorBuffer.append(" ");
989             }
990             errorBuffer.append(errorCodes.item(errorCodes.getLength() - 1));
991         }
992         sendElementEvent("psv:schemaErrorCode", errorBuffer.toString());
993     }
994
995     private void processPSVISchemaInformation(ElementPSVI elemPSVI) {
996         if (elemPSVI == null)
997             return;
998         XSModel schemaInfo = elemPSVI.getSchemaInformation();
999         XSNamespaceItemList schemaNamespaces =
1000            schemaInfo == null ? null : schemaInfo.getNamespaceItems();
1001        if (schemaNamespaces == null || schemaNamespaces.getLength() == 0) {
1002            sendElementEvent("psv:schemaInformation");
1003        }
1004        else {
1005            sendIndentedElement("psv:schemaInformation");
1006            for (int i = 0; i < schemaNamespaces.getLength(); i++) {
1007                processPSVINamespaceItem(schemaNamespaces.item(i));
1008            }
1009            sendUnIndentedElement("psv:schemaInformation");
1010        }
1011    }
1012
1013    private void processPSVINamespaceItem(XSNamespaceItem item) {
1014        if (item == null)
1015            return;
1016
1017        String JavaDoc namespace = item.getSchemaNamespace();
1018        if (namespace != null && namespace.equals(Constants.NS_XMLSCHEMA)) {
1019            // we don't want to output information for schema for schemas
1020
return;
1021        }
1022
1023        sendIndentedElement("psv:namespaceSchemaInformation");
1024        sendElementEvent("psv:schemaNamespace", namespace);
1025
1026        // print out schema components
1027
processPSVISchemaComponents(item);
1028
1029        // print out schema document information
1030
processPSVISchemaDocuments(item);
1031
1032        // print out schema annotations
1033
processPSVISchemaAnnotations(item.getAnnotations());
1034        sendUnIndentedElement("psv:namespaceSchemaInformation");
1035    }
1036
1037    private void processPSVISchemaDocuments(XSNamespaceItem item) {
1038        StringList locations =
1039            item == null ? null : item.getDocumentLocations();
1040        if (locations == null || locations.getLength() == 0) {
1041            sendEmptyElementEvent("psv:schemaDocuments");
1042            return;
1043        }
1044        sendIndentedElement("psv:schemaDocuments");
1045        for (int i = 0; i < locations.getLength(); i++) {
1046            sendIndentedElement("psv:schemaDocument");
1047            sendElementEvent("psv:documentLocation", locations.item(i));
1048            // It's supposed to point to a <document> element, and we're not really
1049
// dealing with those (except for the one at the root)
1050
sendElementEvent("psv:document");
1051            sendUnIndentedElement("psv:schemaDocument");
1052        }
1053        sendUnIndentedElement("psv:schemaDocuments");
1054    }
1055
1056    private void processPSVISchemaComponents(XSNamespaceItem item) {
1057        if (item == null) {
1058            sendEmptyElementEvent("psv:schemaComponents");
1059            return;
1060        }
1061
1062        // it we happen to not get any components, this will output a start tag
1063
// and a close tag, instead of an empty element tag. This isn't a big
1064
// deal, though
1065
sendIndentedElement("psv:schemaComponents");
1066
1067        // typeDefinitions
1068
XSNamedMap components = item.getComponents(XSConstants.TYPE_DEFINITION);
1069        for (int i = 0; i < components.getLength(); i++) {
1070            processPSVITypeDefinition((XSTypeDefinition)components.item(i));
1071        }
1072        // elementDeclarations
1073
components = item.getComponents(XSConstants.ELEMENT_DECLARATION);
1074        for (int i = 0; i < components.getLength(); i++) {
1075            processPSVIElementDeclaration(
1076                (XSElementDeclaration)components.item(i));
1077        }
1078        // attributeDeclarations
1079
components = item.getComponents(XSConstants.ATTRIBUTE_DECLARATION);
1080        for (int i = 0; i < components.getLength(); i++) {
1081            processPSVIAttributeDeclaration(
1082                (XSAttributeDeclaration)components.item(i));
1083        }
1084        // modelGroupDefinitions
1085
components = item.getComponents(XSConstants.MODEL_GROUP_DEFINITION);
1086        for (int i = 0; i < components.getLength(); i++) {
1087            processPSVIModelGroupDefinition(
1088                (XSModelGroupDefinition)components.item(i));
1089        }
1090        // attributeGroupDefinitions
1091
components = item.getComponents(XSConstants.ATTRIBUTE_GROUP);
1092        for (int i = 0; i < components.getLength(); i++) {
1093            processPSVIAttributeGroupDefinition(
1094                (XSAttributeGroupDefinition)components.item(i));
1095        }
1096        // notationDeclarations
1097
components = item.getComponents(XSConstants.NOTATION_DECLARATION);
1098        for (int i = 0; i < components.getLength(); i++) {
1099            processPSVINotationDeclaration(
1100                (XSNotationDeclaration)components.item(i));
1101        }
1102        sendUnIndentedElement("psv:schemaComponents");
1103    }
1104
1105    private void processPSVITypeDefinition(XSTypeDefinition type) {
1106        if (type == null)
1107            return;
1108        if (type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
1109            processPSVIComplexTypeDefinition((XSComplexTypeDefinition)type);
1110        }
1111        else if (type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
1112            processPSVISimpleTypeDefinition((XSSimpleTypeDefinition)type);
1113        }
1114        else {
1115            throw new IllegalArgumentException JavaDoc(
1116                "Unknown type definition value: " + type.getType());
1117        }
1118    }
1119
1120    private void processPSVIComplexTypeDefinition(XSComplexTypeDefinition type) {
1121        if (type == null)
1122            return;
1123        sendIndentedElementWithID("psv:complexTypeDefinition", type);
1124        sendElementEvent("psv:name", type.getName());
1125        sendElementEvent("psv:targetNamespace", type.getNamespace());
1126        processPSVITypeDefinitionOrRef(
1127            "psv:baseTypeDefinition",
1128            type.getBaseType());
1129        sendElementEvent(
1130            "psv:derivationMethod",
1131            this.translateDerivation(type.getDerivationMethod()));
1132        sendElementEvent("psv:final", this.translateBlockOrFinal(type.getFinal()));
1133        sendElementEvent("psv:abstract", String.valueOf(type.getAbstract()));
1134        processPSVIAttributeUses(type.getAttributeUses());
1135        processPSVIAttributeWildcard(type.getAttributeWildcard());
1136        sendIndentedElement("psv:contentType");
1137        sendElementEvent(
1138            "psv:variety",
1139            this.translateContentType(type.getContentType()));
1140        XSSimpleTypeDefinition simpleType = type.getSimpleType();
1141        if(simpleType == null || (!simpleType.getAnonymous() || fDefined.contains(this.getID(simpleType)))) {
1142            processPSVIElementRef("psv:simpleTypeDefinition", simpleType);
1143        }
1144        else {
1145            processPSVISimpleTypeDefinition(simpleType);
1146        }
1147        processPSVIParticle(type.getParticle());
1148        sendUnIndentedElement("psv:contentType");
1149        sendElementEvent(
1150            "psv:prohibitedSubstitutions",
1151            this.translateBlockOrFinal(type.getProhibitedSubstitutions()));
1152        processPSVIAnnotations(type.getAnnotations());
1153        sendUnIndentedElement("psv:complexTypeDefinition");
1154    }
1155
1156    private void processPSVISimpleTypeDefinition(XSSimpleTypeDefinition type) {
1157        if (type == null) {
1158            sendElementEvent("psv:simpleTypeDefinition");
1159            return;
1160        }
1161            
1162        sendIndentedElementWithID("psv:simpleTypeDefinition", type);
1163        sendElementEvent("psv:name", type.getName());
1164        sendElementEvent("psv:targetNamespace", type.getNamespace());
1165        processPSVITypeDefinitionOrRef(
1166            "psv:baseTypeDefinition",
1167            type.getBaseType());
1168        processPSVITypeDefinitionOrRef(
1169            "psv:primitiveTypeDefinition",
1170            type.getPrimitiveType());
1171        processPSVIFacets(type);
1172
1173        sendIndentedElement("psv:fundamentalFacets");
1174        sendIndentedElement("psv:ordered");
1175        sendElementEvent("psv:value", this.translateOrdered(type.getOrdered()));
1176        sendUnIndentedElement("psv:ordered");
1177        sendIndentedElement("psv:bounded");
1178        sendElementEvent("psv:value", String.valueOf(type.getBounded()));
1179        sendUnIndentedElement("psv:bounded");
1180        sendIndentedElement("psv:cardinality");
1181        sendElementEvent("psv:value", String.valueOf(type.getFinite()));
1182        sendUnIndentedElement("psv:cardinality");
1183        sendIndentedElement("psv:numeric");
1184        sendElementEvent("psv:value", String.valueOf(type.getNumeric()));
1185        sendUnIndentedElement("psv:numeric");
1186        sendUnIndentedElement("psv:fundamentalFacets");
1187
1188        sendElementEvent("psv:final", this.translateBlockOrFinal(type.getFinal()));
1189        sendElementEvent(
1190            "psv:variety",
1191            this.translateVariety(type.getVariety()));
1192        processPSVITypeDefinitionOrRef(
1193            "psv:itemTypeDefinition",
1194            type.getItemType());
1195        processPSVIMemberTypeDefinitions(type.getMemberTypes());
1196        processPSVIAnnotations(type.getAnnotations());
1197        sendUnIndentedElement("psv:simpleTypeDefinition");
1198    }
1199
1200    private void processPSVIFacets(XSSimpleTypeDefinition type) {
1201        if (type == null)
1202            return;
1203        XSObjectList facets = type.getFacets();
1204        XSObjectList multiValueFacets = type.getMultiValueFacets();
1205        if ((facets == null || facets.getLength() == 0)
1206            && (multiValueFacets == null || multiValueFacets.getLength() == 0)) {
1207            sendElementEvent("psv:facets");
1208        }
1209        else {
1210            sendIndentedElement("psv:facets");
1211            if (facets != null) {
1212                for (int i = 0; i < facets.getLength(); i++) {
1213                    XSFacet facet = (XSFacet)facets.item(i);
1214                    String JavaDoc name = this.translateFacetKind(facet.getFacetKind());
1215                    sendIndentedElement("psv:" + name);
1216                    sendElementEvent("psv:value", facet.getLexicalFacetValue());
1217                    sendElementEvent(
1218                        "psv:fixed",
1219                        String.valueOf(facet.getFixed()));
1220                    processPSVIAnnotation(facet.getAnnotation());
1221                    sendUnIndentedElement("psv:" + name);
1222                }
1223            }
1224            if (multiValueFacets != null) {
1225                for (int i = 0; i < multiValueFacets.getLength(); i++) {
1226                    XSMultiValueFacet facet =
1227                        (XSMultiValueFacet)multiValueFacets.item(i);
1228                    String JavaDoc name = this.translateFacetKind(facet.getFacetKind());
1229                    sendIndentedElement("psv:" + name);
1230                    StringList values = facet.getLexicalFacetValues();
1231                    for (int j = 0; j < values.getLength(); j++) {
1232                        sendElementEvent("psv:value", values.item(j));
1233                    }
1234                    sendElementEvent("psv:fixed", "false");
1235                    processPSVIAnnotations(facet.getAnnotations());
1236                    sendUnIndentedElement("psv:" + name);
1237                }
1238            }
1239            sendUnIndentedElement("psv:facets");
1240        }
1241    }
1242
1243    private void processPSVIMemberTypeDefinitions(XSObjectList memTypes) {
1244        if (memTypes == null || memTypes.getLength() == 0) {
1245            sendElementEvent("psv:memberTypeDefinitions");
1246        }
1247        else {
1248            sendIndentedElement("psv:memberTypeDefinitions");
1249            for (int i = 0; i < memTypes.getLength(); i++) {
1250                processPSVITypeDefinitionOrRef(
1251                    "psv:memberTypeDefinition",
1252                    (XSTypeDefinition)memTypes.item(i));
1253            }
1254            sendUnIndentedElement("psv:memberTypeDefinitions");
1255        }
1256    }
1257
1258    /* It's possible that this method will send events for null annotations, i.e.
1259     * <psv:annotations>
1260     * <psv:annotation xsi:nil="true"/>
1261     * <psv:annotation>...</psv:annotation>
1262     * </psv:annotations>
1263     *
1264     * This is because of the way multi-value facet is implemented. It represents
1265     * the annotation on each value of the facet, and if a value doesn't have one,
1266     * it's corresponding annotation is null. Thus, it's possible for the first
1267     * annotation to be null, but the second one to be exist.
1268     *
1269     * An exception to this is if all of the annotations are null; then I output
1270     * <psv:annotations xsi:nil="true"/>
1271     */

1272    private void processPSVIAnnotations(XSObjectList annotations) {
1273        boolean empty = true;
1274        if (annotations != null && annotations.getLength() > 0) {
1275            for (int i = 0; i < annotations.getLength(); i++) {
1276                if (annotations.item(i) != null) {
1277                    empty = false;
1278                    break;
1279                }
1280            }
1281        }
1282
1283        if (empty) {
1284            sendElementEvent("psv:annotations");
1285        }
1286        else {
1287            sendIndentedElement("psv:annotations");
1288            for (int i = 0; i < annotations.getLength(); i++) {
1289                processPSVIAnnotation((XSAnnotation)annotations.item(i));
1290            }
1291            sendUnIndentedElement("psv:annotations");
1292        }
1293    }
1294
1295    private void processPSVISchemaAnnotations(XSObjectList annotations) {
1296        if (annotations == null || annotations.getLength() == 0) {
1297            sendElementEvent("psv:schemaAnnotations");
1298        }
1299        else {
1300            sendIndentedElement("psv:schemaAnnotations");
1301            for (int i = 0; i < annotations.getLength(); i++) {
1302                processPSVIAnnotation((XSAnnotation)annotations.item(i));
1303            }
1304            sendUnIndentedElement("psv:schemaAnnotations");
1305        }
1306    }
1307
1308    private void processPSVIAttributeUses(XSObjectList uses) {
1309        if (uses == null || uses.getLength() == 0) {
1310            sendElementEvent("psv:attributeUses");
1311        }
1312        else {
1313            sendIndentedElement("psv:attributeUses");
1314            for (int i = 0; i < uses.getLength(); i++) {
1315                XSAttributeUse use = (XSAttributeUse)uses.item(i);
1316                sendIndentedElement("psv:attributeUse");
1317                sendElementEvent("psv:required", String.valueOf(use.getRequired()));
1318                processPSVIAttributeDeclarationOrRef(use.getAttrDeclaration());
1319                processPSVIValueConstraint(use.getConstraintType(), use.getConstraintValue());
1320                sendUnIndentedElement("psv:attributeUse");
1321            }
1322            sendUnIndentedElement("psv:attributeUses");
1323        }
1324    }
1325
1326    private void processPSVIAttributeWildcard(XSWildcard wildcard) {
1327        if (wildcard == null) {
1328            sendElementEvent("psv:attributeWildcard");
1329        }
1330        else {
1331            sendIndentedElement("psv:attributeWildcard");
1332            processPSVIWildcard(wildcard);
1333            sendUnIndentedElement("psv:attributeWildcard");
1334        }
1335    }
1336
1337    private void processPSVIWildcard(XSWildcard wildcard) {
1338        if (wildcard == null)
1339            return;
1340        sendIndentedElement("psv:wildcard");
1341        sendIndentedElement("psv:namespaceConstraint");
1342        sendElementEvent(
1343            "psv:variety",
1344            this.translateConstraintType(wildcard.getConstraintType()));
1345
1346        StringBuffer JavaDoc constraintBuffer = new StringBuffer JavaDoc();
1347        StringList constraints = wildcard.getNsConstraintList();
1348        if (constraints != null && constraints.getLength() > 0) {
1349            for (int i = 0; i < constraints.getLength() - 1; i++) {
1350                constraintBuffer.append(constraints.item(i));
1351                constraintBuffer.append(" ");
1352            }
1353            constraintBuffer.append(
1354                constraints.item(constraints.getLength() - 1));
1355        }
1356        sendElementEvent("psv:namespaces", constraintBuffer.toString());
1357
1358        sendUnIndentedElement("psv:namespaceConstraint");
1359        sendElementEvent(
1360            "psv:processContents",
1361            this.translateProcessContents(wildcard.getProcessContents()));
1362        processPSVIAnnotation(wildcard.getAnnotation());
1363        sendUnIndentedElement("psv:wildcard");
1364    }
1365
1366    private void processPSVIAnnotation(XSAnnotation ann) {
1367        if (ann == null) {
1368            sendElementEvent("psv:annotation");
1369        }
1370        else {
1371            sendIndentedElement("psv:annotation");
1372            // We can't get all the information from DOM, but I've outputed what
1373
// we can get -- PJM
1374
Node JavaDoc dom = new DocumentImpl();
1375            ann.writeAnnotation(dom, XSAnnotation.W3C_DOM_DOCUMENT);
1376
1377            // this child will be the annotation element
1378
Element JavaDoc annot = DOMUtil.getFirstChildElement(dom);
1379
1380            processDOMElement(
1381                annot,
1382                SchemaSymbols.ELT_APPINFO,
1383                "psv:applicationInformation");
1384            processDOMElement(
1385                annot,
1386                SchemaSymbols.ELT_DOCUMENTATION,
1387                "psv:userInformation");
1388            processDOMAttributes(annot);
1389            sendUnIndentedElement("psv:annotation");
1390        }
1391    }
1392
1393    private void processDOMElement(
1394        Node JavaDoc node,
1395        String JavaDoc elementName,
1396        String JavaDoc tagName) {
1397        if (node == null)
1398            return;
1399        boolean foundElem = false;
1400        for (Element JavaDoc child = DOMUtil.getFirstChildElement(node);
1401            child != null;
1402            child = DOMUtil.getNextSiblingElement(child)) {
1403            if (DOMUtil.getLocalName(child).equals(elementName)) {
1404                if (!foundElem) {
1405                    sendIndentedElement(tagName);
1406                    foundElem = true;
1407                }
1408                sendIndentedElement("element");
1409                sendElementEvent(
1410                    "namespaceName",
1411                    DOMUtil.getNamespaceURI(child));
1412                sendElementEvent("localName", DOMUtil.getLocalName(child));
1413                sendElementEvent("prefix", child.getPrefix());
1414                sendIndentedElement("children");
1415                sendIndentedElement("character");
1416                sendElementEvent("textContent", DOMUtil.getChildText(child));
1417                sendUnIndentedElement("character");
1418                sendUnIndentedElement("children");
1419
1420                //Create XMLAttributes from DOM
1421
Attr JavaDoc[] atts = (Element JavaDoc) child == null ? null : DOMUtil.getAttrs((Element JavaDoc) child);
1422                XMLAttributes attrs = new XMLAttributesImpl();
1423                for (int i=0; i<atts.length; i++) {
1424                    Attr JavaDoc att = (Attr JavaDoc)atts[i];
1425                    attrs.addAttribute(
1426                            new QName(att.getPrefix(), att.getLocalName(), att.getName(), att.getNamespaceURI()),
1427                            "CDATA" ,att.getValue()
1428                            );
1429                }
1430
1431                processAttributes(attrs);
1432                sendUnIndentedElement("element");
1433            }
1434        }
1435        if (foundElem) {
1436            sendUnIndentedElement(tagName);
1437        }
1438        else {
1439            sendEmptyElementEvent(tagName);
1440        }
1441    }
1442
1443    private void processDOMAttributes(Element JavaDoc elem) {
1444        Attr JavaDoc[] atts = elem == null ? null : DOMUtil.getAttrs(elem);
1445
1446        boolean namespaceAttribute = false;
1447        boolean attrElement = false;
1448
1449        int attrCount = atts == null ? 0 : atts.length;
1450
1451        if (attrCount == 0) {
1452            sendEmptyElementEvent("attributes");
1453            sendEmptyElementEvent("namespaceAttributes");
1454            return;
1455        }
1456
1457        for (int i = 0; i < attrCount; i++) {
1458            Attr JavaDoc att = (Attr JavaDoc)atts[i];
1459            String JavaDoc localpart = DOMUtil.getLocalName(att);
1460            String JavaDoc prefix = att.getPrefix();
1461            if (localpart.equals(XMLSymbols.PREFIX_XMLNS)
1462                || prefix.equals(XMLSymbols.PREFIX_XMLNS)) {
1463                namespaceAttribute = true;
1464                continue;
1465            }
1466            if (!attrElement)
1467                sendIndentedElement("attributes");
1468
1469            sendIndentedElement("attribute");
1470            sendElementEvent("namespaceName", DOMUtil.getNamespaceURI(att));
1471            sendElementEvent("localName", DOMUtil.getLocalName(att));
1472            sendElementEvent("prefix", att.getPrefix());
1473            sendElementEvent("normalizedValue", att.getValue());
1474            sendElementEvent(
1475                "specified",
1476                String.valueOf(att.getSpecified()));
1477            sendElementEvent("attributeType");
1478
1479            // this property isn't relevent to PSVI
1480
sendElementEvent("references");
1481
1482            sendUnIndentedElement("attribute");
1483            attrElement = true;
1484        }
1485        if (attrElement) {
1486            sendUnIndentedElement("attributes");
1487        }
1488        else {
1489            sendEmptyElementEvent("attributes");
1490        }
1491
1492        if (namespaceAttribute) {
1493            sendIndentedElement("namespaceAttributes");
1494            for (int i = 0; i < attrCount; i++) {
1495                Attr JavaDoc att = (Attr JavaDoc)atts[i];
1496                String JavaDoc localpart = DOMUtil.getLocalName(att);
1497                String JavaDoc prefix = att.getPrefix();
1498                if (localpart.equals(XMLSymbols.PREFIX_XMLNS)
1499                    || prefix.equals(XMLSymbols.PREFIX_XMLNS)) {
1500
1501                    sendIndentedElement("attribute");
1502                    sendElementEvent("namespaceName", DOMUtil.getNamespaceURI(att));
1503                    sendElementEvent("localName", DOMUtil.getLocalName(att));
1504                    sendElementEvent("prefix", att.getPrefix());
1505                    sendElementEvent("normalizedValue", att.getValue());
1506                    sendElementEvent(
1507                        "specified",
1508                        String.valueOf(att.getSpecified()));
1509                    sendElementEvent("attributeType");
1510
1511                    // this property isn't relevent to PSVI
1512
sendElementEvent("references");
1513
1514                    sendUnIndentedElement("attribute");
1515                }
1516            }
1517            sendUnIndentedElement("namespaceAttributes");
1518        }
1519        else {
1520            sendEmptyElementEvent("namespaceAttributes");
1521        }
1522    }
1523
1524    private void processPSVIElementDeclaration(XSElementDeclaration elem) {
1525        if (elem == null)
1526            return;
1527        sendIndentedElementWithID("psv:elementDeclaration", elem);
1528        sendElementEvent("psv:name", elem.getName());
1529        sendElementEvent("psv:targetNamespace", elem.getNamespace());
1530        processPSVITypeDefinitionOrRef(
1531            "psv:typeDefinition",
1532            elem.getTypeDefinition());
1533        processPSVIScope("psv:scope", elem.getEnclosingCTDefinition(), elem.getScope());
1534        processPSVIValueConstraint(elem.getConstraintType(), elem.getConstraintValue());
1535        sendElementEvent("psv:nillable", String.valueOf(elem.getNillable()));
1536        processPSVIIdentityConstraintDefinitions(elem.getIdentityConstraints());
1537        processPSVISubstitutionGroupAffiliation(elem);
1538
1539        sendElementEvent(
1540            "psv:substitutionGroupExclusions",
1541            this.translateBlockOrFinal(elem.getSubstitutionGroupExclusions()));
1542        sendElementEvent(
1543            "psv:disallowedSubstitutions",
1544            this.translateBlockOrFinal(elem.getDisallowedSubstitutions()));
1545        sendElementEvent("psv:abstract", String.valueOf(elem.getAbstract()));
1546        processPSVIAnnotation(elem.getAnnotation());
1547        sendUnIndentedElement("psv:elementDeclaration");
1548    }
1549
1550    private void processPSVIAttributeDeclaration(XSAttributeDeclaration attr) {
1551        if (attr == null)
1552            return;
1553        sendIndentedElementWithID("psv:attributeDeclaration", attr);
1554        sendElementEvent("psv:name", attr.getName());
1555        sendElementEvent("psv:targetNamespace", attr.getNamespace());
1556        processPSVITypeDefinitionOrRef(
1557            "psv:typeDefinition",
1558            attr.getTypeDefinition());
1559        processPSVIScope("psv:scope", attr.getEnclosingCTDefinition(), attr.getScope());
1560        processPSVIValueConstraint(attr.getConstraintType(), attr.getConstraintValue());
1561        processPSVIAnnotation(attr.getAnnotation());
1562        sendUnIndentedElement("psv:attributeDeclaration");
1563    }
1564
1565    private void processPSVIAttributeGroupDefinition(XSAttributeGroupDefinition ag) {
1566        if (ag == null)
1567            return;
1568        sendIndentedElementWithID("psv:attributeGroupDefinition", ag);
1569        sendElementEvent("psv:name", ag.getName());
1570        sendElementEvent("psv:targetNamespace", ag.getNamespace());
1571        processPSVIAttributeUses(ag.getAttributeUses());
1572        processPSVIAttributeWildcard(ag.getAttributeWildcard());
1573        processPSVIAnnotation(ag.getAnnotation());
1574        sendUnIndentedElement("psv:attributeGroupDefinition");
1575    }
1576
1577    private void processPSVIModelGroupDefinition(XSModelGroupDefinition mgd) {
1578        if (mgd == null) {
1579            sendElementEvent("psv:modelGroupDefinition");
1580        }
1581        else {
1582            sendIndentedElementWithID("psv:modelGroupDefinition", mgd);
1583            sendElementEvent("psv:name", mgd.getName());
1584            sendElementEvent("psv:targetNamespace", mgd.getNamespace());
1585            processPSVIModelGroup(mgd.getModelGroup());
1586            processPSVIAnnotation(mgd.getAnnotation());
1587            sendUnIndentedElement("psv:modelGroupDefinition");
1588        }
1589    }
1590
1591    private void processPSVIModelGroup(XSModelGroup mg) {
1592        if (mg == null) {
1593            sendElementEvent("psv:modelGroup");
1594        }
1595        else {
1596            sendIndentedElement("psv:modelGroup");
1597            sendElementEvent(
1598                "psv:compositor",
1599                this.translateCompositor(mg.getCompositor()));
1600            processPSVIParticles(mg.getParticles());
1601            processPSVIAnnotation(mg.getAnnotation());
1602            sendUnIndentedElement("psv:modelGroup");
1603        }
1604    }
1605
1606    private void processPSVINotationDeclaration(XSNotationDeclaration not) {
1607        if (not == null) {
1608            sendElementEvent("psv:notationDeclaration");
1609        }
1610        else {
1611            sendIndentedElementWithID("psv:notationDeclaration", not);
1612            sendElementEvent("psv:name", not.getName());
1613            sendElementEvent("psv:targetNamespace", not.getNamespace());
1614            sendElementEvent("systemIdentifier", not.getSystemId());
1615            sendElementEvent("publicIdentifier", not.getPublicId());
1616            processPSVIAnnotation(not.getAnnotation());
1617            sendUnIndentedElement("psv:notationDeclaration");
1618        }
1619    }
1620
1621    private void processPSVIIdentityConstraintDefinitions(XSNamedMap constraints) {
1622        if (constraints == null || constraints.getLength() == 0) {
1623            sendElementEvent("psv:identityConstraintDefinitions");
1624        }
1625        else {
1626            sendIndentedElement("psv:identityConstraintDefinitions");
1627            for (int i = 0; i < constraints.getLength(); i++) {
1628                XSIDCDefinition constraint =
1629                    (XSIDCDefinition)constraints.item(i);
1630                sendIndentedElementWithID(
1631                    "psv:identityConstraintDefinition",
1632                    constraint);
1633                sendElementEvent("psv:name", constraint.getName());
1634                sendElementEvent(
1635                    "psv:targetNamespace",
1636                    constraint.getNamespace());
1637                sendElementEvent(
1638                    "psv:identityConstraintCategory",
1639                    this.translateCategory(constraint.getCategory()));
1640                sendIndentedElement("psv:selector");
1641                processPSVIXPath(constraint.getSelectorStr());
1642                sendUnIndentedElement("psv:selector");
1643                processPSVIFields(constraint.getFieldStrs());
1644                processPSVIElementRef(
1645                    "psv:referencedKey",
1646                    constraint.getRefKey());
1647                processPSVIAnnotations(constraint.getAnnotations());
1648                sendUnIndentedElement("psv:identityConstraintDefinition");
1649            }
1650            sendUnIndentedElement("psv:identityConstraintDefinitions");
1651        }
1652    }
1653
1654    private void processPSVIFields(StringList fields) {
1655        if (fields == null || fields.getLength() == 0) {
1656            sendElementEvent("psv:fields");
1657        }
1658        else {
1659            sendIndentedElement("psv:fields");
1660            for (int i = 0; i < fields.getLength(); i++) {
1661                processPSVIXPath(fields.item(i));
1662            }
1663            sendUnIndentedElement("psv:fields");
1664        }
1665    }
1666
1667    private void processPSVIXPath(String JavaDoc path) {
1668        sendIndentedElement("psv:xpath");
1669        sendElementEvent("psv:xpath", path);
1670        sendUnIndentedElement("psv:xpath");
1671    }
1672
1673    private void processPSVIParticles(XSObjectList particles) {
1674        if (particles == null || particles.getLength() == 0) {
1675            sendElementEvent("psv:particles");
1676        }
1677        else {
1678            sendIndentedElement("psv:particles");
1679            for (int i = 0; i < particles.getLength(); i++) {
1680                processPSVIParticle((XSParticle)particles.item(i));
1681            }
1682            sendUnIndentedElement("psv:particles");
1683        }
1684    }
1685
1686    private void processPSVIParticle(XSParticle part) {
1687        if (part == null) {
1688            sendElementEvent("psv:particle");
1689        }
1690        else {
1691            sendIndentedElement("psv:particle");
1692            sendElementEvent(
1693                "psv:minOccurs",
1694                String.valueOf(part.getMinOccurs()));
1695            sendElementEvent(
1696                "psv:maxOccurs",
1697                part.getMaxOccurs() == SchemaSymbols.OCCURRENCE_UNBOUNDED
1698                    ? "unbounded"
1699                    : String.valueOf(part.getMaxOccurs()));
1700            sendIndentedElement("psv:term");
1701            switch (part.getTerm().getType()) {
1702                case XSConstants.ELEMENT_DECLARATION :
1703                    processPSVIElementDeclarationOrRef(
1704                        (XSElementDeclaration)part.getTerm());
1705                    break;
1706                case XSConstants.MODEL_GROUP :
1707                    processPSVIModelGroup((XSModelGroup)part.getTerm());
1708                    break;
1709                case XSConstants.WILDCARD :
1710                    processPSVIWildcard((XSWildcard)part.getTerm());
1711                    break;
1712            }
1713            sendUnIndentedElement("psv:term");
1714            sendUnIndentedElement("psv:particle");
1715        }
1716    }
1717
1718    private void processPSVIElementRef(String JavaDoc elementName, XSObject obj) {
1719        this.processPSVIElementRef(elementName, null, obj);
1720    }
1721
1722    private void processPSVIElementRef(
1723        String JavaDoc elementName,
1724        Vector JavaDoc attributes,
1725        XSObject obj) {
1726        if (attributes == null) {
1727            attributes = new Vector JavaDoc();
1728        }
1729        String JavaDoc ref = this.getID(obj);
1730        if (ref != null) {
1731            attributes.add("ref");
1732            attributes.add(ref);
1733            attributes.add(XMLSymbols.fIDREFSymbol);
1734        }
1735        sendElementEvent(elementName, attributes, (XMLString) null);
1736    }
1737
1738    private void processPSVIAttributeDeclarationOrRef(XSAttributeDeclaration att) {
1739        if (att == null)
1740            return;
1741        // for global attributes, and attributes that have already been printed,
1742
// we always want to print references
1743
if (att.getScope() == XSConstants.SCOPE_GLOBAL
1744            || fDefined.contains(this.getID(att))) {
1745            processPSVIAttributeDeclarationRef(att);
1746        }
1747        else {
1748            processPSVIAttributeDeclaration(att);
1749        }
1750    }
1751
1752    private void processPSVIAttributeDeclarationRef(XSAttributeDeclaration att) {
1753        if (att == null)
1754            return;
1755        Vector JavaDoc attributes = new Vector JavaDoc();
1756        attributes.add("name");
1757        attributes.add(att.getName());
1758        attributes.add(XMLSymbols.fCDATASymbol);
1759        if (att.getNamespace() != null) {
1760            attributes.add("tns");
1761            attributes.add(att.getNamespace());
1762            attributes.add(XMLSymbols.fCDATASymbol);
1763        }
1764        processPSVIElementRef("psv:attributeDeclaration", attributes, att);
1765    }
1766
1767    // always prints a reference
1768
private void processPSVITypeDefinitionRef(
1769        String JavaDoc enclose,
1770        XSTypeDefinition type) {
1771        if (type == null) {
1772            sendElementEvent(enclose);
1773            return;
1774        }
1775
1776        sendIndentedElement(enclose);
1777        if (type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
1778            processPSVIElementRef("psv:complexTypeDefinition", type);
1779        }
1780        else if (type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
1781            processPSVIElementRef("psv:simpleTypeDefinition", type);
1782        }
1783        else {
1784            throw new IllegalArgumentException JavaDoc(
1785                "Unknown type definition value: " + type.getTypeCategory());
1786        }
1787        sendUnIndentedElement(enclose);
1788    }
1789
1790    // prints a reference if the type is anonymous and hasn't already been defined,
1791
// otherwise prints a definition
1792
private void processPSVITypeDefinitionOrRef(
1793        String JavaDoc enclose,
1794        XSTypeDefinition type) {
1795        if (type == null){
1796            sendElementEvent(enclose);
1797            return;
1798        }
1799
1800        // we'll check for anonymous types here, since they only occur in places where
1801
// a reference would be appropriate
1802
if (type.getAnonymous() && !fDefined.contains(this.getID(type))) {
1803            sendIndentedElement(enclose);
1804            processPSVITypeDefinition(type);
1805            sendUnIndentedElement(enclose);
1806        }
1807        else {
1808            processPSVITypeDefinitionRef(enclose, type);
1809        }
1810    }
1811
1812    private void processPSVIElementDeclarationRef(XSElementDeclaration elem) {
1813        if (elem == null)
1814            return;
1815        processPSVIElementRef("psv:elementDeclaration", elem);
1816    }
1817
1818    private void processPSVIElementDeclarationOrRef(XSElementDeclaration elem) {
1819        if (elem == null)
1820            return;
1821        // for global attributes, and attributes that have already been printed,
1822
// we always want to print references
1823
if (elem.getScope() == XSConstants.SCOPE_GLOBAL
1824            || fDefined.contains(this.getID(elem))) {
1825            processPSVIElementDeclarationRef(elem);
1826        }
1827        else {
1828            processPSVIElementDeclaration(elem);
1829        }
1830    }
1831
1832    private void processPSVIScope(
1833        String JavaDoc enclose,
1834        XSComplexTypeDefinition enclosingCTD,
1835        short scope) {
1836        if (scope == XSConstants.SCOPE_ABSENT || scope == XSConstants.SCOPE_GLOBAL) {
1837            sendElementEvent(enclose, this.translateScope(scope));
1838        } else { // XSConstants.SCOPE_LOCAL
1839
processPSVITypeDefinitionRef(enclose, enclosingCTD);
1840        }
1841    }
1842
1843    private void processPSVIValueConstraint(
1844        short constraintType,
1845        String JavaDoc constraintValue) {
1846        if (constraintType == XSConstants.VC_NONE) {
1847            sendElementEvent("psv:valueConstraint");
1848        } else {
1849            sendIndentedElement("psv:valueConstraint");
1850            sendElementEvent("psv:variety", translateValueConstraintType(constraintType));
1851            sendElementEvent("psv:value", constraintValue);
1852            sendUnIndentedElement("psv:valueConstraint");
1853        }
1854    }
1855
1856    private void processPSVISubstitutionGroupAffiliation(XSElementDeclaration elem) {
1857        if (elem.getSubstitutionGroupAffiliation() == null) {
1858            sendElementEvent("psv:substitutionGroupAffiliation");
1859        } else {
1860            sendIndentedElement("psv:substitutionGroupAffiliation");
1861            processPSVIElementRef("psv:elementDeclaration", elem.getSubstitutionGroupAffiliation());
1862            sendUnIndentedElement("psv:substitutionGroupAffiliation");
1863        }
1864    }
1865
1866    /**
1867     * This method writes an empty element at the current indent level.
1868     *
1869     * @param tagname The name of the Element.
1870     *
1871     * @throws IOEXception
1872     */

1873    private void sendEmptyElementEvent(String JavaDoc tagname) {
1874        this.sendEmptyElementEvent(tagname, null);
1875    } //sendEmptyElementEvent
1876

1877    private void sendEmptyElementEvent(String JavaDoc tagname, Vector JavaDoc attributes) {
1878        this.sendIndent();
1879        fDocumentHandler.emptyElement(
1880            createQName(tagname),
1881            createAttributes(attributes),
1882            null);
1883        this.sendNewLine();
1884    } //sendEmptyElementEvent
1885

1886    /**
1887     * This method writes an empty element at the current indent level.
1888     *
1889     * @param tagname The name of the Element.
1890     *
1891     * @throws IOEXception
1892     */

1893    private void sendStartElementEvent(String JavaDoc tagname, Vector JavaDoc attributes) {
1894        fDocumentHandler.startElement(
1895            createQName(tagname),
1896            createAttributes(attributes),
1897            null);
1898    } //sendStartElementEvent
1899

1900    /**
1901     * This method writes a closing tag at the current indent level.
1902     *
1903     * @param tagname The name of the Element.
1904     *
1905     * @throws IOEXception
1906     */

1907    private void sendEndElementEvent(String JavaDoc tagname) {
1908        fDocumentHandler.endElement(this.createQName(tagname), null);
1909    } //sendEndElementEvent
1910

1911    /**
1912     * This method write the element at the current indent level and increase
1913     * the one level of indentation.
1914     *
1915     * @param The name of the Element.
1916     *
1917     * @throws IOException
1918     */

1919    private void sendIndentedElement(String JavaDoc tagName) {
1920        this.sendIndentedElement(tagName, null);
1921    } //sendIndentedElement
1922

1923    private void sendIndentedElement(String JavaDoc tagName, Vector JavaDoc attributes) {
1924        this.sendIndent();
1925        this.sendStartElementEvent(tagName, attributes);
1926        this.sendNewLine();
1927        fIndent++;
1928    } //sendIndentedElement
1929

1930    /**
1931     * This method write the element at the current indent level and decrease
1932     * one level of indentation.
1933     *
1934     * @param the name of the Element.
1935     *
1936     */

1937    private void sendUnIndentedElement(String JavaDoc tagName) {
1938        fIndent--;
1939        this.sendIndent();
1940        this.sendEndElementEvent(tagName);
1941        this.sendNewLine();
1942    } //sendUnIndentedElement
1943

1944    /**
1945     * Write the Element Information Item for each element appearing in the XML
1946     * document. One of the element information items is the value of the
1947     * [document element] property of the document information item, corresponding
1948     * to the root of the element tree, and all other element information items
1949     * are accessible by recursively following its [children] property.
1950     *
1951     * @elementName Name of the elment.
1952     * @elemmentValue Value of the element
1953     */

1954    private void sendElementEvent(String JavaDoc elementName) {
1955        this.sendElementEvent(elementName, null, (XMLString) null);
1956    } //sendElementEvents
1957

1958    private void sendElementEvent(String JavaDoc elementName, String JavaDoc elementValue) {
1959        this.sendElementEvent(elementName, null, elementValue);
1960    } //sendElementEvents
1961

1962    private void sendElementEvent(String JavaDoc elementName, XMLString elementValue) {
1963        this.sendElementEvent(elementName, null, elementValue);
1964    } //sendElementEvents
1965

1966    private void sendElementEvent(
1967        String JavaDoc elementName,
1968        Vector JavaDoc attributes,
1969        String JavaDoc elementValue) {
1970        XMLString text =
1971            elementValue == null
1972                ? null
1973                : new XMLString(
1974                    elementValue.toCharArray(),
1975                    0,
1976                    elementValue.length());
1977        this.sendElementEvent(elementName, attributes, text);
1978    }
1979
1980    private void sendElementEvent(
1981        String JavaDoc elementName,
1982        Vector JavaDoc attributes,
1983        XMLString elementValue) {
1984        if (elementValue == null || elementValue.equals("")) {
1985            if (attributes == null) {
1986                attributes = new Vector JavaDoc();
1987            }
1988            attributes.add("xsi:nil");
1989            attributes.add("true");
1990            attributes.add(XMLSymbols.fCDATASymbol);
1991            this.sendEmptyElementEvent(elementName, attributes);
1992        }
1993        else {
1994            this.sendIndent();
1995            this.sendStartElementEvent(elementName, attributes);
1996            fDocumentHandler.characters(elementValue, null);
1997            this.sendEndElementEvent(elementName);
1998            this.sendNewLine();
1999        }
2000    } //sendElementEvents
2001

2002    private void sendIndentedElementWithID(String JavaDoc elementName, XSObject obj) {
2003        String JavaDoc id = this.getID(obj);
2004        // since this method is called everytime we define something with an ID,
2005
// may as well mark the ID as defined here
2006
fDefined.add(id);
2007        Vector JavaDoc attributes = new Vector JavaDoc();
2008        attributes.add("id");
2009        attributes.add(id);
2010        attributes.add(XMLSymbols.fIDSymbol);
2011        sendIndentedElement(elementName, attributes);
2012    }
2013
2014    private void sendIndent() {
2015        if (fIndent > fIndentChars.length) {
2016            fIndentChars = new char[fIndentChars.length * 2];
2017            for (int i = 0; i < fIndentChars.length; i++) {
2018                fIndentChars[i] = '\t';
2019            }
2020        }
2021        XMLString text = new XMLString(fIndentChars, 0, fIndent);
2022        fDocumentHandler.characters(text, null);
2023    }
2024
2025    private void sendNewLine() {
2026        fDocumentHandler.characters(newLine, null);
2027    }
2028
2029    private QName createQName(String JavaDoc rawname) {
2030        int index = rawname.indexOf(':');
2031        String JavaDoc prefix, localpart;
2032        if (index == -1) {
2033            prefix = "";
2034            localpart = rawname;
2035        }
2036        else {
2037            prefix = rawname.substring(0, index);
2038            localpart = rawname.substring(index + 1);
2039        }
2040        String JavaDoc uri = fPSVINamespaceContext.getURI(prefix);
2041        return new QName(prefix, localpart, rawname, uri);
2042    }
2043
2044    private XMLAttributes createAttributes(Vector JavaDoc atts) {
2045        XMLAttributes attributes = new XMLAttributesImpl();
2046        if (atts != null) {
2047            for (int i = 0; i < atts.size(); i += 3) {
2048                String JavaDoc rawname = (String JavaDoc)atts.elementAt(i);
2049                String JavaDoc value = (String JavaDoc)atts.elementAt(i + 1);
2050                String JavaDoc type = (String JavaDoc)atts.elementAt(i + 2);
2051                attributes.addAttribute(createQName(rawname), type, value);
2052            }
2053        }
2054        return attributes;
2055    }
2056
2057    private String JavaDoc createID(XSObject obj) {
2058        String JavaDoc namespace = obj.getNamespace();
2059        String JavaDoc prefix = fNamespaceContext.getPrefix(obj.getNamespace());
2060        String JavaDoc name = obj.getName();
2061        String JavaDoc type = this.translateType(obj.getType());
2062
2063        // must be anonymous
2064
if (name == null) {
2065            name = "anon_" + fAnonNum++;
2066        }
2067        // no namespace
2068
else if (namespace == null || namespace == XMLSymbols.EMPTY_STRING) {
2069            name = name + "." + fAnonNum++;
2070        }
2071
2072        if (namespace == Constants.NS_XMLSCHEMA) {
2073            return name;
2074        }
2075        else {
2076            return (prefix == null ? "" : prefix + ".") + type + "." + name;
2077        }
2078    }
2079
2080    private String JavaDoc getID(XSObject obj) {
2081        if (obj == null)
2082            return null;
2083        String JavaDoc id = (String JavaDoc)fIDMap.get(obj);
2084        if (id == null) {
2085            id = createID(obj);
2086            fIDMap.put(obj, id);
2087        }
2088        return id;
2089    }
2090
2091    private String JavaDoc translateType(short type) {
2092        switch (type) {
2093            case XSConstants.TYPE_DEFINITION :
2094                return "type";
2095            case XSConstants.ANNOTATION :
2096                return "annot";
2097            case XSConstants.ATTRIBUTE_DECLARATION :
2098                return "attr";
2099            case XSConstants.ATTRIBUTE_GROUP :
2100                return "ag";
2101            case XSConstants.ATTRIBUTE_USE :
2102                return "au";
2103            case XSConstants.ELEMENT_DECLARATION :
2104                return "elt";
2105            case XSConstants.MODEL_GROUP_DEFINITION :
2106                return "mg";
2107            case XSConstants.NOTATION_DECLARATION :
2108                return "not";
2109            case XSConstants.IDENTITY_CONSTRAINT :
2110                return "idc";
2111            default :
2112                return "unknown";
2113        }
2114    }
2115
2116    private String JavaDoc translateFacetKind(short kind) {
2117        switch (kind) {
2118            case XSSimpleTypeDefinition.FACET_WHITESPACE :
2119                return SchemaSymbols.ELT_WHITESPACE;
2120            case XSSimpleTypeDefinition.FACET_LENGTH :
2121                return SchemaSymbols.ELT_LENGTH;
2122            case XSSimpleTypeDefinition.FACET_MINLENGTH :
2123                return SchemaSymbols.ELT_MINLENGTH;
2124            case XSSimpleTypeDefinition.FACET_MAXLENGTH :
2125                return SchemaSymbols.ELT_MAXLENGTH;
2126            case XSSimpleTypeDefinition.FACET_TOTALDIGITS :
2127                return SchemaSymbols.ELT_TOTALDIGITS;
2128            case XSSimpleTypeDefinition.FACET_FRACTIONDIGITS :
2129                return SchemaSymbols.ELT_FRACTIONDIGITS;
2130            case XSSimpleTypeDefinition.FACET_PATTERN :
2131                return SchemaSymbols.ELT_PATTERN;
2132            case XSSimpleTypeDefinition.FACET_ENUMERATION :
2133                return SchemaSymbols.ELT_ENUMERATION;
2134            case XSSimpleTypeDefinition.FACET_MAXINCLUSIVE :
2135                return SchemaSymbols.ELT_MAXINCLUSIVE;
2136            case XSSimpleTypeDefinition.FACET_MAXEXCLUSIVE :
2137                return SchemaSymbols.ELT_MAXEXCLUSIVE;
2138            case XSSimpleTypeDefinition.FACET_MINEXCLUSIVE :
2139                return SchemaSymbols.ELT_MINEXCLUSIVE;
2140            case XSSimpleTypeDefinition.FACET_MININCLUSIVE :
2141                return SchemaSymbols.ELT_MININCLUSIVE;
2142            default :
2143                return "unknown";
2144        }
2145    }
2146
2147    private String JavaDoc translateVariety(short var) {
2148        switch (var) {
2149            case XSSimpleTypeDefinition.VARIETY_LIST :
2150                return "list";
2151            case XSSimpleTypeDefinition.VARIETY_UNION :
2152                return "union";
2153            case XSSimpleTypeDefinition.VARIETY_ATOMIC :
2154                return "atomic";
2155            case XSSimpleTypeDefinition.VARIETY_ABSENT :
2156                return null;
2157            default :
2158                return "unknown";
2159        }
2160    }
2161
2162    private String JavaDoc translateConstraintType(short type) {
2163        switch (type) {
2164            case XSWildcard.NSCONSTRAINT_ANY :
2165                return "any";
2166                // the spec says that when it's a list, the "type" shouldn't be there
2167
case XSWildcard.NSCONSTRAINT_LIST :
2168                return null;
2169            case XSWildcard.NSCONSTRAINT_NOT :
2170                return "not";
2171            default :
2172                return "unknown";
2173        }
2174    }
2175
2176    private String JavaDoc translateValueConstraintType(short type) {
2177        switch (type) {
2178            case XSConstants.VC_DEFAULT :
2179                return "default";
2180            case XSConstants.VC_FIXED :
2181                return "fixed";
2182            default :
2183                return "unknown";
2184        }
2185    }
2186
2187    private String JavaDoc translateBlockOrFinal(short val) {
2188        String JavaDoc ret = "";
2189        if ((val & XSConstants.DERIVATION_EXTENSION) != 0) {
2190            ret += SchemaSymbols.ATTVAL_EXTENSION;
2191        }
2192        if ((val & XSConstants.DERIVATION_LIST) != 0) {
2193            if (ret.length() != 0)
2194                ret += " ";
2195            ret += SchemaSymbols.ATTVAL_LIST;
2196        }
2197        if ((val & XSConstants.DERIVATION_RESTRICTION) != 0) {
2198            if (ret.length() != 0)
2199                ret += " ";
2200            ret += SchemaSymbols.ATTVAL_RESTRICTION;
2201        }
2202        if ((val & XSConstants.DERIVATION_UNION) != 0) {
2203            if (ret.length() != 0)
2204                ret += " ";
2205            ret += SchemaSymbols.ATTVAL_UNION;
2206        }
2207        if ((val & XSConstants.DERIVATION_SUBSTITUTION) != 0) {
2208            if (ret.length() != 0)
2209                ret += " ";
2210            ret += SchemaSymbols.ATTVAL_SUBSTITUTION;
2211        }
2212        return ret;
2213    }
2214
2215    private String JavaDoc translateScope(short scope) {
2216        switch (scope) {
2217            case XSConstants.SCOPE_ABSENT :
2218                return null;
2219            case XSConstants.SCOPE_GLOBAL :
2220                return "global";
2221            case XSConstants.SCOPE_LOCAL :
2222                return "local";
2223            default :
2224                return "unknown";
2225        }
2226    }
2227
2228    private String JavaDoc translateCompositor(short comp) {
2229        switch (comp) {
2230            case XSModelGroup.COMPOSITOR_SEQUENCE :
2231                return SchemaSymbols.ELT_SEQUENCE;
2232            case XSModelGroup.COMPOSITOR_CHOICE :
2233                return SchemaSymbols.ELT_CHOICE;
2234            case XSModelGroup.COMPOSITOR_ALL :
2235                return SchemaSymbols.ELT_ALL;
2236            default :
2237                return "unknown";
2238        }
2239    }
2240
2241    private String JavaDoc translateContentType(short contentType) {
2242        switch (contentType) {
2243            case XSComplexTypeDefinition.CONTENTTYPE_ELEMENT :
2244                return "elementOnly";
2245            case XSComplexTypeDefinition.CONTENTTYPE_EMPTY :
2246                return "empty";
2247            case XSComplexTypeDefinition.CONTENTTYPE_MIXED :
2248                return "mixed";
2249            case XSComplexTypeDefinition.CONTENTTYPE_SIMPLE :
2250                return "simple";
2251            default :
2252                return "unknown";
2253        }
2254    }
2255
2256    private String JavaDoc translateProcessContents(short process) {
2257        switch (process) {
2258            case XSWildcard.PC_LAX :
2259                return SchemaSymbols.ATTVAL_LAX;
2260            case XSWildcard.PC_SKIP :
2261                return SchemaSymbols.ATTVAL_SKIP;
2262            case XSWildcard.PC_STRICT :
2263                return SchemaSymbols.ATTVAL_STRICT;
2264            default :
2265                return "unknown";
2266        }
2267    }
2268
2269    private String JavaDoc translateDerivation(short deriv) {
2270        switch (deriv) {
2271            case XSConstants.DERIVATION_EXTENSION :
2272                return SchemaSymbols.ELT_EXTENSION;
2273            case XSConstants.DERIVATION_LIST :
2274                return SchemaSymbols.ELT_LIST;
2275            case XSConstants.DERIVATION_RESTRICTION :
2276                return SchemaSymbols.ELT_RESTRICTION;
2277            case XSConstants.DERIVATION_SUBSTITUTION :
2278                return SchemaSymbols.ATTVAL_SUBSTITUTION;
2279            case XSConstants.DERIVATION_UNION :
2280                return SchemaSymbols.ELT_UNION;
2281            case XSConstants.DERIVATION_NONE :
2282                return null;
2283            default :
2284                return "unknown";
2285        }
2286    }
2287
2288    private String JavaDoc translateCategory(short cat) {
2289        switch (cat) {
2290            case XSIDCDefinition.IC_KEY :
2291                return SchemaSymbols.ELT_KEY;
2292            case XSIDCDefinition.IC_KEYREF :
2293                return SchemaSymbols.ELT_KEYREF;
2294            case XSIDCDefinition.IC_UNIQUE :
2295                return SchemaSymbols.ELT_UNIQUE;
2296            default :
2297                return "unknown";
2298        }
2299    }
2300
2301    private String JavaDoc translateOrdered(short ordered) {
2302        switch (ordered) {
2303            case XSSimpleTypeDefinition.ORDERED_FALSE :
2304                return "false";
2305            case XSSimpleTypeDefinition.ORDERED_PARTIAL :
2306                return "partial";
2307            case XSSimpleTypeDefinition.ORDERED_TOTAL :
2308                return "total";
2309            default :
2310                return "unknown";
2311        }
2312    }
2313
2314    private String JavaDoc translateValidationAttempted(short val) {
2315        switch (val) {
2316            case ItemPSVI.VALIDATION_NONE :
2317                return "none";
2318            case ItemPSVI.VALIDATION_PARTIAL :
2319                return "partial";
2320            case ItemPSVI.VALIDATION_FULL :
2321                return "full";
2322            default :
2323                return "unknown";
2324        }
2325    }
2326
2327    private String JavaDoc translateValidity(short val) {
2328        switch (val) {
2329            case ItemPSVI.VALIDITY_NOTKNOWN :
2330                return "notKnown";
2331            case ItemPSVI.VALIDITY_VALID :
2332                return "valid";
2333            case ItemPSVI.VALIDITY_INVALID :
2334                return "invalid";
2335            default :
2336                return "unknown";
2337        }
2338    }
2339
2340    /**
2341     * Check whether the calling event is first in children list ,
2342     * if yes print the <children>.
2343     */

2344    private void checkForChildren() {
2345        if (!_elementState.empty()) {
2346            ElementState fElementState = (ElementState)_elementState.peek();
2347            if (fElementState.isEmpty == true) {
2348                sendIndentedElement("children");
2349                fElementState.isEmpty = false;
2350            }
2351        }
2352        else {
2353            sendIndentedElement("children");
2354            _elementState.push(new ElementState(false));
2355        }
2356    } //checkForChildren
2357

2358    class ElementState {
2359        public boolean isEmpty;
2360        XMLAttributes fAttributes;
2361
2362        public ElementState(XMLAttributes attributes) {
2363            fAttributes = attributes;
2364            isEmpty = true;
2365        }
2366        public ElementState(boolean value) {
2367            isEmpty = value;
2368        }
2369        public XMLAttributes getAttributes() {
2370            return fAttributes;
2371        }
2372        public void isEmpty(boolean value) {
2373            isEmpty = value;
2374        }
2375    } //class ElementState
2376
} // class PSVIWriter
2377
Popular Tags