001: /*
002: * Copyright (c) 1998-2006 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 Adam Megacz
028: */
029:
030: package com.caucho.jaxb;
031:
032: import com.caucho.jaxb.adapters.BeanAdapter;
033: import com.caucho.jaxb.skeleton.ClassSkeleton;
034: import com.caucho.xml.stream.StaxUtil;
035: import com.caucho.util.L10N;
036:
037: import java.io.File;
038: import javax.xml.bind.JAXBException;
039: import javax.xml.bind.Marshaller;
040: import javax.xml.bind.MarshalException;
041: import javax.xml.bind.annotation.XmlRootElement;
042: import javax.xml.bind.annotation.XmlType;
043: import javax.xml.bind.annotation.adapters.XmlAdapter;
044: import javax.xml.bind.helpers.AbstractMarshallerImpl;
045: import javax.xml.namespace.QName;
046: import javax.xml.stream.XMLEventWriter;
047: import javax.xml.stream.XMLOutputFactory;
048: import javax.xml.stream.XMLStreamException;
049: import javax.xml.stream.XMLStreamWriter;
050: import javax.xml.transform.Result;
051:
052: public class MarshallerImpl extends AbstractMarshallerImpl {
053: public static final L10N L = new L10N(MarshallerImpl.class);
054:
055: private JAXBContextImpl _context;
056: private Listener _listener;
057: private XMLOutputFactory _xmlOutputFactory;
058:
059: MarshallerImpl(JAXBContextImpl context) throws JAXBException {
060: _context = context;
061: _xmlOutputFactory = XMLOutputFactory.newInstance();
062: _xmlOutputFactory.setProperty(
063: XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
064: }
065:
066: /**
067: * Marshal the content tree rooted at jaxbElement into a .
068: */
069: public void marshal(Object jaxbElement, XMLStreamWriter writer)
070: throws JAXBException {
071: ClassSkeleton skeleton = _context
072: .findSkeletonForObject(jaxbElement);
073:
074: if (skeleton == null)
075: throw new MarshalException(
076: L
077: .l(
078: "Unable to marshal {0}: its type unknown to this JAXBContext",
079: jaxbElement));
080:
081: Class c = skeleton.getType();
082: writer = StaxUtil.toRepairingXMLStreamWriter(writer);
083:
084: // tck/JAXBMarshall
085: if (!_context.createJAXBIntrospector().isElement(jaxbElement)
086: && !c.isAnnotationPresent(XmlRootElement.class))
087: throw new MarshalException(
088: "JAXBIntrospector.isElement()==false");
089:
090: /*
091: String name = null;
092: String namespace = null;
093:
094: /// XXX: put into skeleton?
095: XmlType xmlTypeAnnotation = (XmlType) c.getAnnotation(XmlType.class);
096:
097: if (name == null) {
098: name =
099: (xmlTypeAnnotation == null ? c.getName() : xmlTypeAnnotation.name());
100: }
101:
102: XmlRootElement xre = (XmlRootElement) c.getAnnotation(XmlRootElement.class);
103:
104: if (xre != null)
105: name = xre.name();*/
106:
107: String encoding = getEncoding();
108:
109: if (encoding == null)
110: encoding = "utf-8";
111:
112: try {
113: if (!isFragment())
114: writer.writeStartDocument(encoding, "1.0");
115:
116: // XXX this needs to happen after the startElement is written
117: // jaxb/5003
118: /*
119: if (getNoNSSchemaLocation() != null)
120: writer.writeAttribute("xsi",
121: "http://www.w3.org/2001/XMLSchema-instance",
122: "noNamespaceSchemaLocation",
123: getNoNSSchemaLocation());
124: */
125:
126: skeleton.write(this , writer, jaxbElement, null, null);
127:
128: writer.writeEndDocument();
129: } catch (JAXBException e) {
130: throw e;
131: } catch (Exception e) {
132: throw new JAXBException(e);
133: }
134: }
135:
136: public Listener getListener() {
137: return _listener;
138: }
139:
140: public void setListener(Marshaller.Listener listener) {
141: _listener = listener;
142: }
143:
144: public void marshal(Object obj, XMLEventWriter writer)
145: throws JAXBException {
146: throw new UnsupportedOperationException();
147: }
148:
149: public void marshal(Object obj, File file) throws JAXBException {
150: throw new UnsupportedOperationException();
151: }
152:
153: public void marshal(Object obj, Result result) throws JAXBException {
154: if (!_context.createJAXBIntrospector().isElement(obj))
155: throw new MarshalException(L.l(
156: "Object is not a JAXB element: {0}", obj));
157:
158: try {
159: XMLStreamWriter out = _xmlOutputFactory
160: .createXMLStreamWriter(result);
161:
162: marshal(obj, out);
163:
164: out.flush();
165: } catch (XMLStreamException e) {
166: throw new JAXBException(e);
167: }
168: }
169:
170: public <A extends XmlAdapter> A getAdapter(Class<A> type) {
171: A a = super .getAdapter(type);
172:
173: if (a == null)
174: return (A) new BeanAdapter();
175:
176: return a;
177: }
178: }
|