1 /*
2 * Copyright 2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.springframework.oxm.support;
18
19 import java.io.IOException;
20 import javax.xml.transform.Source;
21 import javax.xml.transform.sax.SAXResult;
22 import javax.xml.transform.sax.SAXSource;
23
24 import org.springframework.oxm.Marshaller;
25 import org.springframework.util.Assert;
26 import org.springframework.xml.sax.AbstractXmlReader;
27 import org.xml.sax.InputSource;
28 import org.xml.sax.SAXException;
29 import org.xml.sax.SAXParseException;
30
31 /**
32 * {@link Source} implementation that uses a {@link Marshaller}.Can be constructed with a <code>Marshaller</code> and an
33 * object to be marshalled.
34 * <p/>
35 * Even though <code>StaxSource</code> extends from <code>SAXSource</code>, calling the methods of
36 * <code>SAXSource</code> is <strong>not supported</strong>. In general, the only supported operation on this class is
37 * to use the <code>XMLReader</code> obtained via {@link #getXMLReader()} to parse the input source obtained via {@link
38 * #getInputSource()}. Calling {@link #setXMLReader(org.xml.sax.XMLReader)} or {@link
39 * #setInputSource(org.xml.sax.InputSource)} will result in <code>UnsupportedOperationException</code>s.
40 *
41 * @author Arjen Poutsma
42 * @see javax.xml.transform.Transformer
43 * @since 1.0.0
44 */
45 public class MarshallingSource extends SAXSource {
46
47 private final Marshaller marshaller;
48
49 private final Object content;
50
51 /**
52 * Creates a new <code>MarshallingSource</code> with the given marshaller and content.
53 *
54 * @param marshaller the marshaller to use
55 * @param content the object to be marshalled
56 */
57 public MarshallingSource(Marshaller marshaller, Object content) {
58 Assert.notNull(marshaller, "'marshaller' must not be null");
59 Assert.notNull(content, "'content' must not be null");
60 this.marshaller = marshaller;
61 this.content = content;
62 setXMLReader(new MarshallingXmlReader());
63 setInputSource(new InputSource());
64 }
65
66 /** Returns the <code>Marshaller</code> used by this <code>MarshallingSource</code>. */
67 public Marshaller getMarshaller() {
68 return marshaller;
69 }
70
71 /** Returns the object to be marshalled. */
72 public Object getContent() {
73 return content;
74 }
75
76 private class MarshallingXmlReader extends AbstractXmlReader {
77
78 public void parse(InputSource input) throws IOException, SAXException {
79 parse();
80 }
81
82 public void parse(String systemId) throws IOException, SAXException {
83 parse();
84 }
85
86 private void parse() throws SAXException {
87 SAXResult result = new SAXResult(getContentHandler());
88 result.setLexicalHandler(getLexicalHandler());
89 try {
90 marshaller.marshal(content, result);
91 }
92 catch (IOException ex) {
93 SAXParseException saxException = new SAXParseException(ex.getMessage(), null, null, -1, -1, ex);
94 if (getErrorHandler() != null) {
95 getErrorHandler().fatalError(saxException);
96 }
97 else {
98 throw saxException;
99 }
100 }
101 }
102
103 }
104 }