| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package xni; |
| |
| import java.io.IOException; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.Stack; |
| import java.util.Vector; |
| |
| import org.apache.xerces.dom.DocumentImpl; |
| import org.apache.xerces.impl.Constants; |
| import org.apache.xerces.impl.xs.SchemaSymbols; |
| import org.apache.xerces.util.DOMUtil; |
| import org.apache.xerces.util.NamespaceSupport; |
| import org.apache.xerces.util.XMLAttributesImpl; |
| import org.apache.xerces.util.XMLSymbols; |
| import org.apache.xerces.xni.Augmentations; |
| import org.apache.xerces.xni.NamespaceContext; |
| import org.apache.xerces.xni.QName; |
| import org.apache.xerces.xni.XMLAttributes; |
| import org.apache.xerces.xni.XMLDocumentHandler; |
| import org.apache.xerces.xni.XMLLocator; |
| import org.apache.xerces.xni.XMLResourceIdentifier; |
| import org.apache.xerces.xni.XMLString; |
| import org.apache.xerces.xni.XNIException; |
| import org.apache.xerces.xni.parser.XMLComponent; |
| import org.apache.xerces.xni.parser.XMLComponentManager; |
| import org.apache.xerces.xni.parser.XMLConfigurationException; |
| import org.apache.xerces.xni.parser.XMLDocumentFilter; |
| import org.apache.xerces.xni.parser.XMLDocumentSource; |
| import org.apache.xerces.xs.AttributePSVI; |
| import org.apache.xerces.xs.ElementPSVI; |
| import org.apache.xerces.xs.ItemPSVI; |
| import org.apache.xerces.xs.StringList; |
| import org.apache.xerces.xs.XSAnnotation; |
| import org.apache.xerces.xs.XSAttributeDeclaration; |
| import org.apache.xerces.xs.XSAttributeGroupDefinition; |
| import org.apache.xerces.xs.XSAttributeUse; |
| import org.apache.xerces.xs.XSComplexTypeDefinition; |
| import org.apache.xerces.xs.XSConstants; |
| import org.apache.xerces.xs.XSElementDeclaration; |
| import org.apache.xerces.xs.XSFacet; |
| import org.apache.xerces.xs.XSIDCDefinition; |
| import org.apache.xerces.xs.XSModel; |
| import org.apache.xerces.xs.XSModelGroup; |
| import org.apache.xerces.xs.XSModelGroupDefinition; |
| import org.apache.xerces.xs.XSMultiValueFacet; |
| import org.apache.xerces.xs.XSNamedMap; |
| import org.apache.xerces.xs.XSNamespaceItem; |
| import org.apache.xerces.xs.XSNamespaceItemList; |
| import org.apache.xerces.xs.XSNotationDeclaration; |
| import org.apache.xerces.xs.XSObject; |
| import org.apache.xerces.xs.XSObjectList; |
| import org.apache.xerces.xs.XSParticle; |
| import org.apache.xerces.xs.XSSimpleTypeDefinition; |
| import org.apache.xerces.xs.XSTypeDefinition; |
| import org.apache.xerces.xs.XSWildcard; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.xml.sax.SAXNotRecognizedException; |
| import org.xml.sax.SAXNotSupportedException; |
| |
| /** |
| * This class is a intersepts XNI events and serialized |
| * XML infoset and Post Schema Validation Infoset. |
| * |
| * @author Arun Yadav,Sun Miscrosystem. |
| * @author Peter McCracken, IBM |
| * @version $Id$ |
| */ |
| public class PSVIWriter implements XMLComponent, XMLDocumentFilter { |
| |
| public static final String XERCES_PSVI_NS = |
| "http://apache.org/xml/2001/PSVInfosetExtension"; |
| |
| /** Feature id: augment Post-Schema-Validation-Infoset */ |
| protected static final String PSVINFOSET = |
| Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI; |
| |
| /** Feature id: include ignorable whitespace. */ |
| protected static final String INCLUDE_IGNORABLE_WHITESPACE = |
| "http://apache.org/xml/features/dom/include-ignorable-whitespace"; |
| |
| /** Include ignorable whitespace. */ |
| protected boolean fIncludeIgnorableWhitespace; |
| |
| /** Recognized features. */ |
| private static final String[] RECOGNIZED_FEATURES = |
| { INCLUDE_IGNORABLE_WHITESPACE, PSVINFOSET, }; |
| |
| /** Feature defaults. */ |
| private static final Boolean[] FEATURE_DEFAULTS = { null, null, }; |
| |
| /** Recognized properties. */ |
| private static final String[] RECOGNIZED_PROPERTIES = { |
| }; |
| |
| /** Property defaults. */ |
| private static final Object[] PROPERTY_DEFAULTS = { |
| }; |
| |
| /** PSVInfoset */ |
| protected boolean fPSVInfoset; |
| |
| /** Document handler. */ |
| protected XMLDocumentHandler fDocumentHandler; |
| |
| /** Document source */ |
| protected XMLDocumentSource fDocumentSource; |
| |
| /** The namespace context for the received event stream */ |
| protected NamespaceContext fNamespaceContext; |
| |
| /** The namespace context for the new event stream */ |
| protected NamespaceContext fPSVINamespaceContext; |
| |
| /** Document Location */ |
| protected XMLLocator fDocumentLocation; |
| |
| /** Attributes and Element Info is cached in stack */ |
| private Stack _elementState = new Stack(); |
| |
| /** The number used for anonymous types */ |
| protected int fAnonNum; |
| |
| /** The number that stores the indent level */ |
| protected int fIndent; |
| |
| /** The map used to store IDs for types and elements */ |
| protected HashMap fIDMap; |
| |
| /** A list of ids for defined XSObjects */ |
| protected Vector fDefined; |
| |
| private char[] fIndentChars = |
| { '\t', '\t', '\t', '\t', '\t', '\t', '\t', '\t' }; |
| |
| private XMLString newLine = new XMLString(new char[] { '\n' }, 0, 1); |
| |
| public PSVIWriter() { |
| /* |
| System.out.println( |
| "Generating Schema Information Set Contribution (PSVI) \n" |
| + "which follow as a consequence of validation and/or assessment."); |
| |
| System.out.println("NOTE: Requires use of -s and -v"); |
| System.out.println("Output: generated in " + PSVI_OUTPUT); |
| */ |
| } // <init>() |
| |
| public void reset(XMLComponentManager componentManager) |
| throws XNIException { |
| |
| try { |
| fPSVInfoset = componentManager.getFeature(PSVINFOSET); |
| } |
| catch (XMLConfigurationException e) { |
| fPSVInfoset = false; |
| } |
| fIncludeIgnorableWhitespace = |
| componentManager.getFeature(INCLUDE_IGNORABLE_WHITESPACE); |
| |
| fAnonNum = 1000; |
| fIDMap = new HashMap(); |
| fDefined = new Vector(); |
| fIndent = 0; |
| fPSVINamespaceContext = new NamespaceSupport(); |
| } // reset(XMLComponentManager) |
| |
| /** |
| * Returns a list of feature identifiers that are recognized by |
| * this component. This method may return null if no features |
| * are recognized by this component. |
| */ |
| public String[] getRecognizedFeatures() { |
| return RECOGNIZED_FEATURES; |
| } // getRecognizedFeatures():String[] |
| |
| /** |
| * Sets the state of a feature. This method is called by the component |
| * manager any time after reset when a feature changes state. |
| * <p> |
| * <strong>Note:</strong> Components should silently ignore features |
| * that do not affect the operation of the component. |
| * |
| * @param featureId The feature identifier. |
| * @param state The state of the feature. |
| * |
| * @throws SAXNotRecognizedException The component should not throw |
| * this exception. |
| * @throws SAXNotSupportedException The component should not throw |
| * this exception. |
| */ |
| public void setFeature(String featureId, boolean state) |
| throws XMLConfigurationException { |
| } // setFeature(String,boolean) |
| |
| /** |
| * Returns a list of property identifiers that are recognized by |
| * this component. This method may return null if no properties |
| * are recognized by this component. |
| */ |
| public String[] getRecognizedProperties() { |
| return RECOGNIZED_PROPERTIES; |
| } // getRecognizedProperties():String[] |
| |
| /** |
| * Sets the value of a property. This method is called by the component |
| * manager any time after reset when a property changes value. |
| * <p> |
| * <strong>Note:</strong> Components should silently ignore properties |
| * that do not affect the operation of the component. |
| * |
| * @param propertyId The property identifier. |
| * @param value The value of the property. |
| * |
| * @throws SAXNotRecognizedException The component should not throw |
| * this exception. |
| * @throws SAXNotSupportedException The component should not throw |
| * this exception. |
| */ |
| public void setProperty(String propertyId, Object value) |
| throws XMLConfigurationException { |
| |
| } // setProperty(String,Object) |
| |
| /** |
| * Returns the default state for a feature, or null if this |
| * component does not want to report a default value for this |
| * feature. |
| * |
| * @param featureId The feature identifier. |
| * |
| * @since Xerces 2.2.0 |
| */ |
| public Boolean getFeatureDefault(String featureId) { |
| for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { |
| if (RECOGNIZED_FEATURES[i].equals(featureId)) { |
| return FEATURE_DEFAULTS[i]; |
| } |
| } |
| return null; |
| } // getFeatureDefault(String):Boolean |
| |
| /** |
| * Returns the default state for a property, or null if this |
| * component does not want to report a default value for this |
| * property. |
| * |
| * @param propertyId The property identifier. |
| * |
| * @since Xerces 2.2.0 |
| */ |
| public Object getPropertyDefault(String propertyId) { |
| for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { |
| if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { |
| return PROPERTY_DEFAULTS[i]; |
| } |
| } |
| return null; |
| } // getPropertyDefault(String):Object |
| |
| // |
| // XMLDocumentSource methods |
| // |
| |
| /** Sets the document handler to receive information about the document. */ |
| public void setDocumentHandler(XMLDocumentHandler documentHandler) { |
| fDocumentHandler = documentHandler; |
| } // setDocumentHandler(XMLDocumentHandler) |
| |
| /** Returns the document handler */ |
| public XMLDocumentHandler getDocumentHandler() { |
| return fDocumentHandler; |
| } // setDocumentHandler(XMLDocumentHandler) |
| |
| // |
| // XMLDocumentHandler methods |
| // |
| |
| /** Sets the document source */ |
| public void setDocumentSource(XMLDocumentSource source) { |
| fDocumentSource = source; |
| } // setDocumentSource |
| |
| /** Returns the document source */ |
| public XMLDocumentSource getDocumentSource() { |
| return fDocumentSource; |
| } // getDocumentSource |
| |
| /** |
| * This method notifies the start of an entity. General entities are just |
| * specified by their name. |
| * <p> |
| * <strong>Note:</strong> This method is not called for entity references |
| * appearing as part of attribute values. |
| * |
| * @param name The name of the entity. |
| * @param publicId The public identifier of the entity if the entity |
| * is external, null otherwise. |
| * @param systemId The system identifier of the entity if the entity |
| * is external, null otherwise. |
| * @param baseSystemId The base system identifier of the entity if |
| * the entity is external, null otherwise. |
| * @param encoding The auto-detected IANA encoding name of the entity |
| * stream. This value will be null in those situations |
| * where the entity encoding is not auto-detected (e.g. |
| * internal entities or a document entity that is |
| * parsed from a java.io.Reader). |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void startGeneralEntity( |
| String name, |
| XMLResourceIdentifier identifier, |
| String encoding, |
| Augmentations augs) |
| throws XNIException { |
| } // startEntity(String,String,String,String,String) |
| |
| /** |
| * Notifies of the presence of a TextDecl line in an entity. If present, |
| * this method will be called immediately following the startEntity call. |
| * <p> |
| * <strong>Note:</strong> This method will never be called for the |
| * document entity; it is only called for external general entities |
| * referenced in document content. |
| * <p> |
| * <strong>Note:</strong> This method is not called for entity references |
| * appearing as part of attribute values. |
| * |
| * @param version The XML version, or null if not specified. |
| * @param encoding The IANA encoding name of the entity. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void textDecl(String version, String encoding, Augmentations augs) |
| throws XNIException { |
| } // textDecl(String,String) |
| |
| /** |
| * The start of the document. |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void startDocument( |
| XMLLocator locator, |
| String encoding, |
| NamespaceContext namespaceContext, |
| Augmentations augs) |
| throws XNIException { |
| fNamespaceContext = namespaceContext; |
| fDocumentLocation = locator; |
| |
| fPSVINamespaceContext.declarePrefix( |
| "xsi", |
| "http://www.w3.org/2001/XMLSchema-instance"); |
| fPSVINamespaceContext.declarePrefix("psv", XERCES_PSVI_NS); |
| fPSVINamespaceContext.declarePrefix( |
| "", |
| "http://www.w3.org/2001/05/XMLInfoset"); |
| |
| if (fDocumentHandler == null) |
| return; |
| |
| fDocumentHandler.startDocument( |
| locator, |
| "UTF-8", |
| fPSVINamespaceContext, |
| null); |
| |
| Vector attributes = new Vector(); |
| attributes.add("xmlns:xsi"); |
| attributes.add("http://www.w3.org/2001/XMLSchema-instance"); |
| attributes.add(XMLSymbols.fCDATASymbol); |
| attributes.add("xmlns:psv"); |
| attributes.add(XERCES_PSVI_NS); |
| attributes.add(XMLSymbols.fCDATASymbol); |
| attributes.add("xmlns"); |
| attributes.add("http://www.w3.org/2001/05/XMLInfoset"); |
| attributes.add(XMLSymbols.fCDATASymbol); |
| sendIndentedElement("document", attributes); |
| } // startDocument(XMLLocator,String) |
| |
| /** |
| * Notifies of the presence of an XMLDecl line in the document. If |
| * present, this method will be called immediately following the |
| * startDocument call. |
| * |
| * @param version The XML version. |
| * @param encoding The IANA encoding name of the document, or null if |
| * not specified. |
| * @param standalone The standalone value, or null if not specified. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void xmlDecl( |
| String version, |
| String encoding, |
| String standalone, |
| Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| sendElementEvent("characterEncodingScheme", encoding); |
| sendElementEvent("standalone", standalone); |
| sendElementEvent("version", version); |
| } // xmlDecl(String,String,String) |
| |
| /** |
| * Notifies of the presence of the DOCTYPE line in the document. |
| * |
| * @param rootElement The name of the root element. |
| * @param publicId The public identifier if an external DTD or null |
| * if the external DTD is specified using SYSTEM. |
| * @param systemId The system identifier if an external DTD, null |
| * otherwise. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void doctypeDecl( |
| String rootElement, |
| String publicId, |
| String systemId, |
| Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| checkForChildren(); |
| sendIndentedElement("docTypeDeclaration"); |
| if (publicId != null) |
| sendElementEvent("publicIdentifier", publicId); |
| if (systemId != null) |
| sendElementEvent("systemIdentifier", systemId); |
| sendUnIndentedElement("docTypeDeclaration"); |
| } // doctypeDecl(String,String,String) |
| |
| /** |
| * A comment. |
| * |
| * @param text The text in the comment. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by application to signal an error. |
| */ |
| public void comment(XMLString text, Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| checkForChildren(); |
| sendIndentedElement("comment"); |
| sendElementEvent("content", text); |
| sendUnIndentedElement("comment"); |
| } // comment(XMLString) |
| |
| /** |
| * A processing instruction. Processing instructions consist of a |
| * target name and, optionally, text data. The data is only meaningful |
| * to the application. |
| * <p> |
| * Typically, a processing instruction's data will contain a series |
| * of pseudo-attributes. These pseudo-attributes follow the form of |
| * element attributes but are <strong>not</strong> parsed or presented |
| * to the application as anything other than text. The application is |
| * responsible for parsing the data. |
| * |
| * @param target The target. |
| * @param data The data or null if none specified. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void processingInstruction( |
| String target, |
| XMLString data, |
| Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| checkForChildren(); |
| sendIndentedElement("processingInstruction"); |
| sendElementEvent("target", target); |
| sendElementEvent("content", data); |
| sendUnIndentedElement("processingInstruction"); |
| } // processingInstruction(String,XMLString) |
| |
| /** |
| * Binds the namespaces. This method will handle calling the |
| * document handler to start the prefix mappings. |
| * <p> |
| * <strong>Note:</strong> This method makes use of the |
| * fAttributeQName variable. Any contents of the variable will |
| * be destroyed. Caller should copy the values out of this |
| * temporary variable before calling this method. |
| * |
| * @param element The name of the element. |
| * @param attributes The element attributes. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void startElement( |
| QName element, |
| XMLAttributes attributes, |
| Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| checkForChildren(); |
| |
| _elementState.push(new ElementState(true)); |
| |
| sendIndentedElement("element"); |
| sendElementEvent("namespaceName", element.uri); |
| sendElementEvent("localName", element.localpart); |
| sendElementEvent("prefix", element.prefix); |
| processAttributes(attributes); |
| processInScopeNamespaces(); |
| sendElementEvent("baseURI", fDocumentLocation.getBaseSystemId()); |
| if (fPSVInfoset) { |
| processPSVIStartElement(augs); |
| } |
| } // startElement(QName,XMLAttributes) |
| |
| /** |
| * An empty element. |
| * |
| * @param element The name of the element. |
| * @param attributes The element attributes. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void emptyElement( |
| QName element, |
| XMLAttributes attributes, |
| Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| checkForChildren(); |
| sendIndentedElement("element"); |
| sendElementEvent("namespaceName", element.uri); |
| sendElementEvent("localName", element.localpart); |
| sendElementEvent("prefix", element.prefix); |
| processAttributes(attributes); |
| processInScopeNamespaces(); |
| sendElementEvent("baseURI", fDocumentLocation.getBaseSystemId()); |
| if (fPSVInfoset) { |
| processPSVIStartElement(augs); |
| } |
| sendEmptyElementEvent("children"); |
| if (fPSVInfoset) { |
| processPSVIEndElement(augs); |
| } |
| sendUnIndentedElement("element"); |
| } // emptyElement(QName,XMLAttributes) |
| |
| /** |
| * Character content. |
| * |
| * @param text The content. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void characters(XMLString text, Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| checkForChildren(); |
| sendIndentedElement("character"); |
| sendElementEvent("textContent", text); |
| // detecting whitespace is not relevant here |
| // this is only useful if characters are output individually |
| sendUnIndentedElement("character"); |
| } // characters(XMLString) |
| |
| /** |
| * Ignorable whitespace. For this method to be called, the document |
| * source must have some way of determining that the text containing |
| * only whitespace characters should be considered ignorable. For |
| * example, the validator can determine if a length of whitespace |
| * characters in the document are ignorable based on the element |
| * content model. |
| * |
| * @param text The ignorable whitespace. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void ignorableWhitespace(XMLString text, Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| if (fIncludeIgnorableWhitespace) { |
| this.characters(text, augs); |
| } |
| } // ignorableWhitespace(XMLString) |
| |
| /** |
| * The end of an element. |
| * |
| * @param element The name of the element. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void endElement(QName element, Augmentations augs) |
| throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| ElementState fElementState = (ElementState)_elementState.peek(); |
| if (fElementState.isEmpty) { |
| sendEmptyElementEvent("children"); |
| } |
| else { |
| sendUnIndentedElement("children"); |
| } |
| _elementState.pop(); |
| if (fPSVInfoset) { |
| processPSVIStartElement(augs); |
| processPSVIEndElement(augs); |
| } |
| sendUnIndentedElement("element"); |
| } // endElement(QName) |
| |
| /** |
| * The start of a CDATA section. |
| * |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void startCDATA(Augmentations augs) throws XNIException { |
| } // startCDATA() |
| |
| /** |
| * The end of a CDATA section. |
| * |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void endCDATA(Augmentations augs) throws XNIException { |
| } // endCDATA() |
| |
| /** |
| * The end of the document. |
| * |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void endDocument(Augmentations augs) throws XNIException { |
| if (fDocumentHandler == null) |
| return; |
| |
| sendUnIndentedElement("children"); |
| sendElementEvent("documentElement"); |
| // these aren't relevent for PSVI |
| sendEmptyElementEvent("notations"); |
| sendEmptyElementEvent("unparsedEntities"); |
| |
| sendElementEvent("baseURI", fDocumentLocation.getBaseSystemId()); |
| |
| // do we ALWAYS process all declarations? I think so - PJM |
| // this isn't relevant to PSVI |
| sendElementEvent("allDeclarationsProcessed", "true"); |
| sendUnIndentedElement("document"); |
| fDocumentHandler.endDocument(null); |
| } // endDocument() |
| |
| /** |
| * This method notifies the end of an entity. General entities are just |
| * specified by their name. |
| * <p> |
| * <strong>Note:</strong> This method is not called for entity references |
| * appearing as part of attribute values. |
| * |
| * @param name The name of the entity. |
| * @param augs Additional information that may include infoset augmentations |
| * |
| * @throws XNIException Thrown by handler to signal an error. |
| */ |
| public void endGeneralEntity(String name, Augmentations augs) |
| throws XNIException { |
| } // endEntity(String) |
| |
| /** |
| * Write an unordered set of attribute information items, one for each of |
| * the attributes (specified or defaulted from the DTD) of this element. |
| * Namespace declarations do not appear in this set. If the element has no |
| * attributes, this set has no members. |
| */ |
| private void processAttributes(XMLAttributes attributes) { |
| boolean namespaceAttribute = false; |
| boolean attrElement = false; |
| |
| int attrCount = attributes == null ? 0 : attributes.getLength(); |
| |
| if (attrCount == 0) { |
| sendEmptyElementEvent("attributes"); |
| sendEmptyElementEvent("namespaceAttributes"); |
| return; |
| } |
| |
| for (int i = 0; i < attrCount; i++) { |
| String localpart = attributes.getLocalName(i); |
| String prefix = attributes.getPrefix(i); |
| if (prefix.equals(XMLSymbols.PREFIX_XMLNS) |
| || localpart.equals(XMLSymbols.PREFIX_XMLNS)) { |
| namespaceAttribute = true; |
| continue; |
| } |
| if (!attrElement) |
| sendIndentedElement("attributes"); |
| |
| sendIndentedElement("attribute"); |
| sendElementEvent("namespaceName", attributes.getURI(i)); |
| sendElementEvent("localName", attributes.getLocalName(i)); |
| sendElementEvent("prefix", attributes.getPrefix(i)); |
| sendElementEvent("normalizedValue", attributes.getValue(i)); |
| sendElementEvent( |
| "specified", |
| String.valueOf(attributes.isSpecified(i))); |
| sendElementEvent("attributeType", attributes.getType(i)); |
| |
| // this property isn't relevent to PSVI |
| sendElementEvent("references"); |
| |
| if (fPSVInfoset) { |
| processPSVIAttribute(attributes.getAugmentations(i)); |
| } |
| sendUnIndentedElement("attribute"); |
| attrElement = true; |
| } |
| if (attrElement) { |
| sendUnIndentedElement("attributes"); |
| } |
| else { |
| sendEmptyElementEvent("attributes"); |
| } |
| |
| if (namespaceAttribute) { |
| processNamespaceAttributes(attributes); |
| } |
| else { |
| sendEmptyElementEvent("namespaceAttributes"); |
| } |
| } //printAttributes |
| |
| /** |
| * Write an unordered set of attribute information items, one for each of |
| * the namespace declarations (specified or defaulted from the DTD) of this |
| * element. A declaration of the form xmlns="", which undeclares the default |
| * namespace, counts as a namespace declaration. By definition, all |
| * namespace attributes (including those named xmlns, whose [prefix] |
| * property has no value) have a namespace URI of |
| * http://www.w3.org/2000/xmlns/. If the element has no namespace |
| * declarations, this set has no members |
| */ |
| private void processNamespaceAttributes(XMLAttributes attributes) { |
| |
| // we don't need to check for null, since that was checked for in processAttributes() |
| int attrCount = attributes.getLength(); |
| |
| sendIndentedElement("namespaceAttributes"); |
| for (int i = 0; i < attrCount; i++) { |
| String localpart = attributes.getLocalName(i); |
| String prefix = attributes.getPrefix(i); |
| if (!(prefix.equals(XMLSymbols.PREFIX_XMLNS) |
| || localpart.equals(XMLSymbols.PREFIX_XMLNS))) |
| continue; |
| sendIndentedElement("attribute"); |
| sendElementEvent("namespaceName", NamespaceContext.XMLNS_URI); |
| sendElementEvent("localName", localpart); |
| sendElementEvent("prefix", prefix); |
| sendElementEvent("normalizedValue", attributes.getValue(i)); |
| sendElementEvent( |
| "specified", |
| String.valueOf(attributes.isSpecified(i))); |
| sendElementEvent("attributeType", attributes.getType(i)); |
| // this property isn't relevent to PSVI |
| sendElementEvent("references"); |
| if (fPSVInfoset) { |
| processPSVIAttribute(attributes.getAugmentations(i)); |
| } |
| sendUnIndentedElement("attribute"); |
| } |
| sendUnIndentedElement("namespaceAttributes"); |
| |
| } //printNamespacesAttributes() |
| |
| /** |
| * Write an unordered set of namespace information items, one for each of the |
| * namespaces in effect for this element. This set always contains an item |
| * with the prefix xml which is implicitly bound to the namespace name |
| * http://www.w3.org/XML/1998/namespace. It does not contain an item with the |
| * prefix xmlns (used for declaring namespaces), since an application can |
| * never encounter an element or attribute with that prefix. The set will |
| * include namespace items corresponding to all of the members of |
| * [namespace attributes], except for any representing a declaration of the |
| * form xmlns="", which does not declare a namespace but rather undeclares |
| * the default namespace |
| */ |
| private void processInScopeNamespaces() { |
| sendIndentedElement("inScopeNamespaces"); |
| sendIndentedElement("namespace"); |
| // print 'xml' binding |
| sendElementEvent("prefix", "xml"); |
| sendElementEvent("namespaceName", NamespaceContext.XML_URI); |
| sendUnIndentedElement("namespace"); |
| Enumeration prefixes = fNamespaceContext.getAllPrefixes(); |
| while (prefixes.hasMoreElements()) { |
| sendIndentedElement("namespace"); |
| |
| String prefix = (String)prefixes.nextElement(); |
| String uri = fNamespaceContext.getURI(prefix); |
| sendElementEvent("prefix", prefix); |
| sendElementEvent("namespaceName", uri); |
| sendUnIndentedElement("namespace"); |
| |
| } |
| sendUnIndentedElement("inScopeNamespaces"); |
| } //printinScopeNamespaces() |
| |
| /* The following information will be available at the startElement call: |
| * name, namespace, type, notation, validation context |
| * |
| * The following information will be available at the endElement call: |
| * nil, specified, normalized value, member type, validity, error codes, |
| * default |
| */ |
| private void processPSVIStartElement(Augmentations augs) { |
| if (augs == null) |
| return; |
| ElementPSVI elemPSVI = |
| (ElementPSVI)augs.getItem(Constants.ELEMENT_PSVI); |
| if (elemPSVI != null) { |
| // Should we store the values till end element call? -- AY |
| // I don't think so -- PJM |
| } |
| } |
| |
| /* The following information will be available at the startElement call: |
| * name, namespace, type, notation, validation context |
| * |
| * The following information will be available at the endElement call: |
| * nil, specified, normalized value, member type, validity, error codes, |
| * default |
| */ |
| private void processPSVIEndElement(Augmentations augs) { |
| if (augs == null) |
| return; |
| ElementPSVI elemPSVI = |
| (ElementPSVI)augs.getItem(Constants.ELEMENT_PSVI); |
| if (elemPSVI != null) { |
| |
| processPSVISchemaInformation(elemPSVI); |
| sendElementEvent( |
| "psv:validationAttempted", |
| this.translateValidationAttempted( |
| elemPSVI.getValidationAttempted())); |
| // Would rather getValidationContext() return element info item. |
| // This is non the same as XSV. |
| sendElementEvent( |
| "psv:validationContext", |
| elemPSVI.getValidationContext()); |
| |
| sendElementEvent( |
| "psv:validity", |
| this.translateValidity(elemPSVI.getValidity())); |
| |
| processPSVISchemaErrorCode(elemPSVI.getErrorCodes()); |
| sendElementEvent( |
| "psv:schemaNormalizedValue", |
| elemPSVI.getSchemaNormalizedValue()); |
| sendElementEvent( |
| "psv:schemaSpecified", |
| elemPSVI.getIsSchemaSpecified() ? "schema" : "infoset"); |
| sendElementEvent("psv:schemaDefault", elemPSVI.getSchemaDefault()); |
| |
| processPSVITypeDefinitionRef( |
| "psv:typeDefinition", |
| elemPSVI.getTypeDefinition()); |
| processPSVITypeDefinitionRef( |
| "psv:memberTypeDefinition", |
| elemPSVI.getMemberTypeDefinition()); |
| // A value for nil is not necessary, since we output declaration, instead. |
| // See http://www.w3.org/TR/xmlschema-1/#section-Element-Declaration-Information-Set-Contributions. |
| sendElementEvent("psv:nil"); |
| |
| sendIndentedElement("psv:declaration"); |
| processPSVIElementRef( |
| "psv:elementDeclaration", |
| elemPSVI.getElementDeclaration()); |
| sendUnIndentedElement("psv:declaration"); |
| processPSVIElementRef("psv:notation", elemPSVI.getNotation()); |
| // idref table does not have to be exposed, and is not exposed |
| sendElementEvent("psv:idIdrefTable"); |
| // identity constraint table does not have to be exposed, and is not exposed |
| sendElementEvent("psv:identityConstraintTable"); |
| } |
| } |
| |
| private void processPSVIAttribute(Augmentations augs) { |
| if (augs == null) |
| return; |
| AttributePSVI attrPSVI = |
| (AttributePSVI)augs.getItem(Constants.ATTRIBUTE_PSVI); |
| if (attrPSVI != null) { |
| sendElementEvent( |
| "psv:validationAttempted", |
| this.translateValidationAttempted( |
| attrPSVI.getValidationAttempted())); |
| // Would rather getValidationContext() return element info item. |
| // This is not the same as XSV. |
| sendElementEvent( |
| "psv:validationContext", |
| attrPSVI.getValidationContext()); |
| |
| sendElementEvent( |
| "psv:validity", |
| this.translateValidity(attrPSVI.getValidity())); |
| |
| processPSVISchemaErrorCode(attrPSVI.getErrorCodes()); |
| sendElementEvent( |
| "psv:schemaNormalizedValue", |
| attrPSVI.getSchemaNormalizedValue()); |
| sendElementEvent( |
| "psv:schemaSpecified", |
| attrPSVI.getIsSchemaSpecified() ? "schema" : "infoset"); |
| sendElementEvent("psv:schemaDefault", attrPSVI.getSchemaDefault()); |
| |
| processPSVITypeDefinitionRef( |
| "psv:typeDefinition", |
| attrPSVI.getTypeDefinition()); |
| processPSVITypeDefinitionRef( |
| "psv:memberTypeDefinition", |
| attrPSVI.getMemberTypeDefinition()); |
| |
| if (attrPSVI.getAttributeDeclaration() == null) { |
| sendElementEvent("psv:declaration"); |
| } |
| else { |
| sendIndentedElement("psv:declaration"); |
| processPSVIAttributeDeclarationRef( |
| attrPSVI.getAttributeDeclaration()); |
| sendUnIndentedElement("psv:declaration"); |
| } |
| } |
| } |
| |
| private void processPSVISchemaErrorCode(StringList errorCodes) { |
| StringBuffer errorBuffer = new StringBuffer(); |
| if (errorCodes != null && errorCodes.getLength() > 0) { |
| for (int i = 0; i < errorCodes.getLength() - 1; i++) { |
| errorBuffer.append(errorCodes.item(i)); |
| errorBuffer.append(" "); |
| } |
| errorBuffer.append(errorCodes.item(errorCodes.getLength() - 1)); |
| } |
| sendElementEvent("psv:schemaErrorCode", errorBuffer.toString()); |
| } |
| |
| private void processPSVISchemaInformation(ElementPSVI elemPSVI) { |
| if (elemPSVI == null) |
| return; |
| XSModel schemaInfo = elemPSVI.getSchemaInformation(); |
| XSNamespaceItemList schemaNamespaces = |
| schemaInfo == null ? null : schemaInfo.getNamespaceItems(); |
| if (schemaNamespaces == null || schemaNamespaces.getLength() == 0) { |
| sendElementEvent("psv:schemaInformation"); |
| } |
| else { |
| sendIndentedElement("psv:schemaInformation"); |
| for (int i = 0; i < schemaNamespaces.getLength(); i++) { |
| processPSVINamespaceItem(schemaNamespaces.item(i)); |
| } |
| sendUnIndentedElement("psv:schemaInformation"); |
| } |
| } |
| |
| private void processPSVINamespaceItem(XSNamespaceItem item) { |
| if (item == null) |
| return; |
| |
| String namespace = item.getSchemaNamespace(); |
| if (namespace != null && namespace.equals(Constants.NS_XMLSCHEMA)) { |
| // we don't want to output information for schema for schemas |
| return; |
| } |
| |
| sendIndentedElement("psv:namespaceSchemaInformation"); |
| sendElementEvent("psv:schemaNamespace", namespace); |
| |
| // print out schema components |
| processPSVISchemaComponents(item); |
| |
| // print out schema document information |
| processPSVISchemaDocuments(item); |
| |
| // print out schema annotations |
| processPSVISchemaAnnotations(item.getAnnotations()); |
| sendUnIndentedElement("psv:namespaceSchemaInformation"); |
| } |
| |
| private void processPSVISchemaDocuments(XSNamespaceItem item) { |
| StringList locations = |
| item == null ? null : item.getDocumentLocations(); |
| if (locations == null || locations.getLength() == 0) { |
| sendEmptyElementEvent("psv:schemaDocuments"); |
| return; |
| } |
| sendIndentedElement("psv:schemaDocuments"); |
| for (int i = 0; i < locations.getLength(); i++) { |
| sendIndentedElement("psv:schemaDocument"); |
| sendElementEvent("psv:documentLocation", locations.item(i)); |
| // It's supposed to point to a <document> element, and we're not really |
| // dealing with those (except for the one at the root) |
| sendElementEvent("psv:document"); |
| sendUnIndentedElement("psv:schemaDocument"); |
| } |
| sendUnIndentedElement("psv:schemaDocuments"); |
| } |
| |
| private void processPSVISchemaComponents(XSNamespaceItem item) { |
| if (item == null) { |
| sendEmptyElementEvent("psv:schemaComponents"); |
| return; |
| } |
| |
| // it we happen to not get any components, this will output a start tag |
| // and a close tag, instead of an empty element tag. This isn't a big |
| // deal, though |
| sendIndentedElement("psv:schemaComponents"); |
| |
| // typeDefinitions |
| XSNamedMap components = item.getComponents(XSConstants.TYPE_DEFINITION); |
| for (int i = 0; i < components.getLength(); i++) { |
| processPSVITypeDefinition((XSTypeDefinition)components.item(i)); |
| } |
| // elementDeclarations |
| components = item.getComponents(XSConstants.ELEMENT_DECLARATION); |
| for (int i = 0; i < components.getLength(); i++) { |
| processPSVIElementDeclaration( |
| (XSElementDeclaration)components.item(i)); |
| } |
| // attributeDeclarations |
| components = item.getComponents(XSConstants.ATTRIBUTE_DECLARATION); |
| for (int i = 0; i < components.getLength(); i++) { |
| processPSVIAttributeDeclaration( |
| (XSAttributeDeclaration)components.item(i)); |
| } |
| // modelGroupDefinitions |
| components = item.getComponents(XSConstants.MODEL_GROUP_DEFINITION); |
| for (int i = 0; i < components.getLength(); i++) { |
| processPSVIModelGroupDefinition( |
| (XSModelGroupDefinition)components.item(i)); |
| } |
| // attributeGroupDefinitions |
| components = item.getComponents(XSConstants.ATTRIBUTE_GROUP); |
| for (int i = 0; i < components.getLength(); i++) { |
| processPSVIAttributeGroupDefinition( |
| (XSAttributeGroupDefinition)components.item(i)); |
| } |
| // notationDeclarations |
| components = item.getComponents(XSConstants.NOTATION_DECLARATION); |
| for (int i = 0; i < components.getLength(); i++) { |
| processPSVINotationDeclaration( |
| (XSNotationDeclaration)components.item(i)); |
| } |
| sendUnIndentedElement("psv:schemaComponents"); |
| } |
| |
| private void processPSVITypeDefinition(XSTypeDefinition type) { |
| if (type == null) |
| return; |
| if (type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) { |
| processPSVIComplexTypeDefinition((XSComplexTypeDefinition)type); |
| } |
| else if (type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) { |
| processPSVISimpleTypeDefinition((XSSimpleTypeDefinition)type); |
| } |
| else { |
| throw new IllegalArgumentException( |
| "Unknown type definition value: " + type.getType()); |
| } |
| } |
| |
| private void processPSVIComplexTypeDefinition(XSComplexTypeDefinition type) { |
| if (type == null) |
| return; |
| sendIndentedElementWithID("psv:complexTypeDefinition", type); |
| sendElementEvent("psv:name", type.getName()); |
| sendElementEvent("psv:targetNamespace", type.getNamespace()); |
| processPSVITypeDefinitionOrRef( |
| "psv:baseTypeDefinition", |
| type.getBaseType()); |
| sendElementEvent( |
| "psv:derivationMethod", |
| this.translateDerivation(type.getDerivationMethod())); |
| sendElementEvent("psv:final", this.translateBlockOrFinal(type.getFinal())); |
| sendElementEvent("psv:abstract", String.valueOf(type.getAbstract())); |
| processPSVIAttributeUses(type.getAttributeUses()); |
| processPSVIAttributeWildcard(type.getAttributeWildcard()); |
| sendIndentedElement("psv:contentType"); |
| sendElementEvent( |
| "psv:variety", |
| this.translateContentType(type.getContentType())); |
| XSSimpleTypeDefinition simpleType = type.getSimpleType(); |
| if(simpleType == null || (!simpleType.getAnonymous() || fDefined.contains(this.getID(simpleType)))) { |
| processPSVIElementRef("psv:simpleTypeDefinition", simpleType); |
| } |
| else { |
| processPSVISimpleTypeDefinition(simpleType); |
| } |
| processPSVIParticle(type.getParticle()); |
| sendUnIndentedElement("psv:contentType"); |
| sendElementEvent( |
| "psv:prohibitedSubstitutions", |
| this.translateBlockOrFinal(type.getProhibitedSubstitutions())); |
| processPSVIAnnotations(type.getAnnotations()); |
| sendUnIndentedElement("psv:complexTypeDefinition"); |
| } |
| |
| private void processPSVISimpleTypeDefinition(XSSimpleTypeDefinition type) { |
| if (type == null) { |
| sendElementEvent("psv:simpleTypeDefinition"); |
| return; |
| } |
| |
| sendIndentedElementWithID("psv:simpleTypeDefinition", type); |
| sendElementEvent("psv:name", type.getName()); |
| sendElementEvent("psv:targetNamespace", type.getNamespace()); |
| processPSVITypeDefinitionOrRef( |
| "psv:baseTypeDefinition", |
| type.getBaseType()); |
| processPSVITypeDefinitionOrRef( |
| "psv:primitiveTypeDefinition", |
| type.getPrimitiveType()); |
| processPSVIFacets(type); |
| |
| sendIndentedElement("psv:fundamentalFacets"); |
| sendIndentedElement("psv:ordered"); |
| sendElementEvent("psv:value", this.translateOrdered(type.getOrdered())); |
| sendUnIndentedElement("psv:ordered"); |
| sendIndentedElement("psv:bounded"); |
| sendElementEvent("psv:value", String.valueOf(type.getBounded())); |
| sendUnIndentedElement("psv:bounded"); |
| sendIndentedElement("psv:cardinality"); |
| sendElementEvent("psv:value", String.valueOf(type.getFinite())); |
| sendUnIndentedElement("psv:cardinality"); |
| sendIndentedElement("psv:numeric"); |
| sendElementEvent("psv:value", String.valueOf(type.getNumeric())); |
| sendUnIndentedElement("psv:numeric"); |
| sendUnIndentedElement("psv:fundamentalFacets"); |
| |
| sendElementEvent("psv:final", this.translateBlockOrFinal(type.getFinal())); |
| sendElementEvent( |
| "psv:variety", |
| this.translateVariety(type.getVariety())); |
| processPSVITypeDefinitionOrRef( |
| "psv:itemTypeDefinition", |
| type.getItemType()); |
| processPSVIMemberTypeDefinitions(type.getMemberTypes()); |
| processPSVIAnnotations(type.getAnnotations()); |
| sendUnIndentedElement("psv:simpleTypeDefinition"); |
| } |
| |
| private void processPSVIFacets(XSSimpleTypeDefinition type) { |
| if (type == null) |
| return; |
| XSObjectList facets = type.getFacets(); |
| XSObjectList multiValueFacets = type.getMultiValueFacets(); |
| if ((facets == null || facets.getLength() == 0) |
| && (multiValueFacets == null || multiValueFacets.getLength() == 0)) { |
| sendElementEvent("psv:facets"); |
| } |
| else { |
| sendIndentedElement("psv:facets"); |
| if (facets != null) { |
| for (int i = 0; i < facets.getLength(); i++) { |
| XSFacet facet = (XSFacet)facets.item(i); |
| String name = this.translateFacetKind(facet.getFacetKind()); |
| sendIndentedElement("psv:" + name); |
| sendElementEvent("psv:value", facet.getLexicalFacetValue()); |
| sendElementEvent( |
| "psv:fixed", |
| String.valueOf(facet.getFixed())); |
| processPSVIAnnotation(facet.getAnnotation()); |
| sendUnIndentedElement("psv:" + name); |
| } |
| } |
| if (multiValueFacets != null) { |
| for (int i = 0; i < multiValueFacets.getLength(); i++) { |
| XSMultiValueFacet facet = |
| (XSMultiValueFacet)multiValueFacets.item(i); |
| String name = this.translateFacetKind(facet.getFacetKind()); |
| sendIndentedElement("psv:" + name); |
| StringList values = facet.getLexicalFacetValues(); |
| for (int j = 0; j < values.getLength(); j++) { |
| sendElementEvent("psv:value", values.item(j)); |
| } |
| sendElementEvent("psv:fixed", "false"); |
| processPSVIAnnotations(facet.getAnnotations()); |
| sendUnIndentedElement("psv:" + name); |
| } |
| } |
| sendUnIndentedElement("psv:facets"); |
| } |
| } |
| |
| private void processPSVIMemberTypeDefinitions(XSObjectList memTypes) { |
| if (memTypes == null || memTypes.getLength() == 0) { |
| sendElementEvent("psv:memberTypeDefinitions"); |
| } |
| else { |
| sendIndentedElement("psv:memberTypeDefinitions"); |
| for (int i = 0; i < memTypes.getLength(); i++) { |
| processPSVITypeDefinitionOrRef( |
| "psv:memberTypeDefinition", |
| (XSTypeDefinition)memTypes.item(i)); |
| } |
| sendUnIndentedElement("psv:memberTypeDefinitions"); |
| } |
| } |
| |
| /* It's possible that this method will send events for null annotations, i.e. |
| * <psv:annotations> |
| * <psv:annotation xsi:nil="true"/> |
| * <psv:annotation>...</psv:annotation> |
| * </psv:annotations> |
| * |
| * This is because of the way multi-value facet is implemented. It represents |
| * the annotation on each value of the facet, and if a value doesn't have one, |
| * it's corresponding annotation is null. Thus, it's possible for the first |
| * annotation to be null, but the second one to be exist. |
| * |
| * An exception to this is if all of the annotations are null; then I output |
| * <psv:annotations xsi:nil="true"/> |
| */ |
| private void processPSVIAnnotations(XSObjectList annotations) { |
| boolean empty = true; |
| if (annotations != null && annotations.getLength() > 0) { |
| for (int i = 0; i < annotations.getLength(); i++) { |
| if (annotations.item(i) != null) { |
| empty = false; |
| break; |
| } |
| } |
| } |
| |
| if (empty) { |
| sendElementEvent("psv:annotations"); |
| } |
| else { |
| sendIndentedElement("psv:annotations"); |
| for (int i = 0; i < annotations.getLength(); i++) { |
| processPSVIAnnotation((XSAnnotation)annotations.item(i)); |
| } |
| sendUnIndentedElement("psv:annotations"); |
| } |
| } |
| |
| private void processPSVISchemaAnnotations(XSObjectList annotations) { |
| if (annotations == null || annotations.getLength() == 0) { |
| sendElementEvent("psv:schemaAnnotations"); |
| } |
| else { |
| sendIndentedElement("psv:schemaAnnotations"); |
| for (int i = 0; i < annotations.getLength(); i++) { |
| processPSVIAnnotation((XSAnnotation)annotations.item(i)); |
| } |
| sendUnIndentedElement("psv:schemaAnnotations"); |
| } |
| } |
| |
| private void processPSVIAttributeUses(XSObjectList uses) { |
| if (uses == null || uses.getLength() == 0) { |
| sendElementEvent("psv:attributeUses"); |
| } |
| else { |
| sendIndentedElement("psv:attributeUses"); |
| for (int i = 0; i < uses.getLength(); i++) { |
| XSAttributeUse use = (XSAttributeUse)uses.item(i); |
| sendIndentedElement("psv:attributeUse"); |
| sendElementEvent("psv:required", String.valueOf(use.getRequired())); |
| processPSVIAttributeDeclarationOrRef(use.getAttrDeclaration()); |
| processPSVIValueConstraint(use.getConstraintType(), use.getConstraintValue()); |
| sendUnIndentedElement("psv:attributeUse"); |
| } |
| sendUnIndentedElement("psv:attributeUses"); |
| } |
| } |
| |
| private void processPSVIAttributeWildcard(XSWildcard wildcard) { |
| if (wildcard == null) { |
| sendElementEvent("psv:attributeWildcard"); |
| } |
| else { |
| sendIndentedElement("psv:attributeWildcard"); |
| processPSVIWildcard(wildcard); |
| sendUnIndentedElement("psv:attributeWildcard"); |
| } |
| } |
| |
| private void processPSVIWildcard(XSWildcard wildcard) { |
| if (wildcard == null) |
| return; |
| sendIndentedElement("psv:wildcard"); |
| sendIndentedElement("psv:namespaceConstraint"); |
| sendElementEvent( |
| "psv:variety", |
| this.translateConstraintType(wildcard.getConstraintType())); |
| |
| StringBuffer constraintBuffer = new StringBuffer(); |
| StringList constraints = wildcard.getNsConstraintList(); |
| if (constraints != null && constraints.getLength() > 0) { |
| for (int i = 0; i < constraints.getLength() - 1; i++) { |
| constraintBuffer.append(constraints.item(i)); |
| constraintBuffer.append(" "); |
| } |
| constraintBuffer.append( |
| constraints.item(constraints.getLength() - 1)); |
| } |
| sendElementEvent("psv:namespaces", constraintBuffer.toString()); |
| |
| sendUnIndentedElement("psv:namespaceConstraint"); |
| sendElementEvent( |
| "psv:processContents", |
| this.translateProcessContents(wildcard.getProcessContents())); |
| processPSVIAnnotation(wildcard.getAnnotation()); |
| sendUnIndentedElement("psv:wildcard"); |
| } |
| |
| private void processPSVIAnnotation(XSAnnotation ann) { |
| if (ann == null) { |
| sendElementEvent("psv:annotation"); |
| } |
| else { |
| sendIndentedElement("psv:annotation"); |
| // We can't get all the information from DOM, but I've outputed what |
| // we can get -- PJM |
| Node dom = new DocumentImpl(); |
| ann.writeAnnotation(dom, XSAnnotation.W3C_DOM_DOCUMENT); |
| |
| // this child will be the annotation element |
| Element annot = DOMUtil.getFirstChildElement(dom); |
| |
| processDOMElement( |
| annot, |
| SchemaSymbols.ELT_APPINFO, |
| "psv:applicationInformation"); |
| processDOMElement( |
| annot, |
| SchemaSymbols.ELT_DOCUMENTATION, |
| "psv:userInformation"); |
| processDOMAttributes(annot); |
| sendUnIndentedElement("psv:annotation"); |
| } |
| } |
| |
| private void processDOMElement( |
| Node node, |
| String elementName, |
| String tagName) { |
| if (node == null) |
| return; |
| boolean foundElem = false; |
| for (Element child = DOMUtil.getFirstChildElement(node); |
| child != null; |
| child = DOMUtil.getNextSiblingElement(child)) { |
| if (DOMUtil.getLocalName(child).equals(elementName)) { |
| if (!foundElem) { |
| sendIndentedElement(tagName); |
| foundElem = true; |
| } |
| sendIndentedElement("element"); |
| sendElementEvent( |
| "namespaceName", |
| DOMUtil.getNamespaceURI(child)); |
| sendElementEvent("localName", DOMUtil.getLocalName(child)); |
| sendElementEvent("prefix", child.getPrefix()); |
| sendIndentedElement("children"); |
| sendIndentedElement("character"); |
| sendElementEvent("textContent", DOMUtil.getChildText(child)); |
| sendUnIndentedElement("character"); |
| sendUnIndentedElement("children"); |
| |
| //Create XMLAttributes from DOM |
| Attr[] atts = (Element) child == null ? null : DOMUtil.getAttrs((Element) child); |
| XMLAttributes attrs = new XMLAttributesImpl(); |
| for (int i=0; i<atts.length; i++) { |
| Attr att = (Attr)atts[i]; |
| attrs.addAttribute( |
| new QName(att.getPrefix(), att.getLocalName(), att.getName(), att.getNamespaceURI()), |
| "CDATA" ,att.getValue() |
| ); |
| } |
| |
| processAttributes(attrs); |
| sendUnIndentedElement("element"); |
| } |
| } |
| if (foundElem) { |
| sendUnIndentedElement(tagName); |
| } |
| else { |
| sendEmptyElementEvent(tagName); |
| } |
| } |
| |
| private void processDOMAttributes(Element elem) { |
| Attr[] atts = elem == null ? null : DOMUtil.getAttrs(elem); |
| |
| boolean namespaceAttribute = false; |
| boolean attrElement = false; |
| |
| int attrCount = atts == null ? 0 : atts.length; |
| |
| if (attrCount == 0) { |
| sendEmptyElementEvent("attributes"); |
| sendEmptyElementEvent("namespaceAttributes"); |
| return; |
| } |
| |
| for (int i = 0; i < attrCount; i++) { |
| Attr att = (Attr)atts[i]; |
| String localpart = DOMUtil.getLocalName(att); |
| String prefix = att.getPrefix(); |
| if (localpart.equals(XMLSymbols.PREFIX_XMLNS) |
| || prefix.equals(XMLSymbols.PREFIX_XMLNS)) { |
| namespaceAttribute = true; |
| continue; |
| } |
| if (!attrElement) |
| sendIndentedElement("attributes"); |
| |
| sendIndentedElement("attribute"); |
| sendElementEvent("namespaceName", DOMUtil.getNamespaceURI(att)); |
| sendElementEvent("localName", DOMUtil.getLocalName(att)); |
| sendElementEvent("prefix", att.getPrefix()); |
| sendElementEvent("normalizedValue", att.getValue()); |
| sendElementEvent( |
| "specified", |
| String.valueOf(att.getSpecified())); |
| sendElementEvent("attributeType"); |
| |
| // this property isn't relevent to PSVI |
| sendElementEvent("references"); |
| |
| sendUnIndentedElement("attribute"); |
| attrElement = true; |
| } |
| if (attrElement) { |
| sendUnIndentedElement("attributes"); |
| } |
| else { |
| sendEmptyElementEvent("attributes"); |
| } |
| |
| if (namespaceAttribute) { |
| sendIndentedElement("namespaceAttributes"); |
| for (int i = 0; i < attrCount; i++) { |
| Attr att = (Attr)atts[i]; |
| String localpart = DOMUtil.getLocalName(att); |
| String prefix = att.getPrefix(); |
| if (localpart.equals(XMLSymbols.PREFIX_XMLNS) |
| || prefix.equals(XMLSymbols.PREFIX_XMLNS)) { |
| |
| sendIndentedElement("attribute"); |
| sendElementEvent("namespaceName", DOMUtil.getNamespaceURI(att)); |
| sendElementEvent("localName", DOMUtil.getLocalName(att)); |
| sendElementEvent("prefix", att.getPrefix()); |
| sendElementEvent("normalizedValue", att.getValue()); |
| sendElementEvent( |
| "specified", |
| String.valueOf(att.getSpecified())); |
| sendElementEvent("attributeType"); |
| |
| // this property isn't relevent to PSVI |
| sendElementEvent("references"); |
| |
| sendUnIndentedElement("attribute"); |
| } |
| } |
| sendUnIndentedElement("namespaceAttributes"); |
| } |
| else { |
| sendEmptyElementEvent("namespaceAttributes"); |
| } |
| } |
| |
| private void processPSVIElementDeclaration(XSElementDeclaration elem) { |
| if (elem == null) |
| return; |
| sendIndentedElementWithID("psv:elementDeclaration", elem); |
| sendElementEvent("psv:name", elem.getName()); |
| sendElementEvent("psv:targetNamespace", elem.getNamespace()); |
| processPSVITypeDefinitionOrRef( |
| "psv:typeDefinition", |
| elem.getTypeDefinition()); |
| processPSVIScope("psv:scope", elem.getEnclosingCTDefinition(), elem.getScope()); |
| processPSVIValueConstraint(elem.getConstraintType(), elem.getConstraintValue()); |
| sendElementEvent("psv:nillable", String.valueOf(elem.getNillable())); |
| processPSVIIdentityConstraintDefinitions(elem.getIdentityConstraints()); |
| processPSVISubstitutionGroupAffiliation(elem); |
| |
| sendElementEvent( |
| "psv:substitutionGroupExclusions", |
| this.translateBlockOrFinal(elem.getSubstitutionGroupExclusions())); |
| sendElementEvent( |
| "psv:disallowedSubstitutions", |
| this.translateBlockOrFinal(elem.getDisallowedSubstitutions())); |
| sendElementEvent("psv:abstract", String.valueOf(elem.getAbstract())); |
| processPSVIAnnotation(elem.getAnnotation()); |
| sendUnIndentedElement("psv:elementDeclaration"); |
| } |
| |
| private void processPSVIAttributeDeclaration(XSAttributeDeclaration attr) { |
| if (attr == null) |
| return; |
| sendIndentedElementWithID("psv:attributeDeclaration", attr); |
| sendElementEvent("psv:name", attr.getName()); |
| sendElementEvent("psv:targetNamespace", attr.getNamespace()); |
| processPSVITypeDefinitionOrRef( |
| "psv:typeDefinition", |
| attr.getTypeDefinition()); |
| processPSVIScope("psv:scope", attr.getEnclosingCTDefinition(), attr.getScope()); |
| processPSVIValueConstraint(attr.getConstraintType(), attr.getConstraintValue()); |
| processPSVIAnnotation(attr.getAnnotation()); |
| sendUnIndentedElement("psv:attributeDeclaration"); |
| } |
| |
| private void processPSVIAttributeGroupDefinition(XSAttributeGroupDefinition ag) { |
| if (ag == null) |
| return; |
| sendIndentedElementWithID("psv:attributeGroupDefinition", ag); |
| sendElementEvent("psv:name", ag.getName()); |
| sendElementEvent("psv:targetNamespace", ag.getNamespace()); |
| processPSVIAttributeUses(ag.getAttributeUses()); |
| processPSVIAttributeWildcard(ag.getAttributeWildcard()); |
| processPSVIAnnotation(ag.getAnnotation()); |
| sendUnIndentedElement("psv:attributeGroupDefinition"); |
| } |
| |
| private void processPSVIModelGroupDefinition(XSModelGroupDefinition mgd) { |
| if (mgd == null) { |
| sendElementEvent("psv:modelGroupDefinition"); |
| } |
| else { |
| sendIndentedElementWithID("psv:modelGroupDefinition", mgd); |
| sendElementEvent("psv:name", mgd.getName()); |
| sendElementEvent("psv:targetNamespace", mgd.getNamespace()); |
| processPSVIModelGroup(mgd.getModelGroup()); |
| processPSVIAnnotation(mgd.getAnnotation()); |
| sendUnIndentedElement("psv:modelGroupDefinition"); |
| } |
| } |
| |
| private void processPSVIModelGroup(XSModelGroup mg) { |
| if (mg == null) { |
| sendElementEvent("psv:modelGroup"); |
| } |
| else { |
| sendIndentedElement("psv:modelGroup"); |
| sendElementEvent( |
| "psv:compositor", |
| this.translateCompositor(mg.getCompositor())); |
| processPSVIParticles(mg.getParticles()); |
| processPSVIAnnotation(mg.getAnnotation()); |
| sendUnIndentedElement("psv:modelGroup"); |
| } |
| } |
| |
| private void processPSVINotationDeclaration(XSNotationDeclaration not) { |
| if (not == null) { |
| sendElementEvent("psv:notationDeclaration"); |
| } |
| else { |
| sendIndentedElementWithID("psv:notationDeclaration", not); |
| sendElementEvent("psv:name", not.getName()); |
| sendElementEvent("psv:targetNamespace", not.getNamespace()); |
| sendElementEvent("systemIdentifier", not.getSystemId()); |
| sendElementEvent("publicIdentifier", not.getPublicId()); |
| processPSVIAnnotation(not.getAnnotation()); |
| sendUnIndentedElement("psv:notationDeclaration"); |
| } |
| } |
| |
| private void processPSVIIdentityConstraintDefinitions(XSNamedMap constraints) { |
| if (constraints == null || constraints.getLength() == 0) { |
| sendElementEvent("psv:identityConstraintDefinitions"); |
| } |
| else { |
| sendIndentedElement("psv:identityConstraintDefinitions"); |
| for (int i = 0; i < constraints.getLength(); i++) { |
| XSIDCDefinition constraint = |
| (XSIDCDefinition)constraints.item(i); |
| sendIndentedElementWithID( |
| "psv:identityConstraintDefinition", |
| constraint); |
| sendElementEvent("psv:name", constraint.getName()); |
| sendElementEvent( |
| "psv:targetNamespace", |
| constraint.getNamespace()); |
| sendElementEvent( |
| "psv:identityConstraintCategory", |
| this.translateCategory(constraint.getCategory())); |
| sendIndentedElement("psv:selector"); |
| processPSVIXPath(constraint.getSelectorStr()); |
| sendUnIndentedElement("psv:selector"); |
| processPSVIFields(constraint.getFieldStrs()); |
| processPSVIElementRef( |
| "psv:referencedKey", |
| constraint.getRefKey()); |
| processPSVIAnnotations(constraint.getAnnotations()); |
| sendUnIndentedElement("psv:identityConstraintDefinition"); |
| } |
| sendUnIndentedElement("psv:identityConstraintDefinitions"); |
| } |
| } |
| |
| private void processPSVIFields(StringList fields) { |
| if (fields == null || fields.getLength() == 0) { |
| sendElementEvent("psv:fields"); |
| } |
| else { |
| sendIndentedElement("psv:fields"); |
| for (int i = 0; i < fields.getLength(); i++) { |
| processPSVIXPath(fields.item(i)); |
| } |
| sendUnIndentedElement("psv:fields"); |
| } |
| } |
| |
| private void processPSVIXPath(String path) { |
| sendIndentedElement("psv:xpath"); |
| sendElementEvent("psv:xpath", path); |
| sendUnIndentedElement("psv:xpath"); |
| } |
| |
| private void processPSVIParticles(XSObjectList particles) { |
| if (particles == null || particles.getLength() == 0) { |
| sendElementEvent("psv:particles"); |
| } |
| else { |
| sendIndentedElement("psv:particles"); |
| for (int i = 0; i < particles.getLength(); i++) { |
| processPSVIParticle((XSParticle)particles.item(i)); |
| } |
| sendUnIndentedElement("psv:particles"); |
| } |
| } |
| |
| private void processPSVIParticle(XSParticle part) { |
| if (part == null) { |
| sendElementEvent("psv:particle"); |
| } |
| else { |
| sendIndentedElement("psv:particle"); |
| sendElementEvent( |
| "psv:minOccurs", |
| String.valueOf(part.getMinOccurs())); |
| sendElementEvent( |
| "psv:maxOccurs", |
| part.getMaxOccurs() == SchemaSymbols.OCCURRENCE_UNBOUNDED |
| ? "unbounded" |
| : String.valueOf(part.getMaxOccurs())); |
| sendIndentedElement("psv:term"); |
| switch (part.getTerm().getType()) { |
| case XSConstants.ELEMENT_DECLARATION : |
| processPSVIElementDeclarationOrRef( |
| (XSElementDeclaration)part.getTerm()); |
| break; |
| case XSConstants.MODEL_GROUP : |
| processPSVIModelGroup((XSModelGroup)part.getTerm()); |
| break; |
| case XSConstants.WILDCARD : |
| processPSVIWildcard((XSWildcard)part.getTerm()); |
| break; |
| } |
| sendUnIndentedElement("psv:term"); |
| sendUnIndentedElement("psv:particle"); |
| } |
| } |
| |
| private void processPSVIElementRef(String elementName, XSObject obj) { |
| this.processPSVIElementRef(elementName, null, obj); |
| } |
| |
| private void processPSVIElementRef( |
| String elementName, |
| Vector attributes, |
| XSObject obj) { |
| if (attributes == null) { |
| attributes = new Vector(); |
| } |
| String ref = this.getID(obj); |
| if (ref != null) { |
| attributes.add("ref"); |
| attributes.add(ref); |
| attributes.add(XMLSymbols.fIDREFSymbol); |
| } |
| sendElementEvent(elementName, attributes, (XMLString) null); |
| } |
| |
| private void processPSVIAttributeDeclarationOrRef(XSAttributeDeclaration att) { |
| if (att == null) |
| return; |
| // for global attributes, and attributes that have already been printed, |
| // we always want to print references |
| if (att.getScope() == XSConstants.SCOPE_GLOBAL |
| || fDefined.contains(this.getID(att))) { |
| processPSVIAttributeDeclarationRef(att); |
| } |
| else { |
| processPSVIAttributeDeclaration(att); |
| } |
| } |
| |
| private void processPSVIAttributeDeclarationRef(XSAttributeDeclaration att) { |
| if (att == null) |
| return; |
| Vector attributes = new Vector(); |
| attributes.add("name"); |
| attributes.add(att.getName()); |
| attributes.add(XMLSymbols.fCDATASymbol); |
| if (att.getNamespace() != null) { |
| attributes.add("tns"); |
| attributes.add(att.getNamespace()); |
| attributes.add(XMLSymbols.fCDATASymbol); |
| } |
| processPSVIElementRef("psv:attributeDeclaration", attributes, att); |
| } |
| |
| // always prints a reference |
| private void processPSVITypeDefinitionRef( |
| String enclose, |
| XSTypeDefinition type) { |
| if (type == null) { |
| sendElementEvent(enclose); |
| return; |
| } |
| |
| sendIndentedElement(enclose); |
| if (type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) { |
| processPSVIElementRef("psv:complexTypeDefinition", type); |
| } |
| else if (type.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) { |
| processPSVIElementRef("psv:simpleTypeDefinition", type); |
| } |
| else { |
| throw new IllegalArgumentException( |
| "Unknown type definition value: " + type.getTypeCategory()); |
| } |
| sendUnIndentedElement(enclose); |
| } |
| |
| // prints a reference if the type is anonymous and hasn't already been defined, |
| // otherwise prints a definition |
| private void processPSVITypeDefinitionOrRef( |
| String enclose, |
| XSTypeDefinition type) { |
| if (type == null){ |
| sendElementEvent(enclose); |
| return; |
| } |
| |
| // we'll check for anonymous types here, since they only occur in places where |
| // a reference would be appropriate |
| if (type.getAnonymous() && !fDefined.contains(this.getID(type))) { |
| sendIndentedElement(enclose); |
| processPSVITypeDefinition(type); |
| sendUnIndentedElement(enclose); |
| } |
| else { |
| processPSVITypeDefinitionRef(enclose, type); |
| } |
| } |
| |
| private void processPSVIElementDeclarationRef(XSElementDeclaration elem) { |
| if (elem == null) |
| return; |
| processPSVIElementRef("psv:elementDeclaration", elem); |
| } |
| |
| private void processPSVIElementDeclarationOrRef(XSElementDeclaration elem) { |
| if (elem == null) |
| return; |
| // for global attributes, and attributes that have already been printed, |
| // we always want to print references |
| if (elem.getScope() == XSConstants.SCOPE_GLOBAL |
| || fDefined.contains(this.getID(elem))) { |
| processPSVIElementDeclarationRef(elem); |
| } |
| else { |
| processPSVIElementDeclaration(elem); |
| } |
| } |
| |
| private void processPSVIScope( |
| String enclose, |
| XSComplexTypeDefinition enclosingCTD, |
| short scope) { |
| if (scope == XSConstants.SCOPE_ABSENT || scope == XSConstants.SCOPE_GLOBAL) { |
| sendElementEvent(enclose, this.translateScope(scope)); |
| } else { // XSConstants.SCOPE_LOCAL |
| processPSVITypeDefinitionRef(enclose, enclosingCTD); |
| } |
| } |
| |
| private void processPSVIValueConstraint( |
| short constraintType, |
| String constraintValue) { |
| if (constraintType == XSConstants.VC_NONE) { |
| sendElementEvent("psv:valueConstraint"); |
| } else { |
| sendIndentedElement("psv:valueConstraint"); |
| sendElementEvent("psv:variety", translateValueConstraintType(constraintType)); |
| sendElementEvent("psv:value", constraintValue); |
| sendUnIndentedElement("psv:valueConstraint"); |
| } |
| } |
| |
| private void processPSVISubstitutionGroupAffiliation(XSElementDeclaration elem) { |
| if (elem.getSubstitutionGroupAffiliation() == null) { |
| sendElementEvent("psv:substitutionGroupAffiliation"); |
| } else { |
| sendIndentedElement("psv:substitutionGroupAffiliation"); |
| processPSVIElementRef("psv:elementDeclaration", elem.getSubstitutionGroupAffiliation()); |
| sendUnIndentedElement("psv:substitutionGroupAffiliation"); |
| } |
| } |
| |
| /** |
| * This method writes an empty element at the current indent level. |
| * |
| * @param tagname The name of the Element. |
| * |
| * @throws IOEXception |
| */ |
| private void sendEmptyElementEvent(String tagname) { |
| this.sendEmptyElementEvent(tagname, null); |
| } //sendEmptyElementEvent |
| |
| private void sendEmptyElementEvent(String tagname, Vector attributes) { |
| this.sendIndent(); |
| fDocumentHandler.emptyElement( |
| createQName(tagname), |
| createAttributes(attributes), |
| null); |
| this.sendNewLine(); |
| } //sendEmptyElementEvent |
| |
| /** |
| * This method writes an empty element at the current indent level. |
| * |
| * @param tagname The name of the Element. |
| * |
| * @throws IOEXception |
| */ |
| private void sendStartElementEvent(String tagname, Vector attributes) { |
| fDocumentHandler.startElement( |
| createQName(tagname), |
| createAttributes(attributes), |
| null); |
| } //sendStartElementEvent |
| |
| /** |
| * This method writes a closing tag at the current indent level. |
| * |
| * @param tagname The name of the Element. |
| * |
| * @throws IOEXception |
| */ |
| private void sendEndElementEvent(String tagname) { |
| fDocumentHandler.endElement(this.createQName(tagname), null); |
| } //sendEndElementEvent |
| |
| /** |
| * This method write the element at the current indent level and increase |
| * the one level of indentation. |
| * |
| * @param The name of the Element. |
| * |
| * @throws IOException |
| */ |
| private void sendIndentedElement(String tagName) { |
| this.sendIndentedElement(tagName, null); |
| } //sendIndentedElement |
| |
| private void sendIndentedElement(String tagName, Vector attributes) { |
| this.sendIndent(); |
| this.sendStartElementEvent(tagName, attributes); |
| this.sendNewLine(); |
| fIndent++; |
| } //sendIndentedElement |
| |
| /** |
| * This method write the element at the current indent level and decrease |
| * one level of indentation. |
| * |
| * @param the name of the Element. |
| * |
| */ |
| private void sendUnIndentedElement(String tagName) { |
| fIndent--; |
| this.sendIndent(); |
| this.sendEndElementEvent(tagName); |
| this.sendNewLine(); |
| } //sendUnIndentedElement |
| |
| /** |
| * Write the Element Information Item for each element appearing in the XML |
| * document. One of the element information items is the value of the |
| * [document element] property of the document information item, corresponding |
| * to the root of the element tree, and all other element information items |
| * are accessible by recursively following its [children] property. |
| * |
| * @elementName Name of the elment. |
| * @elemmentValue Value of the element |
| */ |
| private void sendElementEvent(String elementName) { |
| this.sendElementEvent(elementName, null, (XMLString) null); |
| } //sendElementEvents |
| |
| private void sendElementEvent(String elementName, String elementValue) { |
| this.sendElementEvent(elementName, null, elementValue); |
| } //sendElementEvents |
| |
| private void sendElementEvent(String elementName, XMLString elementValue) { |
| this.sendElementEvent(elementName, null, elementValue); |
| } //sendElementEvents |
| |
| private void sendElementEvent( |
| String elementName, |
| Vector attributes, |
| String elementValue) { |
| XMLString text = |
| elementValue == null |
| ? null |
| : new XMLString( |
| elementValue.toCharArray(), |
| 0, |
| elementValue.length()); |
| this.sendElementEvent(elementName, attributes, text); |
| } |
| |
| private void sendElementEvent( |
| String elementName, |
| Vector attributes, |
| XMLString elementValue) { |
| if (elementValue == null || elementValue.equals("")) { |
| if (attributes == null) { |
| attributes = new Vector(); |
| } |
| attributes.add("xsi:nil"); |
| attributes.add("true"); |
| attributes.add(XMLSymbols.fCDATASymbol); |
| this.sendEmptyElementEvent(elementName, attributes); |
| } |
| else { |
| this.sendIndent(); |
| this.sendStartElementEvent(elementName, attributes); |
| fDocumentHandler.characters(elementValue, null); |
| this.sendEndElementEvent(elementName); |
| this.sendNewLine(); |
| } |
| } //sendElementEvents |
| |
| private void sendIndentedElementWithID(String elementName, XSObject obj) { |
| String id = this.getID(obj); |
| // since this method is called everytime we define something with an ID, |
| // may as well mark the ID as defined here |
| fDefined.add(id); |
| Vector attributes = new Vector(); |
| attributes.add("id"); |
| attributes.add(id); |
| attributes.add(XMLSymbols.fIDSymbol); |
| sendIndentedElement(elementName, attributes); |
| } |
| |
| private void sendIndent() { |
| if (fIndent > fIndentChars.length) { |
| fIndentChars = new char[fIndentChars.length * 2]; |
| for (int i = 0; i < fIndentChars.length; i++) { |
| fIndentChars[i] = '\t'; |
| } |
| } |
| XMLString text = new XMLString(fIndentChars, 0, fIndent); |
| fDocumentHandler.characters(text, null); |
| } |
| |
| private void sendNewLine() { |
| fDocumentHandler.characters(newLine, null); |
| } |
| |
| private QName createQName(String rawname) { |
| int index = rawname.indexOf(':'); |
| String prefix, localpart; |
| if (index == -1) { |
| prefix = ""; |
| localpart = rawname; |
| } |
| else { |
| prefix = rawname.substring(0, index); |
| localpart = rawname.substring(index + 1); |
| } |
| String uri = fPSVINamespaceContext.getURI(prefix); |
| return new QName(prefix, localpart, rawname, uri); |
| } |
| |
| private XMLAttributes createAttributes(Vector atts) { |
| XMLAttributes attributes = new XMLAttributesImpl(); |
| if (atts != null) { |
| for (int i = 0; i < atts.size(); i += 3) { |
| String rawname = (String)atts.elementAt(i); |
| String value = (String)atts.elementAt(i + 1); |
| String type = (String)atts.elementAt(i + 2); |
| attributes.addAttribute(createQName(rawname), type, value); |
| } |
| } |
| return attributes; |
| } |
| |
| private String createID(XSObject obj) { |
| String namespace = obj.getNamespace(); |
| String prefix = fNamespaceContext.getPrefix(obj.getNamespace()); |
| String name = obj.getName(); |
| String type = this.translateType(obj.getType()); |
| |
| // must be anonymous |
| if (name == null) { |
| name = "anon_" + fAnonNum++; |
| } |
| // no namespace |
| else if (namespace == null || namespace == XMLSymbols.EMPTY_STRING) { |
| name = name + "." + fAnonNum++; |
| } |
| |
| if (namespace == Constants.NS_XMLSCHEMA) { |
| return name; |
| } |
| else { |
| return (prefix == null ? "" : prefix + ".") + type + "." + name; |
| } |
| } |
| |
| private String getID(XSObject obj) { |
| if (obj == null) |
| return null; |
| String id = (String)fIDMap.get(obj); |
| if (id == null) { |
| id = createID(obj); |
| fIDMap.put(obj, id); |
| } |
| return id; |
| } |
| |
| private String translateType(short type) { |
| switch (type) { |
| case XSConstants.TYPE_DEFINITION : |
| return "type"; |
| case XSConstants.ANNOTATION : |
| return "annot"; |
| case XSConstants.ATTRIBUTE_DECLARATION : |
| return "attr"; |
| case XSConstants.ATTRIBUTE_GROUP : |
| return "ag"; |
| case XSConstants.ATTRIBUTE_USE : |
| return "au"; |
| case XSConstants.ELEMENT_DECLARATION : |
| return "elt"; |
| case XSConstants.MODEL_GROUP_DEFINITION : |
| return "mg"; |
| case XSConstants.NOTATION_DECLARATION : |
| return "not"; |
| case XSConstants.IDENTITY_CONSTRAINT : |
| return "idc"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateFacetKind(short kind) { |
| switch (kind) { |
| case XSSimpleTypeDefinition.FACET_WHITESPACE : |
| return SchemaSymbols.ELT_WHITESPACE; |
| case XSSimpleTypeDefinition.FACET_LENGTH : |
| return SchemaSymbols.ELT_LENGTH; |
| case XSSimpleTypeDefinition.FACET_MINLENGTH : |
| return SchemaSymbols.ELT_MINLENGTH; |
| case XSSimpleTypeDefinition.FACET_MAXLENGTH : |
| return SchemaSymbols.ELT_MAXLENGTH; |
| case XSSimpleTypeDefinition.FACET_TOTALDIGITS : |
| return SchemaSymbols.ELT_TOTALDIGITS; |
| case XSSimpleTypeDefinition.FACET_FRACTIONDIGITS : |
| return SchemaSymbols.ELT_FRACTIONDIGITS; |
| case XSSimpleTypeDefinition.FACET_PATTERN : |
| return SchemaSymbols.ELT_PATTERN; |
| case XSSimpleTypeDefinition.FACET_ENUMERATION : |
| return SchemaSymbols.ELT_ENUMERATION; |
| case XSSimpleTypeDefinition.FACET_MAXINCLUSIVE : |
| return SchemaSymbols.ELT_MAXINCLUSIVE; |
| case XSSimpleTypeDefinition.FACET_MAXEXCLUSIVE : |
| return SchemaSymbols.ELT_MAXEXCLUSIVE; |
| case XSSimpleTypeDefinition.FACET_MINEXCLUSIVE : |
| return SchemaSymbols.ELT_MINEXCLUSIVE; |
| case XSSimpleTypeDefinition.FACET_MININCLUSIVE : |
| return SchemaSymbols.ELT_MININCLUSIVE; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateVariety(short var) { |
| switch (var) { |
| case XSSimpleTypeDefinition.VARIETY_LIST : |
| return "list"; |
| case XSSimpleTypeDefinition.VARIETY_UNION : |
| return "union"; |
| case XSSimpleTypeDefinition.VARIETY_ATOMIC : |
| return "atomic"; |
| case XSSimpleTypeDefinition.VARIETY_ABSENT : |
| return null; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateConstraintType(short type) { |
| switch (type) { |
| case XSWildcard.NSCONSTRAINT_ANY : |
| return "any"; |
| // the spec says that when it's a list, the "type" shouldn't be there |
| case XSWildcard.NSCONSTRAINT_LIST : |
| return null; |
| case XSWildcard.NSCONSTRAINT_NOT : |
| return "not"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateValueConstraintType(short type) { |
| switch (type) { |
| case XSConstants.VC_DEFAULT : |
| return "default"; |
| case XSConstants.VC_FIXED : |
| return "fixed"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateBlockOrFinal(short val) { |
| String ret = ""; |
| if ((val & XSConstants.DERIVATION_EXTENSION) != 0) { |
| ret += SchemaSymbols.ATTVAL_EXTENSION; |
| } |
| if ((val & XSConstants.DERIVATION_LIST) != 0) { |
| if (ret.length() != 0) |
| ret += " "; |
| ret += SchemaSymbols.ATTVAL_LIST; |
| } |
| if ((val & XSConstants.DERIVATION_RESTRICTION) != 0) { |
| if (ret.length() != 0) |
| ret += " "; |
| ret += SchemaSymbols.ATTVAL_RESTRICTION; |
| } |
| if ((val & XSConstants.DERIVATION_UNION) != 0) { |
| if (ret.length() != 0) |
| ret += " "; |
| ret += SchemaSymbols.ATTVAL_UNION; |
| } |
| if ((val & XSConstants.DERIVATION_SUBSTITUTION) != 0) { |
| if (ret.length() != 0) |
| ret += " "; |
| ret += SchemaSymbols.ATTVAL_SUBSTITUTION; |
| } |
| return ret; |
| } |
| |
| private String translateScope(short scope) { |
| switch (scope) { |
| case XSConstants.SCOPE_ABSENT : |
| return null; |
| case XSConstants.SCOPE_GLOBAL : |
| return "global"; |
| case XSConstants.SCOPE_LOCAL : |
| return "local"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateCompositor(short comp) { |
| switch (comp) { |
| case XSModelGroup.COMPOSITOR_SEQUENCE : |
| return SchemaSymbols.ELT_SEQUENCE; |
| case XSModelGroup.COMPOSITOR_CHOICE : |
| return SchemaSymbols.ELT_CHOICE; |
| case XSModelGroup.COMPOSITOR_ALL : |
| return SchemaSymbols.ELT_ALL; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateContentType(short contentType) { |
| switch (contentType) { |
| case XSComplexTypeDefinition.CONTENTTYPE_ELEMENT : |
| return "elementOnly"; |
| case XSComplexTypeDefinition.CONTENTTYPE_EMPTY : |
| return "empty"; |
| case XSComplexTypeDefinition.CONTENTTYPE_MIXED : |
| return "mixed"; |
| case XSComplexTypeDefinition.CONTENTTYPE_SIMPLE : |
| return "simple"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateProcessContents(short process) { |
| switch (process) { |
| case XSWildcard.PC_LAX : |
| return SchemaSymbols.ATTVAL_LAX; |
| case XSWildcard.PC_SKIP : |
| return SchemaSymbols.ATTVAL_SKIP; |
| case XSWildcard.PC_STRICT : |
| return SchemaSymbols.ATTVAL_STRICT; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateDerivation(short deriv) { |
| switch (deriv) { |
| case XSConstants.DERIVATION_EXTENSION : |
| return SchemaSymbols.ELT_EXTENSION; |
| case XSConstants.DERIVATION_LIST : |
| return SchemaSymbols.ELT_LIST; |
| case XSConstants.DERIVATION_RESTRICTION : |
| return SchemaSymbols.ELT_RESTRICTION; |
| case XSConstants.DERIVATION_SUBSTITUTION : |
| return SchemaSymbols.ATTVAL_SUBSTITUTION; |
| case XSConstants.DERIVATION_UNION : |
| return SchemaSymbols.ELT_UNION; |
| case XSConstants.DERIVATION_NONE : |
| return null; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateCategory(short cat) { |
| switch (cat) { |
| case XSIDCDefinition.IC_KEY : |
| return SchemaSymbols.ELT_KEY; |
| case XSIDCDefinition.IC_KEYREF : |
| return SchemaSymbols.ELT_KEYREF; |
| case XSIDCDefinition.IC_UNIQUE : |
| return SchemaSymbols.ELT_UNIQUE; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateOrdered(short ordered) { |
| switch (ordered) { |
| case XSSimpleTypeDefinition.ORDERED_FALSE : |
| return "false"; |
| case XSSimpleTypeDefinition.ORDERED_PARTIAL : |
| return "partial"; |
| case XSSimpleTypeDefinition.ORDERED_TOTAL : |
| return "total"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateValidationAttempted(short val) { |
| switch (val) { |
| case ItemPSVI.VALIDATION_NONE : |
| return "none"; |
| case ItemPSVI.VALIDATION_PARTIAL : |
| return "partial"; |
| case ItemPSVI.VALIDATION_FULL : |
| return "full"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| private String translateValidity(short val) { |
| switch (val) { |
| case ItemPSVI.VALIDITY_NOTKNOWN : |
| return "notKnown"; |
| case ItemPSVI.VALIDITY_VALID : |
| return "valid"; |
| case ItemPSVI.VALIDITY_INVALID : |
| return "invalid"; |
| default : |
| return "unknown"; |
| } |
| } |
| |
| /** |
| * Check whether the calling event is first in children list , |
| * if yes print the <children>. |
| */ |
| private void checkForChildren() { |
| if (!_elementState.empty()) { |
| ElementState fElementState = (ElementState)_elementState.peek(); |
| if (fElementState.isEmpty == true) { |
| sendIndentedElement("children"); |
| fElementState.isEmpty = false; |
| } |
| } |
| else { |
| sendIndentedElement("children"); |
| _elementState.push(new ElementState(false)); |
| } |
| } //checkForChildren |
| |
| class ElementState { |
| public boolean isEmpty; |
| XMLAttributes fAttributes; |
| |
| public ElementState(XMLAttributes attributes) { |
| fAttributes = attributes; |
| isEmpty = true; |
| } |
| public ElementState(boolean value) { |
| isEmpty = value; |
| } |
| public XMLAttributes getAttributes() { |
| return fAttributes; |
| } |
| public void isEmpty(boolean value) { |
| isEmpty = value; |
| } |
| } //class ElementState |
| } // class PSVIWriter |