001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.helpers;
019:
020: import java.util.ArrayList;
021: import java.util.List;
022: import java.util.ListIterator;
023:
024: public class NSStack {
025:
026: private static final String NS_PREFIX_PREFIX = "ns";
027:
028: private final List<List<NSDecl>> stack = new ArrayList<List<NSDecl>>();
029: private List<NSDecl> top;
030: private int size;
031: private int nsPrefixCount = 1;
032:
033: public synchronized void push() {
034: top = new ArrayList<NSDecl>();
035: stack.add(top);
036: size++;
037: }
038:
039: /**
040: * Leave a scope: this removes any NS declarations that were added
041: * in the last scope. Note that I don't bother to validate that you
042: * don't call popScope too many times; that's your problem.
043: */
044: public synchronized void pop() {
045: stack.remove(--size);
046: top = null;
047: if (size != 0) {
048: top = stack.get(size - 1);
049: }
050: }
051:
052: /**
053: * Add a new declaration to the current scope. This is visible within
054: * the current scope as well as from any nested scopes.
055: *
056: * @param prefix the prefix to be used for this namespace
057: * @param URI the namespace name of this namespace.
058: */
059: public synchronized void add(String prefix, String uri) {
060: top.add(new NSDecl(prefix, uri));
061: }
062:
063: /**
064: * Add a new declaration to the current scope using a unique prefix
065: * and return the prefix. This is useful when one just wants to add a
066: * decl and doesn't want to have to deal with creating unique prefixes.
067: * If the namespace name is already declared and in scope, then the
068: * previously declared prefix is returned.
069: *
070: * @param URI the namespace name of this namespace
071: * @return the unique prefix created or previously declared
072: * for this namespace
073: */
074: public synchronized String add(String uri) {
075: String uniquePrefix = getPrefix(uri);
076:
077: if (uniquePrefix == null) {
078: do {
079: uniquePrefix = NS_PREFIX_PREFIX + nsPrefixCount++;
080: } while (getURI(uniquePrefix) != null);
081: add(uniquePrefix, uri);
082: }
083: return uniquePrefix;
084: }
085:
086: /**
087: * Return the prefix associated with the given namespace name by
088: * looking thru all the namespace declarations that are in scope.
089: *
090: * @param URI the namespace name for whom a declared prefix is desired
091: * @return the prefix or null if namespace name not found
092: */
093: public String getPrefix(String uri) {
094: for (int i = size - 1; i >= 0; i--) {
095: List<NSDecl> scope = stack.get(i);
096: ListIterator<NSDecl> lsIterator = scope.listIterator();
097:
098: while (lsIterator.hasNext()) {
099: NSDecl nsd = lsIterator.next();
100:
101: if (nsd.getUri().equals(uri)) {
102: return nsd.getPrefix();
103: }
104: }
105: }
106: return null;
107: }
108:
109: /**
110: * Return the namespace name associated with the given prefix by
111: * looking thru all the namespace declarations that are in scope.
112: *
113: * @param prefix the prefix for whom a declared namespace name is desired
114: * @return the namespace name or null if prefix not found
115: */
116: public String getURI(String prefix) {
117: for (int i = size - 1; i >= 0; i--) {
118: List<NSDecl> scope = stack.get(i);
119: ListIterator<NSDecl> lsIterator = scope.listIterator();
120:
121: while (lsIterator.hasNext()) {
122: NSDecl nsd = lsIterator.next();
123:
124: if (nsd.getPrefix().equals(prefix)) {
125: return nsd.getUri();
126: }
127: }
128: }
129: return null;
130: }
131:
132: }
|