001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 1999 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "Xerces" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 1999, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package org.apache.xerces.utils;
059:
060: /**
061: * NamespacesScope provides a data structure for mapping namespace prefixes
062: * to their URI's. The mapping accurately reflects the scoping of namespaces
063: * at a particular instant in time.
064: */
065: public class NamespacesScope {
066: /**
067: * NamespacesHandler allows a client to be notified when namespace scopes change
068: */
069: public interface NamespacesHandler {
070: /**
071: * startNamespaceDeclScope is called when a new namespace scope is created
072: *
073: * @param prefix the StringPool handle of the namespace prefix being declared
074: * @param uri the StringPool handle of the namespace's URI
075: * @exception java.lang.Exception
076: */
077: public void startNamespaceDeclScope(int prefix, int uri)
078: throws Exception;
079:
080: /**
081: * endNamespaceDeclScope is called when a namespace scope ends
082: *
083: * @param prefix the StringPool handle of the namespace prefix going out of scope
084: * @exception java.lang.Exception
085: */
086: public void endNamespaceDeclScope(int prefix) throws Exception;
087: }
088:
089: public NamespacesScope() {
090: this (new NamespacesHandler() {
091: public void startNamespaceDeclScope(int prefix, int uri)
092: throws Exception {
093: }
094:
095: public void endNamespaceDeclScope(int prefix)
096: throws Exception {
097: }
098: });
099: }
100:
101: public NamespacesScope(NamespacesHandler handler) {
102: fHandler = handler;
103: fNamespaceMappings[0] = new int[9];
104: fNamespaceMappings[0][0] = 1;
105: }
106:
107: public NamespacesScope(NamespacesHandler handler, int elemDepth,
108: int[][] map) {
109: fHandler = handler;
110: fElementDepth = elemDepth;
111: if (map == null) {
112: fNamespaceMappings = new int[8][];
113: return;
114: }
115: fNamespaceMappings = new int[map.length][];
116: for (int i = 0; i <= fElementDepth; i++) {
117: if (map[i] != null) {
118: fNamespaceMappings[i] = new int[map[i].length];
119: System.arraycopy(map[i], 0, fNamespaceMappings[i], 0,
120: map[i].length);
121: }
122: }
123: }
124:
125: /**
126: * set the namespace URI for given prefix
127: *
128: * @param prefix the StringPool handler of the prefix
129: * @param namespace the StringPool handle of the namespace URI
130: */
131: public void setNamespaceForPrefix(int prefix, int namespace)
132: throws Exception {
133: int offset = fNamespaceMappings[fElementDepth][0];
134: if (offset == fNamespaceMappings[fElementDepth].length) {
135: int[] newMappings = new int[offset + 8];
136: System.arraycopy(fNamespaceMappings[fElementDepth], 0,
137: newMappings, 0, offset);
138: fNamespaceMappings[fElementDepth] = newMappings;
139: }
140: fNamespaceMappings[fElementDepth][offset++] = prefix;
141: fNamespaceMappings[fElementDepth][offset++] = namespace;
142: fNamespaceMappings[fElementDepth][0] = offset;
143: if (fElementDepth > 0)
144: fHandler.startNamespaceDeclScope(prefix, namespace);
145: }
146:
147: /**
148: * retreive the namespace URI for a prefix
149: *
150: * @param prefix the StringPool handle of the prefix
151: */
152: public int getNamespaceForPrefix(int prefix) {
153: for (int depth = fElementDepth; depth >= 0; depth--) {
154: int offset = fNamespaceMappings[depth][0];
155: for (int i = 1; i < offset; i += 2) {
156: if (prefix == fNamespaceMappings[depth][i]) {
157: return fNamespaceMappings[depth][i + 1];
158: }
159: }
160: }
161: return StringPool.EMPTY_STRING;
162: }
163:
164: /**
165: * Add a new namespace mapping
166: */
167: public void increaseDepth() throws Exception {
168: fElementDepth++;
169: if (fElementDepth == fNamespaceMappings.length) {
170: int[][] newMappings = new int[fElementDepth + 8][];
171: System.arraycopy(fNamespaceMappings, 0, newMappings, 0,
172: fElementDepth);
173: fNamespaceMappings = newMappings;
174: }
175: if (fNamespaceMappings[fElementDepth] == null)
176: fNamespaceMappings[fElementDepth] = new int[9];
177: fNamespaceMappings[fElementDepth][0] = 1;
178: }
179:
180: /**
181: * Remove a namespace mappng
182: */
183: public void decreaseDepth() throws Exception {
184: if (fElementDepth > 0) {
185: int offset = fNamespaceMappings[fElementDepth][0];
186: while (offset > 1) {
187: offset -= 2;
188: fHandler
189: .endNamespaceDeclScope(fNamespaceMappings[fElementDepth][offset]);
190: }
191: }
192: fElementDepth--;
193: }
194:
195: // Object methods:
196: public Object clone() {
197: return new NamespacesScope(fHandler, fElementDepth,
198: fNamespaceMappings);
199: } // end clone()
200:
201: private NamespacesHandler fHandler = null;
202: private int fElementDepth = 0;
203: private int[][] fNamespaceMappings = new int[8][];
204: }
|