/**
* 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.bindings.corba.types;
import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.cxf.service.model.ServiceInfo;
import org.apache.schemas.yoko.bindings.corba.Anonarray;
import org.apache.schemas.yoko.bindings.corba.Anonsequence;
import org.apache.schemas.yoko.bindings.corba.Array;
import org.apache.schemas.yoko.bindings.corba.Exception;
import org.apache.schemas.yoko.bindings.corba.MemberType;
import org.apache.schemas.yoko.bindings.corba.Sequence;
import org.apache.schemas.yoko.bindings.corba.Struct;
import org.apache.schemas.yoko.bindings.corba.Union;
import org.apache.schemas.yoko.bindings.corba.Unionbranch;
import org.apache.ws.commons.schema.XmlSchemaAttribute;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaGroupBase;
import org.apache.ws.commons.schema.XmlSchemaGroupRef;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.apache.yoko.bindings.corba.CorbaTypeMap;
import org.apache.yoko.bindings.corba.CorbaUtils;
import org.apache.yoko.wsdl.CorbaTypeImpl;
import org.apache.yoko.wsdl.W3CConstants;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
public class CorbaHandlerUtils {
public static CorbaObjectHandler createTypeHandler(ORB orb,
QName name,
QName idlType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
CorbaObjectHandler handler = null;
TypeCode tc = CorbaUtils.getTypeCode(orb, idlType, typeMaps);
if (CorbaUtils.isPrimitiveIdlType(idlType)) {
// Any is a special primitive
if (tc.kind().value() == TCKind._tk_any) {
handler = new CorbaAnyHandler(name, idlType, tc, null);
} else {
handler = new CorbaPrimitiveHandler(name, idlType, tc, null);
}
} else {
CorbaTypeImpl type = CorbaUtils.getCorbaType(idlType, typeMaps);
switch (tc.kind().value()) {
case TCKind._tk_array:
handler = new CorbaArrayHandler(name, idlType, tc, type);
break;
case TCKind._tk_enum:
handler = new CorbaEnumHandler(name, idlType, tc, type);
break;
case TCKind._tk_except:
handler = new CorbaExceptionHandler(name, idlType, tc, type);
break;
case TCKind._tk_fixed:
handler = new CorbaFixedHandler(name, idlType, tc, type);
break;
case TCKind._tk_sequence:
handler = new CorbaSequenceHandler(name, idlType, tc, type);
break;
case TCKind._tk_struct:
handler = new CorbaStructHandler(name, idlType, tc, type);
break;
case TCKind._tk_union:
handler = new CorbaUnionHandler(name, idlType, tc, type);
break;
case TCKind._tk_string:
case TCKind._tk_wstring:
// These need to be here to catch the anonymous string types.
handler = new CorbaPrimitiveHandler(name, idlType, tc, type);
break;
case TCKind._tk_objref:
handler = new CorbaObjectReferenceHandler(name, idlType, tc, type);
break;
default:
handler = new CorbaObjectHandler(name, idlType, tc, type);
}
}
return handler;
}
public static CorbaObjectHandler initializeObjectHandler(ORB orb,
QName name,
QName idlType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
CorbaTypeImpl type = CorbaUtils.getCorbaType(idlType, typeMaps);
XmlSchemaType schemaType = null;
if (type != null) {
schemaType = CorbaUtils.getXmlSchemaType(serviceInfo, type.getType());
}
return initializeObjectHandler(orb, name, idlType, schemaType, typeMaps, serviceInfo);
}
public static CorbaObjectHandler initializeObjectHandler(ORB orb,
QName name,
QName idlType,
XmlSchemaObject schemaType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
CorbaObjectHandler obj = createTypeHandler(orb, name, idlType, typeMaps, serviceInfo);
if (obj.getType() != null) {
String nsUri = getNamespaceURI(serviceInfo, obj.getType().getType());
name = new QName(nsUri, obj.getName().getLocalPart());
} else {
name = obj.getName();
}
if (!CorbaUtils.isPrimitiveIdlType(idlType)) {
switch (obj.getTypeCode().kind().value()) {
case TCKind._tk_array:
initializeArrayHandler(orb, obj, name, schemaType, typeMaps, serviceInfo);
break;
case TCKind._tk_except:
initializeExceptionHandler(orb, obj, name, schemaType, typeMaps, serviceInfo);
break;
case TCKind._tk_sequence:
initializeSequenceHandler(orb, obj, name, schemaType, typeMaps, serviceInfo);
break;
case TCKind._tk_struct:
initializeStructHandler(orb, obj, name, schemaType, typeMaps, serviceInfo);
break;
case TCKind._tk_union:
initializeUnionHandler(orb, obj, name, schemaType, typeMaps, serviceInfo);
break;
default:
// TODO: Should we raise an exception or log?
}
}
return obj;
}
public static void initializeArrayHandler(ORB orb,
CorbaObjectHandler obj,
QName name,
XmlSchemaObject schemaType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
QName arrayElementType = null;
long arrayBound = 0;
CorbaTypeImpl baseType = obj.getType();
XmlSchemaElement el = CorbaHandlerUtils.getXmlSchemaSequenceElement(schemaType, serviceInfo);
QName elementName = el.getQName();
if (!CorbaUtils.isElementFormQualified(serviceInfo, name.getNamespaceURI())) {
elementName = new QName("", elementName.getLocalPart());
}
if (baseType instanceof Array) {
Array arrayType = (Array)baseType;
arrayElementType = arrayType.getElemtype();
arrayBound = arrayType.getBound();
} else {
Anonarray anonArrayType = (Anonarray)baseType;
arrayElementType = anonArrayType.getElemtype();
arrayBound = anonArrayType.getBound();
}
for (int i = 0; i < arrayBound; ++i) {
CorbaObjectHandler elementObj =
initializeObjectHandler(orb, elementName, arrayElementType, el, typeMaps, serviceInfo);
((CorbaArrayHandler)obj).addElement(elementObj);
}
}
public static void initializeExceptionHandler(ORB orb,
CorbaObjectHandler obj,
QName name,
XmlSchemaObject schemaType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
Exception exceptType = (Exception)obj.getType();
List<MemberType> exceptMembers = exceptType.getMember();
XmlSchemaComplexType ctype = (XmlSchemaComplexType) schemaType;
QName qname = name;
if (ctype.getQName() != null) {
qname = ctype.getQName();
}
String nsURI = getNamespaceURI(serviceInfo, qname);
XmlSchemaGroupBase group = (XmlSchemaGroupBase) ctype.getParticle();
for (int i = 0; i < exceptMembers.size(); ++i) {
MemberType member = exceptMembers.get(i);
QName memberName = new QName(nsURI, member.getName());
QName memberType = member.getIdltype();
CorbaObjectHandler memberObj = initializeObjectHandler(orb,
memberName,
memberType,
group.getItems().getItem(i),
typeMaps,
serviceInfo);
((CorbaExceptionHandler)obj).addMember(memberObj);
}
}
public static void initializeSequenceHandler(ORB orb,
CorbaObjectHandler obj,
QName name,
XmlSchemaObject schemaType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
QName seqElementType = null;
long seqBound = 0;
CorbaTypeImpl baseType = obj.getType();
boolean isOctets = baseType.getType().equals(W3CConstants.NT_SCHEMA_BASE64)
|| baseType.getType().equals(W3CConstants.NT_SCHEMA_HBIN);
QName elementName = name;
if (!isOctets) {
XmlSchemaElement el = CorbaHandlerUtils.getXmlSchemaSequenceElement(schemaType, serviceInfo);
elementName = el.getQName();
if (!CorbaUtils.isElementFormQualified(serviceInfo, name.getNamespaceURI())) {
elementName = new QName("", elementName.getLocalPart());
}
}
if (baseType instanceof Sequence) {
Sequence seqType = (Sequence)baseType;
seqElementType = seqType.getElemtype();
seqBound = seqType.getBound();
} else {
Anonsequence seqType = (Anonsequence)baseType;
seqElementType = seqType.getElemtype();
seqBound = seqType.getBound();
}
if (seqBound == 0) {
// This is an unbounded sequence. Store a 'template' object that we can use to create
// new objects as needed
CorbaObjectHandler elementObj =
initializeObjectHandler(orb, elementName, seqElementType, typeMaps, serviceInfo);
((CorbaSequenceHandler)obj).setTemplateElement(elementObj);
}
for (int i = 0; i < seqBound; ++i) {
CorbaObjectHandler elementObj =
initializeObjectHandler(orb, elementName, seqElementType, typeMaps, serviceInfo);
((CorbaSequenceHandler)obj).addElement(elementObj);
}
}
public static void initializeStructHandler(ORB orb,
CorbaObjectHandler obj,
QName name,
XmlSchemaObject schemaType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
Struct structType = (Struct)obj.getType();
List<MemberType> structMembers = structType.getMember();
XmlSchemaObjectCollection attrs = null;
XmlSchemaObjectCollection members = null;
XmlSchemaObject stype = schemaType;
QName qname = name;
if (schemaType instanceof XmlSchemaElement) {
XmlSchemaElement el = (XmlSchemaElement) schemaType;
if (el.getQName() != null) {
qname = el.getQName();
}
stype = el.getSchemaType();
if (stype == null) {
stype = CorbaUtils.getXmlSchemaType(serviceInfo, el.getRefName());
}
}
if (stype instanceof XmlSchemaComplexType) {
XmlSchemaComplexType ctype = (XmlSchemaComplexType) stype;
if (ctype.getQName() != null) {
qname = ctype.getQName();
}
attrs = ctype.getAttributes();
stype = ctype.getParticle();
}
if (stype instanceof XmlSchemaGroupRef) {
members = ((XmlSchemaGroupRef) stype).getParticle().getItems();
} else if (stype instanceof XmlSchemaGroupBase) {
members = ((XmlSchemaGroupBase) stype).getItems();
}
String nsURI = getNamespaceURI(serviceInfo, qname);
int attrCount = 0;
int memberCount = 0;
for (int i = 0; i < structMembers.size(); ++i) {
XmlSchemaObject schemaObj;
if ((attrs != null) && (attrCount != attrs.getCount())) {
schemaObj = attrs.getItem(attrCount++);
} else {
schemaObj = members.getItem(memberCount++);
}
MemberType member = structMembers.get(i);
QName memberName = new QName(nsURI, member.getName());
QName memberType = member.getIdltype();
CorbaObjectHandler memberObj = initializeObjectHandler(orb,
memberName,
memberType,
schemaObj,
typeMaps,
serviceInfo);
((CorbaStructHandler)obj).addMember(memberObj);
}
}
public static void initializeUnionHandler(ORB orb,
CorbaObjectHandler obj,
QName name,
XmlSchemaObject schemaType,
List<CorbaTypeMap> typeMaps,
ServiceInfo serviceInfo) {
Union unionType = (Union)obj.getType();
// First handle the discriminator
CorbaObjectHandler discObj = initializeObjectHandler(orb,
new QName("discriminator"),
unionType.getDiscriminator(),
typeMaps,
serviceInfo);
((CorbaUnionHandler)obj).setDiscriminator(discObj);
boolean isAttr = false;
boolean isElementNil = false;
XmlSchemaObject stype = schemaType;
QName qname = name;
if (schemaType instanceof XmlSchemaAttribute) {
XmlSchemaAttribute attr = (XmlSchemaAttribute) schemaType;
if (attr.getQName() != null) {
qname = attr.getQName();
}
isAttr = true;
} else if (schemaType instanceof XmlSchemaElement) {
XmlSchemaElement el = (XmlSchemaElement) schemaType;
if (el.isNillable()) {
//should not write the start Element.
isElementNil = true;
}
if (el.getQName() != null) {
qname = el.getQName();
}
stype = el.getSchemaType();
if (stype == null) {
stype = CorbaUtils.getXmlSchemaType(serviceInfo, el.getRefName());
}
}
String nsURI = getNamespaceURI(serviceInfo, qname);
// Now handle all of the branches
List<Unionbranch> unionBranches = unionType.getUnionbranch();
for (Iterator<Unionbranch> iter = unionBranches.iterator(); iter.hasNext();) {
Unionbranch branch = iter.next();
QName branchName = new QName(nsURI, branch.getName());
QName branchIdlType = branch.getIdltype();
CorbaObjectHandler branchObj =
initializeObjectHandler(orb, branchName, branchIdlType, stype, typeMaps, serviceInfo);
((CorbaUnionHandler)obj).addCase(branchObj);
}
}
//Change this method to access the XmlSchemaCollection.
public static String getNamespaceURI(ServiceInfo serviceInfo, QName typeName) {
String nsUri = "";
if ((typeName != null)
&& (CorbaUtils.isElementFormQualified(serviceInfo, typeName.getNamespaceURI()))) {
nsUri = typeName.getNamespaceURI();
}
return nsUri;
}
public static XmlSchemaElement getXmlSchemaSequenceElement(XmlSchemaObject schemaType,
ServiceInfo serviceInfo) {
XmlSchemaObject stype = schemaType;
XmlSchemaElement el = null;
if (schemaType instanceof XmlSchemaElement) {
stype = ((XmlSchemaElement) schemaType).getSchemaType();
if (stype == null) {
stype = CorbaUtils.getXmlSchemaType(serviceInfo, el.getRefName());
}
}
if (stype instanceof XmlSchemaComplexType) {
//only one element inside the XmlSchemaComplexType
XmlSchemaComplexType ctype = (XmlSchemaComplexType) stype;
XmlSchemaGroupBase group = (XmlSchemaGroupBase) ctype.getParticle();
el = (XmlSchemaElement) group.getItems().getItem(0);
} else {
el = (XmlSchemaElement) schemaType;
}
return el;
}
}