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