/**
* 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.yoko.tools.processors.wsdl;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Operation;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.wsdl.JAXBExtensionHelper;
import org.apache.schemas.yoko.bindings.corba.ArgType;
import org.apache.schemas.yoko.bindings.corba.BindingType;
import org.apache.schemas.yoko.bindings.corba.MemberType;
import org.apache.schemas.yoko.bindings.corba.OperationType;
import org.apache.schemas.yoko.bindings.corba.ParamType;
import org.apache.schemas.yoko.bindings.corba.RaisesType;
import org.apache.schemas.yoko.bindings.corba.TypeMappingType;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaAnnotation;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaExternal;
import org.apache.ws.commons.schema.XmlSchemaObjectTable;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.apache.yoko.wsdl.CorbaConstants;
import org.apache.yoko.wsdl.CorbaTypeImpl;
public class WSDLToCorbaBinding {
protected static final Logger LOG = LogUtils.getL7dLogger(WSDLToCorbaBinding.class);
static XmlSchema xmlSchemaType;
static String wsdlFileName;
static String outputFile;
static String namespace;
static boolean verboseOn;
protected Definition def;
protected String idlNamespace;
WSDLToCorbaHelper helper = new WSDLToCorbaHelper();
TypeMappingType typeMappingType;
ExtensionRegistry extReg;
List<Object> interfaceNames = new ArrayList<Object>();
Map<Object, Object> bindingNameMap = new HashMap<Object, Object>();
String bindingName;
WSDLParameter wsdlParameter;
List<Object> bindingNames;
List<XmlSchema> xmlSchemaList;
WSDLToTypeProcessor typeProcessor = new WSDLToTypeProcessor();
public WSDLToCorbaBinding() {
}
public void setXMLSchemaList(List<XmlSchema> list) {
xmlSchemaList = list;
helper.setXMLSchemaList(list);
}
public void setXMLSchema(XmlSchema schema) {
xmlSchemaType = schema;
helper.setXMLSchema(schema);
}
public WSDLToCorbaHelper getHelper() {
return helper;
}
public Definition generateCORBABinding() throws Exception {
try {
extReg = new ExtensionRegistry();
addExtensions(extReg);
typeProcessor.setExtensionRegistry(extReg);
typeProcessor.parseWSDL(getWsdlFileName());
def = typeProcessor.getWSDLDefinition();
generateCORBABinding(def);
} catch (Exception ex) {
throw ex;
}
return def;
}
public Binding[] generateCORBABinding(Definition definition) throws Exception {
def = definition;
helper.setWsdlDefinition(def);
if (extReg == null) {
extReg = def.getExtensionRegistry();
addExtensions(extReg);
typeProcessor.setExtensionRegistry(extReg);
}
typeProcessor.setWSDLDefinition(def);
wsdlParameter = new WSDLParameter();
if (idlNamespace == null) {
setIdlNamespace(def);
}
generateNSPrefix(def, getIdlNamespace(), "ns");
typeProcessor.process();
setXMLSchema(typeProcessor.getXmlSchemaType());
setXMLSchemaList(typeProcessor.getXmlSchemaTypes());
List<PortType> intfs = null;
if (interfaceNames.size() > 0) {
intfs = new ArrayList<PortType>(interfaceNames.size());
for (int i = 0; i < interfaceNames.size(); i++) {
PortType portType = null;
String interfaceName = (String)interfaceNames.get(i);
Map portTypes = def.getPortTypes();
if (portTypes != null) {
Iterator it2 = portTypes.keySet().iterator();
while (it2.hasNext()) {
QName existPortQName = (QName)it2.next();
if (!existPortQName.getLocalPart().equals(interfaceName)) {
portType = null;
} else {
portType = (PortType)portTypes.get(existPortQName);
break;
}
}
}
if (portType == null) {
String msgStr = "PortType " + interfaceName
+ " doesn't exist in WSDL.";
throw new Exception(msgStr);
}
intfs.add(portType);
}
} else {
Map portTypes = def.getPortTypes();
if (portTypes == null) {
org.apache.cxf.common.i18n.Message msg = new org.apache.cxf.common.i18n.Message(
"No PortTypes defined in wsdl", LOG);
throw new Exception(msg.toString());
} else {
PortType portType = null;
if (portTypes.size() > 1) {
throwMultiplePortTypeException(portTypes);
} else {
portType = (PortType) portTypes.values().iterator().next();
interfaceNames.add(portType.getQName().getLocalPart());
}
intfs = new ArrayList<PortType>();
intfs.add(portType);
}
}
Binding[] bindings = new Binding[intfs.size()];
for (int i = 0; i < intfs.size(); i++) {
bindings[i] = generateCORBABinding(def, (PortType) intfs.get(i));
}
return bindings;
}
private void throwMultiplePortTypeException(Map portTypes) throws Exception {
StringBuffer sb = new StringBuffer();
org.apache.cxf.common.i18n.Message msgDef =
new org.apache.cxf.common.i18n.Message("Multiple PortTypes defined in wsdl", LOG);
sb.append(msgDef.toString());
Iterator it2 = portTypes.keySet().iterator();
int cnt = 0;
while (it2.hasNext()) {
cnt++;
sb.append(" " + cnt + " --> " + ((QName) it2.next()).getLocalPart());
}
throw new Exception(sb.toString());
}
private Binding generateCORBABinding(Definition definition, PortType portType) throws Exception {
QName bqname = null;
if (extReg == null) {
extReg = def.getExtensionRegistry();
addExtensions(extReg);
}
bindingNames = new ArrayList<Object>();
String interfaceName = portType.getQName().getLocalPart();
String bname = getMappedBindingName(interfaceName);
String prefix = definition.getPrefix(definition.getTargetNamespace());
if (prefix == null) {
prefix = "";
}
if (bname == null) {
bname = bindingName;
}
if (bname == null) {
bname = mangleInterfaceName(interfaceName) + "CORBABinding";
setBindingName(bname);
bqname = new QName(definition.getTargetNamespace(), bname, prefix);
int count = 0;
while (helper.queryBinding(definition, bqname)) {
bname = bname + count;
bqname = new QName(definition.getTargetNamespace(), bname, prefix);
}
} else {
bqname = new QName(definition.getTargetNamespace(), bname, prefix);
// Check if the Binding with name already exists
if (helper.queryBinding(definition, bqname)) {
String msgStr = "Binding " + bqname.getLocalPart()
+ " already exists in WSDL.";
org.apache.cxf.common.i18n.Message msg =
new org.apache.cxf.common.i18n.Message(msgStr, LOG);
throw new Exception(msg.toString());
}
}
// jwsdl model should have all other bindings in it.
String pfx = definition.getPrefix(CorbaConstants.NU_WSDL_CORBA);
if (pfx == null) {
pfx = new String("corba");
def.addNamespace(pfx, CorbaConstants.NU_WSDL_CORBA);
}
Binding binding = null;
binding = def.createBinding();
binding.setPortType(portType);
binding.setQName(bqname);
bindingNames.add(bname);
mapBindingToInterface(portType.getQName().getLocalPart(), bname);
BindingType bindingType = null;
addCorbaTypeMap(def);
try {
bindingType = (BindingType)extReg
.createExtension(Binding.class, CorbaConstants.NE_CORBA_BINDING);
bindingType.setRepositoryID(helper.REPO_STRING
+ binding.getPortType().getQName().getLocalPart().replace('.', '/')
+ helper.IDL_VERSION);
binding.addExtensibilityElement(bindingType);
} catch (WSDLException ex) {
ex.printStackTrace();
}
try {
addBindingOperations(def, portType, binding);
binding.setUndefined(false);
definition.addBinding(binding);
} catch (Exception ex) {
ex.printStackTrace();
}
return binding;
}
private void addBindingOperations(Definition definition, PortType portType, Binding binding)
throws Exception {
List<Operation> ops = (List<javax.wsdl.Operation>)portType.getOperations();
for (Operation op : ops) {
BindingOperation bindingOperation = definition.createBindingOperation();
addCorbaOperationExtElement(bindingOperation, op);
bindingOperation.setName(op.getName());
if (op.getInput() != null) {
BindingInput bindingInput = definition.createBindingInput();
bindingInput.setName(op.getInput().getName());
bindingOperation.setBindingInput(bindingInput);
}
if (op.getOutput() != null) {
BindingOutput bindingOutput = definition.createBindingOutput();
bindingOutput.setName(op.getOutput().getName());
bindingOperation.setBindingOutput(bindingOutput);
}
// add Faults
if (op.getFaults() != null && op.getFaults().size() > 0) {
Map faults = op.getFaults();
Iterator i = faults.values().iterator();
while (i.hasNext()) {
Fault fault = (Fault)i.next();
BindingFault bindingFault = definition.createBindingFault();
bindingFault.setName(fault.getName());
bindingOperation.addBindingFault(bindingFault);
}
}
bindingOperation.setOperation(op);
binding.addBindingOperation(bindingOperation);
}
}
public void addExtensions(ExtensionRegistry extRegistry) throws JAXBException {
try {
JAXBExtensionHelper.addExtensions(extReg, Binding.class, BindingType.class);
JAXBExtensionHelper.addExtensions(extReg, BindingOperation.class,
org.apache.schemas.yoko.bindings.corba.OperationType.class);
JAXBExtensionHelper.addExtensions(extReg, Definition.class, TypeMappingType.class);
JAXBExtensionHelper.addExtensions(extReg, Port.class,
org.apache.schemas.yoko.bindings.corba.AddressType.class);
extReg.mapExtensionTypes(Binding.class, CorbaConstants.NE_CORBA_BINDING, BindingType.class);
extReg.mapExtensionTypes(BindingOperation.class, CorbaConstants.NE_CORBA_OPERATION,
org.apache.schemas.yoko.bindings.corba.OperationType.class);
extReg.mapExtensionTypes(Definition.class, CorbaConstants.NE_CORBA_TYPEMAPPING,
TypeMappingType.class);
extReg.mapExtensionTypes(Port.class, CorbaConstants.NE_CORBA_ADDRESS,
org.apache.schemas.yoko.bindings.corba.AddressType.class);
} catch (javax.xml.bind.JAXBException ex) {
LOG.log(Level.SEVERE, "Failing to serialize/deserialize extensions", ex);
throw new JAXBException(ex.getMessage());
}
}
private void addCorbaOperationExtElement(BindingOperation bo, Operation op)
throws Exception {
OperationType operationType = null;
try {
operationType = (OperationType)extReg.createExtension(BindingOperation.class,
CorbaConstants.NE_CORBA_OPERATION);
} catch (WSDLException wse) {
LOG.log(Level.SEVERE, "Failed to create a Binding Operation extension", wse);
throw new Exception(LOG.toString(), wse);
}
operationType.setName(op.getName());
List<ParamType> params = new ArrayList<ParamType>();
List<ArgType> returns = new ArrayList<ArgType>();
wsdlParameter.processParameters(this, op, def, xmlSchemaList, params, returns, true);
for (ParamType paramtype : params) {
operationType.getParam().add(paramtype);
}
for (ArgType retType : returns) {
operationType.setReturn(retType);
}
Map faults = op.getFaults();
Iterator i = faults.values().iterator();
while (i.hasNext()) {
Fault fault = (Fault)i.next();
RaisesType raisestype = new RaisesType();
CorbaTypeImpl extype = convertFaultToCorbaType(xmlSchemaType, fault);
if (extype != null) {
raisestype.setException(helper.createQNameCorbaNamespace(extype.getName()));
operationType.getRaises().add(raisestype);
}
}
bo.addExtensibilityElement(operationType);
}
private void addCorbaTypeMap(Definition definition) throws Exception {
Iterator t = definition.getExtensibilityElements().iterator();
Iterator j = definition.getExtensibilityElements().iterator();
while (t.hasNext()) {
if (j.next() instanceof TypeMappingType) {
typeMappingType = (TypeMappingType)t.next();
break;
}
}
if (typeMappingType == null) {
typeMappingType = (TypeMappingType)extReg.createExtension(Definition.class,
CorbaConstants.NE_CORBA_TYPEMAPPING);
typeMappingType.setTargetNamespace(getIdlNamespace());
definition.addExtensibilityElement(typeMappingType);
}
helper.setTypeMap(typeMappingType);
addCorbaTypes(definition);
}
private void addCorbaTypes(Definition definition) throws Exception {
Iterator s = xmlSchemaList.iterator();
while (s.hasNext()) {
XmlSchema xmlSchemaTypes = (XmlSchema)s.next();
Iterator schemas = xmlSchemaTypes.getIncludes().getIterator();
while (schemas.hasNext()) {
Object obj = schemas.next();
if (obj instanceof XmlSchemaExternal) {
XmlSchemaExternal extSchema = (XmlSchemaExternal) obj;
addCorbaTypes(extSchema.getSchema());
}
}
addCorbaTypes(xmlSchemaTypes);
}
}
private void addCorbaTypes(XmlSchema xmlSchemaTypes) throws Exception {
XmlSchemaObjectTable objs = xmlSchemaTypes.getSchemaTypes();
Iterator i = objs.getValues();
CorbaTypeImpl corbaTypeImpl = null;
while (i.hasNext()) {
XmlSchemaType type = (XmlSchemaType)i.next();
boolean anonymous = WSDLTypes.isAnonymous(type.getName());
corbaTypeImpl = helper.convertSchemaToCorbaType(type, type.getQName(), null,
null, anonymous);
if (corbaTypeImpl != null) {
if (corbaTypeImpl.getQName() != null) {
corbaTypeImpl.setQName(null);
}
if (!helper.isDuplicate(corbaTypeImpl)) {
typeMappingType.getStructOrExceptionOrUnion().add(corbaTypeImpl);
}
}
}
addCorbaElements(corbaTypeImpl, xmlSchemaTypes);
}
private void addCorbaElements(CorbaTypeImpl corbaTypeImpl,
XmlSchema xmlSchemaTypes) throws Exception {
XmlSchemaObjectTable elements = xmlSchemaTypes.getElements();
Iterator i2 = elements.getValues();
while (i2.hasNext()) {
XmlSchemaElement el = (XmlSchemaElement)i2.next();
boolean anonymous = false;
if (el.getSchemaType() == null) {
anonymous = true;
} else {
anonymous = WSDLTypes.isAnonymous(el.getSchemaType().getName());
}
if (el.getSchemaType() != null) {
XmlSchemaAnnotation annotation = null;
if (el.getAnnotation() != null) {
annotation = el.getAnnotation();
}
corbaTypeImpl =
helper.convertSchemaToCorbaType(el.getSchemaType(),
el.getQName(), el.getSchemaType(),
annotation, anonymous);
if (el.isNillable()) {
QName uname =
helper.createQNameCorbaNamespace(corbaTypeImpl.getQName().getLocalPart() + "_nil");
corbaTypeImpl = helper.createNillableUnion(uname,
helper.checkPrefix(el.getQName()),
helper.checkPrefix(corbaTypeImpl.getQName()));
}
if (corbaTypeImpl != null) {
if (corbaTypeImpl.getQName() != null) {
corbaTypeImpl.setQName(null);
}
if (!helper.isDuplicate(corbaTypeImpl)) {
typeMappingType.getStructOrExceptionOrUnion().add(corbaTypeImpl);
}
}
}
}
}
private CorbaTypeImpl convertFaultToCorbaType(XmlSchema xmlSchema, Fault fault) throws Exception {
org.apache.schemas.yoko.bindings.corba.Exception corbaex = null;
XmlSchemaType schemaType = null;
String faultName = fault.getMessage().getQName().getLocalPart();
int pos = faultName.indexOf("_exception.");
if (pos != -1) {
faultName = faultName.substring(pos + 11);
faultName = faultName + "Exception";
}
QName name = helper.createQNameCorbaNamespace(faultName);
Iterator parts = fault.getMessage().getParts().values().iterator();
if (parts.hasNext()) {
Part part = (Part)parts.next();
schemaType = helper.lookUpType(part);
if (schemaType != null && !helper.isSchemaTypeException(schemaType)) {
corbaex = new org.apache.schemas.yoko.bindings.corba.Exception();
corbaex.setName(schemaType.getName());
corbaex.setQName(schemaType.getQName());
CorbaTypeImpl corbaTypeImpl =
helper.convertSchemaToCorbaType(schemaType, part.getTypeName(), null, null, false);
if (corbaTypeImpl != null) {
MemberType member = new MemberType();
member.setName(corbaTypeImpl.getQName().getLocalPart());
member.setIdltype(corbaTypeImpl.getQName());
corbaex.getMember().add(member);
}
} else {
QName elementName = part.getElementName();
QName schematypeName = helper.checkPrefix(schemaType.getQName());
corbaex = createCorbaException(name, schematypeName, schemaType, elementName);
}
} else {
String msgStr = "Fault " + fault.getMessage().getQName().getLocalPart()
+ " INCORRECT_FAULT_MSG.";
org.apache.cxf.common.i18n.Message msg =
new org.apache.cxf.common.i18n.Message(msgStr, LOG);
throw new Exception(msg.toString());
}
if (corbaex == null) {
String msgStr = "Fault " + fault.getMessage().getQName().getLocalPart()
+ " UNSUPPORTED_FAULT.";
org.apache.cxf.common.i18n.Message msg =
new org.apache.cxf.common.i18n.Message(msgStr, LOG);
throw new Exception(msg.toString());
} else {
// Set the repository ID for Exception
// add to CorbaTypeMapping
String repoId = helper.REPO_STRING + corbaex.getName().replace('.', '/') + helper.IDL_VERSION;
corbaex.setRepositoryID(repoId);
CorbaTypeImpl corbaTypeImpl = (CorbaTypeImpl)corbaex;
corbaTypeImpl.setQName(null);
if (!helper.isDuplicate(corbaTypeImpl)) {
CorbaTypeImpl dup = helper.isDuplicateException(corbaTypeImpl);
if (dup != null) {
typeMappingType.getStructOrExceptionOrUnion().remove(dup);
typeMappingType.getStructOrExceptionOrUnion().add(corbaTypeImpl);
} else {
typeMappingType.getStructOrExceptionOrUnion().add(corbaTypeImpl);
}
}
}
return corbaex;
}
private org.apache.schemas.yoko.bindings.corba.Exception createCorbaException(QName name,
QName schemaTypeName,
XmlSchemaType stype,
QName elementName)
throws Exception {
org.apache.schemas.yoko.bindings.corba.Exception corbaex = null;
XmlSchemaComplexType complex = null;
if (stype instanceof XmlSchemaComplexType) {
complex = (XmlSchemaComplexType)stype;
corbaex = new org.apache.schemas.yoko.bindings.corba.Exception();
corbaex.setName(name.getLocalPart());
corbaex.setQName(schemaTypeName);
corbaex.setType(helper.checkPrefix(stype.getQName()));
corbaex.setRepositoryID(helper.REPO_STRING + "/" + name.getLocalPart() + helper.IDL_VERSION);
List attributeMembers = helper.processAttributesAsMembers(complex.getAttributes().getIterator());
Iterator iterator = attributeMembers.iterator();
while (iterator.hasNext()) {
MemberType memberType = (MemberType)iterator.next();
corbaex.getMember().add(memberType);
}
List members = helper.processContainerAsMembers(complex.getParticle(),
stype.getQName(),
schemaTypeName);
Iterator it = members.iterator();
while (it.hasNext()) {
MemberType memberType = (MemberType)it.next();
corbaex.getMember().add(memberType);
}
}
return corbaex;
}
public void setWsdlFile(String file) {
wsdlFileName = new String(file);
}
public String getWsdlFileName() {
return wsdlFileName;
}
public void setIdlNamespace(Definition definition) {
if (idlNamespace == null) {
String tns = definition.getTargetNamespace();
if (!tns.endsWith("/")) {
tns += "/";
}
idlNamespace = tns + "corba/typemap/";
}
setNamespace(idlNamespace);
}
public String getIdlNamespace() {
return idlNamespace;
}
public void generateNSPrefix(Definition definition, String namespaceURI, String str) {
String pfx = def.getPrefix(namespaceURI);
if (pfx != null) {
return;
}
int cnt = 0;
while (pfx == null) {
cnt++;
pfx = str + cnt;
if (def.getNamespace(pfx) != null) {
pfx = null;
}
}
def.addNamespace(pfx, namespaceURI);
}
public void setBindingName(String bname) {
bindingName = bname;
}
public void mapBindingToInterface(String intfName, String bName) {
bindingNameMap.put(intfName, bName);
}
public String getMappedBindingName(String interfaceName) {
return (String)bindingNameMap.get(interfaceName);
}
public List getGeneratedBindingNames() {
return bindingNames;
}
private String mangleInterfaceName(String name) {
int idx = name.indexOf("PortType");
if (idx != -1) {
return name.substring(0, idx);
} else {
return name;
}
}
public QName convertToQName(String name) {
String namespaceName = null;
String nametype = null;
String pfx = "";
int i = name.lastIndexOf("}");
int i2 = name.indexOf("}");
if (i >= 1) {
if (i == i2) {
namespaceName = name.substring(1, i);
nametype = name.substring(i + 1, name.length());
} else {
namespaceName = name.substring(1, i2);
pfx = name.substring(i2 + 2, i);
nametype = name.substring(i + 1, name.length());
}
}
return new QName(namespaceName, nametype, pfx);
}
public void setOutputDirectory(String dir) {
// Force directory creation
// before setting output directory
if (dir != null) {
File fileOutputDir = new File(dir);
if (!fileOutputDir.exists()) {
fileOutputDir.mkdir();
}
}
}
public void setExtensionRegistry(ExtensionRegistry reg) {
extReg = reg;
}
public ExtensionRegistry getExtensionRegistry() {
return extReg;
}
public void setOutputFile(String file) {
outputFile = new String(file);
}
public void setNamespace(String nameSpaceName) {
idlNamespace = nameSpaceName;
helper.setIdlNamespace(idlNamespace);
}
public void addInterfaceName(String interfaceName) {
interfaceNames.add(interfaceName);
}
public List getInterfaceNames() {
return interfaceNames;
}
public void setVerboseOn(boolean verbose) {
verboseOn = verbose;
}
public void main(String args[]) {
if (args.length != 6) {
System.err.println("usage: WSDLToCORBABinding "
+ "-w <wsdl file> -i <interfaceName> -o <output wsdl file>");
return;
}
try {
WSDLToCorbaBinding wsdlToCorbaBinding = new WSDLToCorbaBinding();
wsdlToCorbaBinding.setWsdlFile(args[1]);
wsdlToCorbaBinding.addInterfaceName(args[3]);
wsdlToCorbaBinding.setOutputDirectory(".");
wsdlToCorbaBinding.generateCORBABinding();
} catch (Exception ex) {
System.err.println("Error : " + ex.getMessage());
System.err.println();
if (verboseOn) {
ex.printStackTrace();
}
System.exit(1);
}
}
}