001//
002// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v1.0.6-01/24/2006 06:15 PM(kohsuke)-fcs 
003// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
004// Any modifications to this file will be lost upon recompilation of the source schema. 
005// Generated on: 2012.10.03 at 04:27:47 AM CEST 
006//
007
008package org.jdtaus.mojo.resource.model.impl.runtime;
009
010import java.io.BufferedWriter;
011import java.io.FileOutputStream;
012import java.io.IOException;
013import java.io.OutputStream;
014import java.io.OutputStreamWriter;
015import java.io.UnsupportedEncodingException;
016import java.io.Writer;
017
018import javax.xml.bind.DatatypeConverter;
019import javax.xml.bind.JAXBException;
020import javax.xml.bind.MarshalException;
021import javax.xml.bind.PropertyException;
022import javax.xml.bind.helpers.AbstractMarshallerImpl;
023import javax.xml.parsers.DocumentBuilder;
024import javax.xml.parsers.DocumentBuilderFactory;
025import javax.xml.parsers.ParserConfigurationException;
026import javax.xml.transform.Result;
027import javax.xml.transform.dom.DOMResult;
028import javax.xml.transform.sax.SAXResult;
029import javax.xml.transform.stream.StreamResult;
030
031import org.w3c.dom.Document;
032import org.w3c.dom.Node;
033import org.xml.sax.ContentHandler;
034import org.xml.sax.SAXException;
035import org.xml.sax.helpers.LocatorImpl;
036
037import com.sun.xml.bind.DatatypeConverterImpl;
038import com.sun.xml.bind.JAXBAssertionError;
039import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
040import com.sun.xml.bind.marshaller.DataWriter;
041import com.sun.xml.bind.marshaller.DumbEscapeHandler;
042import com.sun.xml.bind.marshaller.Messages;
043import com.sun.xml.bind.marshaller.MinimumEscapeHandler;
044import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
045import com.sun.xml.bind.marshaller.NioEscapeHandler;
046import com.sun.xml.bind.marshaller.SAX2DOMEx;
047import com.sun.xml.bind.marshaller.SchemaLocationFilter;
048import com.sun.xml.bind.marshaller.XMLWriter;
049
050/**
051 * Implementation of {@link Marshaller} interface for JAXB RI.
052 * 
053 * @author Kohsuke Kawaguchi
054 * @author Vivek Pandey
055 */
056public class MarshallerImpl extends AbstractMarshallerImpl
057{
058    /** Indentation string. Default is four whitespaces. */
059    private String indent = "    ";
060    
061    /** Used to assign prefixes to namespace URIs. */
062    private NamespacePrefixMapper prefixMapper = null;
063    
064    /** Object that handles character escaping. */
065    private CharacterEscapeHandler escapeHandler = null; 
066    
067    /** Whether the xml declaration will be printed or not. */
068    private boolean printXmlDeclaration = true;
069    
070    /** XML BLOB written after the XML declaration. */
071    private String header=null;
072    
073    /** reference to the context that created this object */
074    final DefaultJAXBContextImpl context;
075    
076    public MarshallerImpl( DefaultJAXBContextImpl c ) {
077        // initialize datatype converter with ours
078        DatatypeConverter.setDatatypeConverter(DatatypeConverterImpl.theInstance);
079        
080        context = c;
081    }
082    
083    public void marshal(Object obj, Result result) throws JAXBException {
084        //XMLSerializable so = Util.toXMLSerializable(obj);
085        XMLSerializable so = context.getGrammarInfo().castToXMLSerializable(obj);
086
087        if(so==null)
088            throw new MarshalException( 
089                Messages.format( Messages.NOT_MARSHALLABLE ) );
090
091
092        if (result instanceof SAXResult) {
093            write(so, ((SAXResult) result).getHandler());
094            return;
095        }
096        if (result instanceof DOMResult) {
097            Node node = ((DOMResult) result).getNode();
098
099            if (node == null) {
100                try {
101                    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
102                    dbf.setNamespaceAware(true);
103                    DocumentBuilder db = dbf.newDocumentBuilder();
104                    Document doc = db.newDocument();
105                    ((DOMResult) result).setNode(doc);
106                    write(so, new SAX2DOMEx(doc));
107                } catch (ParserConfigurationException pce) {
108                    throw new JAXBAssertionError(pce);
109                }
110            } else {
111                write(so, new SAX2DOMEx(node));
112            }
113
114            return;
115        }
116        if (result instanceof StreamResult) {
117            StreamResult sr = (StreamResult) result;
118            XMLWriter w = null;
119
120            if (sr.getWriter() != null)
121                w = createWriter(sr.getWriter());
122            else if (sr.getOutputStream() != null)
123                w = createWriter(sr.getOutputStream());
124            else if (sr.getSystemId() != null) {
125                String fileURL = sr.getSystemId();
126
127                if (fileURL.startsWith("file:///")) {
128                    if (fileURL.substring(8).indexOf(":") > 0)
129                        fileURL = fileURL.substring(8);
130                    else
131                        fileURL = fileURL.substring(7);
132                } // otherwise assume that it's a file name
133
134                try {
135                    w = createWriter(new FileOutputStream(fileURL));
136                } catch (IOException e) {
137                    throw new MarshalException(e);
138                }
139            }
140
141            if (w == null)
142                throw new IllegalArgumentException();
143
144            write(so, w);
145            return;
146        }
147
148        // unsupported parameter type
149        throw new MarshalException( 
150            Messages.format( Messages.UNSUPPORTED_RESULT ) );
151    }
152    
153    private void write( XMLSerializable obj, ContentHandler writer )
154        throws JAXBException {
155
156        try {
157            if( getSchemaLocation()!=null || getNoNSSchemaLocation()!=null ) {
158                // if we need to add xsi:schemaLocation or its brother,
159                // throw in the component to do that.
160                writer = new SchemaLocationFilter(
161                    getSchemaLocation(),
162                    getNoNSSchemaLocation(),
163                    writer );
164            }
165            
166            SAXMarshaller serializer = new SAXMarshaller(writer,prefixMapper,this);
167        
168            // set a DocumentLocator that doesn't provide any information
169            writer.setDocumentLocator( new LocatorImpl() );
170            writer.startDocument();
171            serializer.childAsBody(obj,null);
172            writer.endDocument();
173            
174            serializer.reconcileID();   // extra check
175        } catch( SAXException e ) {
176            throw new MarshalException(e);
177        }
178    }
179    
180    
181    //
182    //
183    // create XMLWriter by specifing various type of output.
184    //
185    //
186    
187    protected CharacterEscapeHandler createEscapeHandler( String encoding ) {
188        if( escapeHandler!=null )
189            // user-specified one takes precedence.
190            return escapeHandler;
191        
192        if( encoding.startsWith("UTF") )
193            // no need for character reference. Use the handler
194            // optimized for that pattern.
195            return MinimumEscapeHandler.theInstance;
196        
197        // otherwise try to find one from the encoding
198        try {
199            // try new JDK1.4 NIO
200            return new NioEscapeHandler( getJavaEncoding(encoding) );
201        } catch( Throwable e ) {
202            // if that fails, fall back to the dumb mode
203            return DumbEscapeHandler.theInstance;
204        }
205    }
206            
207    public XMLWriter createWriter( Writer w, String encoding ) throws JAXBException {
208        
209        // buffering improves the performance
210        w = new BufferedWriter(w);
211        
212        CharacterEscapeHandler ceh = createEscapeHandler(encoding);
213        XMLWriter xw;
214        
215        if(isFormattedOutput()) {
216            DataWriter d = new DataWriter(w,encoding,ceh);
217            d.setIndentStep(indent);
218            xw=d;
219        } 
220        else
221            xw = new XMLWriter(w,encoding,ceh);
222            
223        xw.setXmlDecl(printXmlDeclaration);
224        xw.setHeader(header);
225        return xw;
226    }
227
228    public XMLWriter createWriter(Writer w) throws JAXBException{
229        return createWriter(w, getEncoding());
230    }
231    
232    public XMLWriter createWriter( OutputStream os ) throws JAXBException {
233        return createWriter(os, getEncoding());
234    }
235    
236    public XMLWriter createWriter( OutputStream os, String encoding ) throws JAXBException {
237        try {
238            return createWriter(
239                new OutputStreamWriter(os,getJavaEncoding(encoding)),
240                encoding );
241        } catch( UnsupportedEncodingException e ) {
242            throw new MarshalException(
243                Messages.format( Messages.UNSUPPORTED_ENCODING, encoding ),
244                e );
245        }
246    }
247    
248    
249    public Object getProperty(String name) throws PropertyException {
250        if( INDENT_STRING.equals(name) )
251            return indent;
252        if( ENCODING_HANDLER.equals(name) )
253            return escapeHandler;
254        if( PREFIX_MAPPER.equals(name) )
255            return prefixMapper;
256        if( XMLDECLARATION.equals(name) )
257            return printXmlDeclaration ? Boolean.TRUE : Boolean.FALSE;
258        if( XML_HEADERS.equals(name) )
259            return header;
260        
261        return super.getProperty(name);
262    }
263
264    public void setProperty(String name, Object value) throws PropertyException {
265        if( INDENT_STRING.equals(name) && value instanceof String ) {
266            indent = (String)value;
267            return;
268        }
269        if( ENCODING_HANDLER.equals(name) ) {
270            escapeHandler = (CharacterEscapeHandler)value;
271            return;
272        }
273        if( PREFIX_MAPPER.equals(name) ) {
274            prefixMapper = (NamespacePrefixMapper)value;
275            return;
276        }
277        if( XMLDECLARATION.equals(name) ) {
278            printXmlDeclaration = ((Boolean)value).booleanValue();
279            return;
280        }
281        if( XML_HEADERS.equals(name) ) {
282            header = (String)value;
283            return;
284        }
285            
286        super.setProperty(name, value);
287    }
288    
289    private static final String INDENT_STRING = "com.sun.xml.bind.indentString"; 
290    private static final String PREFIX_MAPPER = "com.sun.xml.bind.namespacePrefixMapper"; 
291    private static final String ENCODING_HANDLER = "com.sun.xml.bind.characterEscapeHandler"; 
292    private static final String XMLDECLARATION = "com.sun.xml.bind.xmlDeclaration"; 
293    private static final String XML_HEADERS = "com.sun.xml.bind.xmlHeaders";
294}