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