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.databinding.JAXBBlockContext;
028: import org.apache.axis2.jaxws.message.factory.BlockFactory;
029: import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
030: import org.apache.axis2.jaxws.message.factory.MessageFactory;
031: import org.apache.axis2.jaxws.message.factory.SOAPEnvelopeBlockFactory;
032: import org.apache.axis2.jaxws.message.factory.SourceBlockFactory;
033: import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
034: import org.apache.axis2.jaxws.registry.FactoryRegistry;
035: import org.apache.axis2.jaxws.spi.ServiceDelegate;
036: import org.apache.axis2.jaxws.utility.XMLRootElementUtil;
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039:
040: import javax.xml.bind.JAXBContext;
041: import javax.xml.namespace.QName;
042: import javax.xml.stream.XMLStreamException;
043: import javax.xml.transform.Source;
044: import javax.xml.ws.Service.Mode;
045: import javax.xml.ws.WebServiceException;
046:
047: public class JAXBDispatch<T> extends BaseDispatch<T> {
048: private static final Log log = LogFactory
049: .getLog(JAXBDispatch.class);
050: private JAXBContext jaxbContext;
051:
052: public JAXBDispatch(ServiceDelegate svcDelegate,
053: EndpointDescription epDesc) {
054: super (svcDelegate, epDesc);
055: }
056:
057: public JAXBContext getJAXBContext() {
058: return jaxbContext;
059: }
060:
061: public void setJAXBContext(JAXBContext jbc) {
062: jaxbContext = jbc;
063: }
064:
065: public AsyncResponse createAsyncResponseListener() {
066: JAXBDispatchAsyncListener listener = new JAXBDispatchAsyncListener(
067: getEndpointDescription());
068: listener.setJAXBContext(jaxbContext);
069: listener.setMode(mode);
070: return listener;
071: }
072:
073: public Message createMessageFromValue(Object value) {
074: Message message = null;
075:
076: if (value == null) {
077: if (log.isDebugEnabled()) {
078: log.debug("Dispatch invoked with null parameter Value");
079: log.debug("creating empty soap message");
080: }
081: try {
082: return createEmptyMessage(Protocol
083: .getProtocolForBinding(endpointDesc
084: .getClientBindingID()));
085:
086: } catch (XMLStreamException e) {
087: throw ExceptionFactory.makeWebServiceException(e);
088: }
089: }
090:
091: try {
092: JAXBBlockFactory factory = (JAXBBlockFactory) FactoryRegistry
093: .getFactory(JAXBBlockFactory.class);
094:
095: Class clazz = value.getClass();
096: JAXBBlockContext context = null;
097: if (jaxbContext != null) {
098: context = new JAXBBlockContext(jaxbContext);
099: } else {
100: context = new JAXBBlockContext(clazz.getPackage()
101: .getName());
102: }
103: // The protocol of the Message that is created should be based
104: // on the binding information available.
105: Protocol proto = Protocol
106: .getProtocolForBinding(endpointDesc
107: .getClientBindingID());
108:
109: // Create a block from the value
110: QName qName = XMLRootElementUtil
111: .getXmlRootElementQNameFromObject(value);
112: Block block = factory.createFrom(value, context, qName);
113: MessageFactory mf = (MessageFactory) FactoryRegistry
114: .getFactory(MessageFactory.class);
115:
116: if (mode.equals(Mode.PAYLOAD)) {
117: // Normal case
118:
119: message = mf.create(proto);
120: message.setBodyBlock(block);
121: } else {
122: // Message mode..rare case
123:
124: // Create Message from block
125: message = mf.createFrom(block, null, proto);
126: }
127:
128: } catch (Exception e) {
129: throw ExceptionFactory.makeWebServiceException(e);
130: }
131:
132: return message;
133: }
134:
135: public Object getValueFromMessage(Message message) {
136: return getValue(message, mode, jaxbContext);
137: }
138:
139: /**
140: * Common code to get the value for JAXBDispatch and JAXBDispatchAsyncListener
141: *
142: * @param message
143: * @param mode
144: * @param jaxbContext
145: * @return
146: */
147: static Object getValue(Message message, Mode mode,
148: JAXBContext jaxbContext) {
149: Object value = null;
150: try {
151: if (mode.equals(Mode.PAYLOAD)) {
152: // Normal Case
153: JAXBBlockFactory factory = (JAXBBlockFactory) FactoryRegistry
154: .getFactory(JAXBBlockFactory.class);
155: JAXBBlockContext context = new JAXBBlockContext(
156: jaxbContext);
157: Block block = message.getBodyBlock(context, factory);
158:
159: if (block != null) {
160: value = block.getBusinessObject(true);
161: } else {
162: // REVIEW This seems like the correct behavior. If the body is empty, return a null
163: // Any changes here should also be made to XMLDispatch.getValue
164: if (log.isDebugEnabled()) {
165: log
166: .debug("There are no elements in the body to unmarshal. JAXBDispatch returns a null value");
167: }
168: value = null;
169: }
170: } else {
171: BlockFactory factory = (BlockFactory) FactoryRegistry
172: .getFactory(JAXBBlockFactory.class);
173: JAXBBlockContext context = new JAXBBlockContext(
174: jaxbContext);
175: value = message.getValue(context, factory);
176: if (value == null) {
177: if (log.isDebugEnabled()) {
178: log
179: .debug("There are no elements to unmarshal. JAXBDispatch returns a null value");
180: }
181: }
182: }
183: } catch (Exception e) {
184: throw ExceptionFactory.makeWebServiceException(e);
185: }
186:
187: return value;
188: }
189:
190: private Message createEmptyMessage(Protocol protocol)
191: throws WebServiceException, XMLStreamException {
192: MessageFactory mf = (MessageFactory) FactoryRegistry
193: .getFactory(MessageFactory.class);
194: Message m = mf.create(protocol);
195: return m;
196: }
197: }
|