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