/**
* 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.tools.corba.processors.wsdl;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.wsdl.Binding;
import javax.wsdl.Definition;
import javax.wsdl.PortType;
import javax.xml.namespace.QName;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.apache.cxf.binding.corba.wsdl.Anonarray;
import org.apache.cxf.binding.corba.wsdl.Anonfixed;
import org.apache.cxf.binding.corba.wsdl.Anonsequence;
import org.apache.cxf.binding.corba.wsdl.Anonstring;
import org.apache.cxf.binding.corba.wsdl.Array;
import org.apache.cxf.binding.corba.wsdl.BindingType;
import org.apache.cxf.binding.corba.wsdl.CaseType;
import org.apache.cxf.binding.corba.wsdl.CorbaConstants;
import org.apache.cxf.binding.corba.wsdl.CorbaType;
import org.apache.cxf.binding.corba.wsdl.Fixed;
import org.apache.cxf.binding.corba.wsdl.MemberType;
import org.apache.cxf.binding.corba.wsdl.Sequence;
import org.apache.cxf.binding.corba.wsdl.Union;
import org.apache.cxf.binding.corba.wsdl.Unionbranch;
import org.apache.cxf.binding.corba.wsdl.W3CConstants;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.ws.commons.schema.XmlSchemaAnnotation;
import org.apache.ws.commons.schema.XmlSchemaAnnotationItem;
import org.apache.ws.commons.schema.XmlSchemaAppInfo;
import org.apache.ws.commons.schema.XmlSchemaChoice;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaFacet;
import org.apache.ws.commons.schema.XmlSchemaFractionDigitsFacet;
import org.apache.ws.commons.schema.XmlSchemaParticle;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction;
import org.apache.ws.commons.schema.XmlSchemaTotalDigitsFacet;
public final class WSDLTypes {
private static final Logger LOG = LogUtils.getL7dLogger(WSDLTypes.class);
private WSDLTypes() {
}
public static CorbaType processObject(Definition definition, XmlSchemaComplexType complex,
XmlSchemaAnnotation annotation, QName typeName,
QName defaultName, String idlNamespace)
throws Exception {
CorbaType corbaTypeImpl = null;
if (annotation != null) {
for (XmlSchemaAnnotationItem item : annotation.getItems()) {
XmlSchemaAppInfo appInfo = (XmlSchemaAppInfo)item;
if (appInfo != null) {
NodeList nlist = appInfo.getMarkup();
Node node = nlist.item(0);
String info = node.getNodeValue();
info = info.trim();
if ("corba:binding=".equals(info.substring(0, 14))) {
String bindingName = info.substring(14);
QName bqname = new QName(definition.getTargetNamespace(), bindingName);
//Check if the Binding with name already exists
Binding binding = null;
if (WSDLToCorbaHelper.queryBinding(definition, bqname)) {
binding = definition.getBinding(bqname);
}
if (binding != null) {
org.apache.cxf.binding.corba.wsdl.Object obj =
new org.apache.cxf.binding.corba.wsdl.Object();
PortType portT = binding.getPortType();
QName name = new QName(idlNamespace, portT.getQName().getLocalPart(),
definition.getPrefix(idlNamespace));
obj.setName(name.getLocalPart());
obj.setQName(name);
QName bName = binding.getQName();
obj.setBinding(bName);
// get the repository id of the binding.
String repId = null;
Iterator<?> bindIter = binding.getExtensibilityElements().iterator();
while (bindIter.hasNext()) {
BindingType type = (BindingType)bindIter.next();
repId = type.getRepositoryID();
}
obj.setRepositoryID(repId);
obj.setType(typeName);
corbaTypeImpl = obj;
} else {
//if (isVerboseOn()) {
System.out.println("Could not find binding for: " + bqname);
//}
}
}
}
}
}
if (corbaTypeImpl == null) {
org.apache.cxf.binding.corba.wsdl.Object obj =
new org.apache.cxf.binding.corba.wsdl.Object();
QName name = new QName(idlNamespace, "CORBA.Object", definition.getPrefix(idlNamespace));
obj.setName(name.getLocalPart());
obj.setQName(name);
obj.setRepositoryID("IDL:omg.org/CORBA/Object/1.0");
obj.setType(typeName);
corbaTypeImpl = obj;
}
return corbaTypeImpl;
}
public static CorbaType processStringType(CorbaType corbaTypeImpl, QName name,
String maxLength, String length) throws Exception {
boolean boundedString = true;
int bound = 0;
try {
if (maxLength != null) {
bound = Integer.parseInt(maxLength);
} else if (length != null) {
bound = Integer.parseInt(length);
} else {
boundedString = false;
}
} catch (NumberFormatException ex) {
throw new Exception("illegal number", ex);
} catch (Exception e) {
throw new Exception("illegal number", e);
}
if (boundedString) {
// bounded string
Anonstring anonString = new Anonstring();
anonString.setBound(bound);
anonString.setName(name.getLocalPart());
anonString.setQName(name);
anonString.setType(corbaTypeImpl.getQName());
corbaTypeImpl = anonString;
}
return corbaTypeImpl;
}
public static CorbaType mapToArray(QName name, QName schematypeName, QName arrayType,
QName elName, int bound, boolean anonymous) {
CorbaType corbatype = null;
//schematypeName = checkPrefix(schematypeName);
if (!anonymous) {
//Create an Array
Array corbaArray = new Array();
corbaArray.setName(name.getLocalPart());
corbaArray.setType(schematypeName);
corbaArray.setElemtype(arrayType);
corbaArray.setElemname(elName);
corbaArray.setBound(bound);
corbaArray.setRepositoryID(WSDLToCorbaHelper.REPO_STRING
+ name.getLocalPart().replace('.', '/')
+ WSDLToCorbaHelper.IDL_VERSION);
corbaArray.setQName(name);
corbatype = corbaArray;
} else {
//Create an Anonymous Array
Anonarray corbaArray = new Anonarray();
corbaArray.setName(name.getLocalPart());
corbaArray.setType(schematypeName);
corbaArray.setElemtype(arrayType);
corbaArray.setElemname(elName);
corbaArray.setBound(bound);
corbaArray.setQName(name);
corbatype = corbaArray;
}
return corbatype;
}
public static CorbaType mapToSequence(QName name, QName schematypeName, QName arrayType,
QName elName, int bound, boolean anonymous) {
CorbaType corbaTypeImpl = null;
//schematypeName = checkPrefix(schematypeName);
if (!anonymous) {
// Create a Sequence
Sequence corbaSeq = new Sequence();
corbaSeq.setName(name.getLocalPart());
corbaSeq.setQName(name);
corbaSeq.setType(schematypeName);
corbaSeq.setElemtype(arrayType);
corbaSeq.setElemname(elName);
corbaSeq.setBound(bound);
corbaSeq.setRepositoryID(WSDLToCorbaHelper.REPO_STRING
+ name.getLocalPart().replace('.', '/')
+ WSDLToCorbaHelper.IDL_VERSION);
corbaTypeImpl = corbaSeq;
} else {
// Create a Anonymous Sequence
Anonsequence corbaSeq = new Anonsequence();
corbaSeq.setName(name.getLocalPart());
corbaSeq.setQName(name);
corbaSeq.setType(schematypeName);
corbaSeq.setElemtype(arrayType);
corbaSeq.setElemname(elName);
corbaSeq.setBound(bound);
corbaTypeImpl = corbaSeq;
}
return corbaTypeImpl;
}
public static Union processUnionBranches(Union corbaUnion, List<MemberType> fields,
List<String> caselist) {
int caseIndex = 0;
for (int i = 0; i < fields.size(); i++) {
MemberType field = fields.get(i);
Unionbranch branch = new Unionbranch();
branch.setName(field.getName());
branch.setIdltype(field.getIdltype());
if (field.isSetQualified() && field.isQualified()) {
branch.setQualified(true);
}
branch.setDefault(false);
CaseType c = new CaseType();
c.setLabel(caselist.get(caseIndex));
caseIndex++;
branch.getCase().add(c);
corbaUnion.getUnionbranch().add(branch);
}
return corbaUnion;
}
public static boolean isOMGUnion(XmlSchemaComplexType type) {
boolean isUnion = false;
if (type.getParticle() instanceof XmlSchemaSequence
&& type.getAttributes().size() == 0) {
XmlSchemaSequence stype = (XmlSchemaSequence)type.getParticle();
if (stype.getItems().size() == 2) {
XmlSchemaParticle st1 = (XmlSchemaParticle)stype.getItems().get(0);
XmlSchemaParticle st2 = (XmlSchemaParticle)stype.getItems().get(1);
XmlSchemaElement discEl = null;
if (st1 instanceof XmlSchemaChoice && st2 instanceof XmlSchemaElement) {
isUnion = true;
discEl = (XmlSchemaElement)st2;
} else if (st2 instanceof XmlSchemaChoice && st1 instanceof XmlSchemaElement) {
isUnion = true;
discEl = (XmlSchemaElement)st1;
}
if (isUnion && !"discriminator".equals(discEl.getQName().getLocalPart())) {
isUnion = false;
}
}
}
return isUnion;
}
public static boolean isUnion(XmlSchemaComplexType type) {
boolean isUnion = false;
if (type.getParticle() instanceof XmlSchemaChoice && type.getAttributes().size() == 0) {
isUnion = true;
}
return isUnion;
}
public static CorbaType processDecimalType(XmlSchemaSimpleTypeRestriction restrictionType,
QName name, CorbaType corbaTypeImpl,
boolean anonymous) throws Exception {
String tdigits = null;
String fdigits = null;
boolean boundedDecimal = false;
boolean boundedScale = false;
for (XmlSchemaFacet val : restrictionType.getFacets()) {
if (val instanceof XmlSchemaTotalDigitsFacet) {
tdigits = val.getValue().toString();
boundedDecimal = true;
}
if (val instanceof XmlSchemaFractionDigitsFacet) {
fdigits = val.getValue().toString();
boundedScale = true;
}
}
int digits = 0;
int scale = 0;
if (boundedDecimal) {
try {
digits = Integer.parseInt(tdigits);
if ((digits > 31) || (digits < 1)) {
String msg = "totalDigits facet for the type " + name
+ " cannot be more than 31 for corba fixed types";
LOG.log(Level.WARNING, msg);
boundedDecimal = false;
} else if (digits == 31) {
boundedDecimal = false;
}
} catch (NumberFormatException ex) {
String msg = "totalDigits facet on the simple type restriction for type"
+ name.getLocalPart() + "is incorrect.";
throw new Exception(msg);
}
}
if (boundedScale) {
try {
scale = Integer.parseInt(fdigits);
if ((scale > 6) || (scale < 0)) {
String msg = "fixedDigits facet for the type " + name
+ " cannot be more than 6 for corba fixed types";
LOG.log(Level.WARNING, msg);
boundedScale = false;
} else if (scale == 6) {
boundedScale = false;
}
} catch (NumberFormatException ex) {
String msg = "fractionDigits facet on the simple type restriction for type"
+ name.getLocalPart() + " is incorrect.";
throw new Exception(msg);
}
}
if (!boundedDecimal) {
if (anonymous && corbaTypeImpl instanceof Anonfixed) {
Anonfixed fixed = (Anonfixed)corbaTypeImpl;
digits = Integer.parseInt(String.valueOf(fixed.getDigits()));
} else if (corbaTypeImpl instanceof Fixed) {
Fixed fixed = (Fixed)corbaTypeImpl;
digits = Integer.parseInt(String.valueOf(fixed.getDigits()));
}
}
if (!boundedScale) {
if (anonymous) {
Anonfixed fixed = (Anonfixed)corbaTypeImpl;
scale = Integer.parseInt(String.valueOf(fixed.getScale()));
} else {
Fixed fixed = (Fixed)corbaTypeImpl;
scale = Integer.parseInt(String.valueOf(fixed.getScale()));
}
}
if (boundedDecimal || boundedScale) {
if (anonymous) {
corbaTypeImpl = getAnonFixedCorbaType(name, W3CConstants.NT_SCHEMA_DECIMAL,
digits, scale);
} else {
corbaTypeImpl = getFixedCorbaType(name, W3CConstants.NT_SCHEMA_DECIMAL,
digits, scale);
}
}
return corbaTypeImpl;
}
public static CorbaType processBase64Type(CorbaType corbaTypeImpl, QName name,
String maxLength, String length)
throws Exception {
int bound = 0;
boolean boundedOctet = true;
try {
if (maxLength != null) {
bound = Integer.parseInt(maxLength);
} else if (length != null) {
bound = Integer.parseInt(length);
} else {
boundedOctet = false;
}
} catch (NumberFormatException ex) {
String msg = "length facet on the simple type restriction for type"
+ name.getLocalPart() + " is incorrect.";
throw new Exception(msg);
}
if (boundedOctet) {
corbaTypeImpl = getOctetCorbaType(name, corbaTypeImpl.getType(), bound);
}
return corbaTypeImpl;
}
// checks if the type is an anonymous type.
public static boolean isAnonymous(String typeName) {
boolean anonymous = false;
if (typeName == null) {
anonymous = true;
} else {
StringTokenizer strtok = new StringTokenizer(typeName, ".");
while (strtok.hasMoreTokens()) {
String token = strtok.nextToken();
if (token.startsWith("_")
&& Character.isDigit(token.charAt(1))) {
anonymous = true;
break;
}
}
}
return anonymous;
}
public static CorbaType getFixedCorbaType(QName name, QName stype, int digits, int scale) {
Fixed fixed = new Fixed();
fixed.setName(name.getLocalPart());
fixed.setQName(name);
fixed.setType(stype);
fixed.setDigits(digits);
fixed.setScale(scale);
fixed.setRepositoryID(WSDLToCorbaHelper.REPO_STRING
+ name.getLocalPart().replace('.', '/')
+ WSDLToCorbaHelper.IDL_VERSION);
return fixed;
}
public static CorbaType getAnonFixedCorbaType(QName name, QName stype, int digits, int scale) {
Anonfixed fixed = new Anonfixed();
fixed.setName(name.getLocalPart());
fixed.setQName(name);
fixed.setType(stype);
fixed.setDigits(digits);
fixed.setScale(scale);
return fixed;
}
public static CorbaType getOctetCorbaType(QName name, QName stype, int bound) {
Sequence seq = new Sequence();
seq.setName(name.getLocalPart());
seq.setQName(name);
seq.setType(stype);
seq.setElemtype(CorbaConstants.NT_CORBA_OCTET);
seq.setBound(bound);
seq.setRepositoryID(WSDLToCorbaHelper.REPO_STRING
+ name.getLocalPart().replace('.', '/')
+ WSDLToCorbaHelper.IDL_VERSION);
return seq;
}
}