org.apache.cxf.service.factory.ReflectionServiceFactoryBean Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cxf-bundle-minimal Show documentation
Show all versions of cxf-bundle-minimal Show documentation
Apache CXF Minimal Bundle Jar
/**
* 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.cxf.service.factory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.wsdl.Operation;
import javax.xml.bind.annotation.XmlAttachmentRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlList;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.namespace.QName;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
import org.apache.cxf.BusException;
import org.apache.cxf.binding.BindingFactoryManager;
import org.apache.cxf.catalog.CatalogXmlSchemaURIResolver;
import org.apache.cxf.clustering.FailoverFeature;
import org.apache.cxf.common.WSDLConstants;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.common.xmlschema.SchemaCollection;
import org.apache.cxf.common.xmlschema.XmlSchemaUtils;
import org.apache.cxf.common.xmlschema.XmlSchemaValidationManager;
import org.apache.cxf.databinding.DataBinding;
import org.apache.cxf.databinding.source.mime.MimeAttribute;
import org.apache.cxf.databinding.source.mime.MimeSerializer;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.endpoint.EndpointException;
import org.apache.cxf.endpoint.EndpointImpl;
import org.apache.cxf.endpoint.ServiceContractResolverRegistry;
import org.apache.cxf.feature.AbstractFeature;
import org.apache.cxf.frontend.FaultInfoException;
import org.apache.cxf.frontend.MethodDispatcher;
import org.apache.cxf.frontend.SimpleMethodDispatcher;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.MethodComparator;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.FaultOutInterceptor;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.service.Service;
import org.apache.cxf.service.ServiceImpl;
import org.apache.cxf.service.ServiceModelSchemaValidator;
import org.apache.cxf.service.factory.FactoryBeanListener.Event;
import org.apache.cxf.service.invoker.FactoryInvoker;
import org.apache.cxf.service.invoker.Invoker;
import org.apache.cxf.service.invoker.SingletonFactory;
import org.apache.cxf.service.model.AbstractMessageContainer;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.service.model.FaultInfo;
import org.apache.cxf.service.model.InterfaceInfo;
import org.apache.cxf.service.model.MessageInfo;
import org.apache.cxf.service.model.MessagePartInfo;
import org.apache.cxf.service.model.OperationInfo;
import org.apache.cxf.service.model.SchemaInfo;
import org.apache.cxf.service.model.ServiceInfo;
import org.apache.cxf.service.model.UnwrappedOperationInfo;
import org.apache.cxf.wsdl11.WSDLServiceBuilder;
import org.apache.cxf.wsdl11.WSDLServiceFactory;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaForm;
import org.apache.ws.commons.schema.XmlSchemaImport;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaObjectTable;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.apache.ws.commons.schema.constants.Constants;
import org.apache.ws.commons.schema.utils.NamespaceMap;
/**
* Introspects a class and builds a {@link Service} from it. If a WSDL URL is
* specified, a Service model will be directly from the WSDL and then metadata
* will be filled in from the service class. If no WSDL URL is specified, the
* Service will be constructed directly from the class structure.
*/
public class ReflectionServiceFactoryBean extends AbstractServiceFactoryBean {
public static final String ENDPOINT_CLASS = "endpoint.class";
public static final String GENERIC_TYPE = "generic.type";
public static final String RAW_CLASS = "rawclass";
public static final String WRAPPERGEN_NEEDED = "wrapper.gen.needed";
public static final String EXTRA_CLASS = "extra.class";
public static final String MODE_OUT = "messagepart.mode.out";
public static final String MODE_INOUT = "messagepart.mode.inout";
public static final String HOLDER = "messagepart.isholder";
public static final String HEADER = "messagepart.isheader";
public static final String ELEMENT_NAME = "messagepart.elementName";
public static final String METHOD = "operation.method";
public static final String FORCE_TYPES = "operation.force.types";
public static final String METHOD_PARAM_ANNOTATIONS = "method.parameters.annotations";
public static final String METHOD_ANNOTATIONS = "method.return.annotations";
public static final String PARAM_ANNOTATION = "parameter.annotations";
private static final Logger LOG = LogUtils.getL7dLogger(ReflectionServiceFactoryBean.class,
"SimpleMessages");
protected String wsdlURL;
protected Class serviceClass;
protected ParameterizedType serviceType;
protected Map>> parameterizedTypes;
protected final Map schemaLocationMapping = new HashMap();
private List serviceConfigurations =
new ArrayList();
private QName serviceName;
private Invoker invoker;
private Executor executor;
private List ignoredClasses = new ArrayList();
private List ignoredMethods = new ArrayList();
private MethodDispatcher methodDispatcher = new SimpleMethodDispatcher();
private Boolean wrappedStyle;
private Map properties;
private QName endpointName;
private boolean populateFromClass;
private boolean anonymousWrappers;
private boolean qualifiedSchemas = true;
private boolean validate;
private List features;
private Map wrappedCache = new HashMap();
private Map isRpcCache = new HashMap();
private String styleCache;
private Boolean defWrappedCache;
public ReflectionServiceFactoryBean() {
getServiceConfigurations().add(0, new DefaultServiceConfiguration());
ignoredClasses.add("java.lang.Object");
ignoredClasses.add("java.lang.Throwable");
ignoredClasses.add("org.omg.CORBA_2_3.portable.ObjectImpl");
ignoredClasses.add("org.omg.CORBA.portable.ObjectImpl");
ignoredClasses.add("javax.ejb.EJBObject");
ignoredClasses.add("javax.rmi.CORBA.Stub");
}
protected DataBinding createDefaultDataBinding() {
DataBinding retVal = null;
if (getServiceClass() != null) {
org.apache.cxf.annotations.DataBinding db
= getServiceClass().getAnnotation(org.apache.cxf.annotations.DataBinding.class);
if (db != null) {
try {
if (!StringUtils.isEmpty(db.ref())) {
return getBus().getExtension(ResourceManager.class).resolveResource(db.ref(),
db.value());
}
retVal = db.value().newInstance();
} catch (Exception e) {
LOG.log(Level.WARNING, "Could not create databinding "
+ db.value().getName(), e);
}
}
}
if (retVal == null) {
JAXBDataBinding db = new JAXBDataBinding(getQualifyWrapperSchema());
Map props = this.getProperties();
if (props != null && props.get("jaxb.additionalContextClasses") != null) {
Object o = this.getProperties().get("jaxb.additionalContextClasses");
if (o instanceof Class) {
o = new Class[] {(Class)o};
}
Class[] extraClass = (Class[])o;
db.setExtraClass(extraClass);
}
retVal = db;
}
return retVal;
}
public void reset() {
if (!dataBindingSet) {
setDataBinding(null);
}
setService(null);
}
@Override
public synchronized Service create() {
reset();
sendEvent(Event.START_CREATE);
initializeServiceConfigurations();
initializeServiceModel();
initializeDefaultInterceptors();
if (invoker != null) {
getService().setInvoker(getInvoker());
} else {
getService().setInvoker(createInvoker());
}
if (getExecutor() != null) {
getService().setExecutor(getExecutor());
}
if (getDataBinding() != null) {
getService().setDataBinding(getDataBinding());
}
getService().put(MethodDispatcher.class.getName(), getMethodDispatcher());
createEndpoints();
fillInSchemaCrossreferences();
Service serv = getService();
sendEvent(Event.END_CREATE, serv);
return serv;
}
/**
* Code elsewhere in this function will fill in the name of the type of an
* element but not the reference to the type. This function fills in the
* type references. This does not set the type reference for elements that
* are declared as refs to other elements. It is a giant pain to find them,
* since they are not (generally) root elements and the code would have to
* traverse all the types to find all of them. Users should look them up
* through the collection, that's what it is for.
*/
private void fillInSchemaCrossreferences() {
Service service = getService();
for (ServiceInfo serviceInfo : service.getServiceInfos()) {
SchemaCollection schemaCollection = serviceInfo.getXmlSchemaCollection();
// First pass, fill in any types for which we have a name but no
// type.
for (SchemaInfo schemaInfo : serviceInfo.getSchemas()) {
XmlSchemaObjectTable elementsTable = schemaInfo.getSchema().getElements();
Iterator elementsIterator = elementsTable.getNames();
while (elementsIterator.hasNext()) {
QName elementName = (QName)elementsIterator.next();
XmlSchemaElement element = schemaInfo.getSchema().getElementByName(elementName);
if (element.getSchemaType() == null) {
QName typeName = element.getSchemaTypeName();
if (typeName != null) {
XmlSchemaType type = schemaCollection.getTypeByQName(typeName);
if (type == null) {
Message message = new Message("REFERENCE_TO_UNDEFINED_TYPE", LOG, element
.getQName(), typeName, service.getName());
LOG.severe(message.toString());
} else {
element.setSchemaType(type);
}
}
}
}
}
}
}
protected void createEndpoints() {
Service service = getService();
BindingFactoryManager bfm = getBus().getExtension(BindingFactoryManager.class);
for (ServiceInfo inf : service.getServiceInfos()) {
for (EndpointInfo ei : inf.getEndpoints()) {
for (BindingOperationInfo boi : ei.getBinding().getOperations()) {
updateBindingOperation(boi);
}
try {
bfm.getBindingFactory(ei.getBinding().getBindingId());
} catch (BusException e1) {
continue;
}
try {
Endpoint ep = createEndpoint(ei);
service.getEndpoints().put(ei.getName(), ep);
} catch (EndpointException e) {
throw new ServiceConstructionException(e);
}
}
}
}
public void updateBindingOperation(BindingOperationInfo boi) {
//nothing
}
public Endpoint createEndpoint(EndpointInfo ei) throws EndpointException {
Endpoint ep = new EndpointImpl(getBus(), getService(), ei);
sendEvent(Event.ENDPOINT_CREATED, ei, ep, getServiceClass());
return ep;
}
protected void initializeServiceConfigurations() {
for (AbstractServiceConfiguration c : serviceConfigurations) {
c.setServiceFactory(this);
}
}
protected void setServiceProperties() {
getService().put(MethodDispatcher.class.getName(), getMethodDispatcher());
if (properties != null) {
getService().putAll(properties);
}
}
protected void buildServiceFromWSDL(String url) {
sendEvent(Event.CREATE_FROM_WSDL, url);
if (LOG.isLoggable(Level.INFO)) {
LOG.info("Creating Service " + getServiceQName() + " from WSDL: " + url);
}
populateFromClass = false;
WSDLServiceFactory factory = new WSDLServiceFactory(getBus(), url, getServiceQName());
boolean setEPName = true;
if (features != null) {
for (AbstractFeature f : features) {
if (f instanceof FailoverFeature) {
setEPName = false;
}
}
}
if (setEPName) {
factory.setEndpointName(getEndpointName(false));
}
sendEvent(Event.WSDL_LOADED, factory.getDefinition());
setService(factory.create());
setServiceProperties();
sendEvent(Event.SERVICE_SET, getService());
EndpointInfo epInfo = getEndpointInfo();
if (epInfo != null) {
serviceConfigurations.add(new WSDLBasedServiceConfiguration(getEndpointInfo().getBinding()));
}
initializeWSDLOperations();
Set> cls = getExtraClass();
for (ServiceInfo si : getService().getServiceInfos()) {
if (cls != null && !cls.isEmpty()) {
si.setProperty(EXTRA_CLASS, cls);
}
}
initializeDataBindings();
}
protected void buildServiceFromClass() {
if (LOG.isLoggable(Level.INFO)) {
LOG.info("Creating Service " + getServiceQName() + " from class " + getServiceClass().getName());
}
populateFromClass = true;
if (Proxy.isProxyClass(this.getServiceClass())) {
LOG.log(Level.WARNING, "USING_PROXY_FOR_SERVICE", getServiceClass());
}
sendEvent(Event.CREATE_FROM_CLASS, getServiceClass());
ServiceInfo serviceInfo = new ServiceInfo();
SchemaCollection col = serviceInfo.getXmlSchemaCollection();
col.getXmlSchemaCollection().setSchemaResolver(new CatalogXmlSchemaURIResolver(this.getBus()));
col.getExtReg().registerSerializer(MimeAttribute.class, new MimeSerializer());
ServiceImpl service = new ServiceImpl(serviceInfo);
setService(service);
setServiceProperties();
serviceInfo.setName(getServiceQName());
serviceInfo.setTargetNamespace(serviceInfo.getName().getNamespaceURI());
sendEvent(Event.SERVICE_SET, getService());
createInterface(serviceInfo);
Set wrapperClasses = this.getExtraClass();
for (ServiceInfo si : getService().getServiceInfos()) {
if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
si.setProperty(EXTRA_CLASS, wrapperClasses);
}
}
initializeDataBindings();
boolean isWrapped = isWrapped() || hasWrappedMethods(serviceInfo.getInterface());
if (isWrapped) {
initializeWrappedSchema(serviceInfo);
}
for (OperationInfo opInfo : serviceInfo.getInterface().getOperations()) {
Method m = (Method)opInfo.getProperty(METHOD);
if (!isWrapped(m) && !isRPC(m) && opInfo.getInput() != null) {
createBareMessage(serviceInfo, opInfo, false);
}
if (!isWrapped(m) && !isRPC(m) && opInfo.getOutput() != null) {
createBareMessage(serviceInfo, opInfo, true);
}
if (opInfo.hasFaults()) {
// check to make sure the faults are elements
for (FaultInfo fault : opInfo.getFaults()) {
QName qn = (QName)fault.getProperty("elementName");
MessagePartInfo part = fault.getMessagePart(0);
if (!part.isElement()) {
part.setElement(true);
part.setElementQName(qn);
checkForElement(serviceInfo, part);
}
}
}
}
if (LOG.isLoggable(Level.FINE) || isValidate()) {
ServiceModelSchemaValidator validator = new ServiceModelSchemaValidator(serviceInfo);
validator.walk();
String validationComplaints = validator.getComplaints();
if (!"".equals(validationComplaints)) {
if (isValidate()) {
LOG.warning(validationComplaints);
} else {
LOG.fine(validationComplaints);
}
}
}
}
public boolean hasWrappedMethods(InterfaceInfo interfaceInfo) {
for (OperationInfo opInfo : interfaceInfo.getOperations()) {
if (opInfo.isUnwrappedCapable()) {
return true;
}
}
return false;
}
protected boolean isFromWsdl() {
return !populateFromClass && getWsdlURL() != null;
}
protected void initializeServiceModel() {
String wsdlurl = getWsdlURL();
if (isFromWsdl()) {
buildServiceFromWSDL(wsdlurl);
} else {
buildServiceFromClass();
}
if (isValidate()) {
validateServiceModel();
}
}
public void validateServiceModel() {
XmlSchemaValidationManager xsdValidator = getBus().getExtension(XmlSchemaValidationManager.class);
for (ServiceInfo si : getService().getServiceInfos()) {
if (xsdValidator != null) {
validateSchemas(xsdValidator, si.getXmlSchemaCollection());
}
for (OperationInfo opInfo : si.getInterface().getOperations()) {
for (MessagePartInfo mpi : opInfo.getInput().getMessageParts()) {
assert mpi.getXmlSchema() != null;
if (mpi.isElement()) {
assert mpi.getXmlSchema() instanceof XmlSchemaElement;
} else {
assert !(mpi.getXmlSchema() instanceof XmlSchemaElement);
}
}
if (opInfo.hasOutput()) {
for (MessagePartInfo mpi : opInfo.getOutput().getMessageParts()) {
assert mpi.getXmlSchema() != null;
if (mpi.isElement()) {
assert mpi.getXmlSchema() instanceof XmlSchemaElement;
} else {
assert !(mpi.getXmlSchema() instanceof XmlSchemaElement);
}
}
}
if (opInfo.isUnwrappedCapable()) {
opInfo = opInfo.getUnwrappedOperation();
for (MessagePartInfo mpi : opInfo.getInput().getMessageParts()) {
assert mpi.getXmlSchema() != null;
if (mpi.isElement()) {
assert mpi.getXmlSchema() instanceof XmlSchemaElement;
} else {
assert !(mpi.getXmlSchema() instanceof XmlSchemaElement);
}
}
if (opInfo.hasOutput()) {
for (MessagePartInfo mpi : opInfo.getOutput().getMessageParts()) {
assert mpi.getXmlSchema() != null;
if (mpi.isElement()) {
assert mpi.getXmlSchema() instanceof XmlSchemaElement;
} else {
assert !(mpi.getXmlSchema() instanceof XmlSchemaElement);
}
}
}
}
if (opInfo.hasFaults()) {
// check to make sure the faults are elements
for (FaultInfo fault : opInfo.getFaults()) {
MessagePartInfo mpi = fault.getMessagePart(0);
assert mpi != null;
assert mpi.getXmlSchema() != null;
assert mpi.isElement();
assert mpi.getXmlSchema() instanceof XmlSchemaElement;
}
}
}
}
}
private void validateSchemas(XmlSchemaValidationManager xsdValidator,
SchemaCollection xmlSchemaCollection) {
final boolean[] anyErrors = new boolean[1];
final StringBuilder errorBuilder = new StringBuilder();
anyErrors[0] = false;
xsdValidator.validateSchemas(xmlSchemaCollection.getXmlSchemaCollection(), new DOMErrorHandler() {
public boolean handleError(DOMError error) {
anyErrors[0] = true;
errorBuilder.append(error.getMessage());
LOG.warning(error.getMessage());
return true;
}
});
if (anyErrors[0]) {
throw new ServiceConstructionException(new Message("XSD_VALIDATION_ERROR", LOG,
errorBuilder.toString()));
}
}
public boolean isPopulateFromClass() {
return populateFromClass;
}
public void setPopulateFromClass(boolean fomClass) {
this.populateFromClass = fomClass;
}
protected InterfaceInfo getInterfaceInfo() {
if (getEndpointInfo() != null) {
return getEndpointInfo().getInterface();
}
QName qn = this.getInterfaceName();
for (ServiceInfo si : getService().getServiceInfos()) {
if (qn.equals(si.getInterface().getName())) {
return si.getInterface();
}
}
throw new ServiceConstructionException(new Message("COULD_NOT_FIND_PORTTYPE", LOG, qn));
}
protected void initializeWSDLOperations() {
List removes = new ArrayList();
Method[] methods = serviceClass.getMethods();
Arrays.sort(methods, new MethodComparator());
InterfaceInfo intf = getInterfaceInfo();
Map validMethods = new HashMap();
for (Method m : methods) {
if (isValidMethod(m)) {
QName opName = getOperationName(intf, m);
validMethods.put(opName, m);
}
}
for (OperationInfo o : intf.getOperations()) {
Method selected = null;
for (Map.Entry m : validMethods.entrySet()) {
QName opName = m.getKey();
if (o.getName().getNamespaceURI().equals(opName.getNamespaceURI())
&& isMatchOperation(o.getName().getLocalPart(), opName.getLocalPart())) {
selected = m.getValue();
break;
}
}
if (selected == null) {
LOG.log(Level.WARNING, "NO_METHOD_FOR_OP", o.getName());
removes.add(o);
} else {
initializeWSDLOperation(intf, o, selected);
}
}
for (OperationInfo op : removes) {
intf.removeOperation(op);
}
// Some of the operations may have switched from unwrapped to wrapped.
// Update the bindings.
for (ServiceInfo service : getService().getServiceInfos()) {
for (BindingInfo bi : service.getBindings()) {
List biremoves = new ArrayList();
for (BindingOperationInfo binfo : bi.getOperations()) {
if (removes.contains(binfo.getOperationInfo())) {
biremoves.add(binfo);
} else {
binfo.updateUnwrappedOperation();
}
}
for (BindingOperationInfo binfo : biremoves) {
bi.removeOperation(binfo);
}
}
}
sendEvent(Event.INTERFACE_CREATED, intf, getServiceClass());
}
protected void initializeWSDLOperation(InterfaceInfo intf, OperationInfo o, Method method) {
// rpc out-message-part-info class mapping
Operation op = (Operation)o.getProperty(WSDLServiceBuilder.WSDL_OPERATION);
if (initializeClassInfo(o, method, op == null ? null
: CastUtils.cast(op.getParameterOrdering(), String.class))) {
bindOperation(o, method);
o.setProperty(ReflectionServiceFactoryBean.METHOD, method);
sendEvent(Event.INTERFACE_OPERATION_BOUND, o, method);
} else {
LOG.log(Level.WARNING, "NO_METHOD_FOR_OP", o.getName());
}
}
/**
* set the holder generic type info into message part info
*
* @param o
* @param method
*/
protected boolean initializeClassInfo(OperationInfo o, Method method, List paramOrder) {
OperationInfo origOp = o;
if (isWrapped(method)) {
if (o.getUnwrappedOperation() == null) {
//the "normal" algorithm didn't allow for unwrapping,
//but the annotations say unwrap this. We'll need to
//make it.
WSDLServiceBuilder.checkForWrapped(o, true);
}
if (o.getUnwrappedOperation() != null) {
if (o.hasInput()) {
MessageInfo input = o.getInput();
MessagePartInfo part = input.getMessageParts().get(0);
part.setTypeClass(getRequestWrapper(method));
part.setProperty("REQUEST.WRAPPER.CLASSNAME", getRequestWrapperClassName(method));
part.setIndex(0);
}
if (o.hasOutput()) {
MessageInfo input = o.getOutput();
MessagePartInfo part = input.getMessageParts().get(0);
part.setTypeClass(getResponseWrapper(method));
part.setProperty("RESPONSE.WRAPPER.CLASSNAME", getResponseWrapperClassName(method));
part.setIndex(0);
}
setFaultClassInfo(o, method);
o = o.getUnwrappedOperation();
} else {
LOG.warning(new Message("COULD_NOT_UNWRAP", LOG, o.getName(), method).toString());
setFaultClassInfo(o, method);
}
} else if (o.isUnwrappedCapable()) {
// remove the unwrapped operation because it will break the
// the WrapperClassOutInterceptor, and in general makes
// life more confusing
o.setUnwrappedOperation(null);
setFaultClassInfo(o, method);
}
o.setProperty(METHOD_PARAM_ANNOTATIONS, method.getParameterAnnotations());
o.setProperty(METHOD_ANNOTATIONS, method.getAnnotations());
Class[] paramTypes = method.getParameterTypes();
Type[] genericTypes = method.getGenericParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (Exchange.class.equals(paramTypes[i])) {
continue;
}
Class paramType = paramTypes[i];
Type genericType = genericTypes[i];
if (!initializeParameter(o, method, i, paramType, genericType)) {
return false;
}
}
sendEvent(Event.OPERATIONINFO_IN_MESSAGE_SET, origOp, method, origOp.getInput());
// Initialize return type
Class paramType = method.getReturnType();
Type genericType = method.getGenericReturnType();
if (o.hasOutput()
&& !initializeParameter(o, method, -1, paramType, genericType)) {
return false;
}
if (origOp.hasOutput()) {
sendEvent(Event.OPERATIONINFO_OUT_MESSAGE_SET, origOp, method, origOp.getOutput());
}
setFaultClassInfo(o, method);
return true;
}
private boolean initializeParameter(OperationInfo o, Method method, int i,
Class paramType, Type genericType) {
boolean isIn = isInParam(method, i);
boolean isOut = isOutParam(method, i);
boolean isHeader = isHeader(method, i);
Annotation[] paraAnnos = null;
if (i != -1 && o.getProperty(METHOD_PARAM_ANNOTATIONS) != null) {
Annotation[][] anns = (Annotation[][])o.getProperty(METHOD_PARAM_ANNOTATIONS);
paraAnnos = anns[i];
} else if (i == -1 && o.getProperty(METHOD_ANNOTATIONS) != null) {
paraAnnos = (Annotation[])o.getProperty(METHOD_ANNOTATIONS);
}
MessagePartInfo part = null;
if (isIn && !isOut) {
QName name = getInPartName(o, method, i);
part = o.getInput().getMessagePart(name);
if (part == null && isFromWsdl()) {
part = o.getInput().getMessagePartByIndex(i);
}
if (part == null && isHeader && o.isUnwrapped()) {
part = ((UnwrappedOperationInfo)o).getWrappedOperation().getInput().getMessagePart(name);
if (part != null) {
//header part in wsdl, need to get this mapped in to the unwrapped form
MessagePartInfo inf = o.getInput().addMessagePart(part.getName());
inf.setTypeQName(part.getTypeQName());
inf.setElement(part.isElement());
inf.setElementQName(part.getElementQName());
inf.setConcreteName(part.getConcreteName());
inf.setXmlSchema(part.getXmlSchema());
part = inf;
inf.setProperty(HEADER, Boolean.TRUE);
}
}
if (part == null) {
return false;
}
initializeParameter(part, paramType, genericType);
part.setIndex(i);
} else if (!isIn && isOut) {
QName name = getOutPartName(o, method, i);
part = o.getOutput().getMessagePart(name);
if (part == null && isFromWsdl()) {
part = o.getOutput().getMessagePartByIndex(i + 1);
}
if (part == null) {
return false;
}
part.setProperty(ReflectionServiceFactoryBean.MODE_OUT, Boolean.TRUE);
initializeParameter(part, paramType, genericType);
part.setIndex(i + 1);
} else if (isIn && isOut) {
QName name = getInPartName(o, method, i);
part = o.getInput().getMessagePart(name);
if (part == null && this.isFromWsdl()) {
part = o.getInput().getMessagePartByIndex(i);
}
if (part == null && isHeader && o.isUnwrapped()) {
part = o.getUnwrappedOperation().getInput().getMessagePart(name);
}
if (part == null) {
return false;
}
part.setProperty(ReflectionServiceFactoryBean.MODE_INOUT, Boolean.TRUE);
initializeParameter(part, paramType, genericType);
part.setIndex(i);
QName inName = part.getConcreteName();
part = o.getOutput().getMessagePart(name);
if (part == null) {
part = o.getOutput().getMessagePart(inName);
}
if (part == null && isHeader && o.isUnwrapped()) {
part = o.getUnwrappedOperation().getOutput().getMessagePart(name);
if (part == null) {
part = o.getUnwrappedOperation().getOutput().getMessagePart(inName);
}
}
if (part == null) {
return false;
}
part.setProperty(ReflectionServiceFactoryBean.MODE_INOUT, Boolean.TRUE);
initializeParameter(part, paramType, genericType);
part.setIndex(i + 1);
}
if (paraAnnos != null && part != null) {
part.setProperty(PARAM_ANNOTATION, paraAnnos);
}
return true;
}
private void setFaultClassInfo(OperationInfo o, Method selected) {
Class[] types = selected.getExceptionTypes();
for (int i = 0; i < types.length; i++) {
Class exClass = types[i];
Class beanClass = getBeanClass(exClass);
if (beanClass == null) {
continue;
}
QName name = getFaultName(o.getInterface(), o, exClass, beanClass);
for (FaultInfo fi : o.getFaults()) {
List mpis = fi.getMessageParts();
if (mpis.size() != 1) {
Message message = new Message("NO_FAULT_PART", LOG, fi.getFaultName());
LOG.log(Level.WARNING, message.toString());
}
for (MessagePartInfo mpi : mpis) {
String ns = null;
if (mpi.isElement()) {
ns = mpi.getElementQName().getNamespaceURI();
} else {
ns = mpi.getTypeQName().getNamespaceURI();
}
if (mpi.getConcreteName().getLocalPart().equals(name.getLocalPart())
&& name.getNamespaceURI().equals(ns)) {
fi.setProperty(Class.class.getName(), exClass);
mpi.setTypeClass(beanClass);
sendEvent(Event.OPERATIONINFO_FAULT, o, exClass, fi);
}
}
}
}
}
protected Invoker createInvoker() {
Class cls = getServiceClass();
if (cls.isInterface()) {
return null;
}
return new FactoryInvoker(new SingletonFactory(getServiceClass()));
}
protected ServiceInfo createServiceInfo(InterfaceInfo intf) {
ServiceInfo svcInfo = new ServiceInfo();
svcInfo.setInterface(intf);
return svcInfo;
}
protected InterfaceInfo createInterface(ServiceInfo serviceInfo) {
QName intfName = getInterfaceName();
InterfaceInfo intf = new InterfaceInfo(serviceInfo, intfName);
Method[] methods = getServiceClass().getMethods();
// The BP profile states we can't have operations of the same name
// so we have to append numbers to the name. Different JVMs sort methods
// differently.
// We need to keep them ordered so if we have overloaded methods, the
// wsdl is generated the same every time across JVMs and across
// client/servers.
Arrays.sort(methods, new MethodComparator());
for (Method m : methods) {
if (isValidMethod(m)) {
createOperation(serviceInfo, intf, m);
}
}
sendEvent(Event.INTERFACE_CREATED, intf, getServiceClass());
return intf;
}
protected OperationInfo createOperation(ServiceInfo serviceInfo, InterfaceInfo intf, Method m) {
OperationInfo op = intf.addOperation(getOperationName(intf, m));
op.setProperty(m.getClass().getName(), m);
op.setProperty("action", getAction(op, m));
op.setProperty(METHOD_ANNOTATIONS, m.getAnnotations());
op.setProperty(METHOD_PARAM_ANNOTATIONS, m.getParameterAnnotations());
boolean isrpc = isRPC(m);
if (!isrpc && isWrapped(m)) {
UnwrappedOperationInfo uOp = new UnwrappedOperationInfo(op);
uOp.setProperty(METHOD_ANNOTATIONS, m.getAnnotations());
uOp.setProperty(METHOD_PARAM_ANNOTATIONS, m.getParameterAnnotations());
op.setUnwrappedOperation(uOp);
createMessageParts(intf, uOp, m);
if (uOp.hasInput()) {
MessageInfo msg = new MessageInfo(op, MessageInfo.Type.INPUT, uOp.getInput().getName());
op.setInput(uOp.getInputName(), msg);
createInputWrappedMessageParts(uOp, m, msg);
for (MessagePartInfo p : uOp.getInput().getMessageParts()) {
p.setConcreteName(p.getName());
}
}
if (uOp.hasOutput()) {
QName name = uOp.getOutput().getName();
MessageInfo msg = new MessageInfo(op, MessageInfo.Type.OUTPUT, name);
op.setOutput(uOp.getOutputName(), msg);
createOutputWrappedMessageParts(uOp, m, msg);
for (MessagePartInfo p : uOp.getOutput().getMessageParts()) {
p.setConcreteName(p.getName());
}
}
} else {
if (isrpc) {
op.setProperty(FORCE_TYPES, Boolean.TRUE);
}
createMessageParts(intf, op, m);
}
bindOperation(op, m);
sendEvent(Event.INTERFACE_OPERATION_BOUND, op, m);
return op;
}
protected void bindOperation(OperationInfo op, Method m) {
getMethodDispatcher().bind(op, m);
}
protected void initializeWrappedSchema(ServiceInfo serviceInfo) {
for (OperationInfo op : serviceInfo.getInterface().getOperations()) {
if (op.getUnwrappedOperation() != null) {
if (op.hasInput()) {
if (op.getInput().getMessageParts().get(0).getTypeClass() == null) {
QName wrapperBeanName = op.getInput().getMessageParts().get(0).getElementQName();
XmlSchemaElement e = null;
for (SchemaInfo s : serviceInfo.getSchemas()) {
e = s.getElementByQName(wrapperBeanName);
if (e != null) {
op.getInput().getMessageParts().get(0).setXmlSchema(e);
break;
}
}
if (e == null) {
createWrappedSchema(serviceInfo, op.getInput(), op.getUnwrappedOperation()
.getInput(), wrapperBeanName);
}
}
for (MessagePartInfo mpi : op.getInput().getMessageParts()) {
if (Boolean.TRUE.equals(mpi.getProperty(HEADER))) {
QName qn = (QName)mpi.getProperty(ELEMENT_NAME);
mpi.setElement(true);
mpi.setElementQName(qn);
checkForElement(serviceInfo, mpi);
}
}
}
if (op.hasOutput()) {
if (op.getOutput().getMessageParts().get(0).getTypeClass() == null) {
QName wrapperBeanName = op.getOutput().getMessageParts().get(0).getElementQName();
XmlSchemaElement e = null;
for (SchemaInfo s : serviceInfo.getSchemas()) {
e = s.getElementByQName(wrapperBeanName);
if (e != null) {
break;
}
}
if (e == null) {
createWrappedSchema(serviceInfo, op.getOutput(), op.getUnwrappedOperation()
.getOutput(), wrapperBeanName);
}
}
for (MessagePartInfo mpi : op.getOutput().getMessageParts()) {
if (Boolean.TRUE.equals(mpi.getProperty(HEADER))) {
QName qn = (QName)mpi.getProperty(ELEMENT_NAME);
mpi.setElement(true);
mpi.setElementQName(qn);
checkForElement(serviceInfo, mpi);
}
}
}
}
}
}
protected void checkForElement(ServiceInfo serviceInfo, MessagePartInfo mpi) {
for (SchemaInfo s : serviceInfo.getSchemas()) {
XmlSchemaElement e = s.getElementByQName(mpi.getElementQName());
if (e != null) {
mpi.setXmlSchema(e);
return;
}
}
SchemaInfo si = getOrCreateSchema(serviceInfo, mpi.getElementQName().getNamespaceURI(),
getQualifyWrapperSchema());
XmlSchema schema = si.getSchema();
si.setElement(null); //cached element is now invalid
XmlSchemaElement el = new XmlSchemaElement();
XmlSchemaUtils.setElementQName(el, mpi.getElementQName());
if (!isExistSchemaElement(schema, mpi.getElementQName())) {
SchemaCollection.addGlobalElementToSchema(schema, el);
}
el.setNillable(true);
XmlSchemaType tp = (XmlSchemaType)mpi.getXmlSchema();
if (tp == null) {
throw new ServiceConstructionException(new Message("INTRACTABLE_PART", LOG,
mpi.getName(),
mpi.getMessageInfo().getName()));
}
el.setSchemaTypeName(tp.getQName());
mpi.setXmlSchema(el);
}
public boolean getAnonymousWrapperTypes() {
return anonymousWrappers;
}
public boolean isAnonymousWrapperTypes() {
return anonymousWrappers;
}
public void setAnonymousWrapperTypes(boolean b) {
anonymousWrappers = b;
}
public final boolean getQualifyWrapperSchema() {
return qualifiedSchemas;
}
public boolean isQualifyWrapperSchema() {
return qualifiedSchemas;
}
public void setQualifyWrapperSchema(boolean b) {
qualifiedSchemas = b;
}
protected void createWrappedSchema(ServiceInfo serviceInfo, AbstractMessageContainer wrappedMessage,
AbstractMessageContainer unwrappedMessage, QName wrapperBeanName) {
SchemaInfo schemaInfo = getOrCreateSchema(serviceInfo, wrapperBeanName.getNamespaceURI(),
getQualifyWrapperSchema());
createWrappedMessageSchema(serviceInfo, wrappedMessage, unwrappedMessage, schemaInfo,
wrapperBeanName);
}
protected void createBareMessage(ServiceInfo serviceInfo, OperationInfo opInfo, boolean isOut) {
MessageInfo message = isOut ? opInfo.getOutput() : opInfo.getInput();
if (message.getMessageParts().size() == 0) {
return;
}
Method method = (Method)opInfo.getProperty(METHOD);
int paraNumber = 0;
for (MessagePartInfo mpi : message.getMessageParts()) {
SchemaInfo schemaInfo = null;
XmlSchema schema = null;
QName qname = (QName)mpi.getProperty(ELEMENT_NAME);
if (message.getMessageParts().size() == 1) {
qname = qname == null && !isOut ? getInParameterName(opInfo, method, -1) : qname;
qname = qname == null && isOut ? getOutParameterName(opInfo, method, -1) : qname;
if (qname.getLocalPart().startsWith("arg") || qname.getLocalPart().startsWith("return")) {
qname = isOut
? new QName(qname.getNamespaceURI(), method.getName() + "Response") : new QName(qname
.getNamespaceURI(), method.getName());
}
}
if (isOut && message.getMessageParts().size() > 1 && qname == null) {
while (!isOutParam(method, paraNumber)) {
paraNumber++;
}
qname = getOutParameterName(opInfo, method, paraNumber);
} else if (qname == null) {
qname = getInParameterName(opInfo, method, paraNumber);
}
for (SchemaInfo s : serviceInfo.getSchemas()) {
if (s.getNamespaceURI().equals(qname.getNamespaceURI())) {
schemaInfo = s;
break;
}
}
if (schemaInfo == null) {
schemaInfo = getOrCreateSchema(serviceInfo, qname.getNamespaceURI(), true);
schema = schemaInfo.getSchema();
} else {
schema = schemaInfo.getSchema();
if (schema != null && schema.getElementByName(qname) != null) {
mpi.setElement(true);
mpi.setElementQName(qname);
mpi.setXmlSchema(schema.getElementByName(qname));
paraNumber++;
continue;
}
}
schemaInfo.setElement(null); //cached element is now invalid
XmlSchemaElement el = new XmlSchemaElement();
XmlSchemaUtils.setElementQName(el, qname);
el.setNillable(true);
if (!isExistSchemaElement(schema, qname)) {
SchemaCollection.addGlobalElementToSchema(schema, el);
} else {
el = getExistingSchemaElement(schema, qname);
}
if (mpi.isElement()) {
XmlSchemaElement oldEl = (XmlSchemaElement)mpi.getXmlSchema();
if (null != oldEl && !oldEl.getQName().equals(qname)) {
el.setSchemaTypeName(oldEl.getSchemaTypeName());
el.setSchemaType(oldEl.getSchemaType());
if (oldEl.getSchemaTypeName() != null) {
addImport(schema, oldEl.getSchemaTypeName().getNamespaceURI());
}
}
mpi.setElement(true);
mpi.setXmlSchema(el);
mpi.setElementQName(qname);
mpi.setConcreteName(qname);
continue;
} else {
if (null == mpi.getTypeQName() && mpi.getXmlSchema() == null) {
throw new ServiceConstructionException(new Message("UNMAPPABLE_PORT_TYPE", LOG,
method.getDeclaringClass().getName(),
method.getName(),
mpi.getName()));
}
if (mpi.getTypeQName() != null) {
el.setSchemaTypeName(mpi.getTypeQName());
} else {
el.setSchemaType((XmlSchemaType)mpi.getXmlSchema());
}
mpi.setXmlSchema(el);
mpi.setConcreteName(qname);
if (mpi.getTypeQName() != null) {
addImport(schema, mpi.getTypeQName().getNamespaceURI());
}
}
mpi.setElement(true);
mpi.setElementQName(qname);
paraNumber++;
}
}
private void addImport(XmlSchema schema, String ns) {
if (!ns.equals(schema.getTargetNamespace())
&& !ns.equals(WSDLConstants.NS_SCHEMA_XSD)
&& !isExistImport(schema, ns)) {
XmlSchemaImport is = new XmlSchemaImport();
is.setNamespace(ns);
if (this.schemaLocationMapping.get(ns) != null) {
is.setSchemaLocation(this.schemaLocationMapping.get(ns));
}
schema.getItems().add(is);
}
}
private boolean isExistImport(XmlSchema schema, String ns) {
boolean isExist = false;
for (Iterator ite = schema.getItems().getIterator(); ite.hasNext();) {
XmlSchemaObject obj = (XmlSchemaObject)ite.next();
if (obj instanceof XmlSchemaImport) {
XmlSchemaImport xsImport = (XmlSchemaImport)obj;
if (xsImport.getNamespace().equals(ns)) {
isExist = true;
break;
}
}
}
return isExist;
}
private XmlSchemaElement getExistingSchemaElement(XmlSchema schema, QName qn) {
for (Iterator ite = schema.getItems().getIterator(); ite.hasNext();) {
XmlSchemaObject obj = (XmlSchemaObject)ite.next();
if (obj instanceof XmlSchemaElement) {
XmlSchemaElement xsEle = (XmlSchemaElement)obj;
if (xsEle.getQName().equals(qn)) {
return xsEle;
}
}
}
return null;
}
private boolean isExistSchemaElement(XmlSchema schema, QName qn) {
return getExistingSchemaElement(schema, qn) != null;
}
private void createWrappedMessageSchema(ServiceInfo serviceInfo, AbstractMessageContainer wrappedMessage,
AbstractMessageContainer unwrappedMessage, SchemaInfo info,
QName wrapperName) {
XmlSchema schema = info.getSchema();
info.setElement(null); // the cached schema will be no good
XmlSchemaElement el = new XmlSchemaElement();
XmlSchemaUtils.setElementQName(el, wrapperName);
SchemaCollection.addGlobalElementToSchema(schema, el);
wrappedMessage.getMessageParts().get(0).setXmlSchema(el);
XmlSchemaComplexType ct = new XmlSchemaComplexType(schema);
if (!isAnonymousWrapperTypes()) {
ct.setName(wrapperName.getLocalPart());
el.setSchemaTypeName(wrapperName);
SchemaCollection.addGlobalTypeToSchema(schema, ct);
}
el.setSchemaType(ct);
XmlSchemaSequence seq = new XmlSchemaSequence();
ct.setParticle(seq);
for (MessagePartInfo mpi : unwrappedMessage.getMessageParts()) {
el = new XmlSchemaElement();
XmlSchemaUtils.setElementQName(el, mpi.getName());
Map jaxbAnnoMap = getJaxbAnnoMap(mpi);
if (mpi.isElement()) {
addImport(schema, mpi.getElementQName().getNamespaceURI());
XmlSchemaUtils.setElementQName(el, null);
XmlSchemaUtils.setElementRefName(el, mpi.getElementQName());
} else {
if (mpi.getTypeQName() != null && !jaxbAnnoMap.containsKey(XmlList.class)) {
el.setSchemaTypeName(mpi.getTypeQName());
addImport(schema, mpi.getTypeQName().getNamespaceURI());
}
el.setSchemaType((XmlSchemaType)mpi.getXmlSchema());
if (schema.getElementFormDefault().getValue().equals(XmlSchemaForm.UNQUALIFIED)) {
mpi.setConcreteName(new QName(null, mpi.getName().getLocalPart()));
} else {
mpi.setConcreteName(mpi.getName());
}
}
if (!Boolean.TRUE.equals(mpi.getProperty(HEADER))) {
boolean wasType = !mpi.isElement();
if (wasType) {
QName concreteName = mpi.getConcreteName();
mpi.setElement(true);
mpi.setElementQName(el.getQName());
mpi.setConcreteName(concreteName);
}
addMimeType(el, getMethodParameterAnnotations(mpi));
Annotation[] methodAnnotations = getMethodAnnotations(mpi);
if (methodAnnotations != null) {
addMimeType(el, methodAnnotations);
}
long min = getWrapperPartMinOccurs(mpi);
long max = getWrapperPartMaxOccurs(mpi);
boolean nillable = isWrapperPartNillable(mpi);
Boolean qualified = isWrapperPartQualified(mpi);
if (qualified == null) {
qualified = this.isQualifyWrapperSchema();
}
if (qualified
&& StringUtils.isEmpty(mpi.getConcreteName().getNamespaceURI())) {
QName newName = new QName(wrapperName.getNamespaceURI(),
mpi.getConcreteName().getLocalPart());
mpi.setElement(true);
mpi.setElementQName(newName);
mpi.setConcreteName(newName);
XmlSchemaUtils.setElementQName(el, newName);
el.setForm(new XmlSchemaForm(XmlSchemaForm.QUALIFIED));
}
if (Collection.class.isAssignableFrom(mpi.getTypeClass())
&& mpi.getTypeClass().isInterface()) {
Type type = (Type)mpi.getProperty(GENERIC_TYPE);
if (!(type instanceof java.lang.reflect.ParameterizedType)
&& el.getSchemaTypeName() == null && el.getSchemaType() == null) {
max = Long.MAX_VALUE;
el.setSchemaTypeName(Constants.XSD_ANYTYPE);
}
}
el.setMinOccurs(min);
el.setMaxOccurs(max);
if (nillable) {
el.setNillable(nillable);
}
seq.getItems().add(el);
mpi.setXmlSchema(el);
}
if (Boolean.TRUE.equals(mpi.getProperty(HEADER))) {
QName qn = (QName)mpi.getProperty(ELEMENT_NAME);
XmlSchemaUtils.setElementQName(el, qn);
SchemaInfo headerSchemaInfo = getOrCreateSchema(serviceInfo, qn.getNamespaceURI(),
getQualifyWrapperSchema());
if (!isExistSchemaElement(headerSchemaInfo.getSchema(), qn)) {
headerSchemaInfo.getSchema().getItems().add(el);
}
}
}
}
private Annotation[] getMethodParameterAnnotations(final MessagePartInfo mpi) {
Annotation[][] paramAnno = (Annotation[][])mpi.getProperty(METHOD_PARAM_ANNOTATIONS);
int index = mpi.getIndex();
if (paramAnno != null && index < paramAnno.length && index >= 0) {
return paramAnno[index];
}
return null;
}
private Annotation[] getMethodAnnotations(final MessagePartInfo mpi) {
return (Annotation[])mpi.getProperty(METHOD_ANNOTATIONS);
}
private void addMimeType(final XmlSchemaElement element, final Annotation[] annotations) {
if (annotations != null) {
for (Annotation annotation : annotations) {
if (annotation instanceof XmlMimeType) {
MimeAttribute attr = new MimeAttribute();
attr.setValue(((XmlMimeType)annotation).value());
element.addMetaInfo(MimeAttribute.MIME_QNAME, attr);
}
}
}
}
private Map getJaxbAnnoMap(MessagePartInfo mpi) {
Map map = new ConcurrentHashMap();
Annotation[] anns = getMethodParameterAnnotations(mpi);
if (anns != null) {
for (Annotation anno : anns) {
if (anno instanceof XmlList) {
map.put(XmlList.class, true);
}
if (anno instanceof XmlAttachmentRef) {
map.put(XmlAttachmentRef.class, true);
}
if (anno instanceof XmlJavaTypeAdapter) {
map.put(XmlJavaTypeAdapter.class, true);
}
if (anno instanceof XmlElementWrapper) {
map.put(XmlElementWrapper.class, true);
}
}
}
return map;
}
private SchemaInfo getOrCreateSchema(ServiceInfo serviceInfo, String namespaceURI, boolean qualified) {
for (SchemaInfo s : serviceInfo.getSchemas()) {
if (s.getNamespaceURI().equals(namespaceURI)) {
return s;
}
}
SchemaInfo schemaInfo = new SchemaInfo(namespaceURI);
SchemaCollection col = serviceInfo.getXmlSchemaCollection();
XmlSchema schema = col.getSchemaByTargetNamespace(namespaceURI);
if (schema != null) {
schemaInfo.setSchema(schema);
serviceInfo.addSchema(schemaInfo);
return schemaInfo;
}
schema = col.newXmlSchemaInCollection(namespaceURI);
if (qualified) {
schema.setElementFormDefault(new XmlSchemaForm(XmlSchemaForm.QUALIFIED));
}
schemaInfo.setSchema(schema);
Map explicitNamespaceMappings = this.getDataBinding().getDeclaredNamespaceMappings();
if (explicitNamespaceMappings == null) {
explicitNamespaceMappings = Collections.emptyMap();
}
NamespaceMap nsMap = new NamespaceMap();
for (Map.Entry mapping : explicitNamespaceMappings.entrySet()) {
nsMap.add(mapping.getValue(), mapping.getKey());
}
if (!explicitNamespaceMappings.containsKey(WSDLConstants.NS_SCHEMA_XSD)) {
nsMap.add(WSDLConstants.NP_SCHEMA_XSD, WSDLConstants.NS_SCHEMA_XSD);
}
if (!explicitNamespaceMappings.containsKey(serviceInfo.getTargetNamespace())) {
nsMap.add(WSDLConstants.CONVENTIONAL_TNS_PREFIX, serviceInfo.getTargetNamespace());
}
schema.setNamespaceContext(nsMap);
serviceInfo.addSchema(schemaInfo);
return schemaInfo;
}
protected void createMessageParts(InterfaceInfo intf, OperationInfo op, Method method) {
final Class[] paramClasses = method.getParameterTypes();
// Setup the input message
op.setProperty(METHOD, method);
MessageInfo inMsg = op.createMessage(this.getInputMessageName(op, method), MessageInfo.Type.INPUT);
op.setInput(inMsg.getName().getLocalPart(), inMsg);
for (int j = 0; j < paramClasses.length; j++) {
if (Exchange.class.equals(paramClasses[j])) {
continue;
}
if (isInParam(method, j)) {
QName q = getInParameterName(op, method, j);
QName partName = getInPartName(op, method, j);
if (!isRPC(method) && !isWrapped(method)
&& inMsg.getMessagePartsMap().containsKey(partName)) {
LOG.log(Level.WARNING, "INVALID_BARE_METHOD", getServiceClass() + "." + method.getName());
partName = new QName(partName.getNamespaceURI(), partName.getLocalPart() + j);
q = new QName(q.getNamespaceURI(), q.getLocalPart() + j);
}
MessagePartInfo part = inMsg.addMessagePart(partName);
initializeParameter(part, paramClasses[j], method.getGenericParameterTypes()[j]);
//TODO:remove method param annotations
part.setProperty(METHOD_PARAM_ANNOTATIONS, method.getParameterAnnotations());
part.setProperty(PARAM_ANNOTATION, method.getParameterAnnotations()[j]);
if (getJaxbAnnoMap(part).size() > 0) {
op.setProperty(WRAPPERGEN_NEEDED, true);
}
if (!isWrapped(method) && !isRPC(method)) {
part.setProperty(ELEMENT_NAME, q);
}
if (isHeader(method, j)) {
part.setProperty(HEADER, Boolean.TRUE);
if (isRPC(method) || !isWrapped(method)) {
part.setElementQName(q);
} else {
part.setProperty(ELEMENT_NAME, q);
}
}
part.setIndex(j);
}
}
sendEvent(Event.OPERATIONINFO_IN_MESSAGE_SET, op, method, inMsg);
boolean hasOut = hasOutMessage(method);
if (hasOut) {
// Setup the output message
MessageInfo outMsg = op.createMessage(createOutputMessageName(op, method),
MessageInfo.Type.OUTPUT);
op.setOutput(outMsg.getName().getLocalPart(), outMsg);
final Class returnType = method.getReturnType();
if (!returnType.isAssignableFrom(void.class)) {
final QName q = getOutPartName(op, method, -1);
final QName q2 = getOutParameterName(op, method, -1);
MessagePartInfo part = outMsg.addMessagePart(q);
initializeParameter(part, method.getReturnType(), method.getGenericReturnType());
if (!isRPC(method) && !isWrapped(method)) {
part.setProperty(ELEMENT_NAME, q2);
}
part.setProperty(METHOD_ANNOTATIONS, method.getAnnotations());
part.setProperty(PARAM_ANNOTATION, method.getAnnotations());
if (isHeader(method, -1)) {
part.setProperty(HEADER, Boolean.TRUE);
if (isRPC(method) || !isWrapped(method)) {
part.setElementQName(q2);
} else {
part.setProperty(ELEMENT_NAME, q2);
}
}
part.setIndex(0);
}
for (int j = 0; j < paramClasses.length; j++) {
if (Exchange.class.equals(paramClasses[j])) {
continue;
}
if (isOutParam(method, j)) {
if (outMsg == null) {
outMsg = op.createMessage(createOutputMessageName(op, method),
MessageInfo.Type.OUTPUT);
}
QName q = getOutPartName(op, method, j);
QName q2 = getOutParameterName(op, method, j);
if (isInParam(method, j)) {
q = op.getInput().getMessagePartByIndex(j).getName();
q2 = (QName)op.getInput().getMessagePartByIndex(j).getProperty(ELEMENT_NAME);
if (q2 == null) {
q2 = op.getInput().getMessagePartByIndex(j).getElementQName();
}
}
MessagePartInfo part = outMsg.addMessagePart(q);
part.setProperty(METHOD_PARAM_ANNOTATIONS, method.getParameterAnnotations());
part.setProperty(PARAM_ANNOTATION, method.getParameterAnnotations()[j]);
initializeParameter(part, paramClasses[j], method.getGenericParameterTypes()[j]);
part.setIndex(j + 1);
if (!isRPC(method) && !isWrapped(method)) {
part.setProperty(ELEMENT_NAME, q2);
}
if (isInParam(method, j)) {
part.setProperty(MODE_INOUT, Boolean.TRUE);
}
if (isHeader(method, j)) {
part.setProperty(HEADER, Boolean.TRUE);
if (isRPC(method) || !isWrapped(method)) {
part.setElementQName(q2);
} else {
part.setProperty(ELEMENT_NAME, q2);
}
}
}
}
sendEvent(Event.OPERATIONINFO_OUT_MESSAGE_SET, op, method, outMsg);
}
//setting the parameterOrder that
//allows preservation of method signatures
//when doing java->wsdl->java
setParameterOrder(method, paramClasses, op);
if (hasOut) {
// Faults are only valid if not a one-way operation
initializeFaults(intf, op, method);
}
}
private void setParameterOrder(Method method, Class[] paramClasses, OperationInfo op) {
if (isRPC(method) || !isWrapped(method)) {
List paramOrdering = new LinkedList();
boolean hasOut = false;
for (int j = 0; j < paramClasses.length; j++) {
if (Exchange.class.equals(paramClasses[j])) {
continue;
}
if (isInParam(method, j)) {
paramOrdering.add(getInPartName(op, method, j).getLocalPart());
if (isOutParam(method, j)) {
hasOut = true;
}
} else if (isOutParam(method, j)) {
hasOut = true;
paramOrdering.add(getOutPartName(op, method, j).getLocalPart());
}
}
if (!paramOrdering.isEmpty() && hasOut) {
op.setParameterOrdering(paramOrdering);
}
}
}
protected void createInputWrappedMessageParts(OperationInfo op, Method method, MessageInfo inMsg) {
String partName = null;
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
partName = c.getRequestWrapperPartName(op, method);
if (partName != null) {
break;
}
}
if (partName == null) {
partName = "parameters";
}
MessagePartInfo part = inMsg.addMessagePart(partName);
part.setElement(true);
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getRequestWrapperName(op, method);
if (q != null) {
part.setElementQName(q);
}
}
if (part.getElementQName() == null) {
part.setElementQName(inMsg.getName());
} else if (!part.getElementQName().equals(op.getInput().getName())) {
op.getInput().setName(part.getElementQName());
}
if (getRequestWrapper(method) != null) {
part.setTypeClass(this.getRequestWrapper(method));
} else if (getRequestWrapperClassName(method) != null) {
part.setProperty("REQUEST.WRAPPER.CLASSNAME", getRequestWrapperClassName(method));
}
int partIdx = 0;
int maxIdx = 0;
for (MessagePartInfo mpart : op.getInput().getMessageParts()) {
if (Boolean.TRUE.equals(mpart.getProperty(HEADER))) {
int idx = mpart.getIndex();
inMsg.addMessagePart(mpart);
mpart.setIndex(idx);
//make sure the header part and the wrapper part don't share the
//same index. We can move the wrapper part around a bit
//if need be
if (maxIdx < idx) {
maxIdx = idx;
}
if (idx == partIdx) {
maxIdx++;
partIdx = maxIdx;
}
}
}
part.setIndex(partIdx);
}
protected void createOutputWrappedMessageParts(OperationInfo op, Method method, MessageInfo outMsg) {
String partName = null;
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
partName = c.getResponseWrapperPartName(op, method);
if (partName != null) {
break;
}
}
for (MessagePartInfo mpart : op.getOutput().getMessageParts()) {
if (Boolean.TRUE.equals(mpart.getProperty(HEADER))) {
partName = "result";
break;
}
}
if (partName == null) {
partName = "parameters";
}
MessagePartInfo part = outMsg.addMessagePart(partName);
part.setElement(true);
part.setIndex(0);
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getResponseWrapperName(op, method);
if (q != null) {
part.setElementQName(q);
break;
}
}
if (part.getElementQName() == null) {
part.setElementQName(outMsg.getName());
} else if (!part.getElementQName().equals(op.getOutput().getName())) {
op.getOutput().setName(part.getElementQName());
}
if (this.getResponseWrapper(method) != null) {
part.setTypeClass(this.getResponseWrapper(method));
} else if (getResponseWrapperClassName(method) != null) {
part.setProperty("RESPONSE.WRAPPER.CLASSNAME", getResponseWrapperClassName(method));
}
for (MessagePartInfo mpart : op.getOutput().getMessageParts()) {
if (Boolean.TRUE.equals(mpart.getProperty(HEADER))) {
int idx = mpart.getIndex();
outMsg.addMessagePart(mpart);
mpart.setIndex(idx);
}
}
}
private static Class createArrayClass(GenericArrayType atp) {
Type tp = ((GenericArrayType)atp).getGenericComponentType();
Class rawClass = null;
if (tp instanceof Class) {
rawClass = (Class)tp;
} else if (tp instanceof GenericArrayType) {
rawClass = createArrayClass((GenericArrayType)tp);
} else if (tp instanceof ParameterizedType) {
rawClass = (Class)((ParameterizedType)tp).getRawType();
if (List.class.isAssignableFrom(rawClass)) {
rawClass = getClass((ParameterizedType)tp);
rawClass = Array.newInstance(rawClass, 0).getClass();
}
}
return Array.newInstance(rawClass, 0).getClass();
}
private static Class getClass(Type paramType) {
Class rawClass = null;
if (paramType instanceof Class) {
rawClass = (Class)paramType;
} else if (paramType instanceof GenericArrayType) {
rawClass = createArrayClass((GenericArrayType)paramType);
} else if (paramType instanceof ParameterizedType) {
rawClass = (Class)((ParameterizedType)paramType).getRawType();
}
return rawClass;
}
protected void initializeParameter(MessagePartInfo part, Class rawClass, Type type) {
if (isHolder(rawClass, type)) {
Type c = getHolderType(rawClass, type);
if (c != null) {
type = c;
rawClass = getClass(type);
}
}
if (type instanceof TypeVariable) {
if (parameterizedTypes == null) {
processParameterizedTypes();
}
TypeVariable var = (TypeVariable)type;
Map> mp = parameterizedTypes.get(var.getGenericDeclaration());
if (mp != null) {
Class c = parameterizedTypes.get(var.getGenericDeclaration()).get(var.getName());
if (c != null) {
rawClass = c;
type = c;
part.getMessageInfo().setProperty("parameterized", Boolean.TRUE);
}
}
}
part.setProperty(GENERIC_TYPE, type);
// if rawClass is List, it will be converted to array
// and set it to type class
if (Collection.class.isAssignableFrom(rawClass)) {
part.setProperty(RAW_CLASS, rawClass);
}
part.setTypeClass(rawClass);
if (part.getMessageInfo().getOperation().isUnwrapped()
&& Boolean.TRUE.equals(part.getProperty(HEADER))) {
//header from the unwrapped operation, make sure the type is set for the
//approriate header in the wrapped operation
OperationInfo o = ((UnwrappedOperationInfo)part.getMessageInfo().getOperation())
.getWrappedOperation();
if (Boolean.TRUE.equals(part.getProperty(ReflectionServiceFactoryBean.MODE_OUT))
|| Boolean.TRUE.equals(part.getProperty(ReflectionServiceFactoryBean.MODE_INOUT))) {
MessagePartInfo mpi = o.getOutput().getMessagePart(part.getName());
if (mpi != null) {
mpi.setTypeClass(rawClass);
mpi.setProperty(GENERIC_TYPE, type);
if (Collection.class.isAssignableFrom(rawClass)) {
mpi.setProperty(RAW_CLASS, type);
}
}
}
if (!Boolean.TRUE.equals(part.getProperty(ReflectionServiceFactoryBean.MODE_OUT))) {
MessagePartInfo mpi = o.getInput().getMessagePart(part.getName());
if (mpi != null) {
mpi.setTypeClass(rawClass);
mpi.setProperty(GENERIC_TYPE, type);
if (Collection.class.isAssignableFrom(rawClass)) {
mpi.setProperty(RAW_CLASS, type);
}
}
}
}
}
public QName getServiceQName() {
return getServiceQName(true);
}
public QName getServiceQName(boolean lookup) {
if (serviceName == null && lookup) {
serviceName = new QName(getServiceNamespace(), getServiceName());
}
return serviceName;
}
public QName getEndpointName() {
return getEndpointName(true);
}
public QName getEndpointName(boolean lookup) {
if (endpointName != null || !lookup) {
return endpointName;
}
for (AbstractServiceConfiguration c : serviceConfigurations) {
QName name = c.getEndpointName();
if (name != null) {
endpointName = name;
return name;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
public EndpointInfo getEndpointInfo() {
return getService().getEndpointInfo(getEndpointName());
}
public void setEndpointName(QName en) {
this.endpointName = en;
}
protected String getServiceName() {
for (AbstractServiceConfiguration c : serviceConfigurations) {
String name = c.getServiceName();
if (name != null) {
return name;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected String getServiceNamespace() {
if (serviceName != null) {
return serviceName.getNamespaceURI();
}
for (AbstractServiceConfiguration c : serviceConfigurations) {
String name = c.getServiceNamespace();
if (name != null) {
return name;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
public QName getInterfaceName() {
for (AbstractServiceConfiguration c : serviceConfigurations) {
QName name = c.getInterfaceName();
if (name != null) {
return name;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected boolean isValidMethod(final Method method) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Boolean b = c.isOperation(method);
if (b != null) {
return b.booleanValue();
}
}
return true;
}
public boolean isHolder(Class cls, Type type) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Boolean b = c.isHolder(cls, type);
if (b != null) {
return b.booleanValue();
}
}
return false;
}
public Type getHolderType(Class cls, Type type) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Type b = c.getHolderType(cls, type);
if (b != null) {
return b;
}
}
return null;
}
protected boolean isWrapped(final Method method) {
Boolean b = wrappedCache.get(method);
if (b == null) {
if (isRPC(method)) {
wrappedCache.put(method, Boolean.FALSE);
return false;
}
for (AbstractServiceConfiguration c : serviceConfigurations) {
b = c.isWrapped(method);
if (b != null) {
wrappedCache.put(method, b);
return b.booleanValue();
}
}
wrappedCache.put(method, Boolean.TRUE);
return true;
}
return b;
}
protected boolean isMatchOperation(String methodNameInClass, String methodNameInWsdl) {
// TODO: This seems wrong and not sure who put it here. Will revisit -
// DBD
boolean ret = false;
String initOfMethodInClass = methodNameInClass.substring(0, 1);
String initOfMethodInWsdl = methodNameInWsdl.substring(0, 1);
if (initOfMethodInClass.equalsIgnoreCase(initOfMethodInWsdl)
&& methodNameInClass.substring(1, methodNameInClass.length())
.equals(methodNameInWsdl.substring(1, methodNameInWsdl.length()))) {
ret = true;
}
return ret;
}
protected boolean isOutParam(Method method, int j) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
Boolean b = c.isOutParam(method, j);
if (b != null) {
return b.booleanValue();
}
}
return true;
}
protected boolean isInParam(Method method, int j) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
Boolean b = c.isInParam(method, j);
if (b != null) {
return b.booleanValue();
}
}
return true;
}
protected QName getInputMessageName(final OperationInfo op, final Method method) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getInputMessageName(op, method);
if (q != null) {
return q;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected QName createOutputMessageName(final OperationInfo op, final Method method) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getOutputMessageName(op, method);
if (q != null) {
return q;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected boolean hasOutMessage(Method m) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
Boolean b = c.hasOutMessage(m);
if (b != null) {
return b.booleanValue();
}
}
return true;
}
protected void initializeFaults(final InterfaceInfo service,
final OperationInfo op, final Method method) {
// Set up the fault messages
final Class[] exceptionClasses = method.getExceptionTypes();
for (int i = 0; i < exceptionClasses.length; i++) {
Class exClazz = exceptionClasses[i];
// Ignore XFireFaults because they don't need to be declared
if (Fault.class.isAssignableFrom(exClazz)
|| exClazz.equals(RuntimeException.class) || exClazz.equals(Throwable.class)) {
continue;
}
addFault(service, op, exClazz);
}
}
protected void initializeDefaultInterceptors() {
super.initializeDefaultInterceptors();
initializeFaultInterceptors();
}
protected void initializeFaultInterceptors() {
getService().getOutFaultInterceptors().add(new FaultOutInterceptor());
}
protected FaultInfo addFault(final InterfaceInfo service, final OperationInfo op, Class exClass) {
Class beanClass = getBeanClass(exClass);
if (beanClass == null) {
return null;
}
String faultMsgName = null;
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
faultMsgName = c.getFaultMessageName(op, exClass, beanClass);
if (faultMsgName != null) {
break;
}
}
if (faultMsgName == null) {
faultMsgName = exClass.getSimpleName();
}
QName faultName = getFaultName(service, op, exClass, beanClass);
FaultInfo fi = op.addFault(new QName(op.getName().getNamespaceURI(), faultMsgName),
new QName(op.getName().getNamespaceURI(), faultMsgName));
fi.setProperty(Class.class.getName(), exClass);
fi.setProperty("elementName", faultName);
MessagePartInfo mpi = fi.addMessagePart(new QName(faultName.getNamespaceURI(),
exClass.getSimpleName()));
mpi.setElementQName(faultName);
mpi.setTypeClass(beanClass);
sendEvent(Event.OPERATIONINFO_FAULT, op, exClass, fi);
return fi;
}
protected void createFaultForException(Class exClass, FaultInfo fi) {
Field fields[] = exClass.getDeclaredFields();
for (Field field : fields) {
MessagePartInfo mpi = fi
.addMessagePart(new QName(fi.getName().getNamespaceURI(), field.getName()));
mpi.setProperty(Class.class.getName(), field.getType());
}
MessagePartInfo mpi = fi.addMessagePart(new QName(fi.getName().getNamespaceURI(), "message"));
mpi.setProperty(Class.class.getName(), String.class);
}
protected Class getBeanClass(Class exClass) {
if (java.rmi.RemoteException.class.isAssignableFrom(exClass)) {
return null;
}
if (FaultInfoException.class.isAssignableFrom(exClass)) {
try {
Method m = exClass.getMethod("getFaultInfo");
return m.getReturnType();
} catch (SecurityException e) {
throw new ServiceConstructionException(e);
} catch (NoSuchMethodException e) {
throw new ServiceConstructionException(e);
}
}
return exClass;
}
protected QName getFaultName(InterfaceInfo service, OperationInfo o, Class exClass, Class beanClass) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getFaultName(service, o, exClass, beanClass);
if (q != null) {
return q;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected String getAction(OperationInfo op, Method method) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
String s = c.getAction(op, method);
if (s != null) {
return s;
}
}
return "";
}
public boolean isHeader(Method method, int j) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
Boolean b = c.isHeader(method, j);
if (b != null) {
return b.booleanValue();
}
}
return true;
}
/**
* Creates a name for the operation from the method name. If an operation
* with that name already exists, a name is create by appending an integer
* to the end. I.e. if there is already two methods named
* doSomething
, the first one will have an operation name of
* "doSomething" and the second "doSomething1".
*
* @param service
* @param method
*/
protected QName getOperationName(InterfaceInfo service, Method method) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName s = c.getOperationName(service, method);
if (s != null) {
return s;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected boolean isAsync(final Method method) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
Boolean b = c.isAsync(method);
if (b != null) {
return b.booleanValue();
}
}
return true;
}
protected QName getInPartName(final OperationInfo op, final Method method, final int paramNumber) {
if (paramNumber == -1) {
return null;
}
if (isWrapped(method) && !isHeader(method, paramNumber)) {
return getInParameterName(op, method, paramNumber);
}
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getInPartName(op, method, paramNumber);
if (q != null) {
return q;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected QName getInParameterName(final OperationInfo op, final Method method, final int paramNumber) {
if (paramNumber == -1) {
return null;
}
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getInParameterName(op, method, paramNumber);
if (q != null) {
return q;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected QName getOutParameterName(final OperationInfo op, final Method method, final int paramNumber) {
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getOutParameterName(op, method, paramNumber);
if (q != null) {
return q;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected QName getOutPartName(final OperationInfo op, final Method method, final int paramNumber) {
if (isWrapped(method)) {
return getOutParameterName(op, method, paramNumber);
}
for (Iterator itr = serviceConfigurations.iterator(); itr.hasNext();) {
AbstractServiceConfiguration c = (AbstractServiceConfiguration)itr.next();
QName q = c.getOutPartName(op, method, paramNumber);
if (q != null) {
return q;
}
}
throw new IllegalStateException("ServiceConfiguration must provide a value!");
}
protected Class getResponseWrapper(Method selected) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Class cls = c.getResponseWrapper(selected);
if (cls != null) {
return cls;
}
}
return null;
}
protected String getResponseWrapperClassName(Method selected) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
String cls = c.getResponseWrapperClassName(selected);
if (cls != null) {
return cls;
}
}
return null;
}
protected Class getRequestWrapper(Method selected) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Class cls = c.getRequestWrapper(selected);
if (cls != null) {
return cls;
}
}
return null;
}
protected String getRequestWrapperClassName(Method selected) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
String cls = c.getRequestWrapperClassName(selected);
if (cls != null) {
return cls;
}
}
return null;
}
public boolean isWrapperPartQualified(MessagePartInfo mpi) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Boolean b = c.isWrapperPartQualified(mpi);
if (b != null) {
return b;
}
}
return false;
}
public boolean isWrapperPartNillable(MessagePartInfo mpi) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Boolean b = c.isWrapperPartNillable(mpi);
if (b != null) {
return b;
}
}
return false;
}
public long getWrapperPartMaxOccurs(MessagePartInfo mpi) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Long b = c.getWrapperPartMaxOccurs(mpi);
if (b != null) {
return b;
}
}
return 1;
}
public long getWrapperPartMinOccurs(MessagePartInfo mpi) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
Long b = c.getWrapperPartMinOccurs(mpi);
if (b != null) {
return b;
}
}
return 1;
}
protected MethodDispatcher getMethodDispatcher() {
return methodDispatcher;
}
protected void setMethodDispatcher(MethodDispatcher m) {
methodDispatcher = m;
}
public List getConfigurations() {
return serviceConfigurations;
}
public void setConfigurations(List configurations) {
this.serviceConfigurations = configurations;
}
public Class getServiceClass() {
return serviceClass;
}
private void processParameterizedTypes() {
parameterizedTypes = new HashMap>>();
if (serviceClass.isInterface()) {
processTypes(serviceClass, serviceType);
} else {
for (int x = 0; x < serviceClass.getInterfaces().length; x++) {
processTypes(serviceClass.getInterfaces()[x], serviceClass.getGenericInterfaces()[x]);
}
processTypes(serviceClass.getSuperclass(), serviceClass.getGenericSuperclass());
}
}
protected void processTypes(Class sc, Type tp) {
if (tp instanceof ParameterizedType) {
ParameterizedType ptp = (ParameterizedType)tp;
Type c = (Class)ptp.getRawType();
Map> m = new HashMap>();
parameterizedTypes.put(c, m);
for (int x = 0; x < ptp.getActualTypeArguments().length; x++) {
Type t = ptp.getActualTypeArguments()[x];
TypeVariable tv = sc.getTypeParameters()[x];
if (t instanceof Class) {
m.put(tv.getName(), (Class)t);
}
}
}
}
public void setServiceType(ParameterizedType servicetype) {
serviceType = servicetype;
}
public void setServiceClass(Class serviceClass) {
this.serviceClass = serviceClass;
checkServiceClassAnnotations(serviceClass);
}
protected void checkServiceClassAnnotations(Class sc) {
Annotation anns[] = serviceClass.getAnnotations();
if (anns != null) {
for (Annotation ann : anns) {
String pkg = ann.annotationType().getPackage().getName();
if ("javax.xml.ws".equals(pkg)
|| "javax.jws".equals(pkg)) {
LOG.log(Level.WARNING, "JAXWS_ANNOTATION_FOUND", serviceClass.getName());
return;
}
}
}
for (Method m : serviceClass.getMethods()) {
anns = m.getAnnotations();
if (anns != null) {
for (Annotation ann : anns) {
String pkg = ann.annotationType().getPackage().getName();
if ("javax.xml.ws".equals(pkg)
|| "javax.jws".equals(pkg)) {
LOG.log(Level.WARNING, "JAXWS_ANNOTATION_FOUND", serviceClass.getName());
return;
}
}
}
}
}
public String getWsdlURL() {
if (wsdlURL == null) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
wsdlURL = c.getWsdlURL();
if (wsdlURL != null) {
break;
}
}
if (null == wsdlURL && getBus() != null) {
ServiceContractResolverRegistry registry = getBus()
.getExtension(ServiceContractResolverRegistry.class);
if (null != registry) {
URI uri = registry.getContractLocation(this.getServiceQName());
if (null != uri) {
try {
wsdlURL = uri.toURL().toString();
} catch (MalformedURLException e) {
LOG.log(Level.FINE, "resolve qname failed", this.getServiceQName());
}
}
}
}
if (wsdlURL != null) {
// create a unique string so if its an interned string (like
// from an annotation), caches will clear
wsdlURL = new String(wsdlURL);
}
}
return wsdlURL;
}
public void setWsdlURL(String wsdlURL) {
// create a unique string so if its an interned string (like
// from an annotation), caches will clear
this.wsdlURL = new String(wsdlURL);
}
public void setWsdlURL(URL wsdlURL) {
this.wsdlURL = wsdlURL.toString();
}
public List getServiceConfigurations() {
return serviceConfigurations;
}
public void setServiceConfigurations(List serviceConfigurations) {
this.serviceConfigurations = serviceConfigurations;
}
public void setServiceName(QName serviceName) {
this.serviceName = serviceName;
}
public Invoker getInvoker() {
return invoker;
}
public void setInvoker(Invoker invoker) {
this.invoker = invoker;
}
public Executor getExecutor() {
return executor;
}
public void setExecutor(Executor executor) {
this.executor = executor;
}
public List getIgnoredClasses() {
return ignoredClasses;
}
public void setIgnoredClasses(List ignoredClasses) {
this.ignoredClasses = ignoredClasses;
}
protected Set> getExtraClass() {
return null;
}
public boolean isWrapped() {
if (this.wrappedStyle != null) {
defWrappedCache = wrappedStyle;
}
if (this.defWrappedCache == null) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
defWrappedCache = c.isWrapped();
if (defWrappedCache != null) {
return defWrappedCache;
}
}
defWrappedCache = Boolean.TRUE;
}
return defWrappedCache;
}
public String getStyle() {
if (styleCache == null) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
styleCache = c.getStyle();
if (styleCache != null) {
return styleCache;
}
}
styleCache = "document";
}
return styleCache;
}
public boolean isRPC(Method method) {
Boolean b = isRpcCache.get(method);
if (b == null) {
for (AbstractServiceConfiguration c : serviceConfigurations) {
b = c.isRPC(method);
if (b != null) {
isRpcCache.put(method, b);
return b.booleanValue();
}
}
b = "rpc".equals(getStyle());
isRpcCache.put(method, b);
}
return b;
}
public void setWrapped(boolean style) {
this.wrappedStyle = style;
}
/**
* Returns non-null if wrapped mode was explicitely disabled or enabled.
*/
public Boolean getWrapped() {
return this.wrappedStyle;
}
public Map getProperties() {
return properties;
}
public void setProperties(Map properties) {
this.properties = properties;
}
public List getIgnoredMethods() {
return ignoredMethods;
}
public void setIgnoredMethods(List ignoredMethods) {
this.ignoredMethods = ignoredMethods;
}
public List getFeatures() {
return features;
}
public void setFeatures(List f) {
this.features = f;
}
private boolean isValidate() {
return validate || System.getProperty("cxf.validateServiceSchemas", "false").equals("true");
}
/**
* If 'validate' is true, this class will validate the service. It will report problems
* with the service model and the XML schema for the service.
* @param validate
*/
public void setValidate(boolean validate) {
this.validate = validate;
}
public void setSchemaLocations(List schemaLocations) {
this.schemaLocations = schemaLocations;
}
}