Source Code Cross Referenced for JOXBeanInput.java in  » XML » jox » com » wutka » jox » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


001:        package com.wutka.jox;
002:
003:        import java.beans.*;
004:        import java.io.*;
005:        import java.lang.reflect.*;
006:        import java.text.*;
007:        import java.util.*;
008:
009:        import javax.xml.parsers.*;
010:        import org.w3c.dom.*;
011:        import org.xml.sax.*;
012:
013:        /** Performs the actual reading of an XML document and copies the
014:         *  values into a bean. This class uses the DocumentBuilder portion
015:         *  of the Java XML API. It is not as efficient as SAX, but much easier
016:         *  to deal with when copying values into beans.
017:         *
018:         * @author Mark Wutka
019:         * @version 1.0 05/08/2000
020:         * @version 1.1 05/09/2000
021:         * @version 1.6 07/30/2000
022:         */
023:
024:        class JOXBeanInput {
025:            /** The document builder factory used to instantiate new document
026:             *  builders.
027:             */
028:            protected static DocumentBuilderFactory factory = DocumentBuilderFactory
029:                    .newInstance();
030:
031:            protected static Hashtable beanCache = new Hashtable();
032:
033:            /** Reads an XML document from an input source and copies its
034:             *  values into the specified object
035:             * @param ob The object to receive the values
036:             * @param source The location of the XML document
037:             * @throws IOException If there is an error reading the document
038:             */
039:            public void readObject(Object ob, InputSource source)
040:                    throws IOException {
041:                try {
042:                    // Create a document builder to read the document
043:                    DocumentBuilder builder = factory.newDocumentBuilder();
044:
045:                    // Read the document
046:                    Document doc = builder.parse(source);
047:
048:                    // Get the root element
049:                    Element element = doc.getDocumentElement();
050:
051:                    // Copy the root element into the bean
052:                    readObject(ob, element);
053:                } catch (SAXException exc) {
054:                    throw new IOException("Error parsing XML document: "
055:                            + exc.toString());
056:                } catch (ParserConfigurationException exc) {
057:                    throw new IOException("Error parsing XML document: "
058:                            + exc.toString());
059:                }
060:            }
061:
062:            /** Reads the children of an XML element and matches them to properties
063:             *  of a bean.
064:             * @param ob The bean to receive the values
065:             * @param element The element the corresponds to the bean
066:             * @throws IOException If there is an error reading the document
067:             */
068:            public void readObject(Object ob, Element element)
069:                    throws IOException {
070:                // If the object is null, skip the element
071:                if (ob == null) {
072:                    return;
073:                }
074:
075:                try {
076:                    BeanInfo info = (BeanInfo) beanCache.get(ob.getClass());
077:
078:                    if (info == null) {
079:                        // Get the bean info for the object
080:                        info = Introspector.getBeanInfo(ob.getClass(),
081:                                Object.class);
082:
083:                        beanCache.put(ob.getClass(), info);
084:                    }
085:
086:                    // Get the object's properties
087:                    PropertyDescriptor[] props = info.getPropertyDescriptors();
088:
089:                    // Get the attributes of the node
090:                    NamedNodeMap attrs = element.getAttributes();
091:
092:                    // Get the children of the XML element
093:                    NodeList nodes = element.getChildNodes();
094:
095:                    int numNodes = nodes.getLength();
096:
097:                    for (int i = 0; i < props.length; i++) {
098:                        // Treat indexed properties a little differently
099:                        if (props[i] instanceof  IndexedPropertyDescriptor) {
100:                            readIndexedProperty(ob,
101:                                    (IndexedPropertyDescriptor) props[i],
102:                                    nodes, attrs);
103:                        } else {
104:                            readProperty(ob, props[i], nodes, attrs);
105:                        }
106:                    }
107:                } catch (IntrospectionException exc) {
108:                    throw new IOException("Error getting bean info for "
109:                            + ob.getClass().getName() + ": " + exc.toString());
110:                }
111:            }
112:
113:            /** Reads an XML element into a bean property by first locating the
114:             *  XML element corresponding to this property.
115:             * @param ob The bean whose property is being set
116:             * @param desc The property that will be set
117:             * @param nodes The list of XML items that may contain the property
118:             * @throws IOException If there is an error reading the document
119:             */
120:            public void readProperty(Object ob, PropertyDescriptor desc,
121:                    NodeList nodes, NamedNodeMap attrs) throws IOException {
122:                int numAttrs = attrs.getLength();
123:
124:                for (int i = 0; i < numAttrs; i++) {
125:                    // See if the attribute name matches the property name
126:                    if (namesMatch(desc.getName(), attrs.item(i).getNodeName())) {
127:                        // Get the method used to set this property
128:                        Method setter = desc.getWriteMethod();
129:
130:                        // If this object has no setter, don't bother writing it
131:                        if (setter == null)
132:                            continue;
133:
134:                        // Get the value of the property
135:                        Object obValue = getObjectValue(desc, attrs.item(i)
136:                                .getNodeValue());
137:                        if (obValue != null) {
138:                            try {
139:                                // Set the property value
140:                                setter.invoke(ob, new Object[] { obValue });
141:                            } catch (InvocationTargetException exc) {
142:                                throw new IOException("Error setting property "
143:                                        + desc.getName() + ": "
144:                                        + exc.toString());
145:                            } catch (IllegalAccessException exc) {
146:                                throw new IOException("Error setting property "
147:                                        + desc.getName() + ": "
148:                                        + exc.toString());
149:                            }
150:                        }
151:
152:                        return;
153:                    }
154:                }
155:
156:                int numNodes = nodes.getLength();
157:
158:                Vector arrayBuild = null;
159:
160:                for (int i = 0; i < numNodes; i++) {
161:                    Node node = nodes.item(i);
162:
163:                    // If this node isn't an element, skip it
164:                    if (!(node instanceof  Element))
165:                        continue;
166:
167:                    Element element = (Element) node;
168:
169:                    // See if the tag name matches the property name
170:                    if (namesMatch(desc.getName(), element.getTagName())) {
171:                        // Get the method used to set this property
172:                        Method setter = desc.getWriteMethod();
173:
174:                        // If this object has no setter, don't bother writing it
175:                        if (setter == null)
176:                            continue;
177:
178:                        // Get the value of the property
179:                        Object obValue = getObjectValue(desc, element);
180:
181:                        // 070201 MAW: Modified from change submitted by Steve Poulson
182:                        if (setter.getParameterTypes()[0].isArray()) {
183:                            if (arrayBuild == null) {
184:                                arrayBuild = new Vector();
185:                            }
186:                            arrayBuild.addElement(obValue);
187:
188:                            // 070201 MAW: Go ahead and read through the rest of the nodes in case
189:                            //             another one matches the array. This has the effect of skipping
190:                            //             over the "return" statement down below
191:                            continue;
192:                        }
193:
194:                        if (obValue != null) {
195:                            try {
196:                                // Set the property value
197:                                setter.invoke(ob, new Object[] { obValue });
198:                            } catch (InvocationTargetException exc) {
199:                                throw new IOException("Error setting property "
200:                                        + desc.getName() + ": "
201:                                        + exc.toString());
202:                            } catch (IllegalAccessException exc) {
203:                                throw new IOException("Error setting property "
204:                                        + desc.getName() + ": "
205:                                        + exc.toString());
206:                            }
207:                        }
208:                        return;
209:                    }
210:                }
211:
212:                // If we build a vector of array members, convert the vector into
213:                // an array and save it in the property
214:                if (arrayBuild != null) {
215:                    // Get the method used to set this property
216:                    Method setter = desc.getWriteMethod();
217:
218:                    if (setter == null)
219:                        return;
220:
221:                    Object[] obValues = (Object[]) Array.newInstance(desc
222:                            .getPropertyType(), arrayBuild.size());
223:
224:                    arrayBuild.copyInto(obValues);
225:
226:                    try {
227:                        setter.invoke(ob, new Object[] { obValues });
228:                    } catch (InvocationTargetException exc) {
229:                        throw new IOException("Error setting property "
230:                                + desc.getName() + ": " + exc.toString());
231:                    } catch (IllegalAccessException exc) {
232:                        throw new IOException("Error setting property "
233:                                + desc.getName() + ": " + exc.toString());
234:                    }
235:
236:                    return;
237:                }
238:            }
239:
240:            /** Reads XML element(s) into an indexed bean property by first locating
241:             * the  XML element(s) corresponding to this property.
242:             * @param ob The bean whose property is being set
243:             * @param desc The property that will be set
244:             * @param nodes The list of XML items that may contain the property
245:             * @throws IOException If there is an error reading the document
246:             */
247:            public void readIndexedProperty(Object ob,
248:                    IndexedPropertyDescriptor desc, NodeList nodes,
249:                    NamedNodeMap attrs) throws IOException {
250:                // Create a vector to hold the property values
251:                Vector v = new Vector();
252:
253:                int numAttrs = attrs.getLength();
254:
255:                for (int i = 0; i < numAttrs; i++) {
256:                    // See if this attribute matches the property name
257:                    if (namesMatch(desc.getName(), attrs.item(i).getNodeName())) {
258:                        // Get the property value
259:                        Object obValue = getObjectValue(desc, attrs.item(i)
260:                                .getNodeValue());
261:
262:                        if (obValue != null) {
263:                            // Add the value to the list of values to be set
264:                            v.addElement(obValue);
265:                        }
266:                    }
267:                }
268:
269:                int numNodes = nodes.getLength();
270:
271:                for (int i = 0; i < numNodes; i++) {
272:                    Node node = nodes.item(i);
273:
274:                    // Skip non-element nodes
275:                    if (!(node instanceof  Element))
276:                        continue;
277:
278:                    Element element = (Element) node;
279:
280:                    // See if this element tag matches the property name
281:                    if (namesMatch(desc.getName(), element.getTagName())) {
282:                        // Get the property value
283:                        Object obValue = getObjectValue(desc, element);
284:
285:                        if (obValue != null) {
286:                            // Add the value to the list of values to be set
287:                            v.addElement(obValue);
288:                        }
289:                    }
290:                }
291:
292:                // Get the method used to set the property value
293:                Method setter = desc.getWriteMethod();
294:
295:                // If this property has no setter, don't write it
296:                if (setter == null)
297:                    return;
298:
299:                // Create a new array of property values
300:                Object propArray = Array.newInstance(desc.getPropertyType()
301:                        .getComponentType(), v.size());
302:
303:                // Copy the vector into the array
304:                v.copyInto((Object[]) propArray);
305:
306:                try {
307:                    // Store the array of property values
308:                    setter.invoke(ob, new Object[] { propArray });
309:                } catch (InvocationTargetException exc) {
310:                    throw new IOException("Error setting property "
311:                            + desc.getName() + ": " + exc.toString());
312:                } catch (IllegalAccessException exc) {
313:                    throw new IOException("Error setting property "
314:                            + desc.getName() + ": " + exc.toString());
315:                }
316:            }
317:
318:            /** Examines a property's type to see which method should be used
319:             *  to parse the property's value.
320:             * @param desc The description of the property
321:             * @param element The XML element containing the property value
322:             * @return The value stored in the element
323:             * @throws IOException If there is an error reading the document
324:             */
325:            public Object getObjectValue(PropertyDescriptor desc,
326:                    Element element) throws IOException {
327:                // Find out what kind of property it is
328:                Class type = desc.getPropertyType();
329:
330:                // If it's an array, get the base type 
331:                if (type.isArray()) {
332:                    type = type.getComponentType();
333:                }
334:
335:                // For native types, object wrappers for natives, and strings, use the
336:                // basic parse routine
337:                if (type.equals(Integer.TYPE) || type.equals(Long.TYPE)
338:                        || type.equals(Short.TYPE) || type.equals(Byte.TYPE)
339:                        || type.equals(Boolean.TYPE) || type.equals(Float.TYPE)
340:                        || type.equals(Double.TYPE)
341:                        || Integer.class.isAssignableFrom(type)
342:                        || Long.class.isAssignableFrom(type)
343:                        || Short.class.isAssignableFrom(type)
344:                        || Byte.class.isAssignableFrom(type)
345:                        || Boolean.class.isAssignableFrom(type)
346:                        || Float.class.isAssignableFrom(type)
347:                        || Double.class.isAssignableFrom(type)
348:                        || String.class.isAssignableFrom(type)) {
349:                    return readBasicType(type, element);
350:                } else if (java.util.Date.class.isAssignableFrom(type)) {
351:                    // If it's a date, use the date parser
352:                    return readDate(element);
353:                } else {
354:                    try {
355:                        // If it's an object, create a new instance of the object (it should
356:                        // be a bean, or there will be trouble)
357:                        Object newOb = type.newInstance();
358:
359:                        // Copy the XML element into the bean
360:                        readObject(newOb, element);
361:
362:                        return newOb;
363:                    } catch (InstantiationException exc) {
364:                        throw new IOException("Error creating object for "
365:                                + desc.getName() + ": " + exc.toString());
366:                    } catch (IllegalAccessException exc) {
367:                        throw new IOException("Error creating object for "
368:                                + desc.getName() + ": " + exc.toString());
369:                    }
370:                }
371:            }
372:
373:            /** Examines a property's type to see which method should be used
374:             *  to parse the property's value.
375:             * @param desc The description of the property
376:             * @param value The value of the XML attribute containing the prop value
377:             * @return The value stored in the element
378:             * @throws IOException If there is an error reading the document
379:             */
380:            public Object getObjectValue(PropertyDescriptor desc, String value)
381:                    throws IOException {
382:                // Find out what kind of property it is
383:                Class type = desc.getPropertyType();
384:
385:                // If it's an array, get the base type 
386:                if (type.isArray()) {
387:                    type = type.getComponentType();
388:                }
389:
390:                // For native types, object wrappers for natives, and strings, use the
391:                // basic parse routine
392:                if (type.equals(Integer.TYPE) || type.equals(Long.TYPE)
393:                        || type.equals(Short.TYPE) || type.equals(Byte.TYPE)
394:                        || type.equals(Boolean.TYPE) || type.equals(Float.TYPE)
395:                        || type.equals(Double.TYPE)
396:                        || Integer.class.isAssignableFrom(type)
397:                        || Long.class.isAssignableFrom(type)
398:                        || Short.class.isAssignableFrom(type)
399:                        || Byte.class.isAssignableFrom(type)
400:                        || Boolean.class.isAssignableFrom(type)
401:                        || Float.class.isAssignableFrom(type)
402:                        || Double.class.isAssignableFrom(type)) {
403:                    return parseBasicType(type, value);
404:                } else if (String.class.isAssignableFrom(type)) {
405:                    return value;
406:                } else if (java.util.Date.class.isAssignableFrom(type)) {
407:                    // If it's a date, use the date parser
408:                    return parseDate(value, JOXDateHandler
409:                            .determineDateFormat());
410:                } else {
411:                    return null;
412:                }
413:            }
414:
415:            /** Reads an XML text element into a basic type
416:             * @param type The type of the element to read
417:             * @param element The element containing the value
418:             * @return The parsed value of the element
419:             */
420:            public static Object readBasicType(Class type, Element element) {
421:                // Get the text corresponding to this element
422:                String str = getElementString(element);
423:
424:                // If there isn't any, don't parse
425:                if (str == null)
426:                    return null;
427:
428:                // If it's a string, don't need to do anything else
429:                if (String.class.isAssignableFrom(type))
430:                    return str;
431:
432:                return parseBasicType(type, str);
433:            }
434:
435:            /** Reads an string into a basic type
436:             * @param type The type of the string to read
437:             * @param str The string containing the value
438:             * @return The parsed value of the string
439:             */
440:            public static Object parseBasicType(Class type, String str) {
441:                // Parse the text based on the property type
442:
443:                if (type.equals(Integer.TYPE)
444:                        || Integer.class.isAssignableFrom(type)) {
445:                    return new Integer(str);
446:                } else if (type.equals(Long.TYPE)
447:                        || Long.class.isAssignableFrom(type)) {
448:                    return new Long(str);
449:                } else if (type.equals(Short.TYPE)
450:                        || Short.class.isAssignableFrom(type)) {
451:                    return new Short(str);
452:                } else if (type.equals(Byte.TYPE)
453:                        || Byte.class.isAssignableFrom(type)) {
454:                    return new Byte(str);
455:                } else if (type.equals(Boolean.TYPE)
456:                        || Boolean.class.isAssignableFrom(type)) {
457:                    return new Boolean(str);
458:                } else if (type.equals(Float.TYPE)
459:                        || Float.class.isAssignableFrom(type)) {
460:                    return new Float(str);
461:                } else if (type.equals(Double.TYPE)
462:                        || Double.class.isAssignableFrom(type)) {
463:                    return new Double(str);
464:                }
465:
466:                return null;
467:            }
468:
469:            /** Parses an XML element as a date
470:             * @param element The element containing the date
471:             * @return The date value parsed from the element
472:             * @throws IOException If there's an error parsing the date
473:             */
474:            public Object readDate(Element element) throws IOException {
475:                // Get the text corresponding to this element
476:                String str = getElementString(element);
477:                String fmt = element.getAttribute("format");
478:                if ("".equals(fmt)) {
479:                    return parseDate(str, JOXDateHandler.determineDateFormat());
480:                } else {
481:                    return parseDate(str, new SimpleDateFormat(fmt));
482:                }
483:            }
484:
485:            /** Parses a string as a date
486:             * @param str The string containing the date
487:             * @return The date value parsed from the string
488:             * @throws IOException If there's an error parsing the date
489:             */
490:            public Object parseDate(String str, DateFormat dateFormat)
491:                    throws IOException {
492:                // If there isn't any, don't parse
493:                if (str == null)
494:                    return null;
495:
496:                try {
497:                    return dateFormat.parse(str);
498:                } catch (ParseException exc) {
499:                    throw new IOException("Error parsing date " + str);
500:                }
501:            }
502:
503:            /** Searches the children of an element looking for a Text node. If
504:             * it finds one, it returns it.
505:             * @param element The element whose children will be searched
506:             * @return The text for the element, or null if there is none
507:             */
508:            public static String getElementString(Element element) {
509:                NodeList nodes = element.getChildNodes();
510:
511:                int numNodes = nodes.getLength();
512:
513:                for (int i = 0; i < numNodes; i++) {
514:                    Node node = nodes.item(i);
515:
516:                    if (node instanceof  Text) {
517:                        return ((Text) node).getData();
518:                    }
519:                }
520:
521:                return null;
522:            }
523:
524:            /** Returns true if two names match without regard to case or the
525:             *  presence of '-' or '_' characters.
526:             * @param beanName The name of the bean property to compare
527:             * @param elementName The name of the element to compare
528:             * @return True if the names match
529:             */
530:            public static boolean namesMatch(String beanName, String elementName) {
531:                int beanNameLen = beanName.length();
532:                int elementNameLen = elementName.length();
533:
534:                int elementPos = 0;
535:                int beanPos = 0;
536:
537:                // Keep looping until you hit the end of either of the strings
538:                while ((elementPos < elementNameLen) && (beanPos < beanNameLen)) {
539:                    // If the next character in the bean name is a '-' or a '/', skip it
540:                    char beanCh = Character.toLowerCase(beanName
541:                            .charAt(beanPos));
542:                    if ((beanCh == '-') || (beanCh == '_')) {
543:                        beanPos++;
544:                        continue;
545:                    }
546:
547:                    // If the next character in the element name is a '-' or a '/', skip it
548:                    char elementCh = Character.toLowerCase(elementName
549:                            .charAt(elementPos));
550:                    if ((elementCh == '-') || (elementCh == '_')) {
551:                        elementPos++;
552:                        continue;
553:                    }
554:
555:                    // If the characters don't match, the names don't match
556:                    if (elementCh != beanCh)
557:                        return false;
558:                    elementPos++;
559:                    beanPos++;
560:                }
561:
562:                // You hit the end of both names at the same time, the names match
563:                if ((elementPos == elementNameLen) && (beanPos == beanNameLen)) {
564:                    return true;
565:                }
566:
567:                return false;
568:            }
569:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.