Source Code Cross Referenced for ClassSkeleton.java in  » EJB-Server-resin-3.1.5 » extra » com » caucho » jaxb » skeleton » 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 » EJB Server resin 3.1.5 » extra » com.caucho.jaxb.skeleton 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *
0023:         *   Free Software Foundation, Inc.
0024:         *   59 Temple Place, Suite 330
0025:         *   Boston, MA 02111-1307  USA
0026:         *
0027:         * @author Emil Ong, Adam Megacz
0028:         */
0029:
0030:        package com.caucho.jaxb.skeleton;
0031:
0032:        import org.w3c.dom.Node;
0033:
0034:        import static javax.xml.XMLConstants.*;
0035:
0036:        import javax.xml.bind.JAXBException;
0037:        import javax.xml.bind.Marshaller;
0038:        import javax.xml.bind.Unmarshaller;
0039:        import javax.xml.bind.UnmarshalException;
0040:        import javax.xml.bind.annotation.*;
0041:
0042:        import javax.xml.namespace.QName;
0043:
0044:        import javax.xml.stream.Location;
0045:        import javax.xml.stream.XMLStreamException;
0046:        import javax.xml.stream.XMLStreamReader;
0047:        import javax.xml.stream.XMLStreamWriter;
0048:
0049:        import java.io.IOException;
0050:
0051:        import java.lang.reflect.AccessibleObject;
0052:        import java.lang.reflect.Constructor;
0053:        import java.lang.reflect.Field;
0054:        import java.lang.reflect.InvocationTargetException;
0055:        import java.lang.reflect.Method;
0056:        import java.lang.reflect.Modifier;
0057:
0058:        import java.util.ArrayList;
0059:        import java.util.Collection;
0060:        import java.util.Collections;
0061:        import java.util.Comparator;
0062:        import java.util.HashMap;
0063:        import java.util.HashSet;
0064:        import java.util.Set;
0065:        import java.util.TreeSet;
0066:        import java.util.logging.Level;
0067:        import java.util.logging.Logger;
0068:
0069:        import com.caucho.jaxb.BinderImpl;
0070:        import com.caucho.jaxb.JAXBContextImpl;
0071:        import com.caucho.jaxb.JAXBUtil;
0072:        import com.caucho.jaxb.NodeIterator;
0073:        import com.caucho.jaxb.annotation.XmlLocation;
0074:
0075:        import com.caucho.jaxb.accessor.Accessor;
0076:        import com.caucho.jaxb.accessor.FieldAccessor;
0077:        import com.caucho.jaxb.accessor.GetterSetterAccessor;
0078:
0079:        import com.caucho.jaxb.mapping.AnyAttributeMapping;
0080:        import com.caucho.jaxb.mapping.AttributeMapping;
0081:        import com.caucho.jaxb.mapping.AnyElementMapping;
0082:        import com.caucho.jaxb.mapping.ElementMapping;
0083:        import com.caucho.jaxb.mapping.ElementRefMapping;
0084:        import com.caucho.jaxb.mapping.ElementsMapping;
0085:        import com.caucho.jaxb.mapping.Namer;
0086:        import com.caucho.jaxb.mapping.XmlMapping;
0087:        import com.caucho.jaxb.mapping.XmlValueMapping;
0088:
0089:        import com.caucho.util.L10N;
0090:
0091:        import com.caucho.xml.stream.StaxUtil;
0092:
0093:        public class ClassSkeleton<C> {
0094:            public static final String XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
0095:            public static final String XML_SCHEMA_PREFIX = "xsd";
0096:
0097:            private static final L10N L = new L10N(ClassSkeleton.class);
0098:            private static final Logger log = Logger
0099:                    .getLogger(ClassSkeleton.class.getName());
0100:
0101:            private static final Class[] NO_PARAMS = new Class[0];
0102:            private static final Object[] NO_ARGS = new Object[0];
0103:
0104:            protected JAXBContextImpl _context;
0105:            protected QName _elementName;
0106:            private Class<C> _class;
0107:            private ClassSkeleton _parent;
0108:            private Package _package;
0109:            private Method _createMethod;
0110:            private Object _factory;
0111:            private QName _typeName;
0112:
0113:            private HashMap<QName, XmlMapping> _attributeQNameToMappingMap = new HashMap<QName, XmlMapping>();
0114:
0115:            private HashMap<QName, XmlMapping> _elementQNameToMappingMap = new HashMap<QName, XmlMapping>();
0116:
0117:            private ArrayList<XmlMapping> _attributeMappings = new ArrayList<XmlMapping>();
0118:
0119:            private ArrayList<XmlMapping> _elementMappings = new ArrayList<XmlMapping>();
0120:
0121:            private AnyElementMapping _anyElementMapping;
0122:            private AnyAttributeMapping _anyAttributeMapping;
0123:
0124:            private Method _beforeUnmarshal;
0125:            private Method _afterUnmarshal;
0126:            private Method _beforeMarshal;
0127:            private Method _afterMarshal;
0128:
0129:            private Constructor _constructor;
0130:
0131:            /** Special hook to allow injecting the location where an instance was
0132:                unmarshalled from. */
0133:            private Accessor _locationAccessor;
0134:
0135:            /**
0136:             * The value @XmlValue.
0137:             * 
0138:             **/
0139:            protected XmlValueMapping _value;
0140:
0141:            public Class<C> getType() {
0142:                return _class;
0143:            }
0144:
0145:            public String toString() {
0146:                return "ClassSkeleton[" + _class + "]";
0147:            }
0148:
0149:            protected ClassSkeleton(JAXBContextImpl context) {
0150:                _context = context;
0151:            }
0152:
0153:            public ClassSkeleton(JAXBContextImpl context, Class<C> c) {
0154:                this (context);
0155:                _class = c;
0156:            }
0157:
0158:            public void init() throws JAXBException {
0159:                try {
0160:                    _package = _class.getPackage();
0161:
0162:                    // check for special before and after methods
0163:                    try {
0164:                        _beforeUnmarshal = _class.getMethod("beforeUnmarshal",
0165:                                Unmarshaller.class, Object.class);
0166:                    } catch (NoSuchMethodException _) {
0167:                        // deliberate
0168:                    }
0169:
0170:                    try {
0171:                        _afterUnmarshal = _class.getMethod("afterUnmarshal",
0172:                                Unmarshaller.class, Object.class);
0173:                    } catch (NoSuchMethodException _) {
0174:                        // deliberate
0175:                    }
0176:
0177:                    try {
0178:                        _beforeMarshal = _class.getMethod("beforeMarshal",
0179:                                Marshaller.class);
0180:                    } catch (NoSuchMethodException _) {
0181:                        // deliberate
0182:                    }
0183:
0184:                    try {
0185:                        _afterMarshal = _class.getMethod("afterMarshal",
0186:                                Marshaller.class);
0187:                    } catch (NoSuchMethodException _) {
0188:                        // deliberate
0189:                    }
0190:
0191:                    if (Set.class.isAssignableFrom(_class)) {
0192:                        // XXX:
0193:                    }
0194:
0195:                    // XXX: @XmlJavaTypeAdapter
0196:
0197:                    // Find the zero-parameter constructor
0198:                    try {
0199:                        _constructor = _class.getConstructor(NO_PARAMS);
0200:                        _constructor.setAccessible(true);
0201:                    } catch (Exception e1) {
0202:                        try {
0203:                            _constructor = _class
0204:                                    .getDeclaredConstructor(NO_PARAMS);
0205:                            _constructor.setAccessible(true);
0206:                        } catch (Exception e2) {
0207:                            throw new JAXBException(L.l(
0208:                                    "{0}: Zero-arg constructor not found",
0209:                                    _class.getName()), e2);
0210:                        }
0211:                    }
0212:
0213:                    _typeName = JAXBUtil.getXmlSchemaDatatype(_class, _context);
0214:
0215:                    // Special case: when name="", this is an "anonymous" type, bound
0216:                    // exclusively to a particular element name
0217:                    if (!"".equals(_typeName.getLocalPart()))
0218:                        _context.addXmlType(_typeName, this );
0219:
0220:                    // Check for the complete name of the element...
0221:                    String namespace = _context.getTargetNamespace();
0222:
0223:                    // look at package defaults first...
0224:                    XmlSchema schema = (XmlSchema) _package
0225:                            .getAnnotation(XmlSchema.class);
0226:
0227:                    if (schema != null && !"".equals(schema.namespace()))
0228:                        namespace = schema.namespace();
0229:
0230:                    // then look at class specific overrides.
0231:                    XmlRootElement xre = _class
0232:                            .getAnnotation(XmlRootElement.class);
0233:
0234:                    if (xre != null) {
0235:                        String localName = null;
0236:
0237:                        if ("##default".equals(xre.name()))
0238:                            localName = JAXBUtil.identifierToXmlName(_class);
0239:                        else
0240:                            localName = xre.name();
0241:
0242:                        if (!"##default".equals(xre.namespace()))
0243:                            namespace = xre.namespace();
0244:
0245:                        if (namespace == null)
0246:                            _elementName = new QName(localName);
0247:                        else
0248:                            _elementName = new QName(namespace, localName);
0249:
0250:                        _context.addRootElement(this );
0251:                    }
0252:
0253:                    // order the elements, if specified
0254:
0255:                    XmlAccessOrder accessOrder = XmlAccessOrder.UNDEFINED;
0256:
0257:                    XmlAccessorOrder packageOrder = _package
0258:                            .getAnnotation(XmlAccessorOrder.class);
0259:
0260:                    XmlAccessorOrder classOrder = _class
0261:                            .getAnnotation(XmlAccessorOrder.class);
0262:
0263:                    if (packageOrder != null)
0264:                        accessOrder = packageOrder.value();
0265:
0266:                    if (classOrder != null)
0267:                        accessOrder = classOrder.value();
0268:
0269:                    // try property orders too
0270:
0271:                    XmlType xmlType = (XmlType) _class
0272:                            .getAnnotation(XmlType.class);
0273:                    HashMap<String, Integer> orderMap = null;
0274:
0275:                    if (xmlType != null
0276:                            && (xmlType.propOrder().length != 1 || !""
0277:                                    .equals(xmlType.propOrder()[0]))) {
0278:                        // non-default propOrder
0279:                        orderMap = new HashMap<String, Integer>();
0280:
0281:                        for (int i = 0; i < xmlType.propOrder().length; i++)
0282:                            orderMap.put(xmlType.propOrder()[i], i);
0283:                    }
0284:
0285:                    // Collect the fields/properties of the class
0286:                    if (orderMap != null) {
0287:                        for (int i = 0; i < orderMap.size(); i++)
0288:                            _elementMappings.add(null);
0289:                    }
0290:
0291:                    XmlAccessorType accessorType = _class
0292:                            .getAnnotation(XmlAccessorType.class);
0293:
0294:                    XmlAccessType accessType = (accessorType == null ? XmlAccessType.PUBLIC_MEMBER
0295:                            : accessorType.value());
0296:
0297:                    if (accessType != XmlAccessType.FIELD) {
0298:                        // getter/setter
0299:                        TreeSet<Method> methodSet = new TreeSet<Method>(
0300:                                methodComparator);
0301:
0302:                        Method[] declared = _class.getDeclaredMethods();
0303:
0304:                        for (Method m : declared)
0305:                            methodSet.add(m);
0306:
0307:                        Method[] methods = new Method[methodSet.size()];
0308:                        methodSet.toArray(methods);
0309:
0310:                        AccessibleObject.setAccessible(methods, true);
0311:
0312:                        while (methodSet.size() > 0) {
0313:                            Method m = methodSet.first();
0314:                            methodSet.remove(m);
0315:
0316:                            String name = null;
0317:                            Method get = null;
0318:                            Method set = null;
0319:
0320:                            if (m.getName().startsWith("get")) {
0321:                                get = m;
0322:
0323:                                if (Void.TYPE.equals(get.getReturnType()))
0324:                                    continue;
0325:
0326:                                name = get.getName().substring(3); // 3 == "get".length());
0327:
0328:                                Class cl = get.getDeclaringClass();
0329:
0330:                                try {
0331:                                    set = cl.getDeclaredMethod("set" + name,
0332:                                            get.getReturnType());
0333:                                } catch (NoSuchMethodException e) {
0334:                                    continue;
0335:                                }
0336:
0337:                                if (!methodSet.remove(set))
0338:                                    continue;
0339:                            } else if (m.getName().startsWith("set")) {
0340:                                set = m;
0341:
0342:                                Class[] parameterTypes = set
0343:                                        .getParameterTypes();
0344:
0345:                                if (parameterTypes.length != 1)
0346:                                    continue;
0347:
0348:                                name = set.getName().substring(3); // 3 == "set".length());
0349:
0350:                                Class cl = set.getDeclaringClass();
0351:
0352:                                try {
0353:                                    get = cl.getDeclaredMethod("get" + name);
0354:                                } catch (NoSuchMethodException e) {
0355:                                    continue;
0356:                                }
0357:
0358:                                if (!parameterTypes[0].equals(get
0359:                                        .getReturnType()))
0360:                                    continue;
0361:
0362:                                if (!methodSet.remove(get))
0363:                                    continue;
0364:                            } else
0365:                                continue;
0366:
0367:                            name = Character.toLowerCase(name.charAt(0))
0368:                                    + name.substring(1);
0369:
0370:                            // JAXB specifies that a "class" property must be specified as "clazz"
0371:                            // because of Object.getClass()
0372:                            if ("class".equals(name))
0373:                                continue;
0374:
0375:                            // XXX special cases for Throwable specified in JAX-WS
0376:                            // Should it be in the general JAXB?
0377:                            if (Throwable.class.isAssignableFrom(_class)
0378:                                    && ("stackTrace".equals(name)
0379:                                            || "cause".equals(name) || "localizedMessage"
0380:                                            .equals(name)))
0381:                                continue;
0382:
0383:                            // XXX PUBLIC_MEMBER
0384:
0385:                            if (accessType == XmlAccessType.NONE
0386:                                    && !JAXBUtil.isJAXBAnnotated(get)
0387:                                    && !JAXBUtil.isJAXBAnnotated(set))
0388:                                continue;
0389:
0390:                            // jaxb/0456
0391:                            if (Modifier.isStatic(get.getModifiers())
0392:                                    && JAXBUtil.isJAXBAnnotated(get))
0393:                                throw new JAXBException(
0394:                                        L
0395:                                                .l(
0396:                                                        "JAXB annotations cannot be applied to static methods: {0}",
0397:                                                        get));
0398:
0399:                            // jaxb/0457
0400:                            if (Modifier.isStatic(set.getModifiers())
0401:                                    && JAXBUtil.isJAXBAnnotated(set))
0402:                                throw new JAXBException(
0403:                                        L
0404:                                                .l(
0405:                                                        "JAXB annotations cannot be applied to static methods: {0}",
0406:                                                        set));
0407:
0408:                            // jaxb/0374
0409:                            if (Modifier.isStatic(set.getModifiers())
0410:                                    || Modifier.isStatic(get.getModifiers()))
0411:                                continue;
0412:
0413:                            if (get != null
0414:                                    && get
0415:                                            .isAnnotationPresent(XmlTransient.class))
0416:                                continue;
0417:                            if (set != null
0418:                                    && set
0419:                                            .isAnnotationPresent(XmlTransient.class))
0420:                                continue;
0421:
0422:                            get.setAccessible(true);
0423:                            set.setAccessible(true);
0424:
0425:                            Accessor a = new GetterSetterAccessor(name, get,
0426:                                    set);
0427:
0428:                            if (orderMap != null) {
0429:                                Integer i = orderMap.remove(name);
0430:
0431:                                if (i != null)
0432:                                    a.setOrder(i.intValue());
0433:                                // XXX else throw something?
0434:                            }
0435:
0436:                            processAccessor(a);
0437:                        }
0438:                    }
0439:
0440:                    if (accessType != XmlAccessType.PROPERTY) {
0441:                        // XXX Don't overwrite property accessors
0442:                        HashSet<Field> fieldSet = new HashSet<Field>();
0443:
0444:                        Field[] declared = _class.getDeclaredFields();
0445:
0446:                        for (Field f : declared)
0447:                            fieldSet.add(f);
0448:
0449:                        Field[] fields = new Field[fieldSet.size()];
0450:                        fieldSet.toArray(fields);
0451:
0452:                        AccessibleObject.setAccessible(fields, true);
0453:
0454:                        for (Field f : fields) {
0455:                            if (f.isAnnotationPresent(XmlLocation.class)) {
0456:                                if (!f.getType().equals(Location.class))
0457:                                    throw new JAXBException(
0458:                                            L
0459:                                                    .l("Fields annotated by @Location must have type javax.xml.stream.Location"));
0460:
0461:                                _locationAccessor = new FieldAccessor(f);
0462:                            }
0463:
0464:                            // special case: jaxb/0250
0465:                            // fields which are static are skipped _unless_ they are also
0466:                            // both final and attributes
0467:                            if (Modifier.isStatic(f.getModifiers())
0468:                                    && !(Modifier.isFinal(f.getModifiers()) && f
0469:                                            .isAnnotationPresent(XmlAttribute.class)))
0470:                                continue;
0471:
0472:                            if (f.isAnnotationPresent(XmlTransient.class))
0473:                                continue;
0474:                            // jaxb/0176: transient modifier ignored
0475:
0476:                            if (accessType == XmlAccessType.PUBLIC_MEMBER
0477:                                    && !Modifier.isPublic(f.getModifiers())
0478:                                    && !JAXBUtil.isJAXBAnnotated(f))
0479:                                continue;
0480:
0481:                            if (accessType == XmlAccessType.NONE
0482:                                    && !JAXBUtil.isJAXBAnnotated(f))
0483:                                continue;
0484:
0485:                            Accessor a = new FieldAccessor(f);
0486:
0487:                            if (orderMap != null) {
0488:                                Integer i = orderMap.remove(f.getName());
0489:
0490:                                if (i != null)
0491:                                    a.setOrder(i.intValue());
0492:                                // XXX else throw something?
0493:                            }
0494:
0495:                            processAccessor(a);
0496:                        }
0497:                    }
0498:
0499:                    // do ordering if necessary
0500:                    if (orderMap == null
0501:                            && accessOrder == XmlAccessOrder.ALPHABETICAL)
0502:                        Collections.sort(_elementMappings,
0503:                                XmlMapping.nameComparator);
0504:                } catch (JAXBException e) {
0505:                    throw e;
0506:                } catch (Exception e) {
0507:                    throw new JAXBException(L.l("{0}: Initialization error",
0508:                            _class.getName()), e);
0509:                }
0510:
0511:                if (!Object.class.equals(_class.getSuperclass()))
0512:                    _parent = _context.getSkeleton(_class.getSuperclass());
0513:            }
0514:
0515:            /**
0516:             * Handles any processing that needs to happen after all ClassSkeletons
0517:             * have been created and all classes have been discovered.
0518:             **/
0519:            public void postProcess() throws JAXBException {
0520:                if (log.isLoggable(Level.FINEST))
0521:                    log.finest("JAXB: " + _class.getName() + " has children: ");
0522:
0523:                for (int i = 0; i < _elementMappings.size(); i++)
0524:                    _elementMappings.get(i)
0525:                            .putQNames(_elementQNameToMappingMap);
0526:            }
0527:
0528:            /**
0529:             * Create an XmlMapping for this accessor and insert it in the correct
0530:             * mapping or field.
0531:             **/
0532:            private void processAccessor(Accessor accessor)
0533:                    throws JAXBException {
0534:                XmlMapping mapping = XmlMapping.newInstance(_context, accessor);
0535:
0536:                if (mapping instanceof  XmlValueMapping) {
0537:                    if (_value != null)
0538:                        throw new JAXBException(
0539:                                L
0540:                                        .l("Cannot have two @XmlValue annotated fields or properties"));
0541:
0542:                    if (_elementMappings.size() > 0) {
0543:                        // in case of propOrder & XmlValue
0544:                        if (_elementMappings.size() != 1
0545:                                || _elementMappings.get(0) != null)
0546:                            throw new JAXBException(
0547:                                    L
0548:                                            .l(
0549:                                                    "Cannot have both @XmlValue and elements in a JAXB element (e.g. {0})",
0550:                                                    _elementMappings.get(0)));
0551:
0552:                        _elementMappings.clear();
0553:                    }
0554:
0555:                    _value = (XmlValueMapping) mapping;
0556:                } else if (mapping instanceof  AttributeMapping) {
0557:                    mapping.putQNames(_attributeQNameToMappingMap);
0558:                    _attributeMappings.add((AttributeMapping) mapping);
0559:                } else if (mapping instanceof  AnyAttributeMapping) {
0560:                    if (_anyAttributeMapping != null)
0561:                        throw new JAXBException(
0562:                                L
0563:                                        .l("Cannot have two fields or properties with @XmlAnyAttribute annotation"));
0564:
0565:                    _anyAttributeMapping = (AnyAttributeMapping) mapping;
0566:                    _attributeMappings.add(mapping);
0567:                } else if ((mapping instanceof  ElementMapping)
0568:                        || (mapping instanceof  ElementRefMapping)
0569:                        || (mapping instanceof  ElementsMapping)) {
0570:                    if (_value != null)
0571:                        throw new JAXBException(
0572:                                L
0573:                                        .l(
0574:                                                "{0}: Cannot have both @XmlValue and elements in a JAXB element",
0575:                                                _class.getName()));
0576:
0577:                    if (mapping.getAccessor().getOrder() >= 0)
0578:                        _elementMappings.set(mapping.getAccessor().getOrder(),
0579:                                mapping);
0580:                    else
0581:                        _elementMappings.add(mapping);
0582:                } else if (mapping instanceof  AnyElementMapping) {
0583:                    if (_anyElementMapping != null)
0584:                        throw new JAXBException(
0585:                                L
0586:                                        .l(
0587:                                                "{0}: Cannot have two @XmlAnyElement annotations in a single class",
0588:                                                _class.getName()));
0589:
0590:                    _anyElementMapping = (AnyElementMapping) mapping;
0591:                } else {
0592:                    throw new RuntimeException(L.l("Unknown mapping type {0}",
0593:                            mapping.getClass()));
0594:                }
0595:            }
0596:
0597:            private XmlMapping getElementMapping(QName q) throws JAXBException {
0598:                XmlMapping mapping = _elementQNameToMappingMap.get(q);
0599:
0600:                if (mapping != null)
0601:                    return mapping;
0602:
0603:                if (_anyElementMapping != null)
0604:                    return _anyElementMapping;
0605:
0606:                if (_parent != null)
0607:                    return _parent.getElementMapping(q);
0608:
0609:                return null;
0610:            }
0611:
0612:            public XmlMapping getAttributeMapping(QName q) throws JAXBException {
0613:                XmlMapping mapping = _attributeQNameToMappingMap.get(q);
0614:
0615:                if (mapping != null)
0616:                    return mapping;
0617:
0618:                if (_anyAttributeMapping != null)
0619:                    return _anyAttributeMapping;
0620:
0621:                if (_parent != null)
0622:                    return _parent.getAttributeMapping(q);
0623:
0624:                return null;
0625:            }
0626:
0627:            public QName getElementName() {
0628:                if (_elementName != null)
0629:                    return _elementName;
0630:                else
0631:                    return _typeName;
0632:            }
0633:
0634:            public void setElementName(QName elementName) {
0635:                _elementName = elementName;
0636:            }
0637:
0638:            public QName getTypeName() {
0639:                return _typeName;
0640:            }
0641:
0642:            public void setCreateMethod(Method createMethod, Object factory) {
0643:                _createMethod = createMethod;
0644:                _factory = factory;
0645:            }
0646:
0647:            public C newInstance() throws JAXBException {
0648:                try {
0649:                    if (_createMethod != null && _factory != null) {
0650:                        return (C) _createMethod.invoke(_factory);
0651:                    } else {
0652:                        // XXX move into constructor
0653:                        XmlType xmlType = getXmlType();
0654:
0655:                        if (xmlType != null) {
0656:                            Class factoryClass = xmlType.factoryClass();
0657:
0658:                            if (xmlType.factoryClass() == XmlType.DEFAULT.class)
0659:                                factoryClass = _class;
0660:
0661:                            if (!"".equals(xmlType.factoryMethod())) {
0662:                                Method m = factoryClass.getMethod(xmlType
0663:                                        .factoryMethod(), NO_PARAMS);
0664:
0665:                                if (!Modifier.isStatic(m.getModifiers()))
0666:                                    throw new JAXBException(L
0667:                                            .l("Factory method not static"));
0668:
0669:                                return (C) m.invoke(null);
0670:                            }
0671:                        }
0672:
0673:                        Constructor con = _class.getConstructor(NO_PARAMS);
0674:
0675:                        return (C) con.newInstance(NO_ARGS);
0676:                    }
0677:                } catch (JAXBException e) {
0678:                    throw e;
0679:                } catch (Exception e) {
0680:                    throw new JAXBException(e);
0681:                }
0682:            }
0683:
0684:            public XmlType getXmlType() {
0685:                return (XmlType) _class.getAnnotation(XmlType.class);
0686:            }
0687:
0688:            public Object read(Unmarshaller u, XMLStreamReader in)
0689:                    throws IOException, XMLStreamException, JAXBException {
0690:                try {
0691:                    C ret = null;
0692:
0693:                    String nil = in.getAttributeValue(
0694:                            W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
0695:
0696:                    if (!"true".equals(nil))
0697:                        ret = newInstance();
0698:
0699:                    if (_locationAccessor != null)
0700:                        _locationAccessor.set(ret, in.getLocation());
0701:
0702:                    if (_beforeUnmarshal != null)
0703:                        _beforeUnmarshal.invoke(ret, u, null);
0704:
0705:                    if (u.getListener() != null)
0706:                        u.getListener().beforeUnmarshal(ret, null);
0707:
0708:                    if (_value != null) {
0709:                        _value.read(u, in, ret, this );
0710:                    } else {
0711:                        // process the attributes
0712:                        for (int i = 0; i < in.getAttributeCount(); i++) {
0713:                            QName attributeName = in.getAttributeName(i);
0714:                            XmlMapping mapping = getAttributeMapping(attributeName);
0715:
0716:                            if (mapping == null)
0717:                                throw new UnmarshalException(L.l(
0718:                                        "Attribute {0} not found in {1}",
0719:                                        attributeName, getType()));
0720:
0721:                            mapping.readAttribute(in, i, ret);
0722:                        }
0723:
0724:                        int i = 0;
0725:                        in.nextTag();
0726:
0727:                        while (in.getEventType() == in.START_ELEMENT) {
0728:                            XmlMapping mapping = getElementMapping(in.getName());
0729:
0730:                            if (mapping == null) {
0731:                                throw new UnmarshalException(L.l(
0732:                                        "Child <{0}> not found in {1}", in
0733:                                                .getName(), getType()));
0734:                            }
0735:
0736:                            if (!mapping.getAccessor().checkOrder(i++,
0737:                                    u.getEventHandler())) {
0738:                                throw new UnmarshalException(L.l(
0739:                                        "Child <{0}> misordered in {1}", in
0740:                                                .getName(), getType()));
0741:                            }
0742:
0743:                            mapping.read(u, in, ret);
0744:                        }
0745:
0746:                        // essentially a nextTag() that handles end of document gracefully
0747:                        while (in.hasNext()) {
0748:                            in.next();
0749:
0750:                            if (in.getEventType() == in.START_ELEMENT
0751:                                    || in.getEventType() == in.END_ELEMENT)
0752:                                break;
0753:                        }
0754:                    }
0755:
0756:                    if (_afterUnmarshal != null)
0757:                        _afterUnmarshal.invoke(ret, u, null);
0758:
0759:                    if (u.getListener() != null)
0760:                        u.getListener().afterUnmarshal(ret, null);
0761:
0762:                    return ret;
0763:                } catch (InvocationTargetException e) {
0764:                    if (e.getTargetException() != null)
0765:                        throw new UnmarshalException(e.getTargetException());
0766:
0767:                    throw new UnmarshalException(e);
0768:                } catch (IllegalAccessException e) {
0769:                    throw new UnmarshalException(e);
0770:                }
0771:            }
0772:
0773:            public Object bindFrom(BinderImpl binder, Object existing,
0774:                    NodeIterator node) throws IOException, JAXBException {
0775:                Node root = node.getNode();
0776:                C ret = (C) existing;
0777:
0778:                if (ret == null)
0779:                    ret = newInstance();
0780:
0781:                if (_value != null) {
0782:                    _value.bindFrom(binder, node, ret);
0783:                } else {
0784:                    int i = 0;
0785:                    Node child = node.firstChild();
0786:
0787:                    while (child != null) {
0788:                        if (child.getNodeType() == Node.ELEMENT_NODE) {
0789:                            QName name = JAXBUtil.qnameFromNode(child);
0790:
0791:                            XmlMapping mapping = getElementMapping(name);
0792:
0793:                            if (mapping == null)
0794:                                throw new UnmarshalException(L.l(
0795:                                        "Child <{0}> not found", name));
0796:
0797:                            if (!mapping.getAccessor().checkOrder(i++,
0798:                                    binder.getEventHandler()))
0799:                                throw new UnmarshalException(L.l(
0800:                                        "Child <{0}> misordered", name));
0801:
0802:                            mapping.bindFrom(binder, node, ret);
0803:                        }
0804:
0805:                        child = node.nextSibling();
0806:                    }
0807:                }
0808:
0809:                node.setNode(root);
0810:                binder.bind(ret, root);
0811:
0812:                return ret;
0813:            }
0814:
0815:            public void write(Marshaller m, XMLStreamWriter out, Object obj,
0816:                    Namer namer, ArrayList<XmlMapping> attributes)
0817:                    throws IOException, XMLStreamException, JAXBException {
0818:                if (obj == null)
0819:                    return;
0820:
0821:                try {
0822:                    if (_beforeMarshal != null)
0823:                        _beforeMarshal.invoke(obj, m);
0824:
0825:                    if (m.getListener() != null)
0826:                        m.getListener().beforeMarshal(obj);
0827:
0828:                    QName tagName = null;
0829:
0830:                    if (namer != null)
0831:                        tagName = namer.getQName(obj);
0832:
0833:                    if (tagName == null)
0834:                        tagName = _elementName;
0835:
0836:                    if (_value != null) {
0837:                        _value.setQName(tagName);
0838:                        _value.write(m, out, obj, _attributeMappings);
0839:                    } else {
0840:                        if (tagName.getNamespaceURI() == null
0841:                                || "".equals(tagName.getNamespaceURI()))
0842:                            out.writeStartElement(tagName.getLocalPart());
0843:                        else if (tagName.getPrefix() == null
0844:                                || "".equals(tagName.getPrefix()))
0845:                            out.writeStartElement(tagName.getNamespaceURI(),
0846:                                    tagName.getLocalPart());
0847:                        else
0848:                            out.writeStartElement(tagName.getPrefix(), tagName
0849:                                    .getLocalPart(), tagName.getNamespaceURI());
0850:
0851:                        if (attributes != null) {
0852:                            for (int i = 0; i < attributes.size(); i++)
0853:                                attributes.get(i).write(m, out, obj);
0854:                        }
0855:
0856:                        for (XmlMapping mapping : _attributeMappings)
0857:                            mapping.write(m, out, obj);
0858:
0859:                        for (XmlMapping mapping : _elementMappings)
0860:                            mapping.write(m, out, obj);
0861:
0862:                        if (_anyElementMapping != null) // XXX ordering!
0863:                            _anyElementMapping.write(m, out, obj);
0864:
0865:                        out.writeEndElement();
0866:                    }
0867:
0868:                    if (_afterMarshal != null)
0869:                        _afterMarshal.invoke(obj, m);
0870:
0871:                    if (m.getListener() != null)
0872:                        m.getListener().afterMarshal(obj);
0873:                } catch (InvocationTargetException e) {
0874:                    throw new JAXBException(e);
0875:                } catch (IllegalAccessException e) {
0876:                    throw new JAXBException(e);
0877:                }
0878:            }
0879:
0880:            public Node bindTo(BinderImpl binder, Node node, Object obj,
0881:                    Namer namer, ArrayList<XmlMapping> attributes)
0882:                    throws IOException, JAXBException {
0883:                if (obj == null)
0884:                    return null;
0885:
0886:                QName tagName = null;
0887:
0888:                if (namer != null)
0889:                    tagName = namer.getQName(obj);
0890:
0891:                if (tagName == null)
0892:                    tagName = _elementName;
0893:
0894:                if (_value != null) {
0895:                    Node newNode = _value.bindTo(binder, node, obj);
0896:
0897:                    if (newNode != node) {
0898:                        binder.invalidate(node);
0899:                        node = newNode;
0900:                    }
0901:                } else {
0902:                    QName nodeName = JAXBUtil.qnameFromNode(node);
0903:
0904:                    if (tagName.equals(nodeName)) {
0905:                        Node child = node.getFirstChild();
0906:
0907:                        child = JAXBUtil.skipIgnorableNodes(child);
0908:
0909:                        if (attributes != null) {
0910:                            // XXX
0911:                        }
0912:
0913:                        for (XmlMapping mapping : _elementMappings) {
0914:                            if (child != null) {
0915:                                // try to reuse as many of the child nodes as possible
0916:                                Node newNode = mapping.bindTo(binder, child,
0917:                                        obj);
0918:
0919:                                if (newNode != child) {
0920:                                    node.replaceChild(newNode, child);
0921:                                    binder.invalidate(child);
0922:                                    child = newNode;
0923:                                }
0924:
0925:                                child = child.getNextSibling();
0926:                                child = JAXBUtil.skipIgnorableNodes(child);
0927:                            } else {
0928:                                Node newNode = JAXBUtil.elementFromQName(
0929:                                        mapping.getQName(obj), node);
0930:                                node.appendChild(mapping.bindTo(binder,
0931:                                        newNode, obj));
0932:                            }
0933:                        }
0934:                    } else {
0935:                        binder.invalidate(node);
0936:
0937:                        node = JAXBUtil.elementFromQName(tagName, node);
0938:
0939:                        for (XmlMapping mapping : _elementMappings) {
0940:                            Node child = JAXBUtil.elementFromQName(mapping
0941:                                    .getQName(obj), node);
0942:                            node
0943:                                    .appendChild(mapping.bindTo(binder, child,
0944:                                            obj));
0945:                        }
0946:                    }
0947:                }
0948:
0949:                binder.bind(obj, node);
0950:
0951:                return node;
0952:            }
0953:
0954:            public boolean isRootElement() {
0955:                return _elementName != null;
0956:            }
0957:
0958:            public void generateSchema(XMLStreamWriter out)
0959:                    throws JAXBException, XMLStreamException {
0960:                if (_elementName != null) {
0961:
0962:                    if ("".equals(_typeName.getLocalPart()))
0963:                        out.writeStartElement(XML_SCHEMA_PREFIX, "element",
0964:                                XML_SCHEMA_NS);
0965:
0966:                    else {
0967:                        out.writeEmptyElement(XML_SCHEMA_PREFIX, "element",
0968:                                XML_SCHEMA_NS);
0969:                        out.writeAttribute("type", _typeName.getLocalPart());
0970:                    }
0971:
0972:                    out.writeAttribute("name", _elementName.getLocalPart());
0973:                }
0974:
0975:                generateSchemaType(out);
0976:
0977:                if (_elementName != null && "".equals(_typeName.getLocalPart()))
0978:                    out.writeEndElement(); // element
0979:            }
0980:
0981:            public void generateSchemaType(XMLStreamWriter out)
0982:                    throws JAXBException, XMLStreamException {
0983:                if (_value != null) {
0984:                    out.writeStartElement(XML_SCHEMA_PREFIX, "simpleType",
0985:                            XML_SCHEMA_NS);
0986:
0987:                    if (!"".equals(_typeName.getLocalPart()))
0988:                        out.writeAttribute("name", _typeName.getLocalPart());
0989:
0990:                    if (Collection.class.isAssignableFrom(_value.getAccessor()
0991:                            .getType())) {
0992:                        out.writeEmptyElement(XML_SCHEMA_PREFIX, "list",
0993:                                XML_SCHEMA_NS);
0994:
0995:                        String itemType = StaxUtil.qnameToString(out, _value
0996:                                .getSchemaType());
0997:
0998:                        out.writeAttribute("itemType", itemType);
0999:                    } else {
1000:                        out.writeEmptyElement(XML_SCHEMA_PREFIX, "restriction",
1001:                                XML_SCHEMA_NS);
1002:
1003:                        String base = StaxUtil.qnameToString(out, _value
1004:                                .getSchemaType());
1005:
1006:                        out.writeAttribute("base", base);
1007:                    }
1008:
1009:                    for (XmlMapping mapping : _attributeMappings)
1010:                        mapping.generateSchema(out);
1011:
1012:                    out.writeEndElement(); // simpleType
1013:                } else {
1014:                    out.writeStartElement(XML_SCHEMA_PREFIX, "complexType",
1015:                            XML_SCHEMA_NS);
1016:
1017:                    if (Modifier.isAbstract(_class.getModifiers()))
1018:                        out.writeAttribute("abstract", "true");
1019:
1020:                    if (!"".equals(_typeName.getLocalPart()))
1021:                        out.writeAttribute("name", _typeName.getLocalPart());
1022:
1023:                    out.writeStartElement(XML_SCHEMA_PREFIX, "sequence",
1024:                            XML_SCHEMA_NS);
1025:
1026:                    for (XmlMapping mapping : _elementMappings)
1027:                        mapping.generateSchema(out);
1028:
1029:                    if (_anyElementMapping != null)
1030:                        _anyElementMapping.generateSchema(out);
1031:
1032:                    out.writeEndElement(); // sequence
1033:
1034:                    for (XmlMapping mapping : _attributeMappings)
1035:                        mapping.generateSchema(out);
1036:
1037:                    out.writeEndElement(); // complexType
1038:                }
1039:            }
1040:
1041:            //XXX The TreeSet needs this for some reason
1042:            private static final Comparator methodComparator = new java.util.Comparator<Method>() {
1043:                public int compare(Method m1, Method m2) {
1044:                    return m1.toGenericString().compareTo(m2.toGenericString());
1045:                }
1046:
1047:                public boolean equals(Object obj) {
1048:                    return obj == this;
1049:                }
1050:            };
1051:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.