001: /*
002: Copyright (c) 2003-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.binding.def;
030:
031: import org.jibx.binding.classes.*;
032: import org.jibx.runtime.JiBXException;
033:
034: /**
035: * Property reference with marshaller and unmarshaller. This handles loading
036: * and storing the property value, calling the supplied marshaller and
037: * unmarshaller for all else.
038: *
039: * @author Dennis M. Sosnoski
040: * @version 1.0
041: */
042: public class DirectProperty implements IComponent {
043: /** Property definition. */
044: private final PropertyDefinition m_property;
045:
046: /** Property value direct binding. */
047: private final DirectObject m_direct;
048:
049: /**
050: * Constructor.
051: *
052: * @param prop property definition
053: * @param direct object direct binding information
054: */
055: public DirectProperty(PropertyDefinition prop, DirectObject direct) {
056: m_property = prop;
057: m_direct = direct;
058: }
059:
060: //
061: // IComponent interface method definitions
062:
063: public boolean isOptional() {
064: return m_property.isOptional();
065: }
066:
067: public boolean hasAttribute() {
068: return false;
069: }
070:
071: public void genAttrPresentTest(ContextMethodBuilder mb)
072: throws JiBXException {
073: throw new IllegalStateException(
074: "Internal error - no attributes allowed");
075: }
076:
077: public void genAttributeUnmarshal(ContextMethodBuilder mb)
078: throws JiBXException {
079: throw new IllegalStateException(
080: "Internal error - no attributes allowed");
081: }
082:
083: public void genAttributeMarshal(ContextMethodBuilder mb)
084: throws JiBXException {
085: throw new IllegalStateException(
086: "Internal error - no attributes allowed");
087: }
088:
089: public boolean hasContent() {
090: return true;
091: }
092:
093: public void genContentPresentTest(ContextMethodBuilder mb)
094: throws JiBXException {
095: m_direct.genContentPresentTest(mb);
096: }
097:
098: public void genContentUnmarshal(ContextMethodBuilder mb)
099: throws JiBXException {
100:
101: // check type of property binding
102: if (m_property.isImplicit()) {
103:
104: // load null to force create of new object for item in collection
105: mb.appendACONST_NULL();
106: m_direct.genContentUnmarshal(mb);
107:
108: } else if (m_property.isThis()) {
109:
110: // load existing object to unmarshal for "this" reference
111: mb.loadObject();
112: m_direct.genContentUnmarshal(mb);
113:
114: } else {
115:
116: // start by generating code to load owning object so can finish by
117: // storing to property
118: mb.loadObject();
119: BranchWrapper ifpres = null;
120: BranchWrapper tosave = null;
121: if (m_property.isOptional()) {
122:
123: // generate code to check presence for the case of an optional
124: // item, with branch if so; if not present, set a null value
125: // with branch to be targeted at property store.
126: m_direct.genContentPresentTest(mb);
127: ifpres = mb.appendIFNE(this );
128: mb.appendACONST_NULL();
129: tosave = mb.appendUnconditionalBranch(this );
130: }
131:
132: // generate unmarshalling code for not optional, or optional and
133: // present; get existing instance or create a new one and handle
134: // attribute unmarshalling
135: mb.targetNext(ifpres);
136: mb.loadObject();
137: m_property.genLoad(mb);
138: m_direct.genContentUnmarshal(mb);
139: mb.appendCreateCast(m_property.getSetValueType());
140: mb.targetNext(tosave);
141: m_property.genStore(mb);
142: }
143: }
144:
145: public void genContentMarshal(ContextMethodBuilder mb)
146: throws JiBXException {
147:
148: // check type of property binding
149: if (m_property.isImplicit()) {
150:
151: // marshal object already loaded on stack
152: m_direct.genContentMarshal(mb);
153:
154: } else if (m_property.isThis()) {
155:
156: // load object to marshal for "this" reference
157: mb.loadObject();
158: m_direct.genContentMarshal(mb);
159:
160: } else {
161:
162: // start by generating code to load the actual object reference
163: mb.loadObject();
164: m_property.genLoad(mb);
165: BranchWrapper missing = null;
166: if (m_property.isOptional()) {
167:
168: // generate code to check null for the case of an optional item,
169: // with branch if so; if present, just reload object and fall
170: // through.
171: missing = mb.appendIFNULL(this );
172: mb.loadObject();
173: m_property.genLoad(mb);
174: }
175:
176: // generate code for actual marshalling if not optional, or optional
177: // and nonnull; then finish by setting target for optional with
178: // null value case
179: m_direct.genContentMarshal(mb);
180: mb.targetNext(missing);
181: }
182: }
183:
184: public void genNewInstance(ContextMethodBuilder mb) {
185: throw new IllegalStateException(
186: "Internal error - no instance creation");
187: }
188:
189: public String getType() {
190: return m_property.getTypeName();
191: }
192:
193: public boolean hasId() {
194: return false;
195: }
196:
197: public void genLoadId(ContextMethodBuilder mb) throws JiBXException {
198: throw new IllegalStateException(
199: "Internal error - no id defined");
200: }
201:
202: public NameDefinition getWrapperName() {
203: return m_direct.getWrapperName();
204: }
205:
206: public void setLinkages() throws JiBXException {
207: m_direct.setLinkages();
208: }
209:
210: // DEBUG
211: public void print(int depth) {
212: BindingDefinition.indent(depth);
213: if (m_property == null) {
214: System.out.println("direct implicit property");
215: } else {
216: System.out.println("direct property using "
217: + m_property.toString());
218: }
219: m_direct.print(depth + 1);
220: }
221: }
|