Source Code Cross Referenced for NestedCollection.java in  » XML » jibx-1.1.5 » org » jibx » binding » def » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » jibx 1.1.5 » org.jibx.binding.def 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.apache.bcel.generic.*;
032:
033:        import org.jibx.binding.classes.*;
034:        import org.jibx.runtime.JiBXException;
035:
036:        /**
037:         * Collection binding definition. This handles one or more child components,
038:         * which may be ordered or unordered.
039:         *
040:         * @author Dennis M. Sosnoski
041:         * @version 1.0
042:         */
043:        public class NestedCollection extends NestedBase {
044:            //
045:            // Method definitions used in code generation
046:
047:            private static final String GROWARRAY_METHOD = "org.jibx.runtime.Utility.growArray";
048:            private static final String GROWARRAY_SIGNATURE = "(Ljava/lang/Object;)Ljava/lang/Object;";
049:            private static final String RESIZEARRAY_METHOD = "org.jibx.runtime.Utility.resizeArray";
050:            private static final String RESIZEARRAY_SIGNATURE = "(ILjava/lang/Object;)Ljava/lang/Object;";
051:            private static final String CHECK_ISSTART_NAME = "org.jibx.runtime.impl.UnmarshallingContext.isStart";
052:            private static final String CHECK_ISSTART_SIGNATURE = "()Z";
053:            private static final String SKIP_ELEMENT_NAME = "org.jibx.runtime.impl.UnmarshallingContext.skipElement";
054:            private static final String SKIP_ELEMENT_SIGNATURE = "()V";
055:
056:            //
057:            // Actual instance data.
058:
059:            /** Fully qualified class name of values from collection. */
060:            private final String m_itemType;
061:
062:            /** Strategy for generating code to load item from collection. */
063:            private final CollectionLoad m_loadStrategy;
064:
065:            /** Strategy for generating code to store item to collection. */
066:            private final CollectionStore m_storeStrategy;
067:
068:            /** Optional component flag. */
069:            private final boolean m_isOptional;
070:
071:            /**
072:             * Constructor.
073:             *
074:             * @param parent containing binding definition context
075:             * @param objc current object context
076:             * @param ord ordered content flag
077:             * @param opt optional component flag
078:             * @param flex flexible element handling flag
079:             * @param type fully qualified class name of values from collection (may be
080:             * <code>null</code>, if child content present)
081:             * @param load collection load code generation strategy
082:             * @param store collection store code generation strategy
083:             */
084:            public NestedCollection(IContainer parent, IContextObj objc,
085:                    boolean ord, boolean opt, boolean flex, String type,
086:                    CollectionLoad load, CollectionStore store) {
087:                super (parent, objc, ord, flex, false);
088:                m_itemType = type;
089:                m_loadStrategy = load;
090:                m_storeStrategy = store;
091:                m_isOptional = opt;
092:            }
093:
094:            /**
095:             * Get the collection item type.
096:             * 
097:             * @return item type
098:             */
099:            public String getItemType() {
100:                return m_itemType;
101:            }
102:
103:            //
104:            // IComponent interface method definitions
105:
106:            public boolean hasAttribute() {
107:                return false;
108:            }
109:
110:            public void genAttrPresentTest(ContextMethodBuilder mb) {
111:                throw new IllegalStateException(
112:                        "Internal error - no attributes present");
113:            }
114:
115:            public void genAttributeUnmarshal(ContextMethodBuilder mb) {
116:                throw new IllegalStateException(
117:                        "Internal error - no attributes present");
118:            }
119:
120:            public void genAttributeMarshal(ContextMethodBuilder mb) {
121:                throw new IllegalStateException(
122:                        "Internal error - no attributes present");
123:            }
124:
125:            public boolean hasContent() {
126:                return m_contents.size() > 0;
127:            }
128:
129:            public void genContentUnmarshal(ContextMethodBuilder mb)
130:                    throws JiBXException {
131:                if (m_contents.size() > 0) {
132:
133:                    // set up common handling and check for ordered or unordered content
134:                    m_storeStrategy.genStoreInit(mb);
135:                    BranchWrapper link = null;
136:                    int count = m_contents.size();
137:                    if (m_isOrdered) {
138:
139:                        // just generate unmarshal code for each component in order
140:                        for (int i = 0; i < count; i++) {
141:
142:                            // start with branch target for loop and link from last type
143:                            if (link != null) {
144:                                mb.initStackState(link);
145:                            }
146:                            BranchTarget start = mb.appendTargetNOP();
147:                            if (link != null) {
148:                                link.setTarget(start, mb);
149:                            }
150:
151:                            // generate code to check if an element matching this
152:                            //  component type is present
153:                            IComponent child = (IComponent) m_contents.get(i);
154:                            child.genContentPresentTest(mb);
155:                            link = mb.appendIFEQ(this );
156:
157:                            // follow with code to unmarshal the component and store to
158:                            //  collection, ending with loop back to start of this
159:                            //  component
160:                            child.genContentUnmarshal(mb);
161:                            if (m_itemType != null
162:                                    && !ClassItem.isPrimitive(m_itemType)) {
163:                                mb.appendCreateCast(m_itemType);
164:                            }
165:                            m_storeStrategy.genStoreItem(mb);
166:                            mb.appendUnconditionalBranch(this ).setTarget(start,
167:                                    mb);
168:                        }
169:
170:                    } else {
171:
172:                        // generate unmarshal loop code that checks for each component,
173:                        //  branching to the next component until one is found and
174:                        //  exiting the loop only when no component is matched
175:                        BranchTarget first = mb.appendTargetNOP();
176:                        for (int i = 0; i < count; i++) {
177:                            if (link != null) {
178:                                mb.targetNext(link);
179:                            }
180:                            IComponent child = (IComponent) m_contents.get(i);
181:                            child.genContentPresentTest(mb);
182:                            link = mb.appendIFEQ(this );
183:                            child.genContentUnmarshal(mb);
184:                            if (m_itemType != null
185:                                    && !ClassItem.isPrimitive(m_itemType)) {
186:                                mb.appendCreateCast(m_itemType);
187:                            }
188:                            m_storeStrategy.genStoreItem(mb);
189:                            mb.appendUnconditionalBranch(this ).setTarget(first,
190:                                    mb);
191:                        }
192:
193:                        // handle fall through condition depending on flexible flag
194:                        if (m_isFlexible) {
195:
196:                            // exit loop if not positioned at element start
197:                            mb.targetNext(link);
198:                            mb.loadContext();
199:                            mb.appendCallVirtual(CHECK_ISSTART_NAME,
200:                                    CHECK_ISSTART_SIGNATURE);
201:                            link = mb.appendIFEQ(this );
202:
203:                            // ignore unknown element and loop back to start
204:                            mb.loadContext();
205:                            mb.appendCallVirtual(SKIP_ELEMENT_NAME,
206:                                    SKIP_ELEMENT_SIGNATURE);
207:                            mb.appendUnconditionalBranch(this ).setTarget(first,
208:                                    mb);
209:
210:                        }
211:                    }
212:
213:                    // patch final test failure branch to fall through loop
214:                    mb.targetNext(link);
215:                    m_storeStrategy.genStoreDone(mb);
216:
217:                } else {
218:                    throw new IllegalStateException(
219:                            "Internal error - no content present");
220:                }
221:            }
222:
223:            public void genContentMarshal(ContextMethodBuilder mb)
224:                    throws JiBXException {
225:                if (m_contents.size() > 0) {
226:
227:                    // set up common handling of unknown item and collection empty
228:                    BranchWrapper[] ifempties;
229:                    BranchWrapper link = null;
230:                    m_loadStrategy.genLoadInit(mb);
231:
232:                    // check for ordered or unordered content
233:                    int count = m_contents.size();
234:                    if (m_isOrdered) {
235:
236:                        // generate marshal code for each component type in order, with
237:                        //  an exception generated if the end of the possible component
238:                        //  list is reached with anything left in the collection
239:                        ifempties = new BranchWrapper[count];
240:                        for (int i = 0; i < count; i++) {
241:
242:                            // start generated code with loading next value from
243:                            //  collection
244:                            if (link != null) {
245:                                mb.initStackState(link, 1);
246:                            }
247:                            BranchTarget start = mb.appendTargetNOP();
248:                            ifempties[i] = m_loadStrategy.genLoadItem(mb);
249:                            mb.targetNext(link);
250:
251:                            // if multiple types are included in content, append code to
252:                            //  check if item type matches this component
253:                            IComponent child = (IComponent) m_contents.get(i);
254:                            String type = child.getType();
255:                            if (count > 1) {
256:                                mb.appendDUP();
257:                                mb.appendInstanceOf(type);
258:                                link = mb.appendIFEQ(this );
259:                            }
260:                            if ((!"java.lang.Object".equals(type) && !ClassItem
261:                                    .isPrimitive(type))) {
262:                                mb.appendCreateCast(type);
263:                            }
264:
265:                            // finish with code to marshal the component, looping back
266:                            //  to start of block for more of same type
267:                            child.genContentMarshal(mb);
268:                            mb.appendUnconditionalBranch(this ).setTarget(start,
269:                                    mb);
270:                        }
271:
272:                    } else {
273:
274:                        // generate marshal loop code that loads an item from the
275:                        //  collection and then checks to see if it matches a component
276:                        //  type, branching to the next component until a match is found
277:                        //  (or generating an exception on no match)
278:                        BranchTarget start = mb.appendTargetNOP();
279:                        ifempties = new BranchWrapper[1];
280:                        ifempties[0] = m_loadStrategy.genLoadItem(mb);
281:                        for (int i = 0; i < count; i++) {
282:
283:                            // start by setting target for branch from last component
284:                            mb.targetNext(link);
285:
286:                            // if multiple types are included in content, append code to
287:                            //  check if item type matches this component
288:                            IComponent child = (IComponent) m_contents.get(i);
289:                            String type = child.getType();
290:                            if (count > 1
291:                                    || (!"java.lang.Object".equals(type) && !ClassItem
292:                                            .isPrimitive(type))) {
293:                                mb.appendDUP();
294:                                mb.appendInstanceOf(type);
295:                                link = mb.appendIFEQ(this );
296:                                mb.appendCreateCast(type);
297:                            }
298:
299:                            // finish with code to marshal the component, branching back
300:                            //  to start of loop
301:                            child.genContentMarshal(mb);
302:                            mb.appendUnconditionalBranch(this ).setTarget(start,
303:                                    mb);
304:                        }
305:
306:                    }
307:
308:                    // patch final test failure branch to generate an exception
309:                    if (link != null) {
310:
311:                        // instruction sequence for exception is create new exception
312:                        //  object, build message in StringBuffer using type of item
313:                        //  from stack, convert StringBuffer to String, invoke the
314:                        //  exeception constructor with the String, and finally throw
315:                        //  the exception
316:                        mb.targetNext(link);
317:                        mb.appendCreateNew("java.lang.StringBuffer");
318:                        mb.appendDUP();
319:                        mb.appendLoadConstant("Collection item of type ");
320:                        mb.appendCallInit("java.lang.StringBuffer",
321:                                "(Ljava/lang/String;)V");
322:                        mb.appendSWAP();
323:                        mb.appendDUP();
324:                        BranchWrapper ifnull = mb.appendIFNULL(this );
325:                        mb.appendCallVirtual("java.lang.Object.getClass",
326:                                "()Ljava/lang/Class;");
327:                        mb.appendCallVirtual("java.lang.Class.getName",
328:                                "()Ljava/lang/String;");
329:                        BranchWrapper toend = mb
330:                                .appendUnconditionalBranch(this );
331:                        mb.targetNext(ifnull);
332:                        mb.appendPOP();
333:                        mb.appendLoadConstant("NULL");
334:                        mb.targetNext(toend);
335:                        mb.appendCallVirtual("java.lang.StringBuffer.append",
336:                                "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
337:                        mb.appendLoadConstant(" has no binding defined");
338:                        mb.appendCallVirtual("java.lang.StringBuffer.append",
339:                                "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
340:                        mb.appendCallVirtual("java.lang.StringBuffer.toString",
341:                                "()Ljava/lang/String;");
342:                        mb
343:                                .appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
344:                        mb.appendDUP_X1();
345:                        mb.appendSWAP();
346:                        mb.appendCallInit(
347:                                MethodBuilder.FRAMEWORK_EXCEPTION_CLASS,
348:                                MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1);
349:                        mb.appendThrow();
350:                    }
351:
352:                    // finish by setting target for collection empty case(s)
353:                    m_loadStrategy.genLoadDone(mb);
354:                    mb.targetNext(ifempties);
355:
356:                } else {
357:                    throw new IllegalStateException(
358:                            "Internal error - no content present");
359:                }
360:            }
361:
362:            public boolean hasId() {
363:                return false;
364:            }
365:
366:            public void genLoadId(ContextMethodBuilder mb) throws JiBXException {
367:                throw new IllegalStateException("No ID child");
368:            }
369:
370:            public NameDefinition getWrapperName() {
371:                return null;
372:            }
373:
374:            public boolean isOptional() {
375:                return m_isOptional;
376:            }
377:
378:            public void setLinkages() throws JiBXException {
379:                for (int i = 0; i < m_contents.size(); i++) {
380:                    ((IComponent) m_contents.get(i)).setLinkages();
381:                }
382:            }
383:
384:            // DEBUG
385:            public void print(int depth) {
386:                BindingDefinition.indent(depth);
387:                System.out.print("collection "
388:                        + (m_isOrdered ? "ordered" : "unordered"));
389:                if (m_itemType != null) {
390:                    System.out.print(" (" + m_itemType + ")");
391:                }
392:                if (isFlexible()) {
393:                    System.out.print(", flexible");
394:                }
395:                System.out.println();
396:                for (int i = 0; i < m_contents.size(); i++) {
397:                    IComponent comp = (IComponent) m_contents.get(i);
398:                    comp.print(depth + 1);
399:                }
400:            }
401:
402:            /**
403:             * Base class for collection item load strategy. The implementation class
404:             * must handle the appropriate form of code generation for the type of
405:             * collection being used.
406:             */
407:            /*package*/static abstract class CollectionBase {
408:                /** Double word value flag. */
409:                private final boolean m_isDoubleWord;
410:
411:                /**
412:                 * Constructor.
413:                 *
414:                 * @param doubword double word value flag
415:                 */
416:                protected CollectionBase(boolean doubword) {
417:                    m_isDoubleWord = doubword;
418:                }
419:
420:                /**
421:                 * Append the appropriate instruction to swap the top of the stack
422:                 * (which must be a single-word value) with an item value (which may
423:                 * be one or two words, as configured for this collection).
424:                 * 
425:                 * @param mb method
426:                 */
427:                protected void appendSWAP(MethodBuilder mb) {
428:                    if (m_isDoubleWord) {
429:                        mb.appendSWAP1For2();
430:                    } else {
431:                        mb.appendSWAP();
432:                    }
433:                }
434:
435:                /**
436:                 * Append the appropriate instruction to pop the item value (which may
437:                 * be one or two words, as configured for this collection) from the top
438:                 * of the stack.
439:                 * 
440:                 * @param mb method
441:                 */
442:                protected void appendPOP(MethodBuilder mb) {
443:                    if (m_isDoubleWord) {
444:                        mb.appendPOP2();
445:                    } else {
446:                        mb.appendPOP();
447:                    }
448:                }
449:            }
450:
451:            /**
452:             * Base class for collection item load strategy. The implementation class
453:             * must handle the appropriate form of code generation for the type of
454:             * collection being used.
455:             */
456:            /*package*/static abstract class CollectionLoad extends
457:                    CollectionBase {
458:                /**
459:                 * Constructor.
460:                 *
461:                 * @param add method used to add item to collection
462:                 * @param doubword double word value flag
463:                 * @param ret value returned by add flag
464:                 */
465:                protected CollectionLoad(boolean doubword) {
466:                    super (doubword);
467:                }
468:
469:                /**
470:                 * Generate code to initialize collection for loading items. This
471:                 * generates the necessary code for handling the initialization. It
472:                 * must be called before attempting to call the {@link #genLoadItem}
473:                 * method. The base class implementation does nothing.
474:                 *
475:                 * @param mb method builder
476:                 * @throws JiBXException if error in configuration
477:                 */
478:                protected void genLoadInit(ContextMethodBuilder mb)
479:                        throws JiBXException {
480:                }
481:
482:                /**
483:                 * Generate code to load next item from collection. This generates the
484:                 * necessary code for handling the load operation, leaving the item on
485:                 * the stack. The {@link #genLoadInit} method must be called before
486:                 * calling this method, and the {@link #genLoadDone} method must be
487:                 * called after the last call to this method. This method must be
488:                 * overridden by each subclass.
489:                 *
490:                 * @param mb method builder
491:                 * @return branch wrapper for case of done with collection
492:                 * @throws JiBXException if error in configuration
493:                 */
494:                protected abstract BranchWrapper genLoadItem(
495:                        ContextMethodBuilder mb) throws JiBXException;
496:
497:                /**
498:                 * Generate code to clean up after loading items from collection. This
499:                 * generates the necessary code for handling the clean up. It must be
500:                 * called after the last call to {@link #genLoadItem}. The base class
501:                 * implementation does nothing.
502:                 *
503:                 * @param mb method builder
504:                 * @throws JiBXException if error in configuration
505:                 */
506:                protected void genLoadDone(ContextMethodBuilder mb)
507:                        throws JiBXException {
508:                }
509:            }
510:
511:            /**
512:             * Base class for collection item store strategy. The implementation class
513:             * must handle the appropriate form of code generation for the type of
514:             * collection being used.
515:             */
516:            /*package*/static abstract class CollectionStore extends
517:                    CollectionBase {
518:                /**
519:                 * Constructor.
520:                 *
521:                 * @param doubword double word value flag
522:                 */
523:                protected CollectionStore(boolean doubword) {
524:                    super (doubword);
525:                }
526:
527:                /**
528:                 * Generate code to initialize collection for storing items. This
529:                 * generates the necessary code for handling the initialization,
530:                 * including creating the collection object if appropriate. It must be
531:                 * called before attempting to call the {@link #genStoreItem} method.
532:                 * The base class implementation does nothing.
533:                 *
534:                 * @param mb method builder
535:                 * @throws JiBXException if error in configuration
536:                 */
537:                protected void genStoreInit(ContextMethodBuilder mb)
538:                        throws JiBXException {
539:                }
540:
541:                /**
542:                 * Generate code to store next item to collection. This generates the
543:                 * necessary code for handling the store operation, removing the item
544:                 * from the stack. The {@link #genStoreInit} method must be called
545:                 * before calling this method, and the {@link #genStoreDone} method must
546:                 * be called after the last call to this method. This method must be
547:                 * overridden by each subclass.
548:                 *
549:                 * @param mb method builder
550:                 * @throws JiBXException if error in configuration
551:                 */
552:                protected abstract void genStoreItem(ContextMethodBuilder mb)
553:                        throws JiBXException;
554:
555:                /**
556:                 * Generate code to clean up after storing items to collection. This
557:                 * generates the necessary code for handling the clean up. It must be
558:                 * called after the last call to {@link #genStoreItem}. The base class
559:                 * implementation does nothing.
560:                 *
561:                 * @param mb method builder
562:                 * @throws JiBXException if error in configuration
563:                 */
564:                protected void genStoreDone(ContextMethodBuilder mb)
565:                        throws JiBXException {
566:                }
567:            }
568:
569:            /**
570:             * Collection item load strategy for collection with items accessed by
571:             * index number.
572:             */
573:            /*package*/static class IndexedLoad extends CollectionLoad {
574:                /** Method used to get count of items in collection. */
575:                private final ClassItem m_sizeMethod;
576:
577:                /** Method used to get items by index from collection. */
578:                private final ClassItem m_getMethod;
579:
580:                /**
581:                 * Constructor.
582:                 *
583:                 * @param size method used to get count of items in collection
584:                 * @param doubword double word value flag
585:                 * @param get method used to retrieve items by index from collection
586:                 */
587:                /*package*/IndexedLoad(ClassItem size, boolean doubword,
588:                        ClassItem get) {
589:                    super (doubword);
590:                    m_sizeMethod = size;
591:                    m_getMethod = get;
592:                }
593:
594:                protected void genLoadInit(ContextMethodBuilder mb)
595:                        throws JiBXException {
596:
597:                    // create index local with appended code to set initial value
598:                    mb.appendLoadConstant(-1);
599:                    mb.defineSlot(m_getMethod, Type.INT);
600:
601:                    // create size local with appended code to set initial value from
602:                    //  collection method call
603:                    if (!m_sizeMethod.isStatic()) {
604:                        mb.loadObject();
605:                    }
606:                    mb.appendCall(m_sizeMethod);
607:                    mb.defineSlot(m_sizeMethod, Type.INT);
608:                }
609:
610:                protected BranchWrapper genLoadItem(ContextMethodBuilder mb)
611:                        throws JiBXException {
612:
613:                    // start by getting local variable slots for the index and size
614:                    int islot = mb.getSlot(m_getMethod);
615:                    int sslot = mb.getSlot(m_sizeMethod);
616:
617:                    // append code to first increment index, then check for end of
618:                    //  collection reached
619:                    mb.appendIncrementLocal(1, islot);
620:                    mb.appendLoadLocal(islot);
621:                    mb.appendLoadLocal(sslot);
622:                    mb.appendISUB();
623:                    BranchWrapper ifempty = mb.appendIFGE(this );
624:
625:                    // finish by calling collection method to load item at current index
626:                    //  position
627:                    if (!m_getMethod.isStatic()) {
628:                        mb.loadObject();
629:                    }
630:                    mb.appendLoadLocal(islot);
631:                    mb.appendCall(m_getMethod);
632:                    return ifempty;
633:                }
634:
635:                protected void genLoadDone(ContextMethodBuilder mb)
636:                        throws JiBXException {
637:                    mb.freeSlot(m_getMethod);
638:                    mb.freeSlot(m_sizeMethod);
639:                }
640:            }
641:
642:            /**
643:             * Collection item store strategy for collection with items set by
644:             * index number.
645:             */
646:            /*package*/static class IndexedStore extends CollectionStore {
647:                /** Method used to set items by index in collection. */
648:                private final ClassItem m_setMethod;
649:
650:                /** Flag for method returns result. */
651:                private final boolean m_isReturned;
652:
653:                /**
654:                 * Constructor.
655:                 *
656:                 * @param set method used to store items by index in collection
657:                 * @param doubword double word value flag
658:                 * @param ret value returned by add flag
659:                 */
660:                /*package*/IndexedStore(ClassItem set, boolean doubword,
661:                        boolean ret) {
662:                    super (doubword);
663:                    m_setMethod = set;
664:                    m_isReturned = ret;
665:                }
666:
667:                protected void genStoreInit(ContextMethodBuilder mb)
668:                        throws JiBXException {
669:
670:                    // create index local with appended code to set initial value
671:                    mb.appendLoadConstant(-1);
672:                    mb.defineSlot(m_setMethod, Type.INT);
673:                }
674:
675:                protected void genStoreItem(ContextMethodBuilder mb)
676:                        throws JiBXException {
677:
678:                    // start by getting local variable slot for the index
679:                    int islot = mb.getSlot(m_setMethod);
680:
681:                    // append code to first load object and swap with item, then
682:                    //  increment index and swap copy with item, and finally call
683:                    //  collection method to store item at new index position
684:                    if (!m_setMethod.isStatic()) {
685:                        mb.loadObject();
686:                        appendSWAP(mb);
687:                    }
688:                    mb.appendIncrementLocal(1, islot);
689:                    mb.appendLoadLocal(islot);
690:                    appendSWAP(mb);
691:                    mb.appendCall(m_setMethod);
692:                    if (m_isReturned) {
693:                        appendPOP(mb);
694:                    }
695:                }
696:
697:                protected void genStoreDone(ContextMethodBuilder mb)
698:                        throws JiBXException {
699:                    mb.freeSlot(m_setMethod);
700:                }
701:            }
702:
703:            /**
704:             * Collection item load strategy for collection with items accessed by
705:             * iterator or enumeration.
706:             */
707:            /*package*/static class IteratorLoad extends CollectionLoad {
708:                /** Method used to get iterator for collection. */
709:                private final ClassItem m_iterMethod;
710:
711:                /** Fully qualified method name to test if more in iteration. */
712:                private final String m_moreName;
713:
714:                /** Fully qualified method name to get next item in iteration. */
715:                private final String m_nextName;
716:
717:                /**
718:                 * Constructor.
719:                 *
720:                 * @param iter method to get iterator or enumerator from collection
721:                 * @param doubword double word value flag
722:                 * @param more fully qualified method name to test if more in iteration
723:                 * @param next fully qualified method name to get next item in iteration
724:                 */
725:                /*package*/IteratorLoad(ClassItem iter, boolean doubword,
726:                        String more, String next) {
727:                    super (doubword);
728:                    m_iterMethod = iter;
729:                    m_moreName = more;
730:                    m_nextName = next;
731:                }
732:
733:                protected void genLoadInit(ContextMethodBuilder mb)
734:                        throws JiBXException {
735:
736:                    // create iterator local with appended code to set initial value
737:                    if (!m_iterMethod.isStatic()) {
738:                        mb.loadObject();
739:                    }
740:                    mb.appendCall(m_iterMethod);
741:                    mb.defineSlot(m_iterMethod, Type
742:                            .getType("Ljava/util/Iterator;"));
743:                }
744:
745:                protected BranchWrapper genLoadItem(ContextMethodBuilder mb)
746:                        throws JiBXException {
747:
748:                    // start with code to load and test iterator
749:                    int islot = mb.getSlot(m_iterMethod);
750:                    mb.appendLoadLocal(islot);
751:                    mb.appendCallInterface(m_moreName, "()Z");
752:                    BranchWrapper ifempty = mb.appendIFEQ(this );
753:
754:                    // append code to get next item from iterator
755:                    mb.appendLoadLocal(islot);
756:                    mb.appendCallInterface(m_nextName, "()Ljava/lang/Object;");
757:                    return ifempty;
758:                }
759:
760:                protected void genLoadDone(ContextMethodBuilder mb)
761:                        throws JiBXException {
762:                    mb.freeSlot(m_iterMethod);
763:                }
764:            }
765:
766:            /**
767:             * Collection item store strategy for collection with add method.
768:             */
769:            /*package*/static class AddStore extends CollectionStore {
770:                /** Method used to add item to collection. */
771:                private final ClassItem m_addMethod;
772:
773:                /** Flag for method returns result. */
774:                private final boolean m_isReturned;
775:
776:                /**
777:                 * Constructor.
778:                 *
779:                 * @param add method used to add item to collection
780:                 * @param doubword double word value flag
781:                 * @param ret value returned by add flag
782:                 */
783:                /*package*/AddStore(ClassItem add, boolean doubword,
784:                        boolean ret) {
785:                    super (doubword);
786:                    m_addMethod = add;
787:                    m_isReturned = ret;
788:                }
789:
790:                protected void genStoreItem(ContextMethodBuilder mb)
791:                        throws JiBXException {
792:
793:                    // append code to call collection method to add the item
794:                    if (!m_addMethod.isStatic()) {
795:                        mb.loadObject();
796:                        appendSWAP(mb);
797:                    }
798:                    mb.appendCall(m_addMethod);
799:                    if (m_isReturned) {
800:                        appendPOP(mb);
801:                    }
802:                }
803:            }
804:
805:            /**
806:             * Collection item load strategy for array.
807:             */
808:            /*package*/static class ArrayLoad extends CollectionLoad {
809:                /** Array item type. */
810:                private final String m_itemType;
811:
812:                /** Handle for referencing loop counter local variable. */
813:                private Object m_slotHandle = new Object();
814:
815:                /**
816:                 * Constructor.
817:                 *
818:                 * @param itype array item type
819:                 * @param doubword double word value flag
820:                 */
821:                /*package*/ArrayLoad(String itype, boolean doubword) {
822:                    super (doubword);
823:                    m_itemType = itype;
824:                }
825:
826:                protected void genLoadInit(ContextMethodBuilder mb)
827:                        throws JiBXException {
828:
829:                    // create index local with initial value -1
830:                    mb.appendLoadConstant(-1);
831:                    mb.defineSlot(m_slotHandle, Type.INT);
832:                }
833:
834:                protected BranchWrapper genLoadItem(ContextMethodBuilder mb)
835:                        throws JiBXException {
836:
837:                    // start by getting local variable slots for the index
838:                    int islot = mb.getSlot(m_slotHandle);
839:
840:                    // append code to first increment index, then check for end of
841:                    //  collection reached
842:                    mb.appendIncrementLocal(1, islot);
843:                    mb.appendLoadLocal(islot);
844:                    mb.loadObject();
845:                    mb.appendARRAYLENGTH();
846:                    mb.appendISUB();
847:                    BranchWrapper ifempty = mb.appendIFGE(this );
848:
849:                    // finish by loading array item at current index position
850:                    mb.loadObject();
851:                    mb.appendLoadLocal(islot);
852:                    mb.appendALOAD(m_itemType);
853:                    return ifempty;
854:                }
855:
856:                protected void genLoadDone(ContextMethodBuilder mb)
857:                        throws JiBXException {
858:                    mb.freeSlot(m_slotHandle);
859:                }
860:            }
861:
862:            /**
863:             * Collection item store strategy for array.
864:             */
865:            /*package*/static class ArrayStore extends CollectionStore {
866:                /** Array item type. */
867:                private final String m_itemType;
868:
869:                /**
870:                 * Constructor.
871:                 *
872:                 * @param itype array item type
873:                 * @param doubword double word value flag
874:                 */
875:                /*package*/ArrayStore(String itype, boolean doubword) {
876:                    super (doubword);
877:                    m_itemType = itype;
878:                }
879:
880:                protected void genStoreInit(ContextMethodBuilder mb)
881:                        throws JiBXException {
882:
883:                    // create index local with initial value -1
884:                    mb.appendLoadConstant(-1);
885:                    mb.defineSlot(m_itemType, Type.INT);
886:                }
887:
888:                protected void genStoreItem(ContextMethodBuilder mb)
889:                        throws JiBXException {
890:
891:                    // start by getting local variable slot for the index
892:                    int islot = mb.getSlot(m_itemType);
893:
894:                    // append code to first increment index and check array size
895:                    mb.appendIncrementLocal(1, islot);
896:                    mb.appendLoadLocal(islot);
897:                    mb.loadObject();
898:                    mb.appendARRAYLENGTH();
899:                    mb.appendISUB();
900:                    BranchWrapper ifnotfull = mb.appendIFLT(this );
901:
902:                    // grow the array size to make room for more values
903:                    mb.loadObject();
904:                    mb.appendCallStatic(GROWARRAY_METHOD, GROWARRAY_SIGNATURE);
905:                    mb.storeObject();
906:
907:                    // swap the array reference with the item, swap index with item, and
908:                    //  finally store item at new index position
909:                    mb.targetNext(ifnotfull);
910:                    mb.loadObject();
911:                    appendSWAP(mb);
912:                    mb.appendLoadLocal(islot);
913:                    appendSWAP(mb);
914:                    if (!ClassItem.isPrimitive(m_itemType)) {
915:                        mb.appendCreateCast(m_itemType);
916:                    }
917:                    mb.appendASTORE(m_itemType);
918:                }
919:
920:                protected void genStoreDone(ContextMethodBuilder mb)
921:                        throws JiBXException {
922:
923:                    // resize the array to match actual item count
924:                    int islot = mb.getSlot(m_itemType);
925:                    mb.appendIncrementLocal(1, islot);
926:                    mb.appendLoadLocal(islot);
927:                    mb.loadObject();
928:                    mb.appendCallStatic(RESIZEARRAY_METHOD,
929:                            RESIZEARRAY_SIGNATURE);
930:                    mb.storeObject();
931:                    mb.freeSlot(m_itemType);
932:                }
933:            }
934:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.