1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 1999-2005 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xerces.internal.impl.xs.traversers; 22 23 import java.util.Stack; 24 import java.util.Vector; 25 26 import com.sun.org.apache.xerces.internal.impl.validation.ValidationState; 27 import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport; 28 import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; 29 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaException; 30 import com.sun.org.apache.xerces.internal.impl.xs.util.XInt; 31 import com.sun.org.apache.xerces.internal.util.SymbolTable; 32 import org.w3c.dom.Element; 33 import org.w3c.dom.Node; 34 import org.w3c.dom.Attr; 35 import org.w3c.dom.NamedNodeMap; 36 37 /** 38 * Objects of this class hold all information pecular to a 39 * particular XML Schema document. This is needed because 40 * namespace bindings and other settings on the <schema/> element 41 * affect the contents of that schema document alone. 42 * 43 * @xerces.internal 44 * 45 * @author Neil Graham, IBM 46 */ 47 class XSDocumentInfo { 48 49 // Data 50 protected SchemaNamespaceSupport fNamespaceSupport; 51 protected SchemaNamespaceSupport fNamespaceSupportRoot; 52 protected Stack SchemaNamespaceSupportStack = new Stack(); 53 54 // schema's attributeFormDefault 55 protected boolean fAreLocalAttributesQualified; 56 57 // elementFormDefault 58 protected boolean fAreLocalElementsQualified; 59 60 // [block | final]Default 61 protected short fBlockDefault; 62 protected short fFinalDefault; 63 64 // targetNamespace 65 String fTargetNamespace; 66 67 // represents whether this is a chameleon schema (i.e., whether its TNS is natural or comes from without) 68 protected boolean fIsChameleonSchema; 69 70 // the root of the schema Document tree itself 71 protected Element fSchemaElement; 72 73 // all namespaces that this document can refer to 74 Vector fImportedNS = new Vector(); 75 76 protected ValidationState fValidationContext = new ValidationState(); 77 78 SymbolTable fSymbolTable = null; 79 80 // attribute checker to which we'll return the attributes 81 // once we've been told that we're done with them 82 protected XSAttributeChecker fAttrChecker; 83 84 // array of objects on the schema's root element. This is null 85 // once returnSchemaAttrs has been called. 86 protected Object [] fSchemaAttrs; 87 88 // list of annotations contained in the schema document. This is null 89 // once removeAnnotations has been called. 90 protected XSAnnotationInfo fAnnotations = null; 91 92 // note that the caller must ensure to call returnSchemaAttrs() 93 // to avoid memory leaks! 94 XSDocumentInfo (Element schemaRoot, XSAttributeChecker attrChecker, SymbolTable symbolTable) 95 throws XMLSchemaException { 96 fSchemaElement = schemaRoot; 97 initNamespaceSupport(schemaRoot); 98 fIsChameleonSchema = false; 99 100 fSymbolTable = symbolTable; 101 fAttrChecker = attrChecker; 102 103 if (schemaRoot != null) { 104 Element root = schemaRoot; 105 fSchemaAttrs = attrChecker.checkAttributes(root, true, this); 106 // schemaAttrs == null means it's not an <xsd:schema> element 107 // throw an exception, but we don't know the document systemId, 108 // so we leave that to the caller. 109 if (fSchemaAttrs == null) { 110 throw new XMLSchemaException(null, null); 111 } 112 fAreLocalAttributesQualified = 113 ((XInt)fSchemaAttrs[XSAttributeChecker.ATTIDX_AFORMDEFAULT]).intValue() == SchemaSymbols.FORM_QUALIFIED; 114 fAreLocalElementsQualified = 115 ((XInt)fSchemaAttrs[XSAttributeChecker.ATTIDX_EFORMDEFAULT]).intValue() == SchemaSymbols.FORM_QUALIFIED; 116 fBlockDefault = 117 ((XInt)fSchemaAttrs[XSAttributeChecker.ATTIDX_BLOCKDEFAULT]).shortValue(); 118 fFinalDefault = 119 ((XInt)fSchemaAttrs[XSAttributeChecker.ATTIDX_FINALDEFAULT]).shortValue(); 120 fTargetNamespace = 121 (String)fSchemaAttrs[XSAttributeChecker.ATTIDX_TARGETNAMESPACE]; 122 if (fTargetNamespace != null) 123 fTargetNamespace = symbolTable.addSymbol(fTargetNamespace); 124 125 fNamespaceSupportRoot = new SchemaNamespaceSupport(fNamespaceSupport); 126 127 //set namespace support 128 fValidationContext.setNamespaceSupport(fNamespaceSupport); 129 fValidationContext.setSymbolTable(symbolTable); 130 // pass null as the schema document, so that the namespace 131 // context is not popped. 132 133 // don't return the attribute array yet! 134 //attrChecker.returnAttrArray(schemaAttrs, null); 135 } 136 } 137 138 /** 139 * Initialize namespace support by collecting all of the namespace 140 * declarations in the root's ancestors. This is necessary to 141 * support schemas fragments, i.e. schemas embedded in other 142 * documents. See, 143 * 144 * https://jaxp.dev.java.net/issues/show_bug.cgi?id=43 145 * 146 * Requires the DOM to be created with namespace support enabled. 147 */ 148 private void initNamespaceSupport(Element schemaRoot) { 149 fNamespaceSupport = new SchemaNamespaceSupport(); 150 fNamespaceSupport.reset(); 151 152 Node parent = schemaRoot.getParentNode(); 153 while (parent != null && parent.getNodeType() == Node.ELEMENT_NODE 154 && !parent.getNodeName().equals("DOCUMENT_NODE")) 155 { 156 Element eparent = (Element) parent; 157 NamedNodeMap map = eparent.getAttributes(); 158 int length = (map != null) ? map.getLength() : 0; 159 for (int i = 0; i < length; i++) { 160 Attr attr = (Attr) map.item(i); 161 String uri = attr.getNamespaceURI(); 162 163 // Check if attribute is an ns decl -- requires ns support 164 if (uri != null && uri.equals("http://www.w3.org/2000/xmlns/")) { 165 String prefix = attr.getLocalName().intern(); 166 if (prefix == "xmlns") prefix = ""; 167 // Declare prefix if not set -- moving upwards 168 if (fNamespaceSupport.getURI(prefix) == null) { 169 fNamespaceSupport.declarePrefix(prefix, 170 attr.getValue().intern()); 171 } 172 } 173 } 174 parent = parent.getParentNode(); 175 } 176 } 177 178 // backup the current ns support, and use the one passed-in. 179 // if no ns support is passed-in, use the one for <schema> element 180 void backupNSSupport(SchemaNamespaceSupport nsSupport) { 181 SchemaNamespaceSupportStack.push(fNamespaceSupport); 182 if (nsSupport == null) 183 nsSupport = fNamespaceSupportRoot; 184 fNamespaceSupport = new SchemaNamespaceSupport(nsSupport); 185 186 fValidationContext.setNamespaceSupport(fNamespaceSupport); 187 } 188 189 void restoreNSSupport() { 190 fNamespaceSupport = (SchemaNamespaceSupport)SchemaNamespaceSupportStack.pop(); 191 fValidationContext.setNamespaceSupport(fNamespaceSupport); 192 } 193 194 // some Object methods 195 public String toString() { 196 return fTargetNamespace == null?"no targetNamspace":"targetNamespace is " + fTargetNamespace; 197 } 198 199 public void addAllowedNS(String namespace) { 200 fImportedNS.addElement(namespace == null ? "" : namespace); 201 } 202 203 public boolean isAllowedNS(String namespace) { 204 return fImportedNS.contains(namespace == null ? "" : namespace); 205 } 206 207 // store whether we have reported an error about that this document 208 // can't access components from the given namespace 209 private Vector fReportedTNS = null; 210 // check whether we need to report an error against the given uri. 211 // if we have reported an error, then we don't need to report again; 212 // otherwise we reported the error, and remember this fact. 213 final boolean needReportTNSError(String uri) { 214 if (fReportedTNS == null) 215 fReportedTNS = new Vector(); 216 else if (fReportedTNS.contains(uri)) 217 return false; 218 fReportedTNS.addElement(uri); 219 return true; 220 } 221 222 // return the attributes on the schema element itself: 223 Object [] getSchemaAttrs () { 224 return fSchemaAttrs; 225 } 226 227 // deallocate the storage set aside for the schema element's 228 // attributes 229 void returnSchemaAttrs () { 230 fAttrChecker.returnAttrArray (fSchemaAttrs, null); 231 fSchemaAttrs = null; 232 } 233 234 // adds an annotation to the list of annotations 235 void addAnnotation(XSAnnotationInfo info) { 236 info.next = fAnnotations; 237 fAnnotations = info; 238 } 239 240 // returns the list of annotations conatined in the 241 // schema document or null if the document contained no annotations. 242 XSAnnotationInfo getAnnotations() { 243 return fAnnotations; 244 } 245 246 // removes reference to annotation list 247 void removeAnnotations() { 248 fAnnotations = null; 249 } 250 251 } // XSDocumentInfo