286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 2003-2005 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/Apackage com.sun.org.apache.xerces.internal.xinclude;
286N/A
286N/Aimport java.util.Enumeration;
286N/A
286N/Aimport com.sun.org.apache.xerces.internal.util.NamespaceSupport;
286N/Aimport com.sun.org.apache.xerces.internal.util.XMLSymbols;
286N/Aimport com.sun.org.apache.xerces.internal.xni.NamespaceContext;
286N/A
286N/A/**
286N/A * This implementation of NamespaceContext has the ability to maintain multiple
286N/A * scopes of namespace/prefix bindings. This is useful in situations when it is
286N/A * not always appropriate for elements to inherit the namespace bindings of their
286N/A * ancestors (such as included elements in XInclude).
286N/A *
286N/A * When searching for a URI to match a prefix, or a prefix to match a URI, it is
286N/A * searched for in the current context, then the ancestors of the current context,
286N/A * up to the beginning of the current scope. Other scopes are not searched.
286N/A *
286N/A * @author Peter McCracken, IBM
286N/A *
286N/A */
286N/Apublic class MultipleScopeNamespaceSupport extends NamespaceSupport {
286N/A
286N/A protected int[] fScope = new int[8];
286N/A protected int fCurrentScope;
286N/A
286N/A /**
286N/A *
286N/A */
286N/A public MultipleScopeNamespaceSupport() {
286N/A super();
286N/A fCurrentScope = 0;
286N/A fScope[0] = 0;
286N/A }
286N/A
286N/A /**
286N/A * @param context
286N/A */
286N/A public MultipleScopeNamespaceSupport(NamespaceContext context) {
286N/A super(context);
286N/A fCurrentScope = 0;
286N/A fScope[0] = 0;
286N/A }
286N/A
286N/A /* (non-Javadoc)
286N/A * @see com.sun.org.apache.xerces.internal.xni.NamespaceContext#getAllPrefixes()
286N/A */
286N/A public Enumeration getAllPrefixes() {
286N/A int count = 0;
286N/A if (fPrefixes.length < (fNamespace.length / 2)) {
286N/A // resize prefix array
286N/A String[] prefixes = new String[fNamespaceSize];
286N/A fPrefixes = prefixes;
286N/A }
286N/A String prefix = null;
286N/A boolean unique = true;
286N/A for (int i = fContext[fScope[fCurrentScope]];
286N/A i <= (fNamespaceSize - 2);
286N/A i += 2) {
286N/A prefix = fNamespace[i];
286N/A for (int k = 0; k < count; k++) {
286N/A if (fPrefixes[k] == prefix) {
286N/A unique = false;
286N/A break;
286N/A }
286N/A }
286N/A if (unique) {
286N/A fPrefixes[count++] = prefix;
286N/A }
286N/A unique = true;
286N/A }
286N/A return new Prefixes(fPrefixes, count);
286N/A }
286N/A
286N/A public int getScopeForContext(int context) {
286N/A int scope = fCurrentScope;
286N/A while (context < fScope[scope]) {
286N/A scope--;
286N/A }
286N/A return scope;
286N/A }
286N/A
286N/A /* (non-Javadoc)
286N/A * @see com.sun.org.apache.xerces.internal.xni.NamespaceContext#getPrefix(java.lang.String)
286N/A */
286N/A public String getPrefix(String uri) {
286N/A return getPrefix(uri, fNamespaceSize, fContext[fScope[fCurrentScope]]);
286N/A }
286N/A
286N/A /* (non-Javadoc)
286N/A * @see com.sun.org.apache.xerces.internal.xni.NamespaceContext#getURI(java.lang.String)
286N/A */
286N/A public String getURI(String prefix) {
286N/A return getURI(prefix, fNamespaceSize, fContext[fScope[fCurrentScope]]);
286N/A }
286N/A
286N/A public String getPrefix(String uri, int context) {
286N/A return getPrefix(uri, fContext[context+1], fContext[fScope[getScopeForContext(context)]]);
286N/A }
286N/A
286N/A public String getURI(String prefix, int context) {
286N/A return getURI(prefix, fContext[context+1], fContext[fScope[getScopeForContext(context)]]);
286N/A }
286N/A
286N/A public String getPrefix(String uri, int start, int end) {
286N/A // this saves us from having a copy of each of these in fNamespace for each scope
286N/A if (uri == NamespaceContext.XML_URI) {
286N/A return XMLSymbols.PREFIX_XML;
286N/A }
286N/A if (uri == NamespaceContext.XMLNS_URI) {
286N/A return XMLSymbols.PREFIX_XMLNS;
286N/A }
286N/A
286N/A // find uri in current context
286N/A for (int i = start; i > end; i -= 2) {
286N/A if (fNamespace[i - 1] == uri) {
286N/A if (getURI(fNamespace[i - 2]) == uri)
286N/A return fNamespace[i - 2];
286N/A }
286N/A }
286N/A
286N/A // uri not found
286N/A return null;
286N/A }
286N/A
286N/A public String getURI(String prefix, int start, int end) {
286N/A // this saves us from having a copy of each of these in fNamespace for each scope
286N/A if (prefix == XMLSymbols.PREFIX_XML) {
286N/A return NamespaceContext.XML_URI;
286N/A }
286N/A if (prefix == XMLSymbols.PREFIX_XMLNS) {
286N/A return NamespaceContext.XMLNS_URI;
286N/A }
286N/A
286N/A // find prefix in current context
286N/A for (int i = start; i > end; i -= 2) {
286N/A if (fNamespace[i - 2] == prefix) {
286N/A return fNamespace[i - 1];
286N/A }
286N/A }
286N/A
286N/A // prefix not found
286N/A return null;
286N/A }
286N/A
286N/A /**
286N/A * Only resets the current scope -- all namespaces defined in lower scopes
286N/A * remain valid after a call to reset.
286N/A */
286N/A public void reset() {
286N/A fCurrentContext = fScope[fCurrentScope];
286N/A fNamespaceSize = fContext[fCurrentContext];
286N/A }
286N/A
286N/A /**
286N/A * Begins a new scope. None of the previous namespace bindings will be used,
286N/A * until the new scope is popped with popScope()
286N/A */
286N/A public void pushScope() {
286N/A if (fCurrentScope + 1 == fScope.length) {
286N/A int[] contextarray = new int[fScope.length * 2];
286N/A System.arraycopy(fScope, 0, contextarray, 0, fScope.length);
286N/A fScope = contextarray;
286N/A }
286N/A pushContext();
286N/A fScope[++fCurrentScope] = fCurrentContext;
286N/A }
286N/A
286N/A /**
286N/A * Pops the current scope. The namespace bindings from the new current scope
286N/A * are then used for searching for namespaces and prefixes.
286N/A */
286N/A public void popScope() {
286N/A fCurrentContext = fScope[fCurrentScope--];
286N/A popContext();
286N/A }
286N/A}