001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package javax.xml.bind.util;
018    
019    import javax.xml.transform.Source;
020    import javax.xml.transform.sax.SAXSource;
021    import javax.xml.bind.Marshaller;
022    import javax.xml.bind.JAXBContext;
023    import javax.xml.bind.JAXBException;
024    
025    import org.xml.sax.XMLReader;
026    import org.xml.sax.SAXNotRecognizedException;
027    import org.xml.sax.EntityResolver;
028    import org.xml.sax.DTDHandler;
029    import org.xml.sax.ContentHandler;
030    import org.xml.sax.ErrorHandler;
031    import org.xml.sax.SAXException;
032    import org.xml.sax.InputSource;
033    import org.xml.sax.SAXParseException;
034    import org.xml.sax.helpers.XMLFilterImpl;
035    import org.xml.sax.ext.LexicalHandler;
036    
037    public class JAXBSource extends SAXSource {
038    
039        public JAXBSource(JAXBContext context, Object contentObject) throws JAXBException {
040            if (context == null) {
041                throw new JAXBException("context must not be null");
042            }
043            if (contentObject == null) {
044                throw new JAXBException("contentObject must not be null");
045            }
046            setXMLReader(new Reader(context.createMarshaller(), contentObject));
047            setInputSource(new InputSource());
048        }
049    
050        public JAXBSource(final Marshaller marshaller, final Object contentObject) throws JAXBException {
051            if (marshaller == null) {
052                throw new JAXBException("marshaller must not be null");
053            }
054            if (contentObject == null) {
055                throw new JAXBException("contentObject must not be null");
056            }
057            setXMLReader(new Reader(marshaller, contentObject));
058            setInputSource(new InputSource());
059        }
060    
061        private static class Reader implements XMLReader {
062    
063            private LexicalHandler lexicalHandler;
064            private EntityResolver entityResolver;
065            private DTDHandler dtdHandler;
066            private XMLFilterImpl repeater;
067            private ErrorHandler errorHandler;
068            private final Marshaller marshaller;
069            private final Object contentObject;
070    
071            public Reader(Marshaller marshaller, Object contentObject) {
072                this.marshaller = marshaller;
073                this.contentObject = contentObject;
074                repeater = new XMLFilterImpl();
075            }
076    
077            public boolean getFeature(String name) throws SAXNotRecognizedException {
078                if (name.equals("http://xml.org/sax/features/namespaces")) {
079                    return true;
080                }
081                if (name.equals("http://xml.org/sax/features/namespace-prefixes")) {
082                    return false;
083                }
084                throw new SAXNotRecognizedException(name);
085            }
086    
087            public void setFeature(String name, boolean value) throws SAXNotRecognizedException {
088                if (name.equals("http://xml.org/sax/features/namespaces") && value) {
089                    return;
090                }
091                if (name.equals("http://xml.org/sax/features/namespace-prefixes") && !value) {
092                    return;
093                }
094                throw new SAXNotRecognizedException(name);
095            }
096    
097            public Object getProperty(String name) throws SAXNotRecognizedException {
098                if("http://xml.org/sax/properties/lexical-handler".equals(name)) {
099                    return lexicalHandler;
100                }
101                throw new SAXNotRecognizedException(name);
102            }
103    
104            public void setProperty(String name, Object value) throws SAXNotRecognizedException {
105                if("http://xml.org/sax/properties/lexical-handler".equals(name)) {
106                    lexicalHandler = (LexicalHandler) value;
107                    return;
108                }
109                throw new SAXNotRecognizedException(name);
110            }
111    
112            public void setEntityResolver(EntityResolver resolver) {
113                entityResolver = resolver;
114            }
115    
116            public EntityResolver getEntityResolver() {
117                return entityResolver;
118            }
119    
120            public void setDTDHandler(DTDHandler handler) {
121                dtdHandler = handler;
122            }
123    
124            public DTDHandler getDTDHandler() {
125                return dtdHandler;
126            }
127    
128            public void setContentHandler(ContentHandler handler) {
129                repeater.setContentHandler(handler);
130            }
131    
132            public ContentHandler getContentHandler() {
133                return repeater.getContentHandler();
134            }
135    
136            public void setErrorHandler(ErrorHandler handler) {
137                errorHandler = handler;
138            }
139    
140            public ErrorHandler getErrorHandler() {
141                return errorHandler;
142            }
143    
144            public void parse(InputSource input) throws SAXException {
145                parse();
146            }
147    
148            public void parse(String systemId) throws SAXException {
149                parse();
150            }
151    
152            public void parse() throws SAXException {
153                try {
154                    marshaller.marshal(contentObject, repeater);
155                } catch(JAXBException e) {
156                    SAXParseException se = new SAXParseException(e.getMessage(), null, null, -1, -1, e);
157                    if (errorHandler != null) {
158                        errorHandler.fatalError(se);
159                    }
160                    throw se;
161                }
162            }
163    
164        }
165    }