001: /*
002: Copyright (c) 2004, 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 java.io.IOException;
032:
033: import org.jibx.runtime.IAliasable;
034: import org.jibx.runtime.IMarshaller;
035: import org.jibx.runtime.IMarshallingContext;
036: import org.jibx.runtime.IUnmarshaller;
037: import org.jibx.runtime.IUnmarshallingContext;
038: import org.jibx.runtime.JiBXException;
039: import org.jibx.runtime.impl.UnmarshallingContext;
040: import org.w3c.dom.Element;
041:
042: /**
043: * <p>Custom element marshaller/unmarshaller to DOM representation. This allows
044: * you to mix data binding and document model representations for XML within the
045: * same application. You simply use this marshaller/unmarshaller with a linked
046: * object of type <code>org.w3c.dom.Element</code> (the actual runtime type -
047: * the declared type is ignored and can be anything). If a name is supplied on a
048: * reference that element name will always be matched when unmarshalling but
049: * will be ignored when marshalling (with the actual DOM element name used). If
050: * no name is supplied this will unmarshal a single element with any name.</p>
051: *
052: * @author Dennis M. Sosnoski
053: * @version 1.0
054: */
055:
056: public class DomElementMapper extends DomMapperBase implements
057: IMarshaller, IUnmarshaller, IAliasable {
058: /** Root element namespace URI. */
059: private final String m_uri;
060:
061: /** Namespace URI index in binding. */
062: private final int m_index;
063:
064: /** Root element name. */
065: private final String m_name;
066:
067: /**
068: * Default constructor.
069: *
070: * @throws JiBXException on error creating document
071: */
072:
073: public DomElementMapper() throws JiBXException {
074: m_uri = null;
075: m_index = -1;
076: m_name = null;
077: }
078:
079: /**
080: * Aliased constructor. This takes a name definition for the element. It'll
081: * be used by JiBX when a name is supplied by the mapping which references
082: * this custom marshaller/unmarshaller.
083: *
084: * @param uri namespace URI for the top-level element
085: * @param index namespace index corresponding to the defined URI within the
086: * marshalling context definitions
087: * @param name local name for the top-level element
088: * @throws JiBXException on error creating document
089: */
090:
091: public DomElementMapper(String uri, int index, String name)
092: throws JiBXException {
093:
094: // save the simple values
095: m_uri = uri;
096: m_index = index;
097: m_name = name;
098: }
099:
100: /* (non-Javadoc)
101: * @see org.jibx.runtime.IMarshaller#isExtension(int)
102: */
103:
104: public boolean isExtension(int index) {
105: return false;
106: }
107:
108: /* (non-Javadoc)
109: * @see org.jibx.runtime.IMarshaller#marshal(java.lang.Object,
110: * org.jibx.runtime.IMarshallingContext)
111: */
112:
113: public void marshal(Object obj, IMarshallingContext ictx)
114: throws JiBXException {
115:
116: // make sure the parameters are as expected
117: if (!(obj instanceof Element)) {
118: throw new JiBXException(
119: "Mapped object not an org.w3c.dom.Element");
120: } else {
121: try {
122:
123: // marshal element and all content with only leading indentation
124: m_xmlWriter = ictx.getXmlWriter();
125: m_xmlWriter.indent();
126: int indent = ictx.getIndent();
127: ictx.setIndent(-1);
128: m_defaultNamespaceURI = null;
129: marshalElement((Element) obj);
130: ictx.setIndent(indent);
131:
132: } catch (IOException e) {
133: throw new JiBXException("Error writing to document", e);
134: }
135: }
136: }
137:
138: /* (non-Javadoc)
139: * @see org.jibx.runtime.IUnmarshaller#isPresent(org.jibx.runtime.IUnmarshallingContext)
140: */
141:
142: public boolean isPresent(IUnmarshallingContext ctx)
143: throws JiBXException {
144: if (m_name == null) {
145: if (!(ctx instanceof UnmarshallingContext)) {
146: throw new JiBXException(
147: "Unmarshalling context not of expected type");
148: } else {
149: return !((UnmarshallingContext) ctx).isEnd();
150: }
151: } else {
152: return ctx.isAt(m_uri, m_name);
153: }
154: }
155:
156: /* (non-Javadoc)
157: * @see org.jibx.runtime.IUnmarshaller#unmarshal(java.lang.Object,
158: * org.jibx.runtime.IUnmarshallingContext)
159: */
160:
161: public Object unmarshal(Object obj, IUnmarshallingContext ictx)
162: throws JiBXException {
163:
164: // verify the entry conditions
165: if (!(ictx instanceof UnmarshallingContext)) {
166: throw new JiBXException(
167: "Unmarshalling context not of expected type");
168: } else if (m_name != null && !ictx.isAt(m_uri, m_name)) {
169: ((UnmarshallingContext) ictx).throwStartTagNameError(m_uri,
170: m_name);
171: }
172:
173: // position to element start tag
174: m_unmarshalContext = (UnmarshallingContext) ictx;
175: m_unmarshalContext.toStart();
176:
177: // unmarshal element to document model
178: try {
179: return unmarshalElement();
180: } catch (IOException e) {
181: throw new JiBXException("Error reading from document", e);
182: }
183: }
184: }
|