Source Code Cross Referenced for XMLConfiguration.java in  » J2EE » ow2-easybeans » org » ow2 » easybeans » xmlconfig » 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 » J2EE » ow2 easybeans » org.ow2.easybeans.xmlconfig 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * EasyBeans
003:         * Copyright (C) 2006-2007 Bull S.A.S.
004:         * Contact: easybeans@ow2.org
005:         *
006:         * This library is free software; you can redistribute it and/or
007:         * modify it under the terms of the GNU Lesser General Public
008:         * License as published by the Free Software Foundation; either
009:         * version 2.1 of the License, or any later version.
010:         *
011:         * This library is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         * Lesser General Public License for more details.
015:         *
016:         * You should have received a copy of the GNU Lesser General Public
017:         * License along with this library; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
019:         * USA
020:         *
021:         * --------------------------------------------------------------------------
022:         * $Id: XMLConfiguration.java 1970 2007-10-16 11:49:25Z benoitf $
023:         * --------------------------------------------------------------------------
024:         */package org.ow2.easybeans.xmlconfig;
025:
026:        import java.lang.reflect.InvocationTargetException;
027:        import java.lang.reflect.Method;
028:        import java.lang.reflect.ParameterizedType;
029:        import java.lang.reflect.Type;
030:        import java.net.URL;
031:        import java.util.ArrayList;
032:        import java.util.HashMap;
033:        import java.util.List;
034:        import java.util.Map;
035:
036:        import org.ow2.easybeans.util.xml.DocumentParser;
037:        import org.ow2.easybeans.util.xml.DocumentParserException;
038:        import org.ow2.easybeans.xmlconfig.mapping.AttributeMapping;
039:        import org.ow2.easybeans.xmlconfig.mapping.ClassMapping;
040:        import org.ow2.easybeans.xmlconfig.mapping.XMLMapping;
041:        import org.ow2.easybeans.xmlconfig.mapping.XMLMappingBuilder;
042:        import org.ow2.util.log.Log;
043:        import org.ow2.util.log.LogFactory;
044:        import org.w3c.dom.Document;
045:        import org.w3c.dom.Element;
046:        import org.w3c.dom.NamedNodeMap;
047:        import org.w3c.dom.Node;
048:        import org.w3c.dom.NodeList;
049:
050:        /**
051:         * XML configuration class that configure a given object with an xml
052:         * configuration file. <br>
053:         * Additional information will be searched on the namespace with the resource named easybeans-mapping.xml.
054:         * @author Florent Benoit
055:         */
056:        public class XMLConfiguration {
057:
058:            /**
059:             * Http:// namespace.
060:             */
061:            private static final String HTTP_NAMESPACE = "http://";
062:
063:            /**
064:             * By default, no validation.
065:             */
066:            private static final boolean VALIDATING_OFF = false;
067:
068:            /**
069:             * Per-Package mapping file name.
070:             */
071:            private static final String MAPPING_FILENAME = "easybeans-mapping.xml";
072:
073:            /**
074:             * Logger.
075:             */
076:            private Log logger = LogFactory.getLog(XMLConfiguration.class);
077:
078:            /**
079:             * Validating when parsing xml ?
080:             */
081:            private boolean validating = VALIDATING_OFF;
082:
083:            /**
084:             * URL of the configuration file.
085:             */
086:            private URL xmlConfigurationURL;
087:
088:            /**
089:             * Mapping between namespace and XMLMapping object.
090:             */
091:            private Map<String, XMLMapping> mappings = null;
092:
093:            /**
094:             * Link between name and the objects.
095:             */
096:            private HashMap<String, Object> configuredElements = null;
097:
098:            /**
099:             * Build an xml configuration with the given xml configuration file.
100:             * @param xmlConfigurationURL the given xml configuration file
101:             */
102:            public XMLConfiguration(final URL xmlConfigurationURL) {
103:                this .xmlConfigurationURL = xmlConfigurationURL;
104:                this .mappings = new HashMap<String, XMLMapping>();
105:                configuredElements = new HashMap<String, Object>();
106:            }
107:
108:            /**
109:             * Configure the given object with the configuration that was analyzed.
110:             * @param object the object to configure.
111:             * @throws XMLConfigurationException if configuration fails
112:             */
113:            public void configure(final Object object)
114:                    throws XMLConfigurationException {
115:                Element rootElement = analyzeXmlFile();
116:                configure(object, rootElement, null);
117:            }
118:
119:            /**
120:             * Gets the root element of the XML parsed file.
121:             * @return the element object
122:             * @throws XMLConfigurationException if analyze fails.
123:             */
124:            private Element analyzeXmlFile() throws XMLConfigurationException {
125:                // Parse the XML file and build all configuration process.
126:                Document xmlConfigurationDocument = null;
127:                try {
128:                    xmlConfigurationDocument = DocumentParser.getDocument(
129:                            xmlConfigurationURL, validating, null);
130:                } catch (DocumentParserException e) {
131:                    throw new XMLConfigurationException(
132:                            "Cannot get a document on the given url '"
133:                                    + xmlConfigurationURL + "'.", e);
134:                }
135:
136:                // Get the root element
137:                Element rootElement = xmlConfigurationDocument
138:                        .getDocumentElement();
139:
140:                // get namespace of the element
141:                String nameSpace = rootElement.getNamespaceURI();
142:                // and the name
143:                // String nodeName = rootElement.getNodeName();
144:
145:                // init mapping for the element
146:                getXMLMapping(nameSpace);
147:
148:                return rootElement;
149:
150:            }
151:
152:            /**
153:             * Is that the given name should be considered as an XML element (and read the value of this element).
154:             * @param name the given name
155:             * @param classMapping the mapping used to get the info
156:             * @return true if the name should be read from the XML element.
157:             */
158:            public boolean isElementMapping(final String name,
159:                    final ClassMapping classMapping) {
160:                AttributeMapping attributeMapping = classMapping
161:                        .getAttributeMapping(name);
162:                if (attributeMapping != null) {
163:                    return attributeMapping.isElement();
164:                }
165:                return false;
166:            }
167:
168:            /**
169:             * Is that the given name should be used with a list.
170:             * @param name the given name
171:             * @param classMapping the mapping used to get the info
172:             * @return true if the name should be used as a list.
173:             */
174:            public boolean isListElement(final String name,
175:                    final ClassMapping classMapping) {
176:                AttributeMapping attributeMapping = classMapping
177:                        .getAttributeMapping(name);
178:                if (attributeMapping != null) {
179:                    return attributeMapping.isListElement();
180:                }
181:                return false;
182:            }
183:
184:            /**
185:             * Configure the given object by looking at the element (of the
186:             * configuration).
187:             * @param object the given object to configure.
188:             * @param element the element that contains configuration.
189:             * @param parentClassMapping the parent class mapping
190:             * @throws XMLConfigurationException if configuration fails
191:             */
192:            public void configure(final Object object, final Element element,
193:                    final ClassMapping parentClassMapping)
194:                    throws XMLConfigurationException {
195:
196:                // Get all children of the given element
197:                NodeList nodeList = element.getChildNodes();
198:
199:                // For each element, create object and configure it
200:                int length = nodeList.getLength();
201:                for (int i = 0; i < length; i++) {
202:                    Node node = nodeList.item(i);
203:
204:                    // Get an element, create an instance of the element
205:                    if (Node.ELEMENT_NODE == node.getNodeType()) {
206:
207:                        // Is it an element that need to be considered as a string value
208:                        if (parentClassMapping != null
209:                                && isElementMapping(node.getNodeName(),
210:                                        parentClassMapping)) {
211:                            // Get value
212:                            Node txtNode = node.getFirstChild();
213:                            String val = null;
214:                            if (txtNode != null) {
215:                                val = txtNode.getNodeValue();
216:                            }
217:
218:                            // Do nothing if value is null
219:                            if (val == null) {
220:                                continue;
221:                            }
222:
223:                            // Call setter directly
224:                            if (!isListElement(node.getNodeName(),
225:                                    parentClassMapping)) {
226:                                setAttribute(object, node.getNodeName(), val,
227:                                        parentClassMapping);
228:                            } else {
229:                                // Need to call the getters and setters
230:                                addSetElement(object, val, node.getNodeName(),
231:                                        parentClassMapping);
232:                            }
233:                            continue;
234:                        }
235:                        ClassMapping classMapping = getClassMapping(node
236:                                .getNamespaceURI(), node.getNodeName());
237:
238:                        // Build an object for the given class mapping
239:                        Object newObject = newInstance(node, classMapping);
240:
241:                        // Try to see if there is a value for the current object
242:                        Method getterMethod = findSingleGetterMethod(object,
243:                                newObject);
244:                        if (getterMethod != null) {
245:                            // Call the getter method
246:                            logger.debug("Calling method {0} on object {1}",
247:                                    getterMethod, object);
248:                            Object getterObject = null;
249:                            try {
250:                                getterObject = getterMethod.invoke(object);
251:                            } catch (IllegalArgumentException e) {
252:                                throw new XMLConfigurationException(
253:                                        "Cannot call method '" + getterMethod
254:                                                + "' on object '" + object
255:                                                + "'.", e);
256:                            } catch (IllegalAccessException e) {
257:                                throw new XMLConfigurationException(
258:                                        "Cannot call method '" + getterMethod
259:                                                + "' on object '" + object
260:                                                + "'.", e);
261:                            } catch (InvocationTargetException e) {
262:                                throw new XMLConfigurationException(
263:                                        "Cannot call method '" + getterMethod
264:                                                + "' on object '" + object
265:                                                + "'.", e);
266:                            }
267:
268:                            // find an object ?
269:                            if (getterObject != null) {
270:                                // yes, then use the existing object
271:                                newObject = getterObject;
272:                            }
273:                        }
274:
275:                        // Set attributes
276:                        setAttributes((Element) node, newObject, classMapping);
277:
278:                        // add or set element on the given object
279:                        addSetElement(object, newObject, node.getNodeName(),
280:                                classMapping);
281:
282:                        // Store element
283:                        configuredElements.put(node.getNodeName(), newObject);
284:
285:                        // configure sub element of the new object.
286:                        configure(newObject, (Element) node, classMapping);
287:                    }
288:                }
289:            }
290:
291:            /**
292:             * Sets the attributes on the given object.
293:             * @param node the XML element object
294:             * @param object the object to configure
295:             * @param classMapping the mapping data
296:             * @throws XMLConfigurationException if the attributes cannot be set
297:             */
298:            protected void setAttributes(final Element node,
299:                    final Object object, final ClassMapping classMapping)
300:                    throws XMLConfigurationException {
301:                // Set attributes
302:                NamedNodeMap attributes = node.getAttributes();
303:                int attributesLength = attributes.getLength();
304:                for (int a = 0; a < attributesLength; a++) {
305:                    Node nodeAttribute = attributes.item(a);
306:                    if (nodeAttribute.getNamespaceURI() == null) {
307:                        String propertyName = nodeAttribute.getNodeName();
308:                        String propertyValue = nodeAttribute.getNodeValue();
309:                        setAttribute(object, propertyName, propertyValue,
310:                                classMapping);
311:                    }
312:                }
313:
314:                // this element is configured to have a value mapped to an attribute ?
315:                String elementAttribute = classMapping.getElementAttribute();
316:                if (elementAttribute != null) {
317:                    // Get value
318:                    Node txtNode = node.getFirstChild();
319:                    String val = null;
320:                    if (txtNode != null) {
321:                        val = txtNode.getNodeValue();
322:                    }
323:                    setAttribute(object, elementAttribute, val, classMapping);
324:                }
325:            }
326:
327:            /**
328:             * Gets the Mapping for the given nameSpaceURI and the given classname.
329:             * @param nameSpaceURI the namespace of the xml element
330:             * @param name the name of the class
331:             * @return the class mapping object
332:             * @throws XMLConfigurationException if no configuration is found
333:             */
334:            private ClassMapping getClassMapping(final String nameSpaceURI,
335:                    final String name) throws XMLConfigurationException {
336:                // Get classname with the namespace and alias
337:                XMLMapping xmlMapping = mappings.get(nameSpaceURI);
338:                if (xmlMapping == null) {
339:                    // Not yet encountered namespace. Try to get a mapping for it.
340:                    xmlMapping = getXMLMapping(nameSpaceURI);
341:                    if (xmlMapping == null) {
342:                        // Still not found.
343:                        throw new XMLConfigurationException(
344:                                "No mapping found for namespace '"
345:                                        + nameSpaceURI + "'.");
346:                    }
347:                }
348:
349:                // alias present ?
350:                ClassMapping classMapping = xmlMapping.getClassMapping(name);
351:
352:                // no mapping
353:                if (classMapping == null) {
354:                    throw new XMLConfigurationException(
355:                            "No class found for element '" + name
356:                                    + "' withing xmlmapping '" + xmlMapping
357:                                    + "'.");
358:                }
359:                return classMapping;
360:            }
361:
362:            /**
363:             * Build class instance for the given node.
364:             * @param node the element of the xml
365:             * @param classMapping the mapping between node name and class name
366:             * @return the instance of the object
367:             * @throws XMLConfigurationException if no new instance can be done.
368:             */
369:            private Object newInstance(final Node node,
370:                    final ClassMapping classMapping)
371:                    throws XMLConfigurationException {
372:                // get classname
373:                String className = classMapping.getName();
374:
375:                // load class
376:                Class<?> clazz;
377:                try {
378:                    clazz = Thread.currentThread().getContextClassLoader()
379:                            .loadClass(className);
380:                } catch (ClassNotFoundException e) {
381:                    throw new XMLConfigurationException(
382:                            "Cannot load the class '" + className + "'.", e);
383:                }
384:                logger.debug("Building instance of the class {0}", className);
385:                // build a new instance
386:                try {
387:                    return clazz.newInstance();
388:                } catch (InstantiationException e) {
389:                    throw new XMLConfigurationException(
390:                            "Cannot build an instance of class '" + className
391:                                    + "'.", e);
392:                } catch (IllegalAccessException e) {
393:                    throw new XMLConfigurationException(
394:                            "Cannot build an instance of class '" + className
395:                                    + "'.", e);
396:                } catch (NoClassDefFoundError e) {
397:                    throw new XMLConfigurationException(
398:                            "Cannot build an instance of class '" + className
399:                                    + "'.", e);
400:                }
401:            }
402:
403:            /**
404:             * Set attribute on the given object.
405:             * @param configuringObject the object to configure
406:             * @param propertyName the name of the property (for the setter)
407:             * @param propertyValue the value of the property
408:             * @param classMapping the mapping (if there are attributes aliasing)
409:             * @throws XMLConfigurationException if attribute cannot be set.
410:             */
411:            private void setAttribute(final Object configuringObject,
412:                    final String propertyName, final String propertyValue,
413:                    final ClassMapping classMapping)
414:                    throws XMLConfigurationException {
415:
416:                // get class of the configuringObject
417:                Class<?> configuringClass = configuringObject.getClass();
418:
419:                // Get methods
420:                Method[] methods = configuringClass.getMethods();
421:
422:                String updatedPropertyName = propertyName;
423:
424:                // alias ?
425:                AttributeMapping attributeMapping = classMapping
426:                        .getAttributeMapping(propertyName);
427:                if (attributeMapping != null) {
428:                    String name = attributeMapping.getName();
429:                    if (name != null) {
430:                        updatedPropertyName = name;
431:                    }
432:                }
433:
434:                String setterName = "set"
435:                        + updatedPropertyName.substring(0, 1).toUpperCase()
436:                        + updatedPropertyName.substring(1);
437:
438:                Object paramObject = null;
439:                // Search setter
440:                Method foundMethod = null;
441:                if (methods != null) {
442:                    for (Method m : methods) {
443:                        // set or add ?
444:                        if (m.getName().startsWith(setterName)) {
445:                            // only one arg ?
446:                            Class<?>[] parameters = m.getParameterTypes();
447:                            if (parameters.length == 1) {
448:                                foundMethod = m;
449:                                Class<?> parameterClass = parameters[0];
450:
451:                                // Special case of reference
452:                                if (propertyValue.startsWith("#")
453:                                        && propertyValue.length() >= 2) {
454:                                    paramObject = configuredElements
455:                                            .get(propertyValue.substring(1));
456:                                } else if (String.class.equals(parameterClass)) {
457:                                    paramObject = propertyValue;
458:                                } else if (Integer.TYPE.equals(parameterClass)) {
459:                                    paramObject = new Integer(propertyValue);
460:                                } else if (Boolean.TYPE.equals(parameterClass)) {
461:                                    paramObject = Boolean
462:                                            .valueOf(propertyValue);
463:                                }
464:                                break;
465:                            }
466:                        }
467:                    }
468:                }
469:
470:                // build
471:                if (foundMethod != null && paramObject != null) {
472:                    logger.debug("Calling {0} on object {1} with value {2}",
473:                            setterName, configuringObject, paramObject);
474:                    try {
475:                        foundMethod.invoke(configuringObject, paramObject);
476:                    } catch (IllegalArgumentException e) {
477:                        throw new XMLConfigurationException(
478:                                "Cannot call method '" + foundMethod
479:                                        + "' on object '" + configuringObject
480:                                        + "' with parameter '" + paramObject
481:                                        + "'.", e);
482:                    } catch (IllegalAccessException e) {
483:                        throw new XMLConfigurationException(
484:                                "Cannot call method '" + foundMethod
485:                                        + "' on object '" + configuringObject
486:                                        + "' with parameter '" + paramObject
487:                                        + "'.", e);
488:                    } catch (InvocationTargetException e) {
489:                        throw new XMLConfigurationException(
490:                                "Cannot call method '" + foundMethod
491:                                        + "' on object '" + configuringObject
492:                                        + "' with parameter '" + paramObject
493:                                        + "'.", e);
494:                    }
495:                } else {
496:                    throw new XMLConfigurationException(
497:                            "No setter method found for parameter '"
498:                                    + propertyName + "' on class '"
499:                                    + configuringClass + "'.");
500:                }
501:            }
502:
503:            /**
504:             * Finds the add(Class c) or set(Class c) methods.<br>
505:             * The parameter needs to be a single entry and not a list.
506:             * @param configuringObject the object on which call this setter method.
507:             * @param paramObject the parameter object
508:             * @return the found method if any.
509:             */
510:            private Method findSingleSetterMethod(
511:                    final Object configuringObject, final Object paramObject) {
512:                Method setterMethod = null;
513:
514:                // get class of the configuringObject
515:                Class<?> configuringClass = configuringObject.getClass();
516:
517:                // Get methods of the class
518:                Method[] methods = configuringClass.getMethods();
519:
520:                // class of the new object
521:                Class<?> parameterClass = paramObject.getClass();
522:                String className = parameterClass.getSimpleName();
523:
524:                // Search setter
525:                if (methods != null) {
526:                    for (Method m : methods) {
527:                        // set or add ?
528:                        if (m.getName().startsWith("set" + className)
529:                                || m.getName().startsWith("add" + className)) {
530:                            // only one arg ?
531:                            Class<?>[] parameters = m.getParameterTypes();
532:                            if (parameters.length == 1) {
533:                                // valid parameter
534:                                if (parameters[0].equals(parameterClass)) {
535:                                    setterMethod = m;
536:                                    break;
537:                                }
538:                            }
539:                        }
540:                    }
541:                }
542:                return setterMethod;
543:            }
544:
545:            /**
546:             * Finds the get(Class c) method.<br>
547:             * The parameter needs to be a single entry and not a list.
548:             * @param configuringObject the object on which call this getter method.
549:             * @param paramObject the parameter object
550:             * @return the found method if any.
551:             */
552:            private Method findSingleGetterMethod(
553:                    final Object configuringObject, final Object paramObject) {
554:                Method getterMethod = null;
555:
556:                // get class of the configuringObject
557:                Class<?> configuringClass = configuringObject.getClass();
558:
559:                // Get methods of the class
560:                Method[] methods = configuringClass.getMethods();
561:
562:                // class of the new object
563:                Class<?> parameterClass = paramObject.getClass();
564:                String className = parameterClass.getSimpleName();
565:
566:                // Search setter
567:                if (methods != null) {
568:                    for (Method m : methods) {
569:                        // Gettermethod ?
570:                        if (m.getName().startsWith("get" + className)) {
571:                            // no Arg ?
572:                            Class<?>[] parameters = m.getParameterTypes();
573:                            if (parameters.length == 0) {
574:                                // valid parameter and return type ?
575:                                Class<?> returnType = m.getReturnType();
576:                                if (returnType != null
577:                                        && returnType.equals(paramObject
578:                                                .getClass())) {
579:                                    getterMethod = m;
580:                                    break;
581:                                }
582:                            }
583:                        }
584:                    }
585:                }
586:                return getterMethod;
587:            }
588:
589:            /**
590:             * Finds the get(List&lt;Class&gt;) and set(List&lt;Class&gt;) methods. The
591:             * parameter needs to be a list with generics.
592:             * @param configuringObject the object on which call this setter method.
593:             * @param paramObject the parameter object
594:             * @param getter the name of the getter
595:             * @param setter the name of the setter
596:             * @return the getter and setter method with List type.
597:             */
598:            private Method[] findListGetterSetterMethod(
599:                    final Object configuringObject, final Object paramObject,
600:                    final String getter, final String setter) {
601:
602:                // get class of the configuringObject
603:                Class<?> configuringClass = configuringObject.getClass();
604:
605:                // Get methods of the class
606:                Method[] methods = configuringClass.getMethods();
607:
608:                // class of the new object
609:                Class<?> parameterClass = paramObject.getClass();
610:
611:                // Search with class of object
612:                String className = parameterClass.getSimpleName();
613:                // Suffix name (many items)
614:                // (special case for y)
615:                String argName = null;
616:                if (className.endsWith("y")) {
617:                    argName = className.substring(0, className.length() - 1)
618:                            + "ies";
619:                } else if (className.endsWith("ss")) {
620:                    argName = className + "es";
621:                } else {
622:                    argName = className + "s";
623:                }
624:
625:                Method[] searchMethods = searchListGetterSetterMethod(methods,
626:                        argName, parameterClass, getter, setter);
627:
628:                return searchMethods;
629:            }
630:
631:            /**
632:             * Search getter and setter method in the given set of methods. The
633:             * getter/setter are used for a List parameter/return type.
634:             * @param methods the set of methods to search in
635:             * @param argName the name of the argument
636:             * @param parameterClass the parameter class (for the generics on the List)
637:             * @param getter the name of the getter
638:             * @param setter the name of the setter
639:             * @return an array of methods, array[0] = getter, array[1] = setter.
640:             */
641:            private Method[] searchListGetterSetterMethod(
642:                    final Method[] methods, final String argName,
643:                    final Class<?> parameterClass, final String getter,
644:                    final String setter) {
645:                Method[] returnedMethods = null;
646:
647:                Method getterMethod = null;
648:                Method setterMethod = null;
649:                // Search getter and setter
650:                if (methods != null) {
651:                    for (Method m : methods) {
652:                        // setter
653:                        if (m.getName().startsWith("set" + argName)
654:                                || m.getName().equals(setter)) {
655:                            // only one arg ?
656:                            Class<?>[] parameters = m.getParameterTypes();
657:
658:                            // setter
659:                            if (parameters.length == 1) {
660:                                // ensure it is a List type
661:                                if (parameters[0].equals(List.class)) {
662:                                    Type[] types = m.getGenericParameterTypes();
663:                                    // look only the first type if any
664:                                    if (types.length == 1) {
665:                                        if (types[0] instanceof  ParameterizedType) {
666:                                            ParameterizedType parameterizedType = (ParameterizedType) types[0];
667:                                            Type[] typeArguments = parameterizedType
668:                                                    .getActualTypeArguments();
669:                                            if (typeArguments.length == 1) {
670:                                                if (typeArguments[0]
671:                                                        .equals(parameterClass)) {
672:                                                    // found it !
673:                                                    setterMethod = m;
674:                                                }
675:                                            }
676:
677:                                        }
678:                                    }
679:                                }
680:                            }
681:                        } else if (m.getName().startsWith("get" + argName)
682:                                || m.getName().equals(getter)) {
683:                            Class<?> returnTypeClass = m.getReturnType();
684:                            if (returnTypeClass != null
685:                                    && returnTypeClass.equals(List.class)) {
686:
687:                                // no parameter
688:                                Class<?>[] parameters = m.getParameterTypes();
689:                                if (parameters.length == 0) {
690:                                    Type type = m.getGenericReturnType();
691:                                    if (type instanceof  ParameterizedType) {
692:                                        ParameterizedType parameterizedType = (ParameterizedType) type;
693:                                        Type[] typeArguments = parameterizedType
694:                                                .getActualTypeArguments();
695:                                        if (typeArguments.length == 1) {
696:                                            if (typeArguments[0]
697:                                                    .equals(parameterClass)) {
698:                                                // found it !
699:                                                getterMethod = m;
700:                                            }
701:                                        }
702:                                    }
703:                                }
704:                            }
705:                        }
706:                    }
707:                }
708:                // try with interfaces of the current class
709:                Class<?>[] interfaces = parameterClass.getInterfaces();
710:                if (interfaces != null) {
711:                    for (Class<?> itf : interfaces) {
712:                        String itfName = itf.getSimpleName();
713:                        String argItfName = itfName + "s";
714:                        returnedMethods = searchListGetterSetterMethod(methods,
715:                                argItfName, itf, getter, setter);
716:                        if (returnedMethods != null) {
717:                            break;
718:                        }
719:                    }
720:                }
721:
722:                if (getterMethod != null && setterMethod != null) {
723:                    returnedMethods = new Method[2];
724:                    returnedMethods[0] = getterMethod;
725:                    returnedMethods[1] = setterMethod;
726:                }
727:                return returnedMethods;
728:            }
729:
730:            /**
731:             * Add or set element on the given object.
732:             * @param configuringObject the object to configure
733:             * @param newObject the object to add/set on the configuringObject object
734:             * @param attributeName the name of the attribute for this object
735:             * @param classMapping the data about all attributes
736:             * @throws XMLConfigurationException if newObject cannot be set.
737:             */
738:            @SuppressWarnings("unchecked")
739:            private void addSetElement(final Object configuringObject,
740:                    final Object newObject, final String attributeName,
741:                    final ClassMapping classMapping)
742:                    throws XMLConfigurationException {
743:
744:                // Getter and setter set ?
745:                String getter = null;
746:                String setter = null;
747:                boolean isListAttribute = false;
748:
749:                // Read properties if any
750:                AttributeMapping attributeMapping = classMapping
751:                        .getAttributeMapping(attributeName);
752:                if (attributeMapping != null) {
753:                    getter = attributeMapping.getGetter();
754:                    setter = attributeMapping.getSetter();
755:                    isListAttribute = attributeMapping.isListElement();
756:                }
757:
758:                // Single setter method object
759:                Method foundMethod = null;
760:
761:                // Search a single setter if not a list
762:                if (!isListAttribute) {
763:                    foundMethod = findSingleSetterMethod(configuringObject,
764:                            newObject);
765:                }
766:
767:                // single setter ?
768:                if (foundMethod != null) {
769:                    logger.debug(
770:                            "Calling method {0} on object {1} with value {2}",
771:                            foundMethod, configuringObject, newObject);
772:                    try {
773:                        foundMethod.invoke(configuringObject, newObject);
774:                    } catch (IllegalArgumentException e) {
775:                        throw new XMLConfigurationException(
776:                                "Unable to invoke the method '" + foundMethod
777:                                        + "' on '" + configuringObject
778:                                        + "' with arg '" + newObject + "'.", e);
779:                    } catch (IllegalAccessException e) {
780:                        throw new XMLConfigurationException(
781:                                "Unable to invoke the method '" + foundMethod
782:                                        + "' on '" + configuringObject
783:                                        + "' with arg '" + newObject + "'.", e);
784:                    } catch (InvocationTargetException e) {
785:                        throw new XMLConfigurationException(
786:                                "Unable to invoke the method '" + foundMethod
787:                                        + "' on '" + configuringObject
788:                                        + "' with arg '" + newObject + "'.", e);
789:                    }
790:                } else {
791:                    // try a list getter/setter
792:                    Method[] getterAndSetter = findListGetterSetterMethod(
793:                            configuringObject, newObject, getter, setter);
794:                    if (getterAndSetter != null) {
795:                        Method getterMethod = getterAndSetter[0];
796:                        Method setterMethod = getterAndSetter[1];
797:
798:                        // Get current list
799:                        List currentList = null;
800:                        try {
801:                            logger.debug("Calling method {0} on object {1}",
802:                                    getterMethod, configuringObject);
803:                            currentList = (List) getterMethod
804:                                    .invoke(configuringObject);
805:                        } catch (IllegalArgumentException e) {
806:                            throw new XMLConfigurationException(
807:                                    "Unable to invoke the method '"
808:                                            + getterMethod + "' on '"
809:                                            + configuringObject + "'.", e);
810:                        } catch (IllegalAccessException e) {
811:                            throw new XMLConfigurationException(
812:                                    "Unable to invoke the method '"
813:                                            + getterMethod + "' on '"
814:                                            + configuringObject + "'.", e);
815:                        } catch (InvocationTargetException e) {
816:                            throw new XMLConfigurationException(
817:                                    "Unable to invoke the method '"
818:                                            + getterMethod + "' on '"
819:                                            + configuringObject + "'.", e);
820:                        }
821:
822:                        // Null list, create one
823:                        if (currentList == null) {
824:                            currentList = new ArrayList();
825:                        }
826:
827:                        // add element
828:                        logger.debug("Adding element  {0} to the list {1}",
829:                                newObject, currentList);
830:                        currentList.add(newObject);
831:
832:                        // set list
833:                        try {
834:                            logger
835:                                    .debug(
836:                                            "Calling method {0} on object {1} with value {2}",
837:                                            setterMethod, configuringObject,
838:                                            currentList);
839:                            setterMethod.invoke(configuringObject, currentList);
840:                        } catch (IllegalArgumentException e) {
841:                            throw new XMLConfigurationException(
842:                                    "Unable to invoke the method '"
843:                                            + setterMethod + "' on '"
844:                                            + configuringObject + "'.", e);
845:                        } catch (IllegalAccessException e) {
846:                            throw new XMLConfigurationException(
847:                                    "Unable to invoke the method '"
848:                                            + setterMethod + "' on '"
849:                                            + configuringObject + "'.", e);
850:                        } catch (InvocationTargetException e) {
851:                            throw new XMLConfigurationException(
852:                                    "Unable to invoke the method '"
853:                                            + setterMethod + "' on '"
854:                                            + configuringObject + "'.", e);
855:                        }
856:
857:                    } else {
858:                        throw new XMLConfigurationException(
859:                                "No setter method found for parameter '"
860:                                        + newObject.getClass() + "' on class '"
861:                                        + configuringObject.getClass() + "'.");
862:                    }
863:                }
864:            }
865:
866:            /**
867:             * Gets the XML mapping for the given namespace and the node name.
868:             * @param nameSpace current XML namespace.
869:             * @return the XML mapping object.
870:             * @throws XMLConfigurationException if xml mapping is not found.
871:             */
872:            private XMLMapping getXMLMapping(final String nameSpace)
873:                    throws XMLConfigurationException {
874:                if (nameSpace == null || "".equals(nameSpace)) {
875:                    throw new XMLConfigurationException(
876:                            "Empty default namespace not supported.");
877:                }
878:
879:                // already one ?
880:                if (mappings.containsKey(nameSpace)) {
881:                    return mappings.get(nameSpace);
882:                }
883:
884:                XMLMapping xmlMapping = null;
885:                // With the namespace, get the package name for searching the
886:                // <nodeName>-mapping.xml file
887:                if (nameSpace != null) {
888:                    if (nameSpace.startsWith(HTTP_NAMESPACE)) {
889:                        // get package
890:                        String packageName = nameSpace.substring(HTTP_NAMESPACE
891:                                .length());
892:                        // Compute node name and suffix
893:                        String resourceName = packageName
894:                                .replaceAll("\\.", "/")
895:                                + "/" + MAPPING_FILENAME;
896:
897:                        URL mappingURL = Thread.currentThread()
898:                                .getContextClassLoader().getResource(
899:                                        resourceName);
900:                        // found url
901:                        if (mappingURL != null) {
902:                            xmlMapping = createXMLMapping(nameSpace, mappingURL);
903:                        }
904:                    } else {
905:                        logger
906:                                .warn(
907:                                        "Namespace found ''{0}}'' but this is not an HTTP namespace",
908:                                        nameSpace);
909:                    }
910:                }
911:                // even null namespace will have a default xml mapping
912:                mappings.put(nameSpace, xmlMapping);
913:                return xmlMapping;
914:
915:            }
916:
917:            /**
918:             * Create the XML mapping object for the given namespace with the given XML
919:             * mapping file.
920:             * @param nameSpace the namespace of the mapping
921:             * @param mappingURL the URL to the XML mapping file
922:             * @return an instance of XML mapping
923:             * @throws XMLConfigurationException if no XML mapping have been created.
924:             */
925:            private XMLMapping createXMLMapping(final String nameSpace,
926:                    final URL mappingURL) throws XMLConfigurationException {
927:                XMLMappingBuilder xmlMappingBuilder = new XMLMappingBuilder(
928:                        mappingURL);
929:                xmlMappingBuilder.build();
930:                return xmlMappingBuilder.getXmlMapping();
931:            }
932:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.