diff --git a/oxm/src/main/java/org/springframework/oxm/support/MarshallingSource.java b/oxm/src/main/java/org/springframework/oxm/support/MarshallingSource.java new file mode 100644 index 00000000..c8975547 --- /dev/null +++ b/oxm/src/main/java/org/springframework/oxm/support/MarshallingSource.java @@ -0,0 +1,103 @@ +/* + * Copyright 2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.oxm.support; + +import java.io.IOException; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXSource; + +import org.springframework.oxm.Marshaller; +import org.springframework.util.Assert; +import org.springframework.xml.sax.AbstractXmlReader; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +/** + * {@link Source} implementation that uses a {@link Marshaller}.Can be constructed with a Marshaller and an + * object to be marshalled. + *

+ * Even though StaxSource extends from SAXSource, calling the methods of + * SAXSource is not supported. In general, the only supported operation on this class is + * to use the XMLReader obtained via {@link #getXMLReader()} to parse the input source obtained via {@link + * #getInputSource()}. Calling {@link #setXMLReader(org.xml.sax.XMLReader)} or {@link + * #setInputSource(org.xml.sax.InputSource)} will result in UnsupportedOperationExceptions. + * + * @author Arjen Poutsma + * @see javax.xml.transform.Transformer + */ +public class MarshallingSource extends SAXSource { + + private final Marshaller marshaller; + + private final Object content; + + /** + * Creates a new MarshallingSource with the given marshaller and content. + * + * @param marshaller the marshaller to use + * @param content the object to be marshalled + */ + public MarshallingSource(Marshaller marshaller, Object content) { + Assert.notNull(marshaller, "'marshaller' must not be null"); + Assert.notNull(content, "'content' must not be null"); + this.marshaller = marshaller; + this.content = content; + setXMLReader(new MarshallingXmlReader()); + setInputSource(new InputSource()); + } + + /** Returns the Marshaller used by this MarshallingSource. */ + public Marshaller getMarshaller() { + return marshaller; + } + + /** Returns the object to be marshalled. */ + public Object getContent() { + return content; + } + + private class MarshallingXmlReader extends AbstractXmlReader { + + public void parse(InputSource input) throws IOException, SAXException { + parse(); + } + + public void parse(String systemId) throws IOException, SAXException { + parse(); + } + + private void parse() throws SAXException { + SAXResult result = new SAXResult(getContentHandler()); + result.setLexicalHandler(getLexicalHandler()); + try { + marshaller.marshal(content, result); + } + catch (IOException ex) { + SAXParseException saxException = new SAXParseException(ex.getMessage(), null, null, -1, -1, ex); + if (getErrorHandler() != null) { + getErrorHandler().fatalError(saxException); + } + else { + throw saxException; + } + } + } + + } +} diff --git a/oxm/src/main/java/org/springframework/oxm/support/package.html b/oxm/src/main/java/org/springframework/oxm/support/package.html new file mode 100644 index 00000000..ef499235 --- /dev/null +++ b/oxm/src/main/java/org/springframework/oxm/support/package.html @@ -0,0 +1,7 @@ + + +Provides generic support classes for using Spring's O/X Mapping integration within various scenario's. Includes the +MarshallingSource for compatibility with TrAX. + + + \ No newline at end of file diff --git a/src/changes/changes.xml b/src/changes/changes.xml index c5396b75..4780aac0 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -6,8 +6,10 @@ + Added MarshallingSource, a TrAX Source that uses a Marshaller. Reduce the number of overloaded methods on the - WebServiceTemplate class to aid comprehension. + WebServiceTemplate class to aid comprehension. + Allow specifying names of message factory and message receiver in MessageDispatcherServlet diff --git a/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java b/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java index 821f4200..7f7484c5 100644 --- a/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java +++ b/xml/src/main/java/org/springframework/xml/sax/AbstractXmlReader.java @@ -22,6 +22,7 @@ import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.XMLReader; +import org.xml.sax.ext.LexicalHandler; /** * Abstract base class for SAX XMLReader implementations. Contains properties as defined in {@link @@ -43,6 +44,8 @@ public abstract class AbstractXmlReader implements XMLReader { private ErrorHandler errorHandler; + private LexicalHandler lexicalHandler; + public ContentHandler getContentHandler() { return contentHandler; } @@ -75,6 +78,14 @@ public abstract class AbstractXmlReader implements XMLReader { this.errorHandler = errorHandler; } + public LexicalHandler getLexicalHandler() { + return lexicalHandler; + } + + public void setLexicalHandler(LexicalHandler lexicalHandler) { + this.lexicalHandler = lexicalHandler; + } + /** * Throws a SAXNotRecognizedException exception. * @@ -88,30 +99,35 @@ public abstract class AbstractXmlReader implements XMLReader { /** * Throws a SAXNotRecognizedException exception. * - * @throws org.xml.sax.SAXNotRecognizedException - * always + * @throws SAXNotRecognizedException always */ public void setFeature(String name, boolean value) throws SAXNotRecognizedException { throw new SAXNotRecognizedException(name); } /** - * Throws a SAXNotRecognizedException exception. - * - * @throws org.xml.sax.SAXNotRecognizedException - * always + * Throws a SAXNotRecognizedException exception when the given property does not signify a lexical + * handler. The property name for a lexical handler is http://xml.org/sax/properties/lexical-handler. */ public Object getProperty(String name) throws SAXNotRecognizedException { - throw new SAXNotRecognizedException(name); + if ("http://xml.org/sax/properties/lexical-handler".equals(name)) { + return lexicalHandler; + } + else { + throw new SAXNotRecognizedException(name); + } } /** - * Throws a SAXNotRecognizedException exception. - * - * @throws org.xml.sax.SAXNotRecognizedException - * always + * Throws a SAXNotRecognizedException exception when the given property does not signify a lexical + * handler. The property name for a lexical handler is http://xml.org/sax/properties/lexical-handler. */ public void setProperty(String name, Object value) throws SAXNotRecognizedException { - throw new SAXNotRecognizedException(name); + if ("http://xml.org/sax/properties/lexical-handler".equals(name)) { + lexicalHandler = (LexicalHandler) value; + } + else { + throw new SAXNotRecognizedException(name); + } } }