KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jibx > binding > def > ElementWrapper


1 /*
2 Copyright (c) 2003-2004, Dennis M. Sosnoski
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8  * Redistributions of source code must retain the above copyright notice, this
9    list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice,
11    this list of conditions and the following disclaimer in the documentation
12    and/or other materials provided with the distribution.
13  * Neither the name of JiBX nor the names of its contributors may be used
14    to endorse or promote products derived from this software without specific
15    prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */

28
29 package org.jibx.binding.def;
30
31 import org.jibx.binding.classes.*;
32 import org.jibx.runtime.JiBXException;
33
34 /**
35  * Component decorator for element definition. This associates an element name
36  * with a component.
37  *
38  * @author Dennis M. Sosnoski
39  * @version 1.0
40  */

41
42 public class ElementWrapper implements IComponent
43 {
44     //
45
// Constants and such related to code generation.
46

47     private static final String JavaDoc UNMARSHAL_PARSESTARTATTRIBUTES =
48         "org.jibx.runtime.impl.UnmarshallingContext.parseToStartTag";
49     private static final String JavaDoc UNMARSHAL_PARSESTARTNOATTRIBUTES =
50         "org.jibx.runtime.impl.UnmarshallingContext.parsePastStartTag";
51     private static final String JavaDoc UNMARSHAL_PARSEPASTSTART =
52         "org.jibx.runtime.impl.UnmarshallingContext.parsePastStartTag";
53     private static final String JavaDoc UNMARSHAL_PARSESTARTSIGNATURE =
54         "(Ljava/lang/String;Ljava/lang/String;)V";
55     private static final String JavaDoc UNMARSHAL_PARSEENDMETHOD =
56         "org.jibx.runtime.impl.UnmarshallingContext.parsePastEndTag";
57     private static final String JavaDoc UNMARSHAL_PARSEENDSIGNATURE =
58         "(Ljava/lang/String;Ljava/lang/String;)V";
59     private static final String JavaDoc UNMARSHAL_ISATMETHOD =
60         "org.jibx.runtime.IUnmarshallingContext.isAt";
61     private static final String JavaDoc UNMARSHAL_ISATSIGNATURE =
62         "(Ljava/lang/String;Ljava/lang/String;)Z";
63     private static final String JavaDoc UNMARSHAL_SKIPELEMENTMETHOD =
64         "org.jibx.runtime.impl.UnmarshallingContext.parsePastElement";
65     private static final String JavaDoc UNMARSHAL_SKIPELEMENTSIGNATURE =
66         "(Ljava/lang/String;Ljava/lang/String;)V";
67     private static final String JavaDoc MARSHAL_WRITESTARTNAMESPACES =
68         "org.jibx.runtime.impl.MarshallingContext.startTagNamespaces";
69     private static final String JavaDoc MARSHAL_STARTNAMESPACESSIGNATURE =
70         "(ILjava/lang/String;[I[Ljava/lang/String;)" +
71         "Lorg/jibx/runtime/impl/MarshallingContext;";
72     private static final String JavaDoc MARSHAL_WRITESTARTATTRIBUTES =
73         "org.jibx.runtime.impl.MarshallingContext.startTagAttributes";
74     private static final String JavaDoc MARSHAL_WRITESTARTNOATTRIBUTES =
75         "org.jibx.runtime.impl.MarshallingContext.startTag";
76     private static final String JavaDoc MARSHAL_WRITESTARTSIGNATURE =
77         "(ILjava/lang/String;)Lorg/jibx/runtime/impl/MarshallingContext;";
78     private static final String JavaDoc MARSHAL_CLOSESTARTCONTENT =
79         "org.jibx.runtime.impl.MarshallingContext.closeStartContent";
80     private static final String JavaDoc MARSHAL_CLOSESTARTEMPTY =
81         "org.jibx.runtime.impl.MarshallingContext.closeStartEmpty";
82     private static final String JavaDoc MARSHAL_CLOSESTARTSIGNATURE =
83         "()Lorg/jibx/runtime/impl/MarshallingContext;";
84     private static final String JavaDoc MARSHAL_WRITEENDMETHOD =
85         "org.jibx.runtime.impl.MarshallingContext.endTag";
86     private static final String JavaDoc MARSHAL_WRITEENDSIGNATURE =
87         "(ILjava/lang/String;)Lorg/jibx/runtime/impl/MarshallingContext;";
88     private static final String JavaDoc MARSHALLING_CONTEXT =
89         "org.jibx.runtime.impl.MarshallingContext";
90     private static final String JavaDoc UNMARSHALLING_CONTEXT =
91         "org.jibx.runtime.impl.UnmarshallingContext";
92
93     //
94
// Actual instance data.
95

96     /** Property value binding component. */
97     private final IComponent m_component;
98
99     /** Binding definition context. */
100     private final DefinitionContext m_defContext;
101
102     /** Element name information. */
103     private final NameDefinition m_name;
104     
105     /** Flag for value from collection (TODO: fix this in update). */
106     private boolean m_directAccess;
107     
108     /** Flag for optional ignored element (TODO: fix this in update). */
109     private boolean m_optionalIgnored;
110     
111     /** Flag for optional normal element (TODO: fix this in update). */
112     private boolean m_optionalNormal;
113     
114     /** Flag for optional structure object (TODO: fix this in update). */
115     private boolean m_structureObject;
116
117     /**
118      * Constructor.
119      *
120      * @param defc definition context for this component
121      * @param name element name definition
122      * @param wrap wrapped binding component (may be <code>null</code>, in the
123      * case of a throwaway component)
124      */

125
126     public ElementWrapper(DefinitionContext defc, NameDefinition name,
127         IComponent wrap) {
128         m_defContext = defc;
129         m_name = name;
130         m_component = wrap;
131     }
132
133     /**
134      * Set the direct access flag. This controls a variation in the code
135      * generation to handle values loaded from a collection.
136      *
137      * @param direct <code>true</code> if direct access from collection,
138      * <code>false</code> if not
139      */

140     
141     public void setDirect(boolean direct) {
142         m_directAccess = direct;
143     }
144
145     /**
146      * Set flag for an optional ignored element.
147      *
148      * @param opt <code>true</code> if optional ignored element,
149      * <code>false</code> if not
150      */

151     
152     public void setOptionalIgnored(boolean opt) {
153         m_optionalIgnored = opt;
154     }
155
156     /**
157      * Set flag for an optional structure object.
158      *
159      * @param opt <code>true</code> if optional structure object,
160      * <code>false</code> if not
161      */

162     
163     public void setStructureObject(boolean opt) {
164         m_structureObject = opt;
165     }
166
167     /**
168      * Set flag for an optional normal element.
169      *
170      * @param opt <code>true</code> if optional normal element,
171      * <code>false</code> if not
172      */

173     
174     public void setOptionalNormal(boolean opt) {
175         m_optionalNormal = opt;
176     }
177
178     //
179
// IComponent interface method definitions
180

181     public boolean isOptional() {
182         return m_optionalNormal || m_optionalIgnored;
183     }
184
185     public boolean hasAttribute() {
186         return false;
187     }
188
189     public void genAttrPresentTest(ContextMethodBuilder mb) {
190         throw new IllegalStateException JavaDoc
191             ("Internal error - no attributes from child element");
192     }
193
194     public void genAttributeUnmarshal(ContextMethodBuilder mb) {
195         throw new IllegalStateException JavaDoc
196             ("Internal error - no attributes from child element");
197     }
198
199     public void genAttributeMarshal(ContextMethodBuilder mb) {
200         throw new IllegalStateException JavaDoc
201             ("Internal error - no attributes from child element");
202     }
203
204     public boolean hasContent() {
205         return true;
206     }
207
208     public void genContentPresentTest(ContextMethodBuilder mb)
209         throws JiBXException {
210         
211         // create call to unmarshalling context method with namespace and
212
// name, then return result directly
213
mb.loadContext();
214         m_name.genPushUriPair(mb);
215         mb.appendCallInterface(UNMARSHAL_ISATMETHOD, UNMARSHAL_ISATSIGNATURE);
216     }
217
218     public void genContentUnmarshal(ContextMethodBuilder mb)
219         throws JiBXException {
220         
221         // check for optional empty wrapper present
222
BranchWrapper ifmiss = null;
223         if (isOptional()) {
224             genContentPresentTest(mb);
225             ifmiss = mb.appendIFEQ(this);
226         }
227     
228         // set up flags for controlling code generation paths
229
boolean attr = m_component != null && m_component.hasAttribute();
230         boolean cont = m_component != null && m_component.hasContent();
231     
232         // duplicate object reference on stack if both attribute(s) and content
233
if (attr && cont && !m_directAccess) {
234             mb.appendDUP();
235         }
236         
237         // load the unmarshalling context followed by the namespace URI and
238
// element name.
239
mb.loadContext(UNMARSHALLING_CONTEXT);
240         m_name.genPushUriPair(mb);
241         
242         // check type of unmarshalling behavior required
243
if (attr) {
244
245             // unmarshal start tag with attribute(s)
246
mb.appendCallVirtual(UNMARSHAL_PARSESTARTATTRIBUTES,
247                 UNMARSHAL_PARSESTARTSIGNATURE);
248             m_component.genAttributeUnmarshal(mb);
249
250             // generate code to parse past the start tag with another call
251
// to unmarshalling context
252
mb.loadContext(UNMARSHALLING_CONTEXT);
253             m_name.genPushUriPair(mb);
254             mb.appendCallVirtual(UNMARSHAL_PARSEPASTSTART,
255                 UNMARSHAL_PARSESTARTSIGNATURE);
256                 
257         } else if (cont) {
258             
259             // unmarshal start tag without attributes
260
mb.appendCallVirtual(UNMARSHAL_PARSESTARTNOATTRIBUTES,
261                 UNMARSHAL_PARSESTARTSIGNATURE);
262             
263         } else {
264             
265             // unmarshal element discarding all content
266
mb.appendCallVirtual(UNMARSHAL_SKIPELEMENTMETHOD,
267                 UNMARSHAL_SKIPELEMENTSIGNATURE);
268         }
269
270         // unmarshal child content
271
if (cont) {
272             m_component.genContentUnmarshal(mb);
273         }
274
275         // next add code to push context, namespace and name, and call
276
// method to parse past end tag
277
if (attr || cont) {
278             mb.loadContext(UNMARSHALLING_CONTEXT);
279             m_name.genPushUriPair(mb);
280             mb.appendCallVirtual(UNMARSHAL_PARSEENDMETHOD,
281                 UNMARSHAL_PARSEENDSIGNATURE);
282         }
283         if (ifmiss != null) {
284             if (m_directAccess && !attr) {
285                 BranchWrapper toend = mb.appendUnconditionalBranch(this);
286                 mb.targetNext(ifmiss);
287                 mb.appendPOP();
288                 mb.targetNext(toend);
289             } else {
290                 if (m_structureObject && attr && cont) {
291                     mb.appendPOP();
292                 }
293                 mb.targetNext(ifmiss);
294             }
295         }
296     }
297
298     public void genContentMarshal(ContextMethodBuilder mb)
299         throws JiBXException {
300         
301         // nothing to be done if optional ignored element
302
if (!m_optionalIgnored) {
303         
304             // set up flags for controlling code generation paths
305
boolean attr = m_component != null && m_component.hasAttribute();
306             boolean cont = m_component != null && m_component.hasContent();
307             boolean needns = m_defContext.hasNamespace();
308         
309             // duplicate object reference on stack if both attribute(s) and
310
// content
311
if (attr && cont) {
312                 mb.appendDUP();
313             }
314
315             // load the context followed by namespace index and element name
316
mb.loadContext(MARSHALLING_CONTEXT);
317             m_name.genPushIndexPair(mb);
318         
319             // check type of marshalling behavior required
320
if (attr || needns) {
321             
322                 // check for namespace definition required
323
if (needns) {
324                 
325                     // marshal start tag with namespace(s)
326
m_defContext.genLoadNamespaces(mb);
327                     mb.appendCallVirtual(MARSHAL_WRITESTARTNAMESPACES,
328                         MARSHAL_STARTNAMESPACESSIGNATURE);
329                     
330                 } else {
331
332                     // marshal start tag with attribute(s)
333
mb.appendCallVirtual(MARSHAL_WRITESTARTATTRIBUTES,
334                         MARSHAL_WRITESTARTSIGNATURE);
335                 
336                 }
337             
338                 // handle attributes other than namespace declarations
339
if (attr) {
340                     if (!m_directAccess) {
341                         mb.appendSWAP();
342                     }
343                     m_component.genAttributeMarshal(mb);
344                     if (cont && m_directAccess) {
345                         mb.appendSWAP();
346                     }
347                 }
348     
349                 // generate code to close the start tag with another call
350
// to marshalling context
351
if (cont) {
352                     mb.appendCallVirtual(MARSHAL_CLOSESTARTCONTENT,
353                         MARSHAL_CLOSESTARTSIGNATURE);
354                 } else {
355                     mb.appendCallVirtual(MARSHAL_CLOSESTARTEMPTY,
356                         MARSHAL_CLOSESTARTSIGNATURE);
357                 }
358                 
359             } else if (cont) {
360             
361                 // marshal start tag without attributes
362
mb.appendCallVirtual(MARSHAL_WRITESTARTNOATTRIBUTES,
363                     MARSHAL_WRITESTARTSIGNATURE);
364             
365             } else {
366             
367                 // marshal empty tag
368
mb.appendCallVirtual(MARSHAL_WRITESTARTATTRIBUTES,
369                     MARSHAL_WRITESTARTSIGNATURE);
370                 mb.appendCallVirtual(MARSHAL_CLOSESTARTEMPTY,
371                     MARSHAL_CLOSESTARTSIGNATURE);
372             
373             }
374
375             // handle child content if present
376
if (cont) {
377                 if (!m_directAccess) {
378                     mb.appendSWAP();
379                 }
380                 m_component.genContentMarshal(mb);
381                 if (m_directAccess) {
382                     mb.loadContext(MARSHALLING_CONTEXT);
383                 }
384                 m_name.genPushIndexPair(mb);
385                 mb.appendCallVirtual(MARSHAL_WRITEENDMETHOD,
386                     MARSHAL_WRITEENDSIGNATURE);
387             }
388             
389             // finish by discarding extra copy of marshalling context from stack
390
if (!attr || (!cont && !m_directAccess) ||
391                 (m_structureObject && attr && cont)) {
392                 mb.appendPOP();
393             }
394         }
395     }
396     
397     public void genNewInstance(ContextMethodBuilder mb) throws JiBXException {
398         if (m_component == null) {
399             throw new IllegalStateException JavaDoc
400                 ("Internal error - no wrapped component");
401         } else {
402             m_component.genNewInstance(mb);
403         }
404     }
405
406     public String JavaDoc getType() {
407         if (m_component == null) {
408             throw new IllegalStateException JavaDoc
409                 ("Internal error - no wrapped component");
410         } else {
411             return m_component.getType();
412         }
413     }
414
415     public boolean hasId() {
416         if (m_component == null) {
417             return false;
418         } else {
419             return m_component.hasId();
420         }
421     }
422
423     public void genLoadId(ContextMethodBuilder mb) throws JiBXException {
424         if (m_component == null) {
425             throw new IllegalStateException JavaDoc
426                 ("Internal error - no wrapped component");
427         } else {
428             m_component.genLoadId(mb);
429         }
430     }
431
432     public boolean checkContentSequence(boolean text) throws JiBXException {
433         return true;
434     }
435
436     public void setLinkages() throws JiBXException {
437         m_name.fixNamespace(m_defContext);
438         if (m_component != null) {
439             m_component.setLinkages();
440         }
441     }
442     
443     // DEBUG
444
public void print(int depth) {
445         BindingDefinition.indent(depth);
446         System.out.println(toString());
447         if (m_component != null) {
448             m_component.print(depth+1);
449         }
450     }
451     
452     public String JavaDoc toString() {
453         StringBuffer JavaDoc buff = new StringBuffer JavaDoc("element wrapper");
454         if (m_name != null) {
455             buff.append(' ');
456             buff.append(m_name.toString());
457         }
458         if (m_directAccess) {
459             buff.append(" direct");
460         }
461         if (m_optionalIgnored) {
462             buff.append(" optional ignored");
463         }
464         if (m_optionalNormal) {
465             buff.append(" optional");
466         }
467         if (m_structureObject) {
468             buff.append(" structure object");
469         }
470         return buff.toString();
471     }
472 }
Popular Tags