Source Code Cross Referenced for SOAPDataEncoder.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » remote » swf » soap » encoding » 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 » Ajax » Laszlo 4.0.10 » org.openlaszlo.remote.swf.soap.encoding 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ****************************************************************************
002:         * SOAPDataEncoder.java
003:         *
004:         * Compile XML directly to SWF bytecodes.
005:         * ****************************************************************************/
006:
007:        /* J_LZ_COPYRIGHT_BEGIN *******************************************************
008:         * Copyright 2001-2007 Laszlo Systems, Inc.  All Rights Reserved.              *
009:         * Use is subject to license terms.                                            *
010:         * J_LZ_COPYRIGHT_END *********************************************************/
011:
012:        package org.openlaszlo.remote.swf.soap.encoding;
013:
014:        import java.io.*;
015:        import java.util.*;
016:        import java.util.Iterator;
017:
018:        import javax.xml.namespace.QName;
019:        import javax.xml.soap.Name;
020:        import javax.xml.soap.SOAPElement;
021:
022:        import org.openlaszlo.server.LPS;
023:        import org.openlaszlo.iv.flash.api.*;
024:        import org.openlaszlo.iv.flash.api.action.*;
025:        import org.openlaszlo.iv.flash.util.*;
026:        import org.openlaszlo.remote.swf.soap.LZSOAPUtils;
027:        import org.openlaszlo.utils.ChainedException;
028:        import org.openlaszlo.xml.internal.DataCommon;
029:        import org.openlaszlo.xml.internal.DataContext;
030:        import org.apache.axis.AxisFault;
031:        import org.apache.log4j.Logger;
032:        import org.xml.sax.*;
033:        import org.xml.sax.helpers.AttributesImpl;
034:
035:        import org.apache.axis.message.MessageElement;
036:        import org.apache.axis.message.SOAPHeader;
037:        import org.apache.axis.message.Text;
038:
039:        /**
040:         */
041:        public class SOAPDataEncoder implements  ContentHandler {
042:
043:            /* Logger */
044:            private static Logger mLogger = Logger
045:                    .getLogger(SOAPDataEncoder.class);
046:
047:            /** Hint to allocate buffer size large enough to hold output. */
048:            private int initsize = 0;
049:            private static final int DEFAULT_BUFFER_SIZE = 4096;
050:
051:            /** 
052:             * The SWF file
053:             */
054:            private FlashOutput mSWF = null;
055:            /**
056:             * Size of the SWF file.
057:             */
058:            private long mSize = -1;
059:
060:            private int mSWFVersion;
061:
062:            /**
063:             * Constructs an empty SOAPDataEncoder.
064:             */
065:            public SOAPDataEncoder(int swfversion) {
066:                mSWFVersion = swfversion;
067:            }
068:
069:            /**
070:             * Workaround variable for bug 4680.
071:             */
072:            boolean isProgram = false;
073:
074:            /**
075:             * Constructs a SOAPDataEncoder with a buffer allocation size hint.
076:             * @param initsize hint to allocate buffer size large enough to hold output.
077:             */
078:            public SOAPDataEncoder(int swfversion, int initsize) {
079:                this (swfversion);
080:                this .initsize = initsize;
081:            }
082:
083:            public SOAPDataEncoder(int swfversion, Vector v, SOAPHeader h) {
084:                this (swfversion);
085:                buildFromElements(v, h);
086:            }
087:
088:            public SOAPDataEncoder(int swfversion, Program p, SOAPHeader h) {
089:                this (swfversion);
090:                buildFromProgram(p, h);
091:            }
092:
093:            public SOAPDataEncoder buildFromFault(AxisFault fault) {
094:                start();
095:                String actor = fault.getFaultActor(); // can be null
096:                QName code = fault.getFaultCode(); // can be null
097:                String node = fault.getFaultNode(); // SOAP1.2
098:                String reason = fault.getFaultReason(); // SOAP1.2==SOAP1.1 faultstring
099:                String role = fault.getFaultRole(); // SOAP1.2==SOAP1.1 actor
100:                String faultstring = fault.getFaultString(); // never null
101:                QName[] subcodes = fault.getFaultSubCodes(); // can be null
102:                //         Element[] details  = fault.getFaultDetails(); // can be null
103:                //         ArrayList headers = fault.getHeaders();
104:
105:                int count = 0;
106:                if (subcodes != null) {
107:                    program.push("subcodes");
108:                    for (int i = 0; i < subcodes.length; i++) {
109:                        LZSOAPUtils.pushQName(program, subcodes[i], dc);
110:                    }
111:                    program.push(subcodes.length);
112:                    body.writeByte(Actions.InitArray);
113:                    count++;
114:                }
115:                if (actor != null) {
116:                    program.push("actor");
117:                    program.push(actor);
118:                    count++;
119:                }
120:                if (node != null) {
121:                    program.push("node");
122:                    program.push(node);
123:                    count++;
124:                }
125:                if (reason != null) {
126:                    program.push("reason");
127:                    program.push(reason);
128:                    count++;
129:                }
130:                if (role != null) {
131:                    program.push("role");
132:                    program.push(role);
133:                    count++;
134:                }
135:                if (faultstring != null) {
136:                    program.push("faultstring");
137:                    program.push(faultstring);
138:                    count++;
139:                }
140:                if (code != null) {
141:                    program.push("code");
142:                    LZSOAPUtils.pushQName(program, code, dc);
143:                    count++;
144:                }
145:
146:                program.push("errortype");
147:                program.push("fault");
148:
149:                program.push(count + 1);
150:                body.writeByte(Actions.InitObject);
151:                end();
152:
153:                return this ;
154:            }
155:
156:            public SOAPDataEncoder buildFromException(Exception e) {
157:                start();
158:                {
159:                    Throwable cause = e.getCause();
160:                    String message = e.getMessage();
161:                    StringWriter sw = new StringWriter();
162:                    e.printStackTrace(new PrintWriter(sw));
163:
164:                    int count = 3;
165:                    program.push("stacktrace");
166:                    program.push(sw.toString());
167:
168:                    program.push("faultString");
169:                    if (message != null) {
170:                        program.push(message);
171:                    } else {
172:                        program.push(sw.toString());
173:                    }
174:
175:                    if (cause != null) {
176:                        program.push("cause");
177:                        program.push(cause.toString());
178:                        count++;
179:                    }
180:
181:                    program.push("errortype");
182:                    program.push("exception");
183:
184:                    program.push(count);
185:
186:                    body.writeByte(Actions.InitObject);
187:                }
188:                end();
189:                return this ;
190:            }
191:
192:            //============================================================
193:            // SAX API
194:            //============================================================
195:
196:            /**
197:             * Receive notification of character data.
198:             *
199:             * @param ch the characters from the XML document.
200:             * @param start the start position in the array.
201:             * @param length the number of characters to read from the array.
202:             *
203:             * @see #characters(String) characters(String)
204:             */
205:            public void characters(char[] ch, int start, int length) {
206:                String text = new String(ch, start, length);
207:                characters(text);
208:            }
209:
210:            /**
211:             * Receive notification of string data.
212:             *
213:             * @param text the string from the XML document.
214:             *
215:             * @see #characters(char[], int, int) characters(char[], int, int)
216:             */
217:            public void characters(String text) {
218:                // makeTextNode = function (text, parent)
219:                // dup pointer to parent (who is at top of stack)
220:                // DUP
221:                body.writeByte(Actions.PushDuplicate);
222:                // Push text
223:
224:                body.writeByte(Actions.PushData);
225:                // Leave a two byte space for the PUSH length
226:                // Mark where we are, so we can rewrite this with correct length later.
227:                int push_bufferpos = body.getPos();
228:                body.writeWord(0); // placeholder 16-bit length field 
229:
230:                DataCommon.pushMergedStringData(text, body, dc);
231:                // Set up argsnum and function name
232:                // PUSH 2, _tdn
233:                body.writeByte(0x07); // INT type
234:                body.writeDWord(2); // '2' integer constant ; number of args to function
235:                body.writeByte(0x08); //  SHORT DICTIONARY LOOKUP
236:                body.writeByte(textnode_idx); // push function name: index of "_t" string constant
237:
238:                // Now go back and fix up the size arg to the PUSH instruction
239:                int total_size = body.getPos() - (push_bufferpos + 2);
240:                //System.out.println("pos="+body.getPos()+ " total_size = "+total_size+"  push_bufferpos="+push_bufferpos+" nattrs="+nattrs);
241:                body.writeWordAt(total_size, push_bufferpos);
242:
243:                body.writeByte(Actions.CallFunction);
244:                // Pop the node, because there will be no end tag for it, and it has no children.
245:                body.writeByte(Actions.Pop);
246:            }
247:
248:            /**
249:             * Receive notification of the end of an element. This method is equivalent
250:             * to calling {@link #endElement() endElement()} -- the input parameters are
251:             * ignored.
252:             *
253:             * @param uri the Namespace URI, or the empty string if the element has no
254:             * Namespace URI or if Namespace processing is not being performed.
255:             * @param localName the local name (without prefix), or the empty string if
256:             * Namespace processing is not being performed.
257:             * @param qName the qualified XML 1.0 name (with prefix), or the empty
258:             * string if qualified names are not available.
259:             * @see #endElement() endElement()
260:             */
261:            public void endElement(String uri, String localName, String qName) {
262:                // Pop the node off the stack. 
263:                body.writeByte(Actions.Pop);
264:            }
265:
266:            /**
267:             * Receive notification of the end of an element.
268:             *
269:             * @see #endElement(String,String,String) endElement(String,String,String)
270:             */
271:            public void endElement() {
272:                // Pop the node off the stack. 
273:                body.writeByte(Actions.Pop);
274:            }
275:
276:            /**
277:             * End the scope of a prefix-URI mapping. This method is unimplemented.
278:             *
279:             * @param prefix the prefix that was being mapped.
280:             */
281:            public void endPrefixMapping(String prefix) {
282:            }
283:
284:            /**
285:             * Receive notification of ignorable whitespace in element content. This
286:             * method is unimplemented.
287:             *
288:             * @param ch the characters from the XML document.
289:             * @param start the start position in the array.
290:             * @param length the number of characters to read from the array.
291:             */
292:            public void ignorableWhitespace(char[] ch, int start, int length) {
293:            }
294:
295:            /**
296:             * Receive notification of a processing instruction. This method is
297:             * unimplemented.
298:             *
299:             * @param target the processing instruction target.
300:             * @param data the processing instruction data, or null if none was
301:             * supplied. The data does not include any whitespace separating it from the
302:             * target.
303:             */
304:            public void processingInstruction(String target, String data) {
305:            }
306:
307:            /**
308:             * Receive an object for locating the origin of SAX document events. This
309:             * method is unimplemented.
310:             *
311:             * @param locator an object that can return the location of any SAX document
312:             * event.
313:             */
314:            public void setDocumentLocator(Locator locator) {
315:            }
316:
317:            /**
318:             * Receive notification of a skipped entity. This method is unimplemented.
319:             *
320:             * @param name the name of the skipped entity. If it is a parameter entity,
321:             * the name will begin with '%', and if it is the external DTD subset, it
322:             * will be the string "[dtd]".
323:             */
324:            public void skippedEntity(String name) {
325:            }
326:
327:            /** State vars */
328:            DataContext dc;
329:            // The node constructor function name. 
330:            private byte constructor_idx;
331:            private byte textnode_idx;
332:
333:            FlashBuffer body;
334:            Program program;
335:            Program resultProgram;
336:            FlashBuffer out;
337:
338:            public void start() {
339:                // Room at the end of the buffer for maybe some callback code to the runtime to say we're done.
340:                // Allocate enough room to hold the data nodes and strings ; it should be < input XML filesize
341:                body = new FlashBuffer(initsize == 0 ? DEFAULT_BUFFER_SIZE
342:                        : initsize);
343:                program = new Program(body);
344:                dc = new DataContext();
345:            }
346:
347:            public void end() {
348:                FlashBuffer body = program.body();
349:
350:                // Call into viewsystem
351:                program.push("_parent");
352:                program.getVar();
353:                program.push(3); // this, data, header
354:                program.push("_parent");
355:                program.getVar();
356:                program.push("loader");
357:                body.writeByte(Actions.GetMember);
358:                program.push("returnData");
359:                program.callMethod();
360:                program.pop();
361:
362:                // Collect the string dictionary data
363:                byte pooldata[] = DataCommon.makeStringPool(dc);
364:                // 'out' is the main FlashBuffer for composing the output file
365:                final int MISC = 64;
366:                out = new FlashBuffer(body.getSize() + pooldata.length + MISC);
367:                // Write out string constant pool
368:                out.writeByte(Actions.ConstantPool);
369:                out.writeWord(pooldata.length + 2); // number of bytes in pool data + int (# strings)
370:                out.writeWord(dc.cpool.size()); // number of strings in pool
371:                out.writeArray(pooldata, 0, pooldata.length); // copy the data
372:                // Write out the code to build nodes
373:                out.writeArray(body.getBuf(), 0, body.getSize());
374:                resultProgram = new Program(out);
375:            }
376:
377:            /**
378:             * Receive notification of the beginning of a document.
379:             *
380:             * @see #endDocument() endDocument()
381:             */
382:            public void startDocument() {
383:                start();
384:                constructor_idx = (byte) (DataCommon.addStringConstant(
385:                        DataCommon.NODE_INSTANTIATOR_FN, dc) & 0xFF);
386:                textnode_idx = (byte) (DataCommon.addStringConstant(
387:                        DataCommon.TEXT_INSTANTIATOR_FN, dc) & 0xFF);
388:
389:                // Bind the node creation functions to some short local names:
390:                //  element nodes: _root._m => _m
391:                program.push(new Object[] { "_m", "_root" });
392:                program.getVar();
393:                program.push("_m");
394:                body.writeByte(Actions.GetMember);
395:                program.setVar();
396:
397:                //  text nodes: _root._t => _t
398:                program.push(new Object[] { "_t", "_root" });
399:                program.getVar();
400:                program.push("_t");
401:                body.writeByte(Actions.GetMember);
402:                program.setVar();
403:            }
404:
405:            /**
406:             * Receive notification of the end of a document.
407:             *
408:             * @see #startDocument() startDocument()
409:             */
410:            public void endDocument() {
411:                end();
412:            }
413:
414:            /**
415:             * @return the Flash program to build the data set.
416:             */
417:            private Program getProgram() {
418:                return resultProgram;
419:            }
420:
421:            /**
422:             * Make SWF
423:             *
424:             * @return FlashFile containing entire SWF with header
425:             */
426:            private FlashFile makeSWFFile() {
427:                // Create FlashFile object nd include action bytes
428:                FlashFile file = FlashFile.newFlashFile();
429:                Script s = new Script(1);
430:                file.setMainScript(s);
431:                file.setVersion(mSWFVersion);
432:                Frame frame = s.newFrame();
433:                frame.addFlashObject(new DoAction(resultProgram));
434:                return file;
435:            }
436:
437:            /**
438:             * Get the compiled data swf program byte codes.  Only call this after you
439:             * have called {@link #endDocument endDocument()}.
440:             *
441:             * @return input stream containing the compiled SWF data program; only valid 
442:             * after {@link #endDocument endDocument()} has been called.  Must not be called
443:             * before {@link #endDocument endDocument()}.
444:             */
445:            public InputStream getInputStream() throws IOException {
446:
447:                generate();
448:                return mSWF.getInputStream();
449:            }
450:
451:            /**
452:             * Return the size of the output object; only valid after endDocument
453:             * {@link #endDocument endDocument()} has been called.  Must not be called
454:             * before {@link #endDocument endDocument()}.
455:             *
456:             * @return long representing the size
457:             */
458:            public long getSize() throws IOException {
459:
460:                generate();
461:                return mSize;
462:            }
463:
464:            /**
465:             * Generate the SWF file
466:             */
467:            private void generate() throws IOException {
468:
469:                if (mSWF == null) {
470:                    try {
471:                        InputStream input;
472:                        FlashFile file = makeSWFFile();
473:                        mSWF = file.generate();
474:                        mSize = mSWF.pos;
475:                    } catch (IVException ex) {
476:                        throw new ChainedException(ex);
477:                    }
478:                }
479:            }
480:
481:            /**
482:             * A lower level call than startElement(); attributes must be supplied by
483:             * individual calls to addAttribute(). This method is unimplemented.
484:             * @param localName the element name.
485:             */
486:            public void _startElement(String localName) {
487:
488:            }
489:
490:            /** 
491:             * A low level call to add an attribute, must be preceded by call to
492:             * _startElement() for a given element. This method is unimplemented.
493:             */
494:            public void addAttribute(String attrName, String attrVal) {
495:
496:            }
497:
498:            /**
499:             * Receive notification of the beginning of an element. This method is
500:             * equivalent to calling {@link #startElement(String, Attributes)
501:             * startElement(String, Attributes)} -- the uri and qName parameters are
502:             * ignored.
503:             *
504:             * @param uri the Namespace URI, or the empty string if the element has no
505:             * Namespace URI or if Namespace processing is not being performed.
506:             * @param localName the local name (without prefix), or the empty string if
507:             * Namespace processing is not being performed.
508:             * @param qName the qualified name (with prefix), or the empty string if
509:             * qualified names are not available.
510:             * @param atts the attributes attached to the element. If there are no
511:             * attributes, it shall be an empty Attributes object.
512:             *
513:             * @see #startElement(String, Attributes) startElement(String, Attributes)
514:             */
515:            public void startElement(String uri, String localName,
516:                    String qName, Attributes atts) {
517:                startElement(localName, atts);
518:            }
519:
520:            /**
521:             * Receive notification of the beginning of an element.
522:             *
523:             * @param localName the local name (without prefix), or the empty string if
524:             * Namespace processing is not being performed.
525:             * @param atts the attributes attached to the element. If there are no
526:             * attributes, it shall be an empty Attributes object.
527:             *
528:             * @see #startElement(String, String, String, Attributes)
529:             * startElement(String, String, String, Attributes)
530:             */
531:            public void startElement(String localName, Attributes atts) {
532:                int idx; // tmp var to hold a string pool index
533:                // makeNodeNoText = function (attrs, name, parent)
534:                // dup pointer to PARENT (who is at top of stack)
535:                // DUP
536:                body.writeByte(Actions.PushDuplicate);
537:
538:                // We're really squeezing things down, so we are going to merge 
539:                // the PUSH of the element name with the PUSH of the attribute key/value
540:                // data and the attribute count. So the stack will look like
541:                // [eltname attrname1 attrval1 attrname2 attrval2 ... ... nattrs]
542:                // when we're done
543:                body.writeByte(Actions.PushData);
544:                // Leave a two byte space for the PUSH length
545:                // Mark where we are, so we can rewrite this with correct length later.
546:                int push_bufferpos = body.getPos();
547:                body.writeWord(0); // placeholder 16-bit length field 
548:
549:                // Push element NAME
550:                String eltname = localName;
551:                DataCommon.pushMergedStringDataSymbol(eltname, body, dc);
552:
553:                // Fold all the attribute key/value pairs into a single PUSH
554:                // Build ATTRIBUTE object
555:                int nattrs = atts.getLength();
556:
557:                // PUSH := {0x96, lenlo, lenhi, 0x00, char, char, char, ...0x00, }
558:                for (int i = 0; i < nattrs; i++) {
559:                    String attrname = atts.getLocalName(i);
560:                    //System.out.print("Attr " + attrname);
561:                    DataCommon.pushMergedStringDataSymbol(attrname, body, dc);
562:
563:                    String attrval = atts.getValue(i);
564:                    //System.out.println("= " + attrval);
565:                    DataCommon.pushMergedStringData(attrval, body, dc);
566:                }
567:                // create the attrs object; push the attr count
568:                body.writeByte(0x07); // INT type
569:                body.writeDWord(nattrs);
570:                // Now go back and fix up the size arg to the PUSH instruction
571:                int total_size = body.getPos() - (push_bufferpos + 2);
572:                //System.out.println("pos="+body.getPos()+ " total_size = "+total_size+"  push_bufferpos="+push_bufferpos+" nattrs="+nattrs);
573:                body.writeWordAt(total_size, push_bufferpos);
574:                body.writeByte(Actions.InitObject);
575:
576:                // stack now has [parent, name, attrs]
577:                // Push # of args and node-instantiator-function name
578:                // PUSH 3, _mdn
579:                // [PUSHDATA, 7, 0,  0x07, 03 00 00 00 0x08, constructor_idx]
580:                body.writeByte(Actions.PushData);
581:                body.writeWord(7);
582:                body.writeByte(0x07); // INT type
583:                body.writeDWord(3); // '3' integer constant , number of args to node constructor fn
584:                body.writeByte(0x08); //  SHORT DICTIONARY LOOKUP type
585:                body.writeByte(constructor_idx); // index of "_m" string constant
586:                body.writeByte(Actions.CallFunction);
587:                // We leave the new node on the stack, so we can reference it as the parent 
588:                // Stack => [parentnode newnode]
589:            }
590:
591:            /**
592:             * Begin the scope of a prefix-URI Namespace mapping. This method is
593:             * unimplemented.
594:             *
595:             * @param prefix the Namespace prefix being declared.
596:             * @param uri the Namespace URI the prefix is mapped to.
597:             */
598:            public void startPrefixMapping(String prefix, String uri) {
599:            }
600:
601:            //============================================================
602:            // End SAX ContentHandler Compatibility
603:            //============================================================
604:
605:            private void buildHeaders(SOAPHeader h) {
606:                int hCount = 0;
607:                Iterator iter = h.getChildElements();
608:                while (iter.hasNext()) {
609:                    hCount++;
610:                    traverseDOM((SOAPElement) iter.next());
611:                }
612:                if (hCount != 0) {
613:                    program.push(hCount);
614:                    body.writeByte(Actions.InitArray);
615:                } else {
616:                    LZSOAPUtils.pushNull(body);
617:                }
618:            }
619:
620:            /**
621:             * Build from a vector of SOAPElement items.
622:             *
623:             * @param v vector of SOAPElement items.
624:             */
625:            public void buildFromElements(Vector v, SOAPHeader h) {
626:                startDocument();
627:
628:                // soap headers
629:                buildHeaders(h);
630:
631:                // array of documents
632:                for (int i = v.size() - 1; i >= 0; --i) {
633:                    traverseDOM((SOAPElement) v.get(i));
634:                }
635:                program.push(v.size());
636:                body.writeByte(Actions.InitArray);
637:
638:                endDocument();
639:            }
640:
641:            /**
642:             * Build from a vector of SOAPElement items.
643:             *
644:             * @param v vector of SOAPElement items.
645:             */
646:            public void buildFromProgram(Program p, SOAPHeader h) {
647:                // Workaround variable for bug 4680
648:                isProgram = true;
649:
650:                startDocument();
651:
652:                // soap headers
653:                buildHeaders(h);
654:
655:                // program
656:                if (p == null) {
657:                    LZSOAPUtils.pushNull(body);
658:                } else {
659:                    body.writeFOB(p.body());
660:                }
661:
662:                endDocument();
663:            }
664:
665:            /**
666:             * Traverse DOM for single SOAPElement.
667:             */
668:            private void traverseDOM(SOAPElement el) {
669:                // Build a root node by calling the runtime's root node instantiator
670:                // 
671:                // The root node will have $n = 0, and whatever other initial conditions are needed.
672:                program.push(0); // Root node creator function takes no args.
673:                program.push("_root");
674:                program.getVar();
675:                program.push(DataCommon.ROOT_NODE_INSTANTIATOR_FN);
676:                program.callMethod();
677:                // The root node is now on the stack.
678:                // Build data. Invariant is that it leaves the stack the way it found it.
679:
680:                AttributesImpl emptyAttr = new AttributesImpl();
681:                //         startElement("resultset", emptyAttr);
682:                //         startElement("body", emptyAttr);
683:
684:                // we're now set up for a single document...let's traverse the element
685:                _traverseDOM(el);
686:
687:                //         endElement();
688:                //         endElement();
689:
690:                // The root node is sitting on the stack. Finalize; bind the variable
691:                // "root" to the node that the lfc expects.
692:                program.push(1);
693:                program.push("_root");
694:                program.getVar();
695:                program.push(DataCommon.ROOT_NODE_FINAL_FN);
696:                program.callMethod();
697:            }
698:
699:            /**
700:             * Help traverse the DOM. Start point is traverseDOM().
701:             */
702:            private void _traverseDOM(SOAPElement el) {
703:                AttributesImpl attrs = new AttributesImpl();
704:                Iterator iter = el.getAllAttributes();
705:                while (iter.hasNext()) {
706:                    Name attrName = (Name) iter.next();
707:                    String attrValue = el.getAttributeValue(attrName);
708:                    attrs.addAttribute(attrName.getURI(), attrName
709:                            .getLocalName(), attrName.getQualifiedName(), "",
710:                            attrValue);
711:                }
712:
713:                Name elName = el.getElementName();
714:                startElement(elName.getLocalName(), attrs);
715:
716:                iter = el.getChildElements();
717:                while (iter.hasNext()) {
718:                    Object o = iter.next();
719:                    if (Text.class.isInstance(o)) {
720:                        // add text node
721:                        characters(((Text) o).getValue());
722:                    } else {
723:                        SOAPElement child = (SOAPElement) o;
724:                        _traverseDOM(child);
725:                    }
726:                }
727:
728:                endElement();
729:
730:            }
731:
732:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.