blob: 4a760dccf61f5425e4ec25fcd486f1c32d87b27f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.axis2.jaxws.client.dispatch;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.client.async.AsyncResponse;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.message.Block;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.Protocol;
import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
import org.apache.axis2.jaxws.message.factory.BlockFactory;
import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.spi.ServiceDelegate;
import org.apache.axis2.jaxws.utility.XMLRootElementUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.bind.JAXBContext;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.ws.Service.Mode;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
public class JAXBDispatch<T> extends BaseDispatch<T> {
private static final Log log = LogFactory.getLog(JAXBDispatch.class);
private JAXBContext jaxbContext;
public JAXBDispatch(ServiceDelegate svcDelegate,
EndpointDescription epDesc,
WebServiceFeature... features) {
this(svcDelegate, epDesc, null, null, features);
}
public JAXBDispatch(ServiceDelegate svcDelegate,
EndpointDescription epDesc,
EndpointReference epr,
String addressingNamespace,
WebServiceFeature... features) {
super(svcDelegate, epDesc, epr, addressingNamespace, features);
}
public JAXBContext getJAXBContext() {
return jaxbContext;
}
public void setJAXBContext(JAXBContext jbc) {
jaxbContext = jbc;
}
public AsyncResponse createAsyncResponseListener() {
JAXBDispatchAsyncListener listener =
new JAXBDispatchAsyncListener(getEndpointDescription());
listener.setJAXBContext(jaxbContext);
listener.setMode(mode);
return listener;
}
public Message createMessageFromValue(Object value) {
Message message = null;
if (value == null) {
if (log.isDebugEnabled()) {
log.debug("Dispatch invoked with null parameter Value");
log.debug("creating empty soap message");
}
try {
return createEmptyMessage(
Protocol.getProtocolForBinding(endpointDesc.getClientBindingID()));
} catch (XMLStreamException e) {
throw ExceptionFactory.makeWebServiceException(e);
}
}
try {
JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
Class clazz = value.getClass();
JAXBBlockContext context = null;
if (jaxbContext != null) {
context = new JAXBBlockContext(jaxbContext);
} else {
context = new JAXBBlockContext(clazz.getPackage().getName());
}
// The protocol of the Message that is created should be based
// on the binding information available.
Protocol proto = Protocol.getProtocolForBinding(endpointDesc.getClientBindingID());
// Create a block from the value
QName qName = XMLRootElementUtil.getXmlRootElementQNameFromObject(value);
Block block = factory.createFrom(value, context, qName);
MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
if (mode.equals(Mode.PAYLOAD)) {
// Normal case
message = mf.create(proto);
message.setBodyBlock(block);
} else {
// Message mode..rare case
// Create Message from block
message = mf.createFrom(block, null, proto);
}
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
}
return message;
}
public Object getValueFromMessage(Message message) {
return getValue(message, mode, jaxbContext);
}
/**
* Common code to get the value for JAXBDispatch and JAXBDispatchAsyncListener
*
* @param message
* @param mode
* @param jaxbContext
* @return
*/
static Object getValue(Message message, Mode mode, JAXBContext jaxbContext) {
Object value = null;
try {
if (mode.equals(Mode.PAYLOAD)) {
// Normal Case
JAXBBlockFactory factory =
(JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
JAXBBlockContext context = new JAXBBlockContext(jaxbContext);
Block block = message.getBodyBlock(context, factory);
if (block != null) {
value = block.getBusinessObject(true);
} else {
// REVIEW This seems like the correct behavior. If the body is empty, return a null
// Any changes here should also be made to XMLDispatch.getValue
if (log.isDebugEnabled()) {
log.debug(
"There are no elements in the body to unmarshal. JAXBDispatch returns a null value");
}
value = null;
}
} else {
BlockFactory factory =
(BlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);
JAXBBlockContext context = new JAXBBlockContext(jaxbContext);
value = message.getValue(context, factory);
if (value == null) {
if (log.isDebugEnabled()) {
log.debug(
"There are no elements to unmarshal. JAXBDispatch returns a null value");
}
}
}
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
} finally {
message.close();
}
return value;
}
private Message createEmptyMessage(Protocol protocol)
throws WebServiceException, XMLStreamException {
MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
Message m = mf.create(protocol);
return m;
}
}