001: /*
002: Copyright (c) 2003-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.binding.def;
030:
031: import org.jibx.binding.classes.ClassCache;
032: import org.jibx.binding.classes.ClassFile;
033: import org.jibx.binding.classes.ContextMethodBuilder;
034: import org.jibx.runtime.JiBXException;
035:
036: /**
037: * Reference to a structure definition. This is used as a placeholder when
038: * building the component structure of a binding definition. It's necessary
039: * because the referenced structure may not have been parsed yet. During the
040: * linkage phase that follows parsing this looks up the appropriate structure
041: * definition and sets up the corresponding component structure. Thereafter it
042: * operates as a simple pass-through wrapper for the top child component.
043: *
044: * @author Dennis M. Sosnoski
045: * @version 1.0
046: */
047:
048: public class StructureReference extends PassThroughComponent {
049: /** Containing binding component. */
050: private final IContainer m_container;
051:
052: /** Containing binding definition structure. */
053: private final IContextObj m_contextObject;
054:
055: /** Property definition (may be <code>null</code>). */
056: private final PropertyDefinition m_property;
057:
058: /** Identifier for referenced structure definition. */
059: private final String m_label;
060:
061: /** Flag for marshalling code generation to be skipped by component. */
062: private boolean m_skipMarshal;
063:
064: /** Object load needed for marshalling flag (used with object binding). */
065: private boolean m_needLoad;
066:
067: /**
068: * Constructor.
069: *
070: * @param contain containing binding component
071: * @param label reference structure identifier
072: * @param prop property definition (may be <code>null</code>)
073: * @param hasname element name used with reference flag
074: * @param cobj context object
075: */
076:
077: public StructureReference(IContainer contain, String label,
078: PropertyDefinition prop, boolean hasname, IContextObj cobj) {
079: super ();
080: m_container = contain;
081: m_contextObject = cobj;
082: m_property = prop;
083: m_skipMarshal = hasname && prop != null && prop.isOptional();
084: m_label = label;
085: }
086:
087: //
088: // IComponent interface method definitions (overrides of defaults)
089:
090: public void genAttributeMarshal(ContextMethodBuilder mb)
091: throws JiBXException {
092: if (m_needLoad) {
093: mb.loadObject();
094: }
095: m_component.genAttributeMarshal(mb);
096: }
097:
098: public void genContentMarshal(ContextMethodBuilder mb)
099: throws JiBXException {
100: if (m_needLoad) {
101: mb.loadObject();
102: }
103: m_component.genContentMarshal(mb);
104: }
105:
106: public void setLinkages() throws JiBXException {
107:
108: // find the structure being used
109: DefinitionContext defc = m_container.getDefinitionContext();
110: IComponent impl = defc.getNamedStructure(m_label);
111:
112: // verify compatible use of structure
113: String type = (m_property == null) ? m_contextObject
114: .getBoundClass().getClassName() : m_property
115: .getTypeName();
116: ClassFile cf = ClassCache.getClassFile(type);
117: String itype = impl.getType();
118: if (!cf.isSuperclass(itype)) {
119: throw new JiBXException("Reference to structure " + m_label
120: + " has object of type " + type
121: + " rather than required " + itype);
122: }
123:
124: // generate component matching mapping type
125: IComponent wrap;
126: if (impl instanceof DirectObject) {
127: wrap = new DirectProperty(m_property, (DirectObject) impl);
128: } else if (m_property == null || m_property.isImplicit()) {
129: wrap = impl;
130: m_needLoad = impl instanceof ObjectBinding;
131: } else {
132: wrap = new ComponentProperty(m_property, impl,
133: m_skipMarshal);
134: }
135:
136: // set the wrapped component used for all other calls
137: setWrappedComponent(wrap);
138: m_component.setLinkages();
139: }
140:
141: // DEBUG
142: public void print(int depth) {
143: BindingDefinition.indent(depth);
144: System.out.print("structure reference to " + m_label);
145: if (m_property != null) {
146: System.out.println(" using " + m_property.toString());
147: }
148: System.out.println();
149: }
150: }
|