KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.util.ArrayList JavaDoc;
32
33 import org.jibx.binding.classes.*;
34 import org.jibx.runtime.JiBXException;
35
36 /**
37  * Structure binding definition. This handles one or more child components,
38  * which may be ordered or unordered.
39  *
40  * @author Dennis M. Sosnoski
41  * @version 1.0
42  */

43
44 public class NestedStructure extends NestedBase
45 {
46     /** Child supplying ID for bound class. */
47     private IComponent m_idChild;
48     
49     /** Flag for structure has associated object. */
50     private final boolean m_hasObject;
51     
52     /** Flag for already linked (to avoid multiple passes). */
53     private boolean m_isLinked;
54
55     /**
56      * Constructor.
57      *
58      * @param parent containing binding definition context
59      * @param objc current object context
60      * @param ord ordered content flag
61      * @param ctx define context for structure flag
62      */

63
64     public NestedStructure(IContainer parent, IContextObj objc,
65         boolean ord, boolean ctx, boolean hasobj) {
66         super(parent, objc, ord, ctx);
67         m_hasObject = hasobj;
68     }
69     
70     //
71
// IComponent interface method definitions
72

73     public boolean hasAttribute() {
74         return m_attributes != null && m_attributes.size() > 0;
75     }
76
77     public void genAttrPresentTest(ContextMethodBuilder mb)
78         throws JiBXException {
79         if (m_attributes != null && m_attributes.size() > 0) {
80             
81             // if single possiblity just test it directly
82
int count = m_attributes.size();
83             if (count == 1) {
84                 ((IComponent)m_attributes.get(0)).genAttrPresentTest(mb);
85             } else {
86                 
87                 // generate code for chained test with branches to found exit
88
BranchWrapper[] tofound = new BranchWrapper[count];
89                 for (int i = 0; i < count; i++) {
90                     IComponent comp = (IComponent)m_attributes.get(i);
91                     comp.genAttrPresentTest(mb);
92                     tofound[i] = mb.appendIFNE(this);
93                 }
94                 
95                 // fall off end of loop to push "false" on stack and jump to end
96
mb.appendICONST_0();
97                 BranchWrapper toend = mb.appendUnconditionalBranch(this);
98                 
99                 // generate found target to push "true" on stack and continue
100
for (int i = 0; i < count; i++) {
101                     mb.targetNext(tofound[i]);
102                 }
103                 mb.appendICONST_1();
104                 mb.targetNext(toend);
105                 
106             }
107         } else {
108             throw new IllegalStateException JavaDoc
109                 ("Internal error - no attributes present");
110         }
111     }
112
113     public void genAttributeUnmarshal(ContextMethodBuilder mb)
114         throws JiBXException {
115         if (m_attributes != null && m_attributes.size() > 0) {
116             for (int i = 0; i < m_attributes.size(); i++) {
117                 IComponent attr = (IComponent)m_attributes.get(i);
118                 attr.genAttributeUnmarshal(mb);
119             }
120         } else {
121             throw new IllegalStateException JavaDoc
122                 ("Internal error - no attributes present");
123         }
124     }
125
126     public void genAttributeMarshal(ContextMethodBuilder mb)
127         throws JiBXException {
128         if (m_attributes != null && m_attributes.size() > 0) {
129             for (int i = 0; i < m_attributes.size(); i++) {
130                 IComponent attr = (IComponent)m_attributes.get(i);
131                 attr.genAttributeMarshal(mb);
132             }
133         } else {
134             throw new IllegalStateException JavaDoc
135                 ("Internal error - no attributes present");
136         }
137     }
138
139     public boolean hasContent() {
140         return m_contents.size() > 0;
141     }
142
143     public void genContentUnmarshal(ContextMethodBuilder mb)
144         throws JiBXException {
145         if (m_contents.size() > 0) {
146         
147             // check for ordered or unordered content
148
if (m_isOrdered) {
149             
150                 // just generate unmarshal code for each component in order
151
for (int i = 0; i < m_contents.size(); i++) {
152                     IComponent child = (IComponent)m_contents.get(i);
153                     child.genContentUnmarshal(mb);
154                 }
155                 
156             } else {
157             
158                 // generate unmarshal loop code that checks for each component,
159
// branching to the next component until one is found and
160
// exiting the loop only when no component is matched
161
BranchWrapper link = null;
162                 // TODO: initialize default values
163
BranchTarget first = mb.appendTargetNOP();
164                 for (int i = 0; i < m_contents.size(); i++) {
165                     if (link != null) {
166                         mb.targetNext(link);
167                     }
168                     IComponent child = (IComponent)m_contents.get(i);
169                     child.genContentPresentTest(mb);
170                     link = mb.appendIFEQ(this);
171                     child.genContentUnmarshal(mb);
172                     mb.appendUnconditionalBranch(this).setTarget(first, mb);
173                 }
174             
175                 // patch final test failure branch to fall through loop
176
mb.targetNext(link);
177             
178             }
179         } else {
180             throw new IllegalStateException JavaDoc
181                 ("Internal error - no content present");
182         }
183     }
184
185     public void genContentMarshal(ContextMethodBuilder mb)
186         throws JiBXException {
187         if (m_contents.size() > 0) {
188             for (int i = 0; i < m_contents.size(); i++) {
189                 IComponent content = (IComponent)m_contents.get(i);
190                 content.genContentMarshal(mb);
191             }
192         } else {
193             throw new IllegalStateException JavaDoc
194                 ("Internal error - no content present");
195         }
196     }
197
198     public String JavaDoc getType() {
199         if (m_hasObject) {
200             return super.getType();
201         } else if (m_attributes != null && m_attributes.size() > 0) {
202             return ((IComponent)m_attributes.get(0)).getType();
203         } else if (m_contents.size() > 0) {
204             return ((IComponent)m_contents.get(0)).getType();
205         } else {
206             throw new IllegalStateException JavaDoc("Internal error - " +
207                 "no type defined for structure");
208         }
209     }
210     
211     public boolean hasId() {
212         return m_idChild != null;
213     }
214     
215     public void genLoadId(ContextMethodBuilder mb) throws JiBXException {
216         if (m_idChild == null) {
217             throw new IllegalStateException JavaDoc("No ID child defined");
218         } else {
219             m_idChild.genLoadId(mb);
220         }
221     }
222
223     public boolean checkContentSequence(boolean text) throws JiBXException {
224         for (int i = 0; i < m_contents.size(); i++) {
225             IComponent content = (IComponent)m_contents.get(i);
226             text = content.checkContentSequence(text);
227         }
228         return text;
229     }
230
231     public void setLinkages() throws JiBXException {
232         if (!m_isLinked) {
233             
234             // set flag first in case of recursive reference
235
m_isLinked = true;
236         
237             // process all child components to link and sort by type
238
int i = 0;
239             while (i < m_contents.size()) {
240                 IComponent comp = (IComponent)m_contents.get(i);
241                 comp.setLinkages();
242                 if (comp.hasAttribute()) {
243                     if (m_attributes == null) {
244                         m_attributes = new ArrayList JavaDoc();
245                     }
246                     m_attributes.add(comp);
247                 }
248                 if (!comp.hasContent()) {
249                     m_contents.remove(i);
250                 } else {
251                     i++;
252                 }
253             }
254         }
255     }
256     
257     // DEBUG
258
public void print(int depth) {
259         BindingDefinition.indent(depth);
260         System.out.print("structure " +
261             (m_isOrdered ? "ordered" : "unordered"));
262         if (m_idChild != null) {
263             System.out.print(" (ID)");
264         }
265         System.out.println();
266         for (int i = 0; i < m_contents.size(); i++) {
267             IComponent comp = (IComponent)m_contents.get(i);
268             comp.print(depth+1);
269         }
270         if (m_attributes != null) {
271             for (int i = 0; i < m_attributes.size(); i++) {
272                 IComponent comp = (IComponent)m_attributes.get(i);
273                 comp.print(depth+1);
274             }
275         }
276     }
277 }
Popular Tags