You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2005/09/08 03:25:24 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/impl/xs SchemaNamespaceSupport.java
mrglavas 2005/09/07 18:25:24
Modified: java/src/org/apache/xerces/impl/xs
SchemaNamespaceSupport.java
Log:
Fixing a bug. When the schema root provided is not the document element
there may be namespace bindings in effect from ancestors of the schema
root. If we cannot find a URI mapping for a prefix in the context of the
schema root we must look at the ancestors for a binding.
Revision Changes Path
1.7 +147 -2 xml-xerces/java/src/org/apache/xerces/impl/xs/SchemaNamespaceSupport.java
Index: SchemaNamespaceSupport.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/SchemaNamespaceSupport.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- SchemaNamespaceSupport.java 6 Oct 2004 15:14:55 -0000 1.6
+++ SchemaNamespaceSupport.java 8 Sep 2005 01:25:24 -0000 1.7
@@ -16,7 +16,17 @@
package org.apache.xerces.impl.xs;
+import org.apache.xerces.impl.xs.opti.ElementImpl;
import org.apache.xerces.util.NamespaceSupport;
+import org.apache.xerces.util.SymbolTable;
+import org.apache.xerces.util.XMLSymbols;
+import org.apache.xerces.xni.NamespaceContext;
+import org.apache.xerces.xni.QName;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
/**
* This class customizes the behaviour of the util.NamespaceSupport
@@ -31,13 +41,22 @@
*/
public class SchemaNamespaceSupport
extends NamespaceSupport {
+
+ private SchemaRootContext fSchemaRootContext = null;
- public SchemaNamespaceSupport () {
+ public SchemaNamespaceSupport (Element schemaRoot, SymbolTable symbolTable) {
super();
+ if (schemaRoot != null && !(schemaRoot instanceof ElementImpl)) {
+ Document ownerDocument = schemaRoot.getOwnerDocument();
+ if (ownerDocument != null && schemaRoot != ownerDocument.getDocumentElement()) {
+ fSchemaRootContext = new SchemaRootContext(schemaRoot, symbolTable);
+ }
+ }
} // constructor
// more effecient than NamespaceSupport(NamespaceContext)
public SchemaNamespaceSupport(SchemaNamespaceSupport nSupport) {
+ fSchemaRootContext = nSupport.fSchemaRootContext;
fNamespaceSize = nSupport.fNamespaceSize;
if (fNamespace.length < fNamespaceSize)
fNamespace = new String[fNamespaceSize];
@@ -106,4 +125,130 @@
fNamespaceSize = fContext[3];
}
} // makeGlobal
+
+ public String getURI(String prefix) {
+ String uri = super.getURI(prefix);
+ if (uri == null && fSchemaRootContext != null) {
+ if (!fSchemaRootContext.fDOMContextBuilt) {
+ fSchemaRootContext.fillNamespaceContext();
+ fSchemaRootContext.fDOMContextBuilt = true;
+ }
+ if (fSchemaRootContext.fNamespaceSize > 0 &&
+ !containsPrefix(prefix)) {
+ uri = fSchemaRootContext.getURI(prefix);
+ }
+ }
+ return uri;
+ }
+
+ /**
+ * This class keeps track of the namespace bindings
+ * declared on ancestors of the schema root.
+ */
+ static final class SchemaRootContext {
+
+ //
+ // Data
+ //
+
+ /**
+ * Namespace binding information. This array is composed of a
+ * series of tuples containing the namespace binding information:
+ * <prefix, uri>.
+ */
+ String[] fNamespace = new String[16 * 2];
+
+ /** The size of the namespace information array. */
+ int fNamespaceSize = 0;
+
+ /**
+ * Flag indicating whether the namespace context
+ * has been from the root node's ancestors.
+ */
+ boolean fDOMContextBuilt = false;
+
+ /** Schema root. **/
+ private final Element fSchemaRoot;
+
+ /** Symbol table. **/
+ private final SymbolTable fSymbolTable;
+
+ /** Temporary storage for attribute QNames. **/
+ private final QName fAttributeQName = new QName();
+
+ SchemaRootContext(Element schemaRoot, SymbolTable symbolTable) {
+ fSchemaRoot = schemaRoot;
+ fSymbolTable = symbolTable;
+ }
+
+ void fillNamespaceContext() {
+ if (fSchemaRoot != null) {
+ Node currentNode = fSchemaRoot.getParentNode();
+ while (currentNode != null) {
+ if (Node.ELEMENT_NODE == currentNode.getNodeType()) {
+ NamedNodeMap attributes = currentNode.getAttributes();
+ final int attrCount = attributes.getLength();
+ for (int i = 0; i < attrCount; ++i) {
+ Attr attr = (Attr) attributes.item(i);
+ String value = attr.getValue();
+ if (value == null) {
+ value = XMLSymbols.EMPTY_STRING;
+ }
+ fillQName(fAttributeQName, attr);
+ // REVISIT: Should we be looking at non-namespace attributes
+ // for additional mappings? Should we detect illegal namespace
+ // declarations and exclude them from the context? -- mrglavas
+ if (fAttributeQName.uri == NamespaceContext.XMLNS_URI) {
+ // process namespace attribute
+ if (fAttributeQName.prefix == XMLSymbols.PREFIX_XMLNS) {
+ declarePrefix(fAttributeQName.localpart, value.length() != 0 ? fSymbolTable.addSymbol(value) : null);
+ }
+ else {
+ declarePrefix(XMLSymbols.EMPTY_STRING, value.length() != 0 ? fSymbolTable.addSymbol(value) : null);
+ }
+ }
+ }
+
+ }
+ currentNode = currentNode.getParentNode();
+ }
+ }
+ }
+
+ String getURI(String prefix) {
+ // find prefix in the DOM context
+ for (int i = 0; i < fNamespaceSize; i += 2) {
+ if (fNamespace[i] == prefix) {
+ return fNamespace[i + 1];
+ }
+ }
+ // prefix not found
+ return null;
+ }
+
+ private void declarePrefix(String prefix, String uri) {
+ // resize array, if needed
+ if (fNamespaceSize == fNamespace.length) {
+ String[] namespacearray = new String[fNamespaceSize * 2];
+ System.arraycopy(fNamespace, 0, namespacearray, 0, fNamespaceSize);
+ fNamespace = namespacearray;
+ }
+
+ // bind prefix to uri in current context
+ fNamespace[fNamespaceSize++] = prefix;
+ fNamespace[fNamespaceSize++] = uri;
+ }
+
+ private void fillQName(QName toFill, Node node) {
+ final String prefix = node.getPrefix();
+ final String localName = node.getLocalName();
+ final String rawName = node.getNodeName();
+ final String namespace = node.getNamespaceURI();
+ toFill.prefix = (prefix != null) ? fSymbolTable.addSymbol(prefix) : XMLSymbols.EMPTY_STRING;
+ toFill.localpart = (localName != null) ? fSymbolTable.addSymbol(localName) : XMLSymbols.EMPTY_STRING;
+ toFill.rawname = (rawName != null) ? fSymbolTable.addSymbol(rawName) : XMLSymbols.EMPTY_STRING;
+ toFill.uri = (namespace != null && namespace.length() > 0) ? fSymbolTable.addSymbol(namespace) : null;
+ }
+ }
+
} // class NamespaceSupport
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org