Source Code Cross Referenced for DeSAXalizer.java in  » Web-Framework » RSF » uk » org » ponder » saxalizer » 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 » Web Framework » RSF » uk.org.ponder.saxalizer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package uk.org.ponder.saxalizer;
002:
003:        import java.io.ByteArrayOutputStream;
004:        import java.io.OutputStream;
005:        import java.util.ArrayList;
006:        import java.util.Enumeration;
007:        import java.util.Iterator;
008:        import java.util.List;
009:        import java.util.Map;
010:
011:        import uk.org.ponder.arrayutil.ListUtil;
012:        import uk.org.ponder.util.EnumerationConverter;
013:        import uk.org.ponder.util.Logger;
014:        import uk.org.ponder.util.UniversalRuntimeException;
015:        import uk.org.ponder.xml.XMLWriter;
016:
017:        /**
018:         * The DeSAXalizer takes a tree of Java objects and writes them to an XML
019:         * stream. Architectural note - this used to be a stateless class with only
020:         * static methods. This resulted in a slightly cleaner design since all state
021:         * alterations were transparent, but in the end the number of arguments to
022:         * internal methods began to snowball. Constructing a DeSAXalizer costs
023:         * virtually nothing in the modern world.
024:         */
025:        public class DeSAXalizer {
026:            // one of these objects is allocated in a stack for each tag level.
027:            static class SerialContext {
028:                Object object; // The object being serialised
029:                MethodAnalyser ma;
030:                // the current index through the get methods
031:                SAMIterator getenum;
032:                // enumeration for a vector tag, while enum is active, currentgetindex
033:                // progress
034:                // is suspended. enum will be set to null when it expires.
035:                Enumeration enumm;
036:                // The (original) tag name of the enum in progress
037:                // String enumtagname;
038:                String stashedclosingtag;
039:                boolean writtenchild = false;
040:
041:                SerialContext(Object object,
042:                        SAXalizerMappingContext mappingcontext) {
043:                    this .object = object;
044:                    this .ma = mappingcontext.getAnalyser(object.getClass());
045:                    // for generic objects, currentgetindex has an honorary value of -1
046:                    // representing
047:                    // getChildEnum()
048:                    // currentgetindex = object instanceof GenericSAX ? -1 : 0;
049:                    stashedclosingtag = null;
050:                    getenum = ma.tagmethods.getGetEnumeration();
051:                }
052:            }
053:
054:            // These five members constitute the state of the DeSAXalizer.
055:            // This is a Stack of serialcontexts.
056:            private List desaxingobjects;
057:
058:            public SerialContext getDeSAXingObject() {
059:                return (SerialContext) ListUtil.peek(desaxingobjects);
060:            }
061:
062:            private XMLWriter xmlw;
063:            private SAXalizerMappingContext mappingcontext;
064:            private DeSAXalizerForbidder forbidder = null;
065:
066:            public DeSAXalizer() {
067:                this (SAXalizerMappingContext.instance());
068:            }
069:
070:            public DeSAXalizer(SAXalizerMappingContext mappingcontext) {
071:                this .mappingcontext = mappingcontext;
072:            }
073:
074:            private int indentlevel;
075:
076:            public int getIndent() {
077:                return indentlevel == COMPACT_MODE ? COMPACT_MODE : indentlevel
078:                        + desaxingobjects.size();
079:            }
080:
081:            public void setForbidder(DeSAXalizerForbidder forbidder) {
082:                this .forbidder = forbidder;
083:            }
084:
085:            private void blastState() {
086:                xmlw = null;
087:                desaxingobjects.clear();
088:                forbidder = null;
089:            }
090:
091:            /**
092:             * Render a <code>DeSAXalizable</code> object as a string.
093:             * 
094:             * @param root The object to be rendered as a string.
095:             * @param roottag The root tag of the rendered tree
096:             * @return The supplied object rendered as a <code>String</code> of XML
097:             *         tags, minus declaration.
098:             */
099:
100:            public String toString(Object root, String roottag,
101:                    boolean compactmode) {
102:                ByteArrayOutputStream baos = new ByteArrayOutputStream();
103:                if (root == null)
104:                    return "null";
105:                try {
106:                    serializeSubtree(root, roottag, baos,
107:                            compactmode ? COMPACT_MODE : 0);
108:                    baos.close();
109:                    return baos.toString(XMLWriter.DEFAULT_ENCODING);
110:                } catch (Throwable t) {
111:                    throw UniversalRuntimeException.accumulate(t,
112:                            "Error writing object for " + roottag);
113:                }
114:            }
115:
116:            /**
117:             * Write a serialized representation of an object subtree as XML to an output
118:             * stream. This method DOES NOT close the supplied output stream.
119:             * 
120:             * @param root The root object of the tree to be serialized. Must implement
121:             *          the <code>DeSAXalizable</code> interface, as must all
122:             *          descendents, or have types registered with the
123:             *          <code>SAXLeafParser</code>.
124:             * @param roottag The tag to be supplied to the root object (all subobjects
125:             *          have their tags supplied through the <code>DeSAXalizable</code>
126:             *          interface.
127:             * @param os The output stream to receive the serialized data. The data will
128:             *          be written in UTF-8 format.
129:             */
130:
131:            public void serializeSubtree(Object root, String roottag,
132:                    OutputStream os) {
133:                serializeSubtree(root, roottag, os, 0);
134:            }
135:
136:            private void appendAttr(String attrname, Object attrvalue) {
137:                xmlw.writeRaw(" ");
138:                xmlw.writeRaw(attrname); // attribute names may not contain escapes
139:                xmlw.writeRaw("=\"");
140:                xmlw.write(mappingcontext.saxleafparser.render(attrvalue));
141:                xmlw.writeRaw("\"");
142:            }
143:
144:            private void renderAttrs(Object torender, SAMIterator getattrenum) {
145:                for (; getattrenum.valid(); getattrenum.next()) {
146:                    SAXAccessMethod getattr = getattrenum.get();
147:                    Object attrvalue = getattr.getChildObject(torender);
148:                    Logger.println("Attr " + getattr.tagname
149:                            + ": returned object " + attrvalue,
150:                            Logger.DEBUG_SUBATOMIC);
151:                    if (attrvalue != null) {
152:                        appendAttr(getattr.tagname, attrvalue);
153:                    }
154:                }
155:                // now find and write any extra attributes
156:                if (torender instanceof  SAXalizableExtraAttrs) {
157:                    Map extraattrs = ((SAXalizableExtraAttrs) torender)
158:                            .getAttributes();
159:                    if (extraattrs != null) {
160:                        Iterator attrs = extraattrs.keySet().iterator();
161:                        while (attrs.hasNext()) {
162:                            String attributename = (String) attrs.next();
163:                            String attributevalue = (String) extraattrs
164:                                    .get(attributename);
165:                            appendAttr(attributename, attributevalue);
166:                        }
167:                    }
168:                }
169:            }
170:
171:            private SerialContext writeOpeningTag(Object child,
172:                    String childtagname, SAXAccessMethod topgetmethod) {
173:                SerialContext top = null;
174:                try {
175:                    SerialContext oldtop = getDeSAXingObject();
176:                    if (oldtop != null && !oldtop.writtenchild) {
177:                        xmlw.writeRaw(">");
178:                        if (indentlevel != COMPACT_MODE) {
179:                            xmlw.writeRaw("\n");
180:                        }
181:                        oldtop.writtenchild = true;
182:                    }
183:
184:                    xmlw.writeRaw("<" + childtagname, getIndent());
185:                    String genericdata = null;
186:                    if (child instanceof  GenericSAX) {
187:                        GenericSAX generic = (GenericSAX) child;
188:                        SAXAccessMethodSpec[] getmethods = generic
189:                                .getSAXGetMethods();
190:                        // QQQQQ There may be getmethods defined by other means.
191:                        // Generic needs review!
192:                        if (generic.size() == 0
193:                                && (getmethods == null || getmethods.length == 0))
194:                            genericdata = generic.getData();
195:                    }
196:                    boolean isleaf = mappingcontext.saxleafparser
197:                            .isLeafType(child.getClass());
198:                    // TODO: It may be a leaf as a result of a parent class (ViewParameters)
199:                    top = isleaf ? null : new SerialContext(child,
200:                            mappingcontext);
201:                    // leaf is NOT DeSAXalizable OR we found some valid text
202:                    boolean closenow = (isleaf || genericdata != null);
203:                    Logger.println("Got generic data |" + genericdata + "|",
204:                            Logger.DEBUG_SUBATOMIC);
205:
206:                    if (closenow) {
207:                        // it is a leaf object
208:                        xmlw.writeRaw(">", 0);
209:                        // NB - 10/11/05 - final end of support for "Generic" objects. Check SVN
210:                        // should it ever need to come back.
211:                        // use leafparser to render it into text
212:                        if (genericdata == null) {
213:                            xmlw.write(mappingcontext.saxleafparser
214:                                    .render(child));
215:                        }
216:                        // use writeRaw so that < is not deentitised
217:                        xmlw.writeRaw("</" + childtagname + ">\n", 0);
218:                        top = null;
219:                    } else { // it is not a leaf object. writing it will require another pass
220:                        // around
221:                        Logger.println("Pushed", Logger.DEBUG_EXTRA_INFO);
222:                        String polynick = mappingcontext.classnamemanager
223:                                .getClassName(child.getClass());
224:                        if (polynick != null && topgetmethod != null
225:                                && topgetmethod.ispolymorphic) {
226:                            appendAttr(Constants.TYPE_ATTRIBUTE_NAME, polynick);
227:                        }
228:                        SAMIterator getattrenum = top.ma.attrmethods
229:                                .getGetEnumeration();
230:                        if (getattrenum.valid()
231:                                || child instanceof  SAXalizableExtraAttrs) {
232:                            Logger.println("Child has attributes",
233:                                    Logger.DEBUG_SUBATOMIC);
234:                            // renderinto.clear();
235:                            renderAttrs(child, getattrenum);
236:                            // xmlw.write(renderinto.storage, renderinto.offset, renderinto.size);
237:                        }
238:
239:                        // xmlw.writeRaw(">\n", 0);
240:                        desaxingobjects.add(top);
241:                    } // else not a leaf object
242:                } catch (Throwable t) {
243:                    throw UniversalRuntimeException.accumulate(t,
244:                            "Error while writing tag " + childtagname);
245:                }
246:                return top;
247:            }
248:
249:            /**
250:             * A value for indentlevel that will suppress writing of the XML declaration.
251:             */
252:            public static final int COMPACT_MODE = -1;
253:
254:            /**
255:             * Write a serialized representation of an object subtree as XML to an output
256:             * stream. This method DOES NOT close the supplied output stream.
257:             * 
258:             * @param root The root object of the tree to be serialized. Must implement
259:             *          the <code>DeSAXalizable</code> interface, as must all
260:             *          descendents, or have types registered with the
261:             *          <code>SAXLeafParser</code>.
262:             * @param roottag The tag to be supplied to the root object (all subobjects
263:             *          have their tags supplied through the <code>DeSAXalizable</code>
264:             *          interface.
265:             * @param os The output stream to receive the serialized data. The data will
266:             *          be written in UTF-8 format.
267:             * @param forbidder An interface through which clients may countermand the
268:             *          serialization of a particular subobject of the root. Each object
269:             *          and tag will be supplied to this interface before serialization.
270:             *          <code>null</code> if all objects to be serialized without
271:             *          restriction.
272:             * @param maxdepth If this is not -1, subobjects below this depth from the
273:             *          root will not be serialized.
274:             * @param indentlevel The initial indent level in the XML output file to be
275:             *          applied to the tag representing the root object. If this is not 0,
276:             *          an XML declaration will not be written to the file. If this is
277:             *          COMPACT_MODE, newlines and indentation will not be written.
278:             */
279:
280:            public void serializeSubtree(Object root, String roottagname,
281:                    OutputStream os, int indentlevel) {
282:                // Store the stack of desaxing objects locally, to avoid having to allocate
283:                // thread-local
284:                // desaxalizers. This is a stack of SerialContexts.
285:                desaxingobjects = new ArrayList();
286:                this .indentlevel = indentlevel;
287:
288:                try {
289:                    this .xmlw = new XMLWriter(os);
290:                    if (indentlevel == 0) {
291:                        xmlw.writeDeclaration();
292:                    }
293:                    SerialContext top = writeOpeningTag(root, roottagname, null);
294:                    SAXAccessMethod topgetmethod = null;
295:
296:                    // ONE ITERATION ROUND THE FOLLOWING LOOP CORRESPONDS TO ONE COMPLETE XML
297:                    // TAG
298:                    // at the top of this loop, the opening tag for the object on top of the
299:                    // stack has just been written.
300:                    Object child = null;
301:                    String childtagname = null;
302:                    while (true) {
303:                        // traverse downwards
304:                        if (Logger.passDebugLevel(Logger.DEBUG_EXTRA_INFO)) {
305:                            Logger.println("At top", Logger.DEBUG_EXTRA_INFO);
306:                        }
307:                        if (top.enumm == null && !top.getenum.valid()) {
308:                            // we have reached the last child node. pop the stack and write
309:                            // closing tag.
310:                            Logger.println("Popped", Logger.DEBUG_EXTRA_INFO);
311:                            boolean writtenchild = top.writtenchild;
312:                            ListUtil.pop(desaxingobjects);
313:
314:                            if (desaxingobjects.isEmpty())
315:                                break; // GLOBAL EXIT POINT
316:                            top = getDeSAXingObject();
317:                            xmlw.closeTag(top.stashedclosingtag, getIndent(),
318:                                    writtenchild);
319:                            continue;
320:                        } // end if pop required
321:
322:                        // Step 2: get the child object that the index on top of stack refers to
323:                        child = null;
324:                        topgetmethod = top.getenum.get();
325:                        childtagname = topgetmethod.tagname;
326:
327:                        // so long as the top object is not in an enum, get the enclosed object
328:                        if (top.enumm == null) {
329:                            child = topgetmethod.getChildObject(top.object);
330:
331:                            Logger.println("Object " + child
332:                                    + " delivered for tag "
333:                                    + topgetmethod.tagname,
334:                                    Logger.DEBUG_EXTRA_INFO);
335:
336:                            // if we discover it is an enum, begin chewing on it.
337:                            if (child != null && topgetmethod.ismultiple) {
338:                                top.enumm = EnumerationConverter
339:                                        .getEnumeration(child);
340:                            } else {
341:                                top.getenum.next();
342:                            }
343:                        }
344:                        Logger.println("About to check enum: childtagname is "
345:                                + childtagname, Logger.DEBUG_EXTRA_INFO);
346:                        // if the top object IS within an enum, see whether it has another
347:                        // element
348:                        if (top.enumm != null) {
349:                            if (top.enumm.hasMoreElements()) {
350:                                child = top.enumm.nextElement();
351:                                // if it is a GenericSAX enum, the tagname must be initialised with
352:                                // the value reported by the GenericSAX
353:                                if (child instanceof  GenericSAX) {
354:                                    childtagname = ((GenericSAX) child)
355:                                            .getTag();
356:                                }
357:                                // if it is a polymorphic enum, the tagname must be replaced with
358:                                // the actual object class
359:                                else if (topgetmethod.tagname.equals("*")) {
360:                                    childtagname = child.getClass().getName();
361:                                }
362:                                // otherwise, the value set from
363:                                // top.getmethods[top.currentgetindex].tagname is correct
364:                                Logger
365:                                        .println("Got next child " + child
366:                                                + " from enum",
367:                                                Logger.DEBUG_EXTRA_INFO);
368:                            } else { // the enum is finished, leave child null so that following
369:                                // branch will pass on
370:                                Logger.println("enum finished",
371:                                        Logger.DEBUG_EXTRA_INFO);
372:                                top.enumm = null;
373:                                top.getenum.next();
374:                                child = null; // this line deals with the case of 0-element
375:                                // enumerations
376:                            }
377:                        }
378:                        // Step 3: We have made all attempts to get a child object on this
379:                        // iteration - child will be null if there is simply no object to be
380:                        // delivered or an enum just finished. Otherwise, we have a child
381:                        // object and so write out its opening tag.
382:                        // If the child is a leaf object, we also write out the closing tag
383:                        // here.
384:                        if (child != null) {
385:                            top.stashedclosingtag = childtagname;
386:                            Logger.println("Tag name determined to be "
387:                                    + childtagname, Logger.DEBUG_EXTRA_INFO);
388:                            if ((forbidder == null || forbidder
389:                                    .permitSerialization(childtagname, child))
390:                            // maxdepth parameter removed - forbidders should do everything AMB
391:                            // 1/10/04
392:                            // && (maxdepth == -1 || desaxingobjects.size() <= maxdepth)
393:                            ) {
394:                                // Once we have got the child object, we can write the opening tag
395:                                // name. If it is a leaf, write closing tag as well.
396:                                SerialContext returnedtop = writeOpeningTag(
397:                                        child, childtagname, topgetmethod);
398:                                if (returnedtop != null)
399:                                    top = returnedtop;
400:                                // prettySpaces(desaxingobjects.size(), w);
401:                            } // end if the writing was not forbidden
402:                            else
403:                                Logger.println("Tag writing forbidden",
404:                                        Logger.DEBUG_EXTRA_INFO);
405:                        } // end if there was a child to write
406:                    } // end enormous loop
407:
408:                    xmlw.closeTag(roottagname, indentlevel, top.writtenchild);
409:                } finally {
410:                    if (xmlw != null) {
411:                        xmlw.close();
412:                    }
413:                    blastState();
414:                }
415:            } // end method serializeSubtree
416:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.