org.apache.cxf.wsdl11.WSDLServiceBuilder 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.wsdl11;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Import;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.WSDLElement;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap12.SOAP12Binding;
import javax.xml.namespace.QName;
import org.w3c.dom.Element;
import org.apache.cxf.Bus;
import org.apache.cxf.BusException;
import org.apache.cxf.binding.BindingFactory;
import org.apache.cxf.binding.WSDLBindingFactory;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.xmlschema.SchemaCollection;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.service.model.AbstractMessageContainer;
import org.apache.cxf.service.model.AbstractPropertiesHolder;
import org.apache.cxf.service.model.BindingFaultInfo;
import org.apache.cxf.service.model.BindingInfo;
import org.apache.cxf.service.model.BindingMessageInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.DescriptionInfo;
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.ServiceInfo;
import org.apache.cxf.service.model.ServiceSchemaInfo;
import org.apache.cxf.service.model.UnwrappedOperationInfo;
import org.apache.cxf.transport.DestinationFactory;
import org.apache.cxf.transport.DestinationFactoryManager;
import org.apache.cxf.wsdl.WSDLManager;
import org.apache.ws.commons.schema.XmlSchemaComplexContentExtension;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaSequenceMember;
import org.apache.ws.commons.schema.XmlSchemaType;
import static org.apache.cxf.helpers.CastUtils.cast;
public class WSDLServiceBuilder {
public static final String WSDL_SCHEMA_LIST = WSDLServiceBuilder.class.getName() + ".SCHEMA";
public static final String WSDL_DEFINITION = WSDLServiceBuilder.class.getName() + ".DEFINITION";
public static final String WSDL_SERVICE = WSDLServiceBuilder.class.getName() + ".SERVICE";
public static final String WSDL_PORTTYPE = WSDLServiceBuilder.class.getName() + ".WSDL_PORTTYPE";
public static final String WSDL_PORT = WSDLServiceBuilder.class.getName() + ".PORT";
public static final String WSDL_BINDING = WSDLServiceBuilder.class.getName() + ".BINDING";
public static final String WSDL_SCHEMA_ELEMENT_LIST = WSDLServiceBuilder.class.getName()
+ ".SCHEMA_ELEMENTS";
public static final String WSDL_OPERATION = WSDLServiceBuilder.class.getName() + ".OPERATION";
public static final String WSDL_BINDING_OPERATION = WSDLServiceBuilder.class.getName()
+ ".BINDING_OPERATION";
private static final Logger LOG = LogUtils.getL7dLogger(WSDLServiceBuilder.class);
private Bus bus;
private Map schemaList = new HashMap();
private boolean recordOriginal = true;
private boolean allowRefs;
private boolean ignoreUnknownBindings;
private Level unwrapLogLevel = Level.FINE;
public WSDLServiceBuilder(Bus bus) {
this.bus = bus;
}
public WSDLServiceBuilder(Bus bus, boolean record) {
this.bus = bus;
recordOriginal = record;
}
public void setUnwrapLogLevel(Level l) {
unwrapLogLevel = l;
}
public void setIgnoreUnknownBindings(boolean b) {
ignoreUnknownBindings = b;
}
public void setAllowElementRefs(boolean b) {
allowRefs = b;
}
private void copyExtensors(AbstractPropertiesHolder info, List> extList) {
if (info != null) {
for (ExtensibilityElement ext : cast(extList, ExtensibilityElement.class)) {
if (!info.containsExtensor(ext)) {
info.addExtensor(ext);
}
}
}
}
private void copyExtensionAttributes(AbstractPropertiesHolder info,
javax.wsdl.extensions.AttributeExtensible ae) {
Map attrs = CastUtils.cast(ae.getExtensionAttributes());
if (!attrs.isEmpty()) {
info.setExtensionAttributes(attrs);
}
}
private void copyDocumentation(AbstractPropertiesHolder info, WSDLElement el) {
if (el.getDocumentationElement() != null) {
String doc = DOMUtils.getRawContent(el.getDocumentationElement());
info.setDocumentation(doc);
}
}
public List buildServices(Definition d) {
DescriptionInfo description = new DescriptionInfo();
if (recordOriginal) {
description.setProperty(WSDL_DEFINITION, d);
}
description.setName(d.getQName());
description.setBaseURI(d.getDocumentBaseURI());
copyExtensors(description, d.getExtensibilityElements());
copyExtensionAttributes(description, d);
List serviceList = new ArrayList();
for (java.util.Iterator ite = CastUtils.cast(d.getServices().keySet().iterator()); ite
.hasNext();) {
QName qn = ite.next();
serviceList.addAll(buildServices(d, qn, null, description));
}
return serviceList;
}
public List buildServices(Definition d, QName name) {
return buildServices(d, name, null, null);
}
public List buildServices(Definition d, QName name, QName endpointName) {
return buildServices(d, name, endpointName, null);
}
private List buildServices(Definition d,
QName name,
QName endpointName,
DescriptionInfo description) {
Service service = d.getService(name);
if (service == null) {
org.apache.cxf.common.i18n.Message msg =
new org.apache.cxf.common.i18n.Message("MISSING_SERVICE",
LOG,
name);
throw new WSDLRuntimeException(msg);
}
return buildServices(d, service, endpointName, description);
}
public List buildServices(Definition def, Service serv) {
return buildServices(def, serv, null, null);
}
public List buildServices(Definition def, Service serv, QName endpointName) {
return buildServices(def, serv, endpointName, null);
}
public List buildMockServices(Definition d) {
List serviceList = new ArrayList();
List defList = new ArrayList();
defList.add(d);
parseImports(d, defList);
for (Definition def : defList) {
for (Iterator> ite = def.getPortTypes().entrySet().iterator(); ite.hasNext();) {
Entry, ?> entry = (Entry, ?>)ite.next();
PortType portType = def.getPortType((QName)entry.getKey());
ServiceInfo serviceInfo = this.buildMockService(def, portType);
serviceList.add(serviceInfo);
for (Iterator> it2 = d.getAllBindings().values().iterator(); it2.hasNext();) {
Binding b = (Binding)it2.next();
if (b.getPortType() == portType) {
this.buildBinding(serviceInfo, b);
break;
}
}
}
if (def.getPortTypes().size() == 0) {
DescriptionInfo description = new DescriptionInfo();
if (recordOriginal) {
description.setProperty(WSDL_DEFINITION, def);
}
description.setName(def.getQName());
description.setBaseURI(def.getDocumentBaseURI());
copyExtensors(description, def.getExtensibilityElements());
copyExtensionAttributes(description, def);
ServiceInfo service = new ServiceInfo();
service.setDescription(description);
if (recordOriginal) {
service.setProperty(WSDL_DEFINITION, def);
}
getSchemas(def, service);
service.setProperty(WSDL_SCHEMA_ELEMENT_LIST, this.schemaList);
serviceList.add(service);
}
}
return serviceList;
}
public ServiceInfo buildMockService(Definition def, PortType p) {
DescriptionInfo description = new DescriptionInfo();
if (recordOriginal) {
description.setProperty(WSDL_DEFINITION, def);
}
description.setName(def.getQName());
description.setBaseURI(def.getDocumentBaseURI());
copyExtensors(description, def.getExtensibilityElements());
copyExtensionAttributes(description, def);
ServiceInfo service = new ServiceInfo();
service.setDescription(description);
if (recordOriginal) {
service.setProperty(WSDL_DEFINITION, def);
}
getSchemas(def, service);
service.setProperty(WSDL_SCHEMA_ELEMENT_LIST, this.schemaList);
buildInterface(service, p);
return service;
}
private List buildServices(Definition def,
Service serv,
QName endpointName,
DescriptionInfo d) {
Map services = new LinkedHashMap();
DescriptionInfo description = d;
if (null == description) {
description = new DescriptionInfo();
if (recordOriginal) {
description.setProperty(WSDL_DEFINITION, def);
}
description.setName(def.getQName());
description.setBaseURI(def.getDocumentBaseURI());
copyExtensors(description, def.getExtensibilityElements());
copyExtensionAttributes(description, def);
Set done = new HashSet();
done.add(def);
Collection> values = CastUtils.cast(def.getImports().values());
for (List imports : values) {
for (Import imp : imports) {
if (!done.contains(imp.getDefinition())) {
done.add(imp.getDefinition());
copyExtensors(description, imp.getExtensibilityElements());
copyExtensionAttributes(description, imp);
copyExtensors(description, imp.getDefinition().getExtensibilityElements());
copyExtensionAttributes(description, imp.getDefinition());
}
}
}
}
for (Port port : cast(serv.getPorts().values(), Port.class)) {
if (endpointName != null
&& !endpointName.getLocalPart().equals(port.getName())) {
continue;
}
Binding binding = port.getBinding();
PortType bindingPt = binding.getPortType();
if (bindingPt == null) {
org.apache.cxf.common.i18n.Message msg = new
org.apache.cxf.common.i18n.Message("BINDING_MISSING_TYPE",
LOG,
binding.getQName());
throw new WSDLRuntimeException(msg);
}
//TODO: wsdl4j's bug. if there is recursive import,
//wsdl4j can not get operation input message
PortType pt = def.getPortType(bindingPt.getQName());
if (pt == null) {
pt = bindingPt;
}
ServiceInfo service = services.get(pt.getQName());
if (service == null) {
service = new ServiceInfo();
service.setDescription(description);
description.getDescribed().add(service);
if (recordOriginal) {
service.setProperty(WSDL_DEFINITION, def);
service.setProperty(WSDL_SERVICE, serv);
}
getSchemas(def, service);
copyDocumentation(service, serv);
service.setProperty(WSDL_SCHEMA_ELEMENT_LIST, this.schemaList);
service.setTargetNamespace(def.getTargetNamespace());
service.setName(serv.getQName());
copyExtensors(service, serv.getExtensibilityElements());
copyExtensionAttributes(service, serv);
buildInterface(service, pt);
services.put(pt.getQName(), service);
}
BindingInfo bi = service.getBinding(binding.getQName());
if (bi == null) {
bi = buildBinding(service, binding);
}
buildEndpoint(service, bi, port);
}
return new ArrayList(services.values());
}
private void getSchemas(Definition def, ServiceInfo serviceInfo) {
ServiceSchemaInfo serviceSchemaInfo = null;
WSDLManager wsdlManager = bus.getExtension(WSDLManager.class);
if (wsdlManager != null) {
serviceSchemaInfo = wsdlManager.getSchemasForDefinition(def);
}
if (serviceSchemaInfo == null) {
SchemaUtil schemaUtil = new SchemaUtil(bus, this.schemaList);
schemaUtil.getSchemas(def, serviceInfo);
serviceSchemaInfo = new ServiceSchemaInfo();
serviceSchemaInfo.setSchemaElementList(this.schemaList);
serviceSchemaInfo.setSchemaCollection(serviceInfo.getXmlSchemaCollection());
serviceSchemaInfo.setSchemaInfoList(serviceInfo.getSchemas());
if (wsdlManager != null) {
wsdlManager.putSchemasForDefinition(def, serviceSchemaInfo);
}
} else {
serviceInfo.setServiceSchemaInfo(serviceSchemaInfo);
schemaList.putAll(serviceSchemaInfo.getSchemaElementList());
}
}
private void parseImports(Definition def, List defList) {
List importList = new ArrayList();
Collection> ilist = cast(def.getImports().values());
for (List list : ilist) {
importList.addAll(list);
}
for (Import impt : importList) {
if (!defList.contains(impt.getDefinition())) {
defList.add(impt.getDefinition());
parseImports(impt.getDefinition(), defList);
}
}
}
public EndpointInfo buildEndpoint(ServiceInfo service, BindingInfo bi, Port port) {
List> elements = port.getExtensibilityElements();
String ns = null;
DestinationFactory factory = null;
EndpointInfo ei = null;
if (null != elements && elements.size() > 0) {
for (ExtensibilityElement el : CastUtils.cast(elements, ExtensibilityElement.class)) {
ns = el.getElementType().getNamespaceURI();
try {
factory = bus.getExtension(DestinationFactoryManager.class).getDestinationFactory(ns);
} catch (BusException e) {
// do nothing
}
if (factory != null) {
break;
}
}
if (factory == null) {
ns = ((ExtensibilityElement)elements.get(0)).getElementType().getNamespaceURI();
}
}
if (factory == null) { // get the transport id from bindingInfo
elements = port.getBinding().getExtensibilityElements();
if (null != elements && elements.size() > 0) {
for (ExtensibilityElement el : CastUtils.cast(elements, ExtensibilityElement.class)) {
if (el instanceof SOAPBinding) {
ns = ((SOAPBinding)el).getTransportURI();
break;
} else if (el instanceof SOAP12Binding) {
ns = ((SOAP12Binding)el).getTransportURI();
break;
// TODO: this is really ugly, but how to link between
// this binding and this transport ?
}
}
}
if (ns == null) {
if (ignoreUnknownBindings) {
return null;
}
org.apache.cxf.common.i18n.Message msg = new
org.apache.cxf.common.i18n.Message("MISSING_DESTINATION_FACTORY",
LOG,
port.getName());
throw new WSDLRuntimeException(msg);
}
try {
factory = bus.getExtension(DestinationFactoryManager.class).getDestinationFactory(ns);
} catch (BusException e) {
// do nothing
}
}
if (factory instanceof WSDLEndpointFactory) {
WSDLEndpointFactory wFactory = (WSDLEndpointFactory)factory;
ei = wFactory.createEndpointInfo(service, bi,
port.getExtensibilityElements());
}
if (ei == null) {
ei = new EndpointInfo(service, ns);
}
copyDocumentation(ei, port);
ei.setName(new QName(service.getName().getNamespaceURI(), port.getName()));
ei.setBinding(bi);
copyExtensors(ei, port.getExtensibilityElements());
copyExtensionAttributes(ei, port);
service.addEndpoint(ei);
DescriptionInfo d = service.getDescription();
if (null != d) {
d.getDescribed().add(ei);
}
return ei;
}
public BindingInfo buildBinding(ServiceInfo service, Binding binding) {
BindingInfo bi = null;
StringBuilder ns = new StringBuilder(100);
BindingFactory factory = WSDLServiceUtils.getBindingFactory(binding, bus, ns);
if (factory instanceof WSDLBindingFactory) {
WSDLBindingFactory wFactory = (WSDLBindingFactory)factory;
bi = wFactory.createBindingInfo(service, binding, ns.toString());
copyExtensors(bi, binding.getExtensibilityElements());
copyExtensionAttributes(bi, binding);
}
if (bi == null) {
bi = new BindingInfo(service, ns.toString());
bi.setName(binding.getQName());
copyExtensors(bi, binding.getExtensibilityElements());
copyExtensionAttributes(bi, binding);
for (BindingOperation bop : cast(binding.getBindingOperations(), BindingOperation.class)) {
LOG.finer("binding operation name is " + bop.getName());
String inName = null;
String outName = null;
if (bop.getBindingInput() != null) {
inName = bop.getBindingInput().getName();
}
if (bop.getBindingOutput() != null) {
outName = bop.getBindingOutput().getName();
}
BindingOperationInfo bop2 = bi.buildOperation(new QName(service.getName().getNamespaceURI(),
bop.getName()), inName, outName);
if (bop2 != null) {
copyExtensors(bop2, bop.getExtensibilityElements());
copyExtensionAttributes(bop2, bop);
bi.addOperation(bop2);
if (bop.getBindingInput() != null) {
copyExtensors(bop2.getInput(), bop.getBindingInput().getExtensibilityElements());
copyExtensionAttributes(bop2.getInput(), bop.getBindingInput());
handleHeader(bop2.getInput());
}
if (bop.getBindingOutput() != null) {
copyExtensors(bop2.getOutput(), bop.getBindingOutput().getExtensibilityElements());
copyExtensionAttributes(bop2.getOutput(), bop.getBindingOutput());
handleHeader(bop2.getOutput());
}
for (BindingFault f : cast(bop.getBindingFaults().values(), BindingFault.class)) {
BindingFaultInfo bif = bop2.getFault(new QName(service.getTargetNamespace(), f
.getName()));
copyExtensors(bif, bop.getBindingFault(f.getName()).getExtensibilityElements());
copyExtensionAttributes(bif, bop.getBindingFault(f.getName()));
}
}
}
}
service.addBinding(bi);
DescriptionInfo d = service.getDescription();
if (null != d) {
d.getDescribed().add(bi);
}
return bi;
}
private void handleHeader(BindingMessageInfo bindingMessageInfo) {
// mark all message part which should be in header
List extensiblilityElement = bindingMessageInfo
.getExtensors(ExtensibilityElement.class);
// for non-soap binding, the extensiblilityElement could be null
if (extensiblilityElement == null) {
return;
}
// for (ExtensibilityElement element : extensiblilityElement) {
// LOG.info("the extensibility is " + element.getClass().getName());
// if (element instanceof SOAPHeader) {
// LOG.info("the header is " + ((SOAPHeader)element).getPart());
// }
// }
}
public void buildInterface(ServiceInfo si, PortType p) {
InterfaceInfo inf = si.createInterface(p.getQName());
DescriptionInfo d = si.getDescription();
if (null != d) {
d.getDescribed().add(inf);
}
copyDocumentation(inf, p);
this.copyExtensors(inf, p.getExtensibilityElements());
this.copyExtensionAttributes(inf, p);
if (recordOriginal) {
inf.setProperty(WSDL_PORTTYPE, p);
}
for (Operation op : cast(p.getOperations(), Operation.class)) {
buildInterfaceOperation(inf, op);
}
}
private void buildInterfaceOperation(InterfaceInfo inf, Operation op) {
OperationInfo opInfo = inf.addOperation(new QName(inf.getName().getNamespaceURI(), op.getName()));
if (recordOriginal) {
opInfo.setProperty(WSDL_OPERATION, op);
}
copyDocumentation(opInfo, op);
List porderList = CastUtils.cast((List>)op.getParameterOrdering());
opInfo.setParameterOrdering(porderList);
this.copyExtensors(opInfo, op.getExtensibilityElements());
this.copyExtensionAttributes(opInfo, op);
Input input = op.getInput();
if (input != null) {
if (input.getMessage() == null) {
throw new WSDLRuntimeException(LOG, "NO_MESSAGE", "input", op.getName(), input.getName());
}
MessageInfo minfo = opInfo.createMessage(input.getMessage().getQName(), MessageInfo.Type.INPUT);
opInfo.setInput(input.getName(), minfo);
buildMessage(minfo, input.getMessage());
copyExtensors(minfo, input.getExtensibilityElements());
copyExtensionAttributes(minfo, input);
}
Output output = op.getOutput();
if (output != null) {
if (output.getMessage() == null) {
throw new WSDLRuntimeException(LOG, "NO_MESSAGE", "output", op.getName(), output.getName());
}
MessageInfo minfo = opInfo.createMessage(output.getMessage().getQName(), MessageInfo.Type.OUTPUT);
opInfo.setOutput(output.getName(), minfo);
buildMessage(minfo, output.getMessage());
copyExtensors(minfo, output.getExtensibilityElements());
copyExtensionAttributes(minfo, output);
}
Map, ?> m = op.getFaults();
for (Map.Entry, ?> rawentry : m.entrySet()) {
Map.Entry entry = cast(rawentry, String.class, Fault.class);
FaultInfo finfo = opInfo.addFault(new QName(inf.getName().getNamespaceURI(), entry.getKey()),
entry.getValue().getMessage().getQName());
copyDocumentation(finfo, entry.getValue());
buildMessage(finfo, entry.getValue().getMessage());
copyExtensors(finfo, entry.getValue().getExtensibilityElements());
copyExtensionAttributes(finfo, entry.getValue());
}
checkForWrapped(opInfo, allowRefs, false, unwrapLogLevel);
}
public static void checkForWrapped(OperationInfo opInfo, boolean relaxed) {
checkForWrapped(opInfo, relaxed, relaxed);
}
public static void checkForWrapped(OperationInfo opInfo, boolean allowRefs, boolean relaxed) {
checkForWrapped(opInfo, allowRefs, relaxed, Level.FINE);
}
public static void checkForWrapped(OperationInfo opInfo, boolean allowRefs,
boolean relaxed, Level logLevel) {
MessageInfo inputMessage = opInfo.getInput();
MessageInfo outputMessage = opInfo.getOutput();
boolean passedRule = true;
// RULE No.1:
// The operation's input and output message (if present) each contain
// only a single part
// input message must exist
if (inputMessage == null || inputMessage.size() == 0
|| (inputMessage.size() > 1 && !relaxed)) {
passedRule = false;
}
if (outputMessage != null && outputMessage.size() > 1) {
passedRule = false;
}
if (!passedRule) {
org.apache.cxf.common.i18n.Message message
= new org.apache.cxf.common.i18n.Message("WRAPPED_RULE_1", LOG, opInfo.getName());
LOG.log(logLevel, message.toString());
return;
}
SchemaCollection schemas = opInfo.getInterface().getService().getXmlSchemaCollection();
XmlSchemaElement inputEl = null;
XmlSchemaElement outputEl = null;
// RULE No.2:
// The input message part refers to a global element declaration whose
// local name is equal to the operation name.
MessagePartInfo inputPart = inputMessage.getMessagePartByIndex(0);
if (!inputPart.isElement()) {
passedRule = false;
} else {
QName inputElementName = inputPart.getElementQName();
inputEl = schemas.getElementByQName(inputElementName);
if (inputEl == null) {
passedRule = false;
} else if (!opInfo.getName().getLocalPart().equals(inputElementName.getLocalPart())) {
passedRule = relaxed;
}
}
if (!passedRule) {
org.apache.cxf.common.i18n.Message message
= new org.apache.cxf.common.i18n.Message("WRAPPED_RULE_2", LOG, opInfo.getName());
LOG.log(logLevel, message.toString());
return;
}
// RULE No.3:
// The output message part refers to a global element declaration
MessagePartInfo outputPart = null;
if (outputMessage != null && outputMessage.size() == 1) {
outputPart = outputMessage.getMessagePartByIndex(0);
if (outputPart != null) {
if (!outputPart.isElement()
|| schemas.getElementByQName(outputPart.getElementQName()) == null) {
passedRule = false;
} else {
outputEl = schemas.getElementByQName(outputPart.getElementQName());
}
}
}
if (!passedRule) {
org.apache.cxf.common.i18n.Message message
= new org.apache.cxf.common.i18n.Message("WRAPPED_RULE_3", LOG, opInfo.getName());
LOG.log(logLevel, message.toString());
return;
}
// RULE No.4 and No5:
// wrapper element should be pure complex type
// Now lets see if we have any attributes...
// This should probably look at the restricted and substitute types too.
OperationInfo unwrapped = new UnwrappedOperationInfo(opInfo);
MessageInfo unwrappedInput = new MessageInfo(unwrapped, MessageInfo.Type.INPUT,
inputMessage.getName());
MessageInfo unwrappedOutput = null;
XmlSchemaComplexType xsct = null;
if (inputEl.getSchemaType() instanceof XmlSchemaComplexType) {
xsct = (XmlSchemaComplexType)inputEl.getSchemaType();
if (hasAttributes(xsct)
|| (inputEl.isNillable() && !relaxed)
|| !isWrappableSequence(xsct, inputEl.getQName().getNamespaceURI(),
unwrappedInput, allowRefs)) {
passedRule = false;
}
} else {
passedRule = false;
}
if (!passedRule) {
org.apache.cxf.common.i18n.Message message
= new org.apache.cxf.common.i18n.Message("WRAPPED_RULE_4", LOG, opInfo.getName());
LOG.log(logLevel, message.toString());
return;
}
if (outputMessage != null) {
unwrappedOutput = new MessageInfo(unwrapped, MessageInfo.Type.OUTPUT, outputMessage.getName());
if (outputEl != null && outputEl.getSchemaType() instanceof XmlSchemaComplexType) {
xsct = (XmlSchemaComplexType)outputEl.getSchemaType();
if (xsct.isAbstract()) {
passedRule = false;
}
if (hasAttributes(xsct)
|| (outputEl.isNillable() && !relaxed)
|| !isWrappableSequence(xsct, outputEl.getQName().getNamespaceURI(), unwrappedOutput,
allowRefs)) {
passedRule = false;
}
} else {
passedRule = false;
}
}
if (!passedRule) {
org.apache.cxf.common.i18n.Message message
= new org.apache.cxf.common.i18n.Message("WRAPPED_RULE_5", LOG, opInfo.getName());
LOG.log(logLevel, message.toString());
return;
}
// we are wrappable!!
opInfo.setUnwrappedOperation(unwrapped);
unwrapped.setInput(opInfo.getInputName(), unwrappedInput);
if (outputMessage != null) {
unwrapped.setOutput(opInfo.getOutputName(), unwrappedOutput);
}
}
private static boolean hasAttributes(XmlSchemaComplexType complexType) {
// Now lets see if we have any attributes...
// This should probably look at the restricted and substitute types too.
if (complexType.getAnyAttribute() != null || !complexType.getAttributes().isEmpty()) {
return true;
}
return false;
}
private static boolean isWrappableSequence(XmlSchemaComplexType type, String namespaceURI,
MessageInfo wrapper, boolean allowRefs) {
if (type.getParticle() instanceof XmlSchemaSequence) {
XmlSchemaSequence seq = (XmlSchemaSequence)type.getParticle();
return buildMessageParts(seq, namespaceURI, wrapper, allowRefs);
} else if (type.getParticle() == null) {
if (type.getContentModel() == null) {
return true;
}
if (type.getContentModel().getContent() instanceof XmlSchemaComplexContentExtension) {
XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)type
.getContentModel().getContent();
QName baseTypeName = extension.getBaseTypeName();
ServiceInfo serviceInfo = wrapper.getOperation().getInterface().getService();
XmlSchemaType schemaType = serviceInfo.getXmlSchemaCollection().getTypeByQName(baseTypeName);
if (!(schemaType instanceof XmlSchemaComplexType)
|| !isWrappableSequence((XmlSchemaComplexType)schemaType, namespaceURI, wrapper,
allowRefs)) {
return false;
}
if (extension.getParticle() instanceof XmlSchemaSequence) {
XmlSchemaSequence seq = (XmlSchemaSequence)extension.getParticle();
return buildMessageParts(seq, namespaceURI, wrapper, allowRefs);
}
}
return true;
}
return false;
}
private static boolean buildMessageParts(XmlSchemaSequence seq, String namespaceURI, MessageInfo wrapper,
boolean allowRefs) {
List items = seq.getItems();
boolean ret = true;
for (XmlSchemaSequenceMember seqItem : items) {
if (!(seqItem instanceof XmlSchemaElement)) {
return false;
}
XmlSchemaElement el = (XmlSchemaElement)seqItem;
if (el.getSchemaTypeName() != null) {
MessagePartInfo mpi = wrapper.addMessagePart(new QName(namespaceURI, el.getName()));
mpi.setTypeQName(el.getSchemaTypeName());
mpi.setElement(true);
mpi.setElementQName(el.getWireName());
mpi.setConcreteName(el.getWireName());
mpi.setXmlSchema(el);
} else if (el.getRef().getTargetQName() != null) {
MessagePartInfo mpi = wrapper.addMessagePart(el.getRef().getTargetQName());
mpi.setTypeQName(el.getRef().getTargetQName());
mpi.setElementQName(el.getRef().getTargetQName());
mpi.setElement(true);
mpi.setXmlSchema(el);
mpi.setProperty("isRefElement", true);
// element reference is not permitted for wrapper element
if (!allowRefs) {
ret = false;
}
} else {
// anonymous type
MessagePartInfo mpi = wrapper.addMessagePart(new QName(namespaceURI, el.getName()));
mpi.setElementQName(mpi.getName());
mpi.setConcreteName(el.getWireName());
mpi.setElement(true);
mpi.setXmlSchema(el);
}
}
return ret;
}
private void buildMessage(AbstractMessageContainer minfo, Message msg) {
SchemaCollection schemas = minfo.getOperation().getInterface().getService()
.getXmlSchemaCollection();
List> orderedParam = msg.getOrderedParts(null);
for (Part part : cast(orderedParam, Part.class)) {
MessagePartInfo pi = minfo.addMessagePart(new QName(minfo.getName().getNamespaceURI(), part
.getName()));
if (part.getTypeName() != null) {
pi.setTypeQName(part.getTypeName());
pi.setElement(false);
pi.setXmlSchema(schemas.getTypeByQName(part.getTypeName()));
} else if (part.getElementName() != null) {
pi.setElementQName(part.getElementName());
XmlSchemaElement schemaElement = schemas.getElementByQName(part.getElementName());
if (null == schemaElement) {
org.apache.cxf.common.i18n.Message errorMessage =
new org.apache.cxf.common.i18n.Message("WSDL4J_BAD_ELEMENT_PART",
LOG,
part.getName(),
part.getElementName());
throw new WSDLRuntimeException(errorMessage);
}
pi.setElement(true);
pi.setXmlSchema(schemaElement);
} else {
org.apache.cxf.common.i18n.Message errorMessage =
new org.apache.cxf.common.i18n.Message("PART_NO_NAME_NO_TYPE",
LOG,
part.getName());
throw new WSDLRuntimeException(errorMessage);
}
}
}
}