Source Code Cross Referenced for XMLAdapter.java in  » Web-Framework » cocoon » org » apache » cocoon » forms » util » 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 » cocoon » org.apache.cocoon.forms.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.forms.util;
018:
019:        import java.util.Iterator;
020:        import java.util.Locale;
021:
022:        import org.apache.cocoon.xml.AbstractXMLConsumer;
023:        import org.apache.cocoon.forms.datatype.Datatype;
024:        import org.apache.cocoon.forms.datatype.convertor.ConversionResult;
025:        import org.apache.cocoon.forms.formmodel.Action;
026:        import org.apache.cocoon.forms.formmodel.AggregateField;
027:        import org.apache.cocoon.forms.formmodel.BooleanField;
028:        import org.apache.cocoon.forms.formmodel.ContainerWidget;
029:        import org.apache.cocoon.forms.formmodel.DataWidget;
030:        import org.apache.cocoon.forms.formmodel.Form;
031:        import org.apache.cocoon.forms.formmodel.MultiValueField;
032:        import org.apache.cocoon.forms.formmodel.Repeater;
033:        import org.apache.cocoon.forms.formmodel.Widget;
034:        import org.apache.excalibur.xml.sax.XMLizable;
035:        import org.xml.sax.Attributes;
036:        import org.xml.sax.ContentHandler;
037:        import org.xml.sax.SAXException;
038:        import org.xml.sax.helpers.AttributesImpl;
039:
040:        /**
041:         * Adapter class that wraps a <code>Form</code> object and makes it
042:         * possible to populate a widget hierarchy from XML in form of SAX
043:         * events and serialize the content of the widget hierarchy as XML.
044:         *
045:         * <p>The XML format is such that there is one XML element for each
046:         * widget and the element get the widgets id as name. Exceptions from
047:         * this is that the elements in a repeater gets the name
048:         * <code>item</code> and a attribute <code>position</code> with the
049:         * position of the repeater child, instead of just a number (which is
050:         * not allowed as element name). Childs of a
051:         * <code>MultiValueField</code> are also embeded within a
052:         * <code>item</code> element. If the <code>Form</code> widget does
053:         * not have an id it get the name <code>uknown</code>.</p>
054:         *
055:         * <p>An <code>AggregateField</code> can both be interpreted as one value
056:         * and as several widgets. This ambiguity is resolved by chosing to emit
057:         * the single value rather than the fields as XML. For population of the
058:         * form both forms are however allowed.</p>
059:         *
060:         * @version $Id: XMLAdapter.java 451957 2006-10-02 10:33:13Z vgritsenko $
061:         */
062:        public class XMLAdapter extends AbstractXMLConsumer implements 
063:                XMLizable {
064:
065:            /** Name of element in list. */
066:            private final static String ITEM = "item";
067:            /** Name of unkown element. */
068:            private final static String UNKNOWN = "unknown";
069:            /** Name of position attribute in list. */
070:            private final static String POSITION = "position";
071:            /** The namespace prefix of this component. */
072:            private final static String PREFIX = "";
073:            /** The namespace URI of this component. */
074:            private final static String URI = "";
075:
076:            /** The <code>ContentHandler</code> receiving SAX events. */
077:            private ContentHandler contentHandler;
078:            /** The <code>Widget</code> to read and write XML to. */
079:            private Widget widget;
080:            /** The <code>Widget</code> that we are currently writing to. */
081:            private Widget currentWidget;
082:            /** The <code>Locale</code> that decides how to convert widget values to strings */
083:            private Locale locale;
084:            /** Is a <code>MultiValueField</code> handled? */
085:            private boolean isMultiValueItem;
086:            /** The buffer used to receive character events */
087:            private StringBuffer textBuffer;
088:
089:            /**
090:             * Wrap a <code>Form</code> with an <code>XMLAdapter</code>
091:             */
092:            public XMLAdapter(Widget widget) {
093:                this .widget = widget;
094:                this .locale = Locale.US;
095:            }
096:
097:            /**
098:             * Set the locale used for conversion between XML data and Java objects
099:             */
100:            public void setLocale(Locale locale) {
101:                this .locale = locale;
102:            }
103:
104:            /**
105:             * Get the locale used for conversion between XML data and Java objects
106:             */
107:            public Locale getLocale() {
108:                return this .locale;
109:            }
110:
111:            /* ================ SAX -> Widget ================ */
112:
113:            /*
114:             * The current state during handling of input events is described
115:             * by <code>currentWidget</code> that points to the widget that is
116:             * beeing populated. The state that the population has not began
117:             * yet or that it is finished is encoded by setting
118:             * <code>currentWidget</code> to <code>null</code> and the state of
119:             * being within a <code>item</code> within a
120:             * <code>MultiValueField</code> is encoded by setting the variable
121:             * <code>isMultiValueItem</code> to true.
122:             */
123:
124:            /**
125:             * Receive notification of the beginning of an element.
126:             *
127:             * @param uri The Namespace URI, or the empty string if the element has no
128:             *            Namespace URI or if Namespace
129:             *            processing is not being performed.
130:             * @param loc The local name (without prefix), or the empty string if
131:             *            Namespace processing is not being performed.
132:             * @param raw The raw XML 1.0 name (with prefix), or the empty string if
133:             *            raw names are not available.
134:             * @param a The attributes attached to the element. If there are no
135:             *          attributes, it shall be an empty Attributes object.
136:             */
137:            public void startElement(String uri, String loc, String raw,
138:                    Attributes a) throws SAXException {
139:                handleText();
140:
141:                if (this .currentWidget == null) {
142:                    // The name of the root element is ignored
143:                    this .currentWidget = this .widget;
144:
145:                } else if (this .currentWidget instanceof  ContainerWidget) {
146:                    Widget child = ((ContainerWidget) this .currentWidget)
147:                            .getChild(loc);
148:                    if (child == null) {
149:                        throw new SAXException("There is no widget with id: "
150:                                + loc + " as child to: "
151:                                + this .currentWidget.getId());
152:                    }
153:                    this .currentWidget = child;
154:
155:                } else if (this .currentWidget instanceof  Repeater) {
156:                    // In a repeater the XML elements are added in the order
157:                    // they are recieved, the position attribute is not used
158:                    if (!ITEM.equals(loc)) {
159:                        throw new SAXException(
160:                                "The element: "
161:                                        + loc
162:                                        + " is not allowed as a direct child of a Repeater");
163:                    }
164:                    Repeater repeater = (Repeater) currentWidget;
165:                    this .currentWidget = repeater.addRow();
166:
167:                } else if (this .currentWidget instanceof  MultiValueField) {
168:                    this .isMultiValueItem = true;
169:                    if (!ITEM.equals(loc)) {
170:                        throw new SAXException(
171:                                "The element: "
172:                                        + loc
173:                                        + " is not allowed as a direct child of a MultiValueField");
174:                    }
175:                }
176:            }
177:
178:            /**
179:             * Receive notification of the end of an element.
180:             *
181:             * @param uri The Namespace URI, or the empty string if the element has no
182:             *            Namespace URI or if Namespace
183:             *            processing is not being performed.
184:             * @param loc The local name (without prefix), or the empty string if
185:             *            Namespace processing is not being performed.
186:             * @param raw The raw XML 1.0 name (with prefix), or the empty string if
187:             *            raw names are not available.
188:             */
189:            public void endElement(String uri, String loc, String raw)
190:                    throws SAXException {
191:                handleText();
192:                if (this .currentWidget == null)
193:                    throw new SAXException("Wrong state");
194:
195:                String id = this .currentWidget.getId();
196:
197:                if (this .currentWidget instanceof  Form) {
198:                    this .currentWidget = null;
199:                    return;
200:                } else if (this .currentWidget instanceof  AggregateField) {
201:                    ((AggregateField) this .currentWidget).combineFields();
202:                } else if (this .currentWidget instanceof  Repeater.RepeaterRow) {
203:                    id = ITEM;
204:                } else if (this .currentWidget instanceof  MultiValueField
205:                        && loc.equals(ITEM)) {
206:                    this .isMultiValueItem = false;
207:                    return;
208:                }
209:
210:                if (loc.equals(id))
211:                    this .currentWidget = this .currentWidget.getParent();
212:                else
213:                    throw new SAXException("Unexpected element, was: " + loc
214:                            + " expected: " + id);
215:            }
216:
217:            /**
218:             * Receive notification of character data.
219:             *
220:             * @param ch The characters from the XML document.
221:             * @param start The start position in the array.
222:             * @param len The number of characters to read from the array.
223:             */
224:            public void characters(char ch[], int start, int len)
225:                    throws SAXException {
226:                // Buffer text, as a single text node can be sent in several chunks.
227:                if (this .textBuffer == null) {
228:                    this .textBuffer = new StringBuffer();
229:                }
230:                this .textBuffer.append(ch, start, len);
231:            }
232:
233:            /**
234:             * Handle text nodes, if any. Called on every potential text node boundary,
235:             * i.e. start and end element events.
236:             *
237:             * @throws SAXException
238:             */
239:            private void handleText() throws SAXException {
240:                if (this .textBuffer == null)
241:                    return;
242:
243:                String input = this .textBuffer.toString().trim();
244:                this .textBuffer = null; // clear buffer
245:                if (input.length() == 0)
246:                    return;
247:
248:                if (this .currentWidget instanceof  MultiValueField
249:                        && isMultiValueItem) {
250:                    MultiValueField field = (MultiValueField) this .currentWidget;
251:                    Datatype type = field.getDatatype();
252:                    ConversionResult conv = type.convertFromString(input,
253:                            this .locale);
254:                    if (!conv.isSuccessful()) {
255:                        throw new SAXException("Could not convert: " + input
256:                                + " to " + type.getTypeClass());
257:                    }
258:                    Object[] values = (Object[]) field.getValue();
259:                    int valLen = values == null ? 0 : values.length;
260:                    Object[] newValues = new Object[valLen + 1];
261:                    for (int i = 0; i < valLen; i++) {
262:                        newValues[i] = values[i];
263:                    }
264:                    newValues[valLen] = conv.getResult();
265:                    field.setValues(newValues);
266:                } else if (this .currentWidget instanceof  DataWidget) {
267:                    DataWidget data = (DataWidget) this .currentWidget;
268:                    Datatype type = data.getDatatype();
269:                    ConversionResult conv = type.convertFromString(input,
270:                            this .locale);
271:                    if (!conv.isSuccessful()) {
272:                        throw new SAXException("Could not convert: " + input
273:                                + " to " + type.getTypeClass());
274:                    }
275:                    data.setValue(conv.getResult());
276:                } else if (this .currentWidget instanceof  BooleanField) {
277:                    // FIXME: BooleanField should implement DataWidget, which
278:                    // would make this case unnecessary
279:                    if ("true".equals(input))
280:                        this .currentWidget.setValue(Boolean.TRUE);
281:                    else if ("false".equals(input))
282:                        this .currentWidget.setValue(Boolean.FALSE);
283:                    else
284:                        throw new SAXException("Unkown boolean: " + input);
285:                } else {
286:                    throw new SAXException("Unknown widget type: "
287:                            + this .currentWidget);
288:                }
289:            }
290:
291:            /* ================ Widget -> SAX ================ */
292:
293:            /*
294:             * Just recurses in deep first order over the widget hierarchy and
295:             * emits XML
296:             */
297:
298:            /**
299:             * Generates SAX events representing the object's state.
300:             */
301:            public void toSAX(ContentHandler handler) throws SAXException {
302:                this .contentHandler = handler;
303:
304:                this .contentHandler.startDocument();
305:                this .contentHandler.startPrefixMapping(PREFIX, URI);
306:
307:                generateSAX(this .widget);
308:
309:                this .contentHandler.endPrefixMapping(PREFIX);
310:                this .contentHandler.endDocument();
311:            }
312:
313:            /**
314:             * Generate XML data.
315:             */
316:            private void generateSAX(Widget widget) throws SAXException {
317:                generateSAX(widget, null);
318:            }
319:
320:            private void generateSAX(Widget widget, String id)
321:                    throws SAXException {
322:
323:                // no XML output for actions
324:                if (widget instanceof  Action)
325:                    return;
326:
327:                if (id == null)
328:                    id = widget.getId().length() == 0 ? UNKNOWN : widget
329:                            .getId();
330:
331:                final AttributesImpl attr = new AttributesImpl();
332:                if (widget instanceof  Repeater.RepeaterRow)
333:                    attribute(attr, POSITION, widget.getId());
334:
335:                start(id, attr);
336:                // Placing the handling DataWidget before ContainerWidget
337:                // means that an AggregateField is handled like a DataWidget
338:                if (widget instanceof  MultiValueField) {
339:                    Datatype datatype = ((MultiValueField) widget)
340:                            .getDatatype();
341:                    Object[] values = (Object[]) widget.getValue();
342:                    if (values != null)
343:                        for (int i = 0; i < values.length; i++) {
344:                            start(ITEM, attr);
345:                            data(datatype.convertToString(values[i],
346:                                    this .locale));
347:                            end(ITEM);
348:                        }
349:                } else if (widget instanceof  DataWidget) {
350:                    Datatype datatype = ((DataWidget) widget).getDatatype();
351:                    if (widget.getValue() != null)
352:                        data(datatype.convertToString(widget.getValue(),
353:                                this .locale));
354:                } else if (widget instanceof  BooleanField) {
355:                    // FIXME: BooleanField should implement DataWidget, which
356:                    // would make this case unnecessary
357:                    if (widget.getValue() != null) {
358:                        data(widget.getValue().toString());
359:                    }
360:                } else if (widget instanceof  ContainerWidget) {
361:                    Iterator children = ((ContainerWidget) widget)
362:                            .getChildren();
363:                    while (children.hasNext())
364:                        generateSAX((Widget) children.next());
365:                } else if (widget instanceof  Repeater) {
366:                    Repeater repeater = (Repeater) widget;
367:                    for (int i = 0; i < repeater.getSize(); i++)
368:                        generateSAX(repeater.getRow(i), ITEM);
369:                }
370:                end(id);
371:            }
372:
373:            private void attribute(AttributesImpl attr, String name,
374:                    String value) {
375:                attr.addAttribute("", name, name, "CDATA", value);
376:            }
377:
378:            private void start(String name, AttributesImpl attr)
379:                    throws SAXException {
380:                String qName = PREFIX == "" ? name : PREFIX + ":" + name;
381:                this .contentHandler.startElement(URI, name, qName, attr);
382:                attr.clear();
383:            }
384:
385:            private void end(String name) throws SAXException {
386:                String qName = PREFIX == "" ? name : PREFIX + ":" + name;
387:                this .contentHandler.endElement(URI, name, qName);
388:            }
389:
390:            private void data(String data) throws SAXException {
391:                this .contentHandler.characters(data.toCharArray(), 0, data
392:                        .length());
393:            }
394:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.