001: /*
002: * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Emil Ong
028: */
029:
030: package com.caucho.jaxb.skeleton;
031:
032: import com.caucho.jaxb.BinderImpl;
033: import com.caucho.jaxb.JAXBContextImpl;
034: import com.caucho.jaxb.JAXBUtil;
035: import com.caucho.jaxb.NodeIterator;
036: import com.caucho.jaxb.mapping.XmlInstanceWrapper;
037: import com.caucho.jaxb.mapping.Namer;
038: import com.caucho.jaxb.mapping.XmlMapping;
039: import com.caucho.jaxb.property.Property;
040: import com.caucho.util.L10N;
041: import com.caucho.xml.stream.StaxUtil;
042:
043: import org.w3c.dom.Document;
044: import org.w3c.dom.Node;
045:
046: import static javax.xml.XMLConstants.*;
047: import javax.xml.bind.annotation.*;
048: import javax.xml.bind.JAXBElement;
049: import javax.xml.bind.JAXBException;
050: import javax.xml.bind.Marshaller;
051: import javax.xml.bind.Unmarshaller;
052: import javax.xml.namespace.QName;
053: import javax.xml.stream.XMLInputFactory;
054: import javax.xml.stream.XMLOutputFactory;
055: import javax.xml.stream.XMLStreamConstants;
056: import javax.xml.stream.XMLStreamException;
057: import javax.xml.stream.XMLStreamReader;
058: import javax.xml.stream.XMLStreamWriter;
059: import javax.xml.transform.dom.DOMResult;
060: import javax.xml.transform.dom.DOMSource;
061:
062: import java.io.IOException;
063:
064: import java.lang.annotation.*;
065: import java.lang.reflect.*;
066:
067: import java.util.ArrayList;
068: import java.util.logging.Logger;
069:
070: /**
071: *
072: **/
073: public class AnyTypeSkeleton extends ClassSkeleton<Object> {
074: private static final Logger log = Logger
075: .getLogger(AnyTypeSkeleton.class.getName());
076: private static final L10N L = new L10N(AnyTypeSkeleton.class);
077:
078: public AnyTypeSkeleton(JAXBContextImpl context)
079: throws JAXBException {
080: super (context);
081: }
082:
083: public Object read(Unmarshaller u, XMLStreamReader in)
084: throws IOException, XMLStreamException, JAXBException {
085: String type = in.getAttributeValue(
086: W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
087:
088: if (type != null) {
089: QName typeQName = StaxUtil.resolveStringToQName(type, in);
090: Class cl = JAXBUtil.getClassForDatatype(typeQName);
091:
092: Property property = _context.createProperty(cl);
093:
094: return property.read(u, in, null);
095: } else {
096: DOMResult result = new DOMResult();
097: XMLOutputFactory factory = _context.getXMLOutputFactory();
098: XMLStreamWriter out = factory.createXMLStreamWriter(result);
099:
100: StaxUtil.copyReaderToWriter(in, out);
101:
102: Node node = result.getNode();
103:
104: if (node.getNodeType() == Node.DOCUMENT_NODE)
105: node = ((Document) node).getDocumentElement();
106:
107: return node;
108: }
109: }
110:
111: public Object bindFrom(BinderImpl binder, Object existing,
112: NodeIterator node) throws JAXBException {
113: // skipping a subtree is much easier in DOM =D
114: return null;
115: }
116:
117: public void write(Marshaller m, XMLStreamWriter out, Object obj,
118: Namer namer, ArrayList<XmlMapping> attributes)
119: throws IOException, XMLStreamException, JAXBException {
120: if (obj != null) {
121: ClassSkeleton skeleton = _context
122: .findSkeletonForObject(obj);
123:
124: if (skeleton != null) {
125: // XXX if (skeleton.getTypeName() == null) {}
126:
127: /*
128: XmlInstanceWrapper instanceWrapper
129: = new XmlInstanceWrapper(skeleton.getTypeName());
130:
131: attributes = instanceWrapper.getExtendedIterator(attributes);*/
132:
133: skeleton.write(m, out, obj, null, attributes);
134: return;
135: }
136:
137: Property property = _context.getSimpleTypeProperty(obj
138: .getClass());
139:
140: if (property != null) {
141: XmlInstanceWrapper instanceWrapper = XmlInstanceWrapper
142: .getInstance(property.getSchemaType());
143:
144: if (attributes == null)
145: attributes = new ArrayList<XmlMapping>(1);
146:
147: attributes.add(instanceWrapper);
148:
149: // XXX the second obj here is a hack: we just need it not to be null.
150: // Figure out if the api is wrong or there is a reasonable value for
151: // the fifth argument instead of this second obj.
152: property.write(m, out, obj, namer, obj, attributes);
153: return;
154: }
155:
156: if (obj instanceof Node) {
157: XMLInputFactory factory = _context.getXMLInputFactory();
158: DOMSource source = new DOMSource((Node) obj);
159: XMLStreamReader in = factory
160: .createXMLStreamReader(source);
161:
162: StaxUtil.copyReaderToWriter(in, out);
163:
164: return;
165: }
166:
167: QName fieldName = namer.getQName(obj);
168:
169: if (fieldName.getNamespaceURI() == null)
170: out.writeEmptyElement(fieldName.getLocalPart());
171: else if (fieldName.getPrefix() == null)
172: out.writeEmptyElement(fieldName.getNamespaceURI(),
173: fieldName.getLocalPart());
174: else
175: out.writeEmptyElement(fieldName.getPrefix(), fieldName
176: .getLocalPart(), fieldName.getNamespaceURI());
177: }
178: }
179:
180: public Node bindTo(BinderImpl binder, Node node, Object obj,
181: Namer namer) throws JAXBException {
182: return node;
183: }
184:
185: public String toString() {
186: return "AnyTypeSkeleton[]";
187: }
188: }
|