001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.jaxws.client.dispatch;
020:
021: import org.apache.axis2.jaxws.ExceptionFactory;
022: import org.apache.axis2.jaxws.client.async.AsyncResponse;
023: import org.apache.axis2.jaxws.description.EndpointDescription;
024: import org.apache.axis2.jaxws.message.Block;
025: import org.apache.axis2.jaxws.message.Message;
026: import org.apache.axis2.jaxws.message.Protocol;
027: import org.apache.axis2.jaxws.message.factory.BlockFactory;
028: import org.apache.axis2.jaxws.message.factory.MessageFactory;
029: import org.apache.axis2.jaxws.message.factory.SOAPEnvelopeBlockFactory;
030: import org.apache.axis2.jaxws.message.factory.SourceBlockFactory;
031: import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
032: import org.apache.axis2.jaxws.registry.FactoryRegistry;
033: import org.apache.axis2.jaxws.spi.ServiceDelegate;
034: import org.apache.commons.logging.Log;
035: import org.apache.commons.logging.LogFactory;
036:
037: import javax.xml.soap.SOAPEnvelope;
038: import javax.xml.soap.SOAPMessage;
039: import javax.xml.stream.XMLStreamException;
040: import javax.xml.transform.Source;
041: import javax.xml.ws.Service.Mode;
042: import javax.xml.ws.WebServiceException;
043:
044: public class XMLDispatch<T> extends BaseDispatch<T> {
045: private static final Log log = LogFactory.getLog(XMLDispatch.class);
046: private Class type;
047: private Class blockFactoryType;
048:
049: public XMLDispatch(ServiceDelegate svcDelegate,
050: EndpointDescription enpdointDesc) {
051: super (svcDelegate, enpdointDesc);
052: }
053:
054: public Class getType() {
055: return type;
056: }
057:
058: public void setType(Class c) {
059: type = c;
060: }
061:
062: public AsyncResponse createAsyncResponseListener() {
063: if (log.isDebugEnabled()) {
064: log.debug("Creating new AsyncListener for XMLDispatch");
065: }
066:
067: XMLDispatchAsyncListener al = new XMLDispatchAsyncListener(
068: getEndpointDescription());
069: al.setMode(mode);
070: al.setType(type);
071: al.setBlockFactoryType(blockFactoryType);
072: return al;
073: }
074:
075: public Message createMessageFromValue(Object value) {
076: if (value != null) {
077: type = value.getClass();
078: if (log.isDebugEnabled()) {
079: log.debug("Parameter type: " + type.getName());
080: log.debug("Message mode: " + mode.name());
081: }
082: } else {
083: if (log.isDebugEnabled()) {
084: log.debug("Dispatch invoked with null parameter Value");
085: log.debug("creating empty soap message");
086: }
087: try {
088: blockFactoryType = getBlockFactory();
089: return createEmptyMessage(Protocol
090: .getProtocolForBinding(endpointDesc
091: .getClientBindingID()));
092:
093: } catch (XMLStreamException e) {
094: throw ExceptionFactory.makeWebServiceException(e);
095: }
096:
097: }
098: Block block = null;
099: blockFactoryType = getBlockFactory(value);
100: BlockFactory factory = (BlockFactory) FactoryRegistry
101: .getFactory(blockFactoryType);
102: if (log.isDebugEnabled()) {
103: log.debug("Loaded block factory type ["
104: + blockFactoryType.getName());
105: }
106: // The protocol of the Message that is created should be based
107: // on the binding information available.
108: Protocol proto = Protocol.getProtocolForBinding(endpointDesc
109: .getClientBindingID());
110: Message message = null;
111: if (mode.equals(Mode.PAYLOAD)) {
112: try {
113: MessageFactory mf = (MessageFactory) FactoryRegistry
114: .getFactory(MessageFactory.class);
115: block = factory.createFrom(value, null, null);
116:
117: message = mf.create(proto);
118: message.setBodyBlock(block);
119: } catch (Exception e) {
120: throw ExceptionFactory.makeWebServiceException(e);
121: }
122: } else if (mode.equals(Mode.MESSAGE)) {
123: try {
124: MessageFactory mf = (MessageFactory) FactoryRegistry
125: .getFactory(MessageFactory.class);
126: // If the value contains just the xml data, then you can create the Message directly from the
127: // Block. If the value contains attachments, you need to do more.
128: // TODO For now the only value that contains Attachments is SOAPMessage
129: if (value instanceof SOAPMessage) {
130: message = mf.createFrom((SOAPMessage) value);
131: } else {
132: block = factory.createFrom(value, null, null);
133: message = mf.createFrom(block, null, proto);
134: }
135: } catch (Exception e) {
136: throw ExceptionFactory.makeWebServiceException(e);
137: }
138: }
139:
140: return message;
141: }
142:
143: public Object getValueFromMessage(Message message) {
144: return getValue(message, mode, blockFactoryType);
145: }
146:
147: /**
148: * Common code used by XMLDispatch and XMLDispatchAsyncListener
149: *
150: * @param message
151: * @return object
152: */
153: static Object getValue(Message message, Mode mode,
154: Class blockFactoryType) {
155: Object value = null;
156: Block block = null;
157:
158: if (log.isDebugEnabled()) {
159: log
160: .debug("Attempting to get the value object from the returned message");
161: }
162:
163: try {
164: if (mode.equals(Mode.PAYLOAD)) {
165: BlockFactory factory = (BlockFactory) FactoryRegistry
166: .getFactory(blockFactoryType);
167: block = message.getBodyBlock(null, factory);
168: if (block != null) {
169: value = block.getBusinessObject(true);
170: } else {
171: // REVIEW This seems like the correct behavior. If the body is empty, return a null
172: // Any changes here should also be made to XMLDispatch.getValue
173: if (log.isDebugEnabled()) {
174: log
175: .debug("There are no elements in the body to unmarshal. XMLDispatch returns a null value");
176: }
177: value = null;
178: }
179:
180: } else if (mode.equals(Mode.MESSAGE)) {
181: BlockFactory factory = (BlockFactory) FactoryRegistry
182: .getFactory(blockFactoryType);
183: value = message.getValue(null, factory);
184: if (value == null) {
185: if (log.isDebugEnabled()) {
186: log
187: .debug("There are no elements to unmarshal. XMLDispatch returns a null value");
188: }
189: }
190: }
191:
192: } catch (Exception e) {
193: if (log.isDebugEnabled()) {
194: log.debug("An error occured while creating the block");
195: }
196: throw ExceptionFactory.makeWebServiceException(e);
197: }
198:
199: if (log.isDebugEnabled()) {
200: if (value == null)
201: log.debug("Returning a null value");
202: else
203: log.debug("Returning value of type: "
204: + value.getClass().getName());
205: }
206:
207: return value;
208: }
209:
210: private Class getBlockFactory(Object o) {
211: if (o instanceof String) {
212: if (log.isDebugEnabled()) {
213: log.debug(">> returning XMLStringBlockFactory");
214: }
215: return XMLStringBlockFactory.class;
216: } else if (Source.class.isAssignableFrom(o.getClass())) {
217: if (log.isDebugEnabled()) {
218: log.debug(">> returning SourceBlockFactory");
219: }
220: return SourceBlockFactory.class;
221: } else if (SOAPMessage.class.isAssignableFrom(o.getClass())) {
222: if (log.isDebugEnabled()) {
223: log.debug(">> returning SOAPMessageFactory");
224: }
225: return SOAPEnvelopeBlockFactory.class;
226: } else if (SOAPEnvelope.class.isAssignableFrom(o.getClass())) {
227: if (log.isDebugEnabled()) {
228: log.debug(">> returning SOAPEnvelope");
229: }
230: return SOAPEnvelopeBlockFactory.class;
231: }
232: if (log.isDebugEnabled()) {
233: log.debug(">> ERROR: Factory not found");
234: }
235: return null;
236: }
237:
238: private Class getBlockFactory() {
239:
240: if (String.class.isAssignableFrom(type)) {
241: if (log.isDebugEnabled()) {
242: log.debug(">> returning XMLStringBlockFactory");
243: }
244: return XMLStringBlockFactory.class;
245: } else if (Source.class.isAssignableFrom(type)) {
246: if (log.isDebugEnabled()) {
247: log.debug(">> returning SourceBlockFactory");
248: }
249: return SourceBlockFactory.class;
250: } else if (SOAPMessage.class.isAssignableFrom(type)) {
251: if (log.isDebugEnabled()) {
252: log.debug(">> returning SOAPMessageFactory");
253: }
254: return SOAPEnvelopeBlockFactory.class;
255: } else if (SOAPEnvelope.class.isAssignableFrom(type)) {
256: if (log.isDebugEnabled()) {
257: log.debug(">> returning SOAPEnvelope");
258: }
259: return SOAPEnvelopeBlockFactory.class;
260: }
261: if (log.isDebugEnabled()) {
262: log.debug(">> ERROR: Factory not found");
263: }
264: return null;
265: }
266:
267: private Message createEmptyMessage(Protocol protocol)
268: throws WebServiceException, XMLStreamException {
269: MessageFactory mf = (MessageFactory) FactoryRegistry
270: .getFactory(MessageFactory.class);
271: Message m = mf.create(protocol);
272: return m;
273: }
274:
275: }
|