001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.commons.xml.namespace;
020:
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.Map;
024: import java.util.logging.*;
025: import java.util.logging.Level;
026:
027: import org.w3c.dom.Node;
028:
029: /**
030: * This class provides methods to support NamespaceResolver implementations. It stores
031: * Namespace URI/Prefix mappings, checks for clashes and generates new safe prefixes for
032: * Namespaces that do not already have a prefix associated to them.
033: *
034: * @author Matthew Large
035: * @version $Revision: 1.3 $
036: */
037: public abstract class AbstractNamespaceResolver implements
038: NamespaceResolver {
039:
040: /**
041: * Prefix to Namespace mapping
042: */
043: private Map m_namespaces = new HashMap(11);
044:
045: /**
046: * Number to append to the next namespace prefix that is created, e.g. ns1, ns2 etc
047: */
048: private int m_nNextPrefixAppend = 0;
049:
050: /**
051: * Logger for this class
052: */
053: private static final Logger m_logger = Logger
054: .getLogger(AbstractNamespaceResolver.class.getName());
055:
056: /**
057: * Adds the default namespace URI-prefix mappings.
058: *
059: * @see NamespaceType
060: */
061: protected void addDefaultNamespaces() {
062: try {
063: this .addNamespace(NamespaceType.COL_RDF);
064: this .addNamespace(NamespaceType.DAV);
065: this .addNamespace(NamespaceType.LOM_CLS);
066: this .addNamespace(NamespaceType.LOM_XML);
067: this .addNamespace(NamespaceType.RDF);
068: this .addNamespace(NamespaceType.RDF_SCHEMA);
069: this .addNamespace(NamespaceType.XML);
070: this .addNamespace(NamespaceType.XML_SCHEMA);
071: this .addNamespace(NamespaceType.XML_SCHEMA_INSTANCE);
072: this .addNamespace(NamespaceType.OHRM);
073: this .addNamespace(NamespaceType.XSLFO);
074: this .addNamespace(NamespaceType.XSLT);
075: } catch (NamespaceClashException e) {
076: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
077: }
078: }
079:
080: /**
081: * Adds a namespace URI-prefix mapping from a {@link NamespaceType}
082: * object.
083: *
084: * @param namespace Namespace information to add
085: * @throws NamespaceClashException Thrown if this prefix has already been used
086: */
087: private void addNamespace(NamespaceType namespace)
088: throws NamespaceClashException {
089: this .addNamespace(namespace.getURI(), namespace.getPrefix());
090: }
091:
092: /* (non-Javadoc)
093: * @see org.openharmonise.commons.xml.namespace.NamespaceResolver#addNamespace(java.lang.String, java.lang.String)
094: */
095: public void addNamespace(String sURI, String sPrefix)
096: throws NamespaceClashException {
097:
098: boolean bFound = false;
099:
100: synchronized (this .m_namespaces) {
101: Iterator itor = this .m_namespaces.values().iterator();
102: while (itor.hasNext()) {
103: Namespace ns = (Namespace) itor.next();
104: if (ns.getPrefix().equals(sPrefix)) {
105: bFound = true;
106: }
107: }
108: }
109:
110: if (bFound) {
111: throw new NamespaceClashException();
112: } else {
113: m_namespaces.put(sPrefix, new Namespace(sURI, sPrefix));
114: }
115:
116: }
117:
118: /* (non-Javadoc)
119: * @see org.openharmonise.commons.xml.namespace.NamespaceResolver#getNamespaceByPrefix(java.lang.String)
120: */
121: public String getNamespaceByPrefix(String sPrefix) {
122: String sReturn = null;
123:
124: Namespace ns = (Namespace) m_namespaces.get(sPrefix);
125: if (ns != null) {
126: sReturn = ns.getURI();
127: }
128:
129: return sReturn;
130: }
131:
132: /* (non-Javadoc)
133: * @see org.openharmonise.commons.xml.namespace.NamespaceResolver#getPrefixByNamespace(java.lang.String)
134: */
135: public String getPrefixByNamespace(String sURI) {
136: String sPrefix = null;
137:
138: synchronized (this .m_namespaces) {
139: Iterator itor = this .m_namespaces.values().iterator();
140: while (itor.hasNext()) {
141: Namespace ns = (Namespace) itor.next();
142: if (ns.getURI().equals(sURI)) {
143: sPrefix = ns.getPrefix();
144: }
145: }
146: }
147:
148: if (sPrefix == null) {
149: sPrefix = this .createPrefix(sURI);
150: try {
151: this .addNamespace(sURI, sPrefix);
152: } catch (NamespaceClashException e) {
153: m_logger.log(Level.WARNING, e.getLocalizedMessage(), e);
154: }
155: }
156:
157: return sPrefix;
158: }
159:
160: /* (non-Javadoc)
161: * @see org.openharmonise.commons.xml.namespace.NamespaceResolver#getPrefixByNode(org.w3c.dom.Node)
162: */
163: public String getPrefixByNode(Node node)
164: throws NamespaceClashException {
165: String sPrefix = null;
166:
167: String sURI = node.getNamespaceURI();
168: String sNodePrefix = node.getPrefix();
169:
170: if (sNodePrefix != null
171: && this .m_namespaces.containsKey(sNodePrefix)) {
172: Namespace ns = (Namespace) this .m_namespaces
173: .get(sNodePrefix);
174: if (sURI == null
175: || (sURI != null && sURI.equals(ns.m_sURI))) {
176: sPrefix = ns.getPrefix();
177: } else {
178: throw new NamespaceClashException(
179: "Node has a namespace prefix that is already in the resolver associated to a different namespace URI than the one associates to the node.");
180: }
181: } else if (sNodePrefix != null
182: && !this .m_namespaces.containsKey(sNodePrefix)) {
183: if (sURI != null) {
184: this .addNamespace(sURI, sNodePrefix);
185: sPrefix = sNodePrefix;
186: } else {
187: throw new NamespaceClashException(
188: "Node has prefix but no namespace URI and resolver does not have a namespace URI for that prefix.");
189: }
190: } else if (sNodePrefix == null && sURI != null) {
191: sPrefix = this .getPrefixByNamespace(sURI);
192: }
193:
194: return sPrefix;
195: }
196:
197: /* (non-Javadoc)
198: * @see org.openharmonise.commons.xml.namespace.NamespaceResolver#removeNamespace(java.lang.String)
199: */
200: public void removeNamespace(String sURI) {
201: String sPrefix = null;
202:
203: synchronized (this .m_namespaces) {
204: Iterator itor = this .m_namespaces.values().iterator();
205: while (itor.hasNext()) {
206: Namespace ns = (Namespace) itor.next();
207: if (ns.getURI().equals(sURI)) {
208: sPrefix = ns.getPrefix();
209: }
210: }
211: }
212:
213: if (sPrefix != null) {
214: this .m_namespaces.remove(sPrefix);
215: }
216: }
217:
218: /**
219: * Creates a prefix for a namespace URI, e.g. ns1, ns2 etc.
220: *
221: * @param sURI Namespace URI
222: * @return Namespace prefix
223: */
224: private String createPrefix(String sURI) {
225: String sPrefix = "ns" + this .m_nNextPrefixAppend;
226: this .m_nNextPrefixAppend++;
227:
228: while (this .m_namespaces.containsKey(sPrefix)) {
229: sPrefix = "ns" + this .m_nNextPrefixAppend;
230: this .m_nNextPrefixAppend++;
231: }
232:
233: return sPrefix;
234: }
235:
236: /**
237: * Holder for Namespace information, URI and prefix.
238: *
239: * @author Matthew Large
240: * @version $Revision: 1.3 $
241: *
242: */
243: private class Namespace {
244:
245: /**
246: * Namespace URI.
247: */
248: private String m_sURI;
249:
250: /**
251: * Namespace prefix.
252: */
253: private String m_sPrefix;
254:
255: /**
256: * Constructs new instance.
257: *
258: * @param sURI Namespace URI
259: * @param sPrefix Namespace prefix
260: */
261: public Namespace(String sURI, String sPrefix) {
262: this .m_sURI = sURI;
263: this .m_sPrefix = sPrefix;
264: }
265:
266: /**
267: * Returns the Namespace URI.
268: *
269: * @return Namespace URI
270: */
271: public String getURI() {
272: return this .m_sURI;
273: }
274:
275: /**
276: * Returns the Namespace prefix.
277: *
278: * @return Namespace prefix
279: */
280: public String getPrefix() {
281: return this .m_sPrefix;
282: }
283:
284: /* (non-Javadoc)
285: * @see java.lang.Object#toString()
286: */
287: public String toString() {
288: return m_sPrefix;
289: }
290: }
291:
292: }
|