001: /*
002: * Copyright 2005 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.ws.server.endpoint;
018:
019: import java.io.IOException;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023: import org.springframework.beans.factory.InitializingBean;
024: import org.springframework.oxm.Marshaller;
025: import org.springframework.oxm.Unmarshaller;
026: import org.springframework.util.Assert;
027: import org.springframework.ws.WebServiceMessage;
028: import org.springframework.ws.context.MessageContext;
029: import org.springframework.ws.support.MarshallingUtils;
030:
031: /**
032: * Endpoint that unmarshals the request payload, and marshals the response object. This endpoint needs a
033: * <code>Marshaller</code> and <code>Unmarshaller</code>, both of which can be set using properties. An abstract
034: * template method is invoked using the request object as a parameter, and allows for a response object to be returned.
035: *
036: * @author Arjen Poutsma
037: * @see #setMarshaller(org.springframework.oxm.Marshaller)
038: * @see Marshaller
039: * @see #setUnmarshaller(org.springframework.oxm.Unmarshaller)
040: * @see Unmarshaller
041: * @see #invokeInternal(Object)
042: * @since 1.0.0
043: */
044: public abstract class AbstractMarshallingPayloadEndpoint implements
045: MessageEndpoint, InitializingBean {
046:
047: /** Logger available to subclasses. */
048: protected final Log logger = LogFactory.getLog(getClass());
049:
050: private Marshaller marshaller;
051:
052: private Unmarshaller unmarshaller;
053:
054: /**
055: * Creates a new <code>AbstractMarshallingPayloadEndpoint</code>. The {@link Marshaller} and {@link Unmarshaller}
056: * must be injected using properties.
057: *
058: * @see #setMarshaller(org.springframework.oxm.Marshaller)
059: * @see #setUnmarshaller(org.springframework.oxm.Unmarshaller)
060: */
061: protected AbstractMarshallingPayloadEndpoint() {
062: }
063:
064: /**
065: * Creates a new <code>AbstractMarshallingPayloadEndpoint</code> with the given marshaller. The given {@link
066: * Marshaller} should also implements the {@link Unmarshaller}, since it is used for both marshalling and
067: * unmarshalling. If it is not, an exception is thrown.
068: * <p/>
069: * Note that all {@link Marshaller} implementations in Spring-WS also implement the {@link Unmarshaller} interface,
070: * so that you can safely use this constructor.
071: *
072: * @param marshaller object used as marshaller and unmarshaller
073: * @throws IllegalArgumentException when <code>marshaller</code> does not implement the {@link Unmarshaller}
074: * interface
075: * @see #AbstractMarshallingPayloadEndpoint(Marshaller,Unmarshaller)
076: */
077: protected AbstractMarshallingPayloadEndpoint(Marshaller marshaller) {
078: Assert.notNull(marshaller, "marshaller must not be null");
079: if (!(marshaller instanceof Unmarshaller)) {
080: throw new IllegalArgumentException(
081: "Marshaller ["
082: + marshaller
083: + "] does not implement the Unmarshaller "
084: + "interface. Please set an Unmarshaller explicitely by using the "
085: + "AbstractMarshallingPayloadEndpoint(Marshaller, Unmarshaller) constructor.");
086: } else {
087: setMarshaller(marshaller);
088: setUnmarshaller((Unmarshaller) marshaller);
089: }
090: }
091:
092: /**
093: * Creates a new <code>AbstractMarshallingPayloadEndpoint</code> with the given marshaller and unmarshaller.
094: *
095: * @param marshaller the marshaller to use
096: * @param unmarshaller the unmarshaller to use
097: */
098: protected AbstractMarshallingPayloadEndpoint(Marshaller marshaller,
099: Unmarshaller unmarshaller) {
100: Assert.notNull(marshaller, "marshaller must not be null");
101: Assert.notNull(unmarshaller, "unmarshaller must not be null");
102: setMarshaller(marshaller);
103: setUnmarshaller(unmarshaller);
104: }
105:
106: /** Returns the marshaller used for transforming objects into XML. */
107: public Marshaller getMarshaller() {
108: return marshaller;
109: }
110:
111: /** Sets the marshaller used for transforming objects into XML. */
112: public final void setMarshaller(Marshaller marshaller) {
113: this .marshaller = marshaller;
114: }
115:
116: /** Returns the unmarshaller used for transforming XML into objects. */
117: public Unmarshaller getUnmarshaller() {
118: return unmarshaller;
119: }
120:
121: /** Sets the unmarshaller used for transforming XML into objects. */
122: public final void setUnmarshaller(Unmarshaller unmarshaller) {
123: this .unmarshaller = unmarshaller;
124: }
125:
126: public final void afterPropertiesSet() throws Exception {
127: Assert.notNull(getMarshaller(), "marshaller is required");
128: Assert.notNull(getUnmarshaller(), "unmarshaller is required");
129: afterMarshallerSet();
130: }
131:
132: public final void invoke(MessageContext messageContext)
133: throws Exception {
134: WebServiceMessage request = messageContext.getRequest();
135: Object requestObject = unmarshalRequest(request);
136: Object responseObject = invokeInternal(requestObject);
137: if (responseObject != null) {
138: WebServiceMessage response = messageContext.getResponse();
139: marshalResponse(responseObject, response);
140: }
141: }
142:
143: private Object unmarshalRequest(WebServiceMessage request)
144: throws IOException {
145: Object requestObject = MarshallingUtils.unmarshal(
146: getUnmarshaller(), request);
147: if (logger.isDebugEnabled()) {
148: logger.debug("Unmarshalled payload request to ["
149: + requestObject + "]");
150: }
151: return requestObject;
152: }
153:
154: private void marshalResponse(Object responseObject,
155: WebServiceMessage response) throws IOException {
156: if (logger.isDebugEnabled()) {
157: logger.debug("Marshalling [" + responseObject
158: + "] to response payload");
159: }
160: MarshallingUtils.marshal(getMarshaller(), responseObject,
161: response);
162: }
163:
164: /**
165: * Template method that gets called after the marshaller and unmarshaller have been set.
166: * <p/>
167: * The default implementation does nothing.
168: */
169: public void afterMarshallerSet() throws Exception {
170: }
171:
172: /**
173: * Template method that subclasses must implement to process a request.
174: * <p/>
175: * The unmarshaled request object is passed as a parameter, and the returned object is marshalled to a response. If
176: * no response is required, return <code>null</code>.
177: *
178: * @param requestObject the unnmarshalled message payload as an object
179: * @return the object to be marshalled as response, or <code>null</code> if a response is not required
180: */
181: protected abstract Object invokeInternal(Object requestObject)
182: throws Exception;
183: }
|