001: /*
002: Copyright (c) 2005, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.extras;
030:
031: import org.jibx.runtime.IMarshallingContext;
032: import org.jibx.runtime.IUnmarshallingContext;
033: import org.jibx.runtime.IXMLWriter;
034: import org.jibx.runtime.JiBXException;
035: import org.jibx.runtime.impl.MarshallingContext;
036: import org.jibx.runtime.impl.UnmarshallingContext;
037:
038: /**
039: * Representation of a qualified name. This includes the serializer/deserializer
040: * methods for the representation. It assumes that the actual namespace
041: * declarations are being handled separately for marshalling.
042: *
043: * @author Dennis M. Sosnoski
044: */
045: public class QName {
046: private String m_uri;
047: private String m_prefix;
048: private String m_name;
049:
050: /**
051: * Default constructor.
052: */
053: public QName() {
054: }
055:
056: /**
057: * Constructor from full set of components.
058: *
059: * @param uri
060: * @param prefix
061: * @param name
062: */
063: public QName(String uri, String prefix, String name) {
064: m_uri = uri;
065: m_prefix = prefix;
066: m_name = name;
067: }
068:
069: /**
070: * Get local name.
071: *
072: * @return name
073: */
074: public String getName() {
075: return m_name;
076: }
077:
078: /**
079: * Set local name.
080: *
081: * @param name name
082: */
083: public void setName(String name) {
084: m_name = name;
085: }
086:
087: /**
088: * Get namespace prefix.
089: *
090: * @return prefix
091: */
092: public String getPrefix() {
093: return m_prefix;
094: }
095:
096: /**
097: * Set namespace prefix.
098: *
099: * @param prefix prefix
100: */
101: public void setPrefix(String prefix) {
102: m_prefix = prefix;
103: }
104:
105: /**
106: * Get namespace URI.
107: *
108: * @return uri
109: */
110: public String getUri() {
111: return m_uri;
112: }
113:
114: /**
115: * Set namespace URI.
116: *
117: * @param uri uri
118: */
119: public void setUri(String uri) {
120: m_uri = uri;
121: }
122:
123: /**
124: * JiBX deserializer method. This is intended for use as a deserializer for
125: * instances of the class.
126: *
127: * @param text value text
128: * @param ictx unmarshalling context
129: * @return created class instance
130: * @throws JiBXException on error in unmarshalling
131: */
132: public static QName deserialize(String text,
133: IUnmarshallingContext ictx) throws JiBXException {
134:
135: // check for prefix used in text representation
136: int split = text.indexOf(':');
137: if (split > 0) {
138:
139: // strip off prefix
140: String prefix = text.substring(0, split);
141: text = text.substring(split + 1);
142:
143: // make sure there aren't multiple colons
144: if (text.indexOf(':') >= 0) {
145: throw new JiBXException("Not a valid QName");
146: } else {
147:
148: // look up the namespace URI associated with the prefix
149: String uri = ((UnmarshallingContext) ictx)
150: .getNamespaceUri(prefix);
151: if (uri == null) {
152: throw new JiBXException("Undefined prefix "
153: + prefix);
154: } else {
155:
156: // create an instance of class to hold all components
157: return new QName(uri, prefix, text);
158:
159: }
160: }
161: } else {
162:
163: // get the default namespace URI
164: String uri = ((UnmarshallingContext) ictx)
165: .getNamespaceUri("");
166: if (uri == null) {
167: uri = "";
168: }
169:
170: // create an instance of class to hold all components
171: return new QName(uri, "", text);
172: }
173: }
174:
175: /**
176: * JiBX serializer method. This is intended for use as a serializer for
177: * instances of the class. The namespace must be active in the output
178: * document at the point where this is called.
179: *
180: * @param qname instance to be serialized
181: * @param ictx unmarshalling context
182: * @return created class instance
183: * @throws JiBXException on error in marshalling
184: */
185: public static String serialize(QName qname, IMarshallingContext ictx)
186: throws JiBXException {
187:
188: // check if prefix is alread defined in document with correct URI
189: IXMLWriter ixw = ((MarshallingContext) ictx).getXmlWriter();
190: int index = -1;
191: int tryidx = ixw.getPrefixIndex(qname.m_prefix);
192: if (tryidx >= 0
193: && qname.m_uri.equals(ixw.getNamespaceUri(tryidx))) {
194: index = tryidx;
195: }
196: if (index < 0) {
197:
198: // prefix not defined, find the namespace index in binding
199: String[] nss = ixw.getNamespaces();
200: for (int i = 0; i < nss.length; i++) {
201: if (nss[i].equals(qname.m_uri)) {
202: index = i;
203: break;
204: }
205: }
206: if (index < 0) {
207:
208: // namespace not in binding, check extensions
209: String[][] nsss = ixw.getExtensionNamespaces();
210: if (nsss != null) {
211: int base = nss.length;
212: outer: for (int i = 0; i < nsss.length; i++) {
213: nss = nsss[i];
214: for (int j = 0; j < nss.length; j++) {
215: if (nss[j].equals(qname.m_uri)) {
216: index = base + j;
217: break outer;
218: }
219: }
220: base += nss.length;
221: }
222: }
223:
224: }
225: }
226: if (index >= 0) {
227:
228: // get prefix defined for namespace
229: String prefix = ixw.getNamespacePrefix(index);
230: if (prefix == null) {
231: throw new JiBXException("Namespace URI " + qname.m_uri
232: + " cannot be used since it is not active");
233: } else if (prefix.length() > 0) {
234: return prefix + ':' + qname.m_name;
235: } else {
236: return qname.m_name;
237: }
238:
239: } else {
240: throw new JiBXException("Unknown namespace URI "
241: + qname.m_uri);
242: }
243: }
244: }
|