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


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