/*
* XmlBeanWSDLProcessor.java
*
* Copyright 2001-2004 The Apache Software Foundation.
*
*
* Licensed 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.beehive.wsm.model.wsdl;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jws.WebParam;
import javax.jws.soap.SOAPBinding;
import javax.xml.namespace.QName;
import org.apache.beehive.wsm.databinding.BindingLookupService;
import org.apache.beehive.wsm.util.TypeMappingUtil;
import org.apache.beehive.wsm.util.XmlBeanTypeMappingUtil;
import org.apache.beehive.wsm.wsdl.WSDLProcessor;
import org.apache.beehive.wsm.model.BeehiveWsSOAPBindingInfo;
import org.apache.beehive.wsm.model.BeehiveWsMethodMetadata;
import org.apache.beehive.wsm.model.BeehiveWsParameterMetadata;
import org.apache.beehive.wsm.model.BeehiveWsTypeMetadata;
import org.apache.beehive.wsm.model.jsr181.Jsr181MethodMetadataImpl;
import org.apache.beehive.wsm.model.jsr181.Jsr181ParameterMetadataImpl;
import org.apache.beehive.wsm.model.jsr181.Jsr181TypeMetadataImpl;
import org.apache.beehive.wsm.model.jsr181.SOAPBindingInfo;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlBeans;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.xmlsoap.schemas.wsdl.DefinitionsDocument;
import org.xmlsoap.schemas.wsdl.TBinding;
import org.xmlsoap.schemas.wsdl.TBindingOperation;
import org.xmlsoap.schemas.wsdl.TBindingOperationMessage;
import org.xmlsoap.schemas.wsdl.TDefinitions;
import org.xmlsoap.schemas.wsdl.TMessage;
import org.xmlsoap.schemas.wsdl.TOperation;
import org.xmlsoap.schemas.wsdl.TParam;
import org.xmlsoap.schemas.wsdl.TPart;
import org.xmlsoap.schemas.wsdl.TPort;
import org.xmlsoap.schemas.wsdl.TPortType;
import org.xmlsoap.schemas.wsdl.TService;
import org.xmlsoap.schemas.wsdl.TTypes;
import org.xmlsoap.schemas.wsdl.soap.HeaderDocument;
import org.xmlsoap.schemas.wsdl.soap.TStyleChoice;
import org.xmlsoap.schemas.wsdl.soap.UseChoice;
import org.apache.xmlbeans.impl.xb.xsdschema.Element;
import org.apache.xmlbeans.impl.xb.xsdschema.Group;
import org.apache.xmlbeans.impl.xb.xsdschema.ComplexType;
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument.Schema;
/*******************************************************************************
* An Implementation of WSDLProcessor that uses XmlBeans to convert the WSDL
* into the WSM Object Model.
*
* @author Jonathan Colwell
*/
public class XmlBeanWSDLProcessor {
private BindingLookupService lookupService;
DefinitionsDocument defDoc;
public QName getServiceName() {
TService[] services = defDoc.getDefinitions().getServiceArray();
return new QName(services[0].getName());
}
public static final String TRANSPORT = "http://schemas.xmlsoap.org/soap/http";
public static final String SOAPENCODING = "http://schemas.xmlsoap.org/soap/encoding/";
public static final String WSDLNS = "http://schemas.xmlsoap.org/wsdl/soap/";
public static final String WSDLSOAPNS = "http://schemas.xmlsoap.org/wsdl/soap/";
public BeehiveWsTypeMetadata getObjectModel(BindingLookupService lookupService)
throws Exception {
this.lookupService = lookupService;
BeehiveWsTypeMetadata wsm = new Jsr181TypeMetadataImpl();
Map<String, BeehiveWsMethodMetadata> methodMap = new HashMap<String, BeehiveWsMethodMetadata>();
TDefinitions defs = defDoc.getDefinitions();
wsm.setWsTargetNamespace(defs.getTargetNamespace());
Map<String, TPart[]> messageMap = new HashMap<String, TPart[]>();
if (defs.sizeOfServiceArray() > 0) {
wsm.setWsServiceName(defs.getServiceArray(0).getName());
}
if (defs.sizeOfMessageArray() > 0) {
TMessage[] messages = defs.getMessageArray();
for (TMessage msg : messages) {
messageMap.put(msg.getName(), msg.getPartArray());
}
}
TBinding tBind = null;
if (defs.sizeOfBindingArray() > 0) {
tBind = defs.getBindingArray(0);
processTBinding(tBind, wsm);
}
if (defs.sizeOfPortTypeArray() > 0) {
TPortType tP = defs.getPortTypeArray(0);
wsm.setWsName(tP.getName());
TOperation[] operations = tP.getOperationArray();
TTypes types = null;
if (defs.sizeOfTypesArray() > 0) {
types = defs.getTypesArray(0);
}
for (TOperation op : operations) {
processTOperation(op, wsm, methodMap, messageMap, tBind, types);
}
}
if (tBind != null) {
processTBindingOperation(tBind, wsm, methodMap);
}
return wsm;
}
private void processTOperation(TOperation op, BeehiveWsTypeMetadata wsm,
Map<String, BeehiveWsMethodMetadata> methodMap,
Map<String, TPart[]> messageMap, TBinding tBind, TTypes types) throws Exception {
String opName = op.getName();
TParam outputParam = op.getOutput();
Map<String, BeehiveWsParameterMetadata> outParamMap = null;
BeehiveWsParameterMetadata[] paraMeta = new BeehiveWsParameterMetadata[0]; // defualt value
if( null != outputParam ) {
TPart[] messageParts = messageMap.get(outputParam.getMessage()
.getLocalPart());
paraMeta = processParameters(opName, messageParts, tBind, types,
messageMap, wsm, true); // output parameters are not wrapped
}
Class returnType;
QName returnXMLType;
if (paraMeta == null) {
// Should not happen, may be need to send runtime exception, or
// define a new type of exception!
throw new Exception("Can't resolve the return type");
} else if (paraMeta.length == 1) {
returnType = paraMeta[0].getJavaType();
returnXMLType = paraMeta[0].getXmlType();
} else {
// either there is no return value or there are multiple so make
// this a
// void function and later set OUT parameters if needed.
returnType = Void.TYPE;
returnXMLType = null;
if (paraMeta.length > 1) {
outParamMap = new HashMap<String, BeehiveWsParameterMetadata>(
paraMeta.length);
boolean returnIsSet = false;
for (BeehiveWsParameterMetadata cpm : paraMeta) {
outParamMap.put(cpm.getWpName(), cpm);
}
}
}
BeehiveWsMethodMetadata wmm = new Jsr181MethodMetadataImpl(opName, returnType,
returnXMLType);
wmm.setWmOperationName(opName);
// FIXME jcolwell@bea.com 2004-Nov-10 --
// do something better with the action
wmm.setWmAction(opName);
if (Void.TYPE.equals(returnType)) {
if (paraMeta.length == 0) {
// FIXME jcolwell@bea.com 2004-Nov-22 --
// also check for faults before setting as oneway.
wmm.setOneWay(true);
}
} else {
wmm.setWrName(paraMeta[0].getWpName());
wmm.setWrTargetNamespace(paraMeta[0].getWpTargetNamespace());
}
methodMap.put(opName, wmm);
List paramOrder = op.getParameterOrder(); // this is the one used by
// rpc wsdls.
TParam inputParam = op.getInput();
if (inputParam != null) {
TPart[] messageParts = messageMap.get(inputParam.getMessage()
.getLocalPart());
BeehiveWsParameterMetadata[] params = processParameters(opName, messageParts, tBind, types,
messageMap, wsm, false);
if (paramOrder != null) {
// Paramorder is only used for rpc.
// if there is a paramoder then order the parameters, remove all the in/out parameters
// from the out map
for (Object ord : paramOrder) {
for (BeehiveWsParameterMetadata wpm : params) {
if (ord.equals(wpm.getWpName())) {
if (outParamMap != null && outParamMap.containsKey(wpm.getWpName())) {
outParamMap.remove(wpm.getWpName()); // important...
// if this param is in.out it was in the out list
// also, so removeit.
wpm.setWpMode(WebParam.Mode.INOUT);
} else {
wpm.setWpMode(WebParam.Mode.IN);
}
wmm.addParam(wpm);
break;
}
}
}
} else if (params.length > 0) {
for (BeehiveWsParameterMetadata wpm : params) {
// FIXME jcolwell@bea.com 2005-Jan-04 --
// Double check DOC/Lit rules
if (outParamMap != null && outParamMap.containsKey(wpm.getWpName())) {
outParamMap.remove(wpm.getWpName()); // important...
// if
// this param is
// in.out it was
// in the out list
// also, so remove
// it.
wpm.setWpMode(WebParam.Mode.INOUT);
} else {
wpm.setWpMode(WebParam.Mode.IN);
}
wmm.addParam(wpm);
}
}
}
// do the pure out parameters.
if (outParamMap != null && outParamMap.size() > 0) {
if (outParamMap.size() == 1) {
BeehiveWsParameterMetadata wpm = outParamMap.values().iterator().next();
wmm.setXmlReturnType(wpm.getXmlType());
wmm.setReturnType(wpm.getJavaType());
wmm.setOneWay(false);
} else {
for (BeehiveWsParameterMetadata wpm : outParamMap.values()) {
wpm.setWpMode(WebParam.Mode.OUT);
wmm.addParam(wpm);
}
}
}
/*
* Collection<BeehiveWsParameterMetadata> params = wmm.getParams();
* System.out.println("adding method " + wmm.getWmOperationName() + "
* returning " + wmm.getJavaReturnType() + " with the following " +
* params.size() + " parameters");
*
* for (Jsr181ParameterMetadata wpm : params) {
* System.out.println(wpm.getWpName() + ':' + wpm.getJavaType()); }
*/
wsm.addMethod(wmm);
}
private BeehiveWsParameterMetadata[] processParameters(String operationName, TPart[] messageParts, TBinding tBind,
TTypes types, Map<String, TPart[]> messageMap, BeehiveWsTypeMetadata wsm, boolean isOutputParameters) {
// When you have parts of the message in the header, you would have multiple wsdl:part. In case of
// wrapped we would have JUST ONE part that has name="parameters"
// but the header parts would have their name which looks like a bare
// So in the processing if there is any part that has name=parameters then the service is called wrapped, and from then
// on the parameter style is not changed.
// Update.... "parameters" test is not enough, in some cases it may be called "body" For wrapped there can only be one body element, and the element attribute's local
// name should be the same as the name of the opeartion.
boolean paramStyleIsSet = false;
boolean shouldUnwrap;
if(isOutputParameters ) {
paramStyleIsSet = true; // only set this for input parameters
}
shouldUnwrap = isWrapped(operationName, messageParts, tBind, isOutputParameters);
List<BeehiveWsParameterMetadata> paramList = new ArrayList<BeehiveWsParameterMetadata>(
messageParts.length);
int j = 0;
for (TPart messagePart : messageParts) {
QName paramXmlType;
// if element attribute is set we are looking at document style
// in case of rpc message part would look something like:
// <part name="key type="xsd:string"/>
// otherwise it case of document it looks liek
// <part element="xxxx" name="parameters">
if (messagePart.isSetElement()) {
// we know we are document, and thus literal. and most
// likely using xml beans, but can use axis too.
QName element = messagePart.getElement();
Class javaType = findClassForQname(element);
// in case of xmlbeans(or other registered types) we don't
// need
// to dig any further
String name = messagePart.getName();
// if name is "parameters" then we need to unwrap the type
// and the service is doc/literal wrapped./
if (shouldUnwrap &&
unwrapMessagePart(operationName, isOutputParameters, messagePart) // when we do want to unwrap, we should only unwrap the parts the parameters
// the parts that are for headers, for instance, should remain intact.
) {
if( !isOutputParameters) {// only set the mode if this is input parameters
wsm.getSoapBinding().setParameterStyle(
SOAPBinding.ParameterStyle.WRAPPED);
paramStyleIsSet = true;
}
if (types != null) { // if there are some type
try {
Schema[] schemas = selectChildren(types, Schema.class);
// We are looking at schemas that are defined in
// this schema.
// ---- // THIS WOULD NOT RECOGNIZE IMPORTED
// SCHEMAS.
for (Schema s : schemas) {
if (!s.getTargetNamespace().equals(element.getNamespaceURI()))
continue;
Element[] elements = s.getElementArray();
for (Element e : elements) {
if (!e.getName().equals(element.getLocalPart()))
continue;
if (e.isSetType()) {
/*
* simple type, element has name and type in same node.
* complextype only has name and type is defined as
* <complexType> child
*/
paramList.add(elementToParamMetaData(s
.getTargetNamespace(), e));
} else {
// we have <element
// name=xxx> and its child
// must be comlexType, or
// somethig is wrong
ComplexType ct = e.getComplexType();
if (ct != null && ct.isSetSequence()) {
// DOC/LIT WSDL
/* NOTE: There may be other groupings that this code needs
* to understand also. At this point we expect:
* <element name="xxx" type="yyy">
* or <element ref="zzz">
*/
Group g = ct.getSequence();
for (Element el : g.getElementArray()) {
paramList.add(elementToParamMetaData(s
.getTargetNamespace(), el));
}
}
}
break;
}
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
// if we did find object form qname we know
// that there are xml-aware classes that can decode
// the xml we let them do the
// processing.
if(!paramStyleIsSet) // Only set the style to bare if it hasn't been done in previous parts processing
wsm.getSoapBinding().setParameterStyle(
SOAPBinding.ParameterStyle.BARE);
BeehiveWsParameterMetadata wpm = new Jsr181ParameterMetadataImpl();
wpm.setWpTargetNamespace(element.getNamespaceURI());
wpm.setWpName(name); // NAME SHOULD BE THE NAME OF THE MESSAGE PART. element.getLocalPart());
wpm.setXmlType(element);
wpm.setJavaType(javaType);
paramList.add(wpm);
}
} else { // this is an rpc and with no element attribute
BeehiveWsParameterMetadata wpm = new Jsr181ParameterMetadataImpl();
// FIXME jcolwell@bea.com 2004-Nov-09 -- figure out where
// RPC parameter namespaces should be specified in the WSDL.
wpm.setWpTargetNamespace(wsm.getWsTargetNamespace());
wpm.setWpName(messagePart.getName());
QName type = messagePart.getType();
wpm.setXmlType(type);
wpm.setJavaType(findClassForQname(type));
/*
* System.out.println(wpm.getWpName() + " of type " +
* wpm.getJavaType());
*/
paramList.add(wpm);
}
}
return paramList.toArray(new BeehiveWsParameterMetadata[paramList.size()]);
}
private Class findClassForQname(QName element) {
//return new XmlBeanTypeMappingUtil().q2Class(element);
return lookupService.qname2class(element);
}
// To detect the wrapped walk the message parts, if there is a part that has name="parameters"
// or if there is a part that its element name is the same as the operation name, return true.
// NOTE: for MIME multiparts, or when there are headers the tBind should be checked to determine
// if a part is on the header or is a MIME. The header and MIME parts should not effect the wrapped
// determination.
// TODO: the logic here may not work with MIME types, verify later.
private boolean isWrapped( String operationName, TPart[] messagePart, TBinding tBind,boolean isOutputParameters) {
for( TPart message : messagePart) {
if( !message.isSetElement()) return false; // RPC-Encoded
if( true == unwrapMessagePart(operationName, isOutputParameters, message)) return true;
}
return false;
}
private boolean unwrapMessagePart(String operationName, boolean isOutputParameters, TPart message) {
String name = message.getName();
if("parameters".equals(name)) return true;
if( isOutputParameters) {
if(message.getElement().getLocalPart().equals(operationName+"Response")) return true;
} else {
if(message.getElement().getLocalPart().equals(operationName)) return true;
}
return false;
}
/**
* @param paramList
* @param s
* @param el
*/
private BeehiveWsParameterMetadata elementToParamMetaData(
String targetNamespace, Element el) {
BeehiveWsParameterMetadata wpm = new Jsr181ParameterMetadataImpl();
// FIXME
// jcolwell@bea.com
// 2004-Nov-09
// double check the
// namespace stuff
wpm.setWpTargetNamespace(targetNamespace);
boolean isArray = false;
if (el.isSetMaxOccurs()) {
if (0 != "1".compareTo(el.getMaxOccurs().toString()))
isArray = true;
} else if (el.isSetMinOccurs()) {
String minOccur = el.getMinOccurs().toString();
// If minoccur is other than 0, or 1 then it is array also
if ("0" != minOccur && "1" != minOccur)
isArray = true;
}
String name = null;
QName xmlType = null;
if (el.isSetName() && el.isSetType()) {
name = el.getName();
xmlType = el.getType();
} else if (el.isSetRef()) {
QName ref = el.getRef();
name = ref.getLocalPart();
xmlType = ref;
} else
throw new RuntimeException("invalid element: " + el);
Class javaType = findClassForQname(xmlType);
if (isArray) {
// create an array of the type, then get its type.
Object realType = Array.newInstance(javaType, 1);
javaType = realType.getClass();
}
wpm.setWpName(name);
wpm.setXmlType(xmlType);
wpm.setJavaType(javaType);
return wpm;
}
/**
* @param types
*/
private void doUnknownTypes(TTypes types) {
// sections.
}
private void processTBinding(TBinding tBind, BeehiveWsTypeMetadata wsm)
throws IllegalAccessException, NoSuchFieldException {
org.xmlsoap.schemas.wsdl.soap.TBinding[] soapBinding = getSOAPBinding(tBind);
BeehiveWsSOAPBindingInfo soapInfo = new SOAPBindingInfo();
if (soapBinding != null && soapBinding.length > 0) {
if (TStyleChoice.RPC.equals(soapBinding[0].getStyle())) {
soapInfo.setStyle(SOAPBinding.Style.RPC);
}
wsm.setSoapBinding(soapInfo);
}
}
private void processTBindingOperation(TBinding tBind,
BeehiveWsTypeMetadata wsm,
Map<String, BeehiveWsMethodMetadata> methodMap)
throws IllegalAccessException, NoSuchFieldException {
TBindingOperation[] tBops = tBind.getOperationArray();
for (TBindingOperation tBop : tBops) {
BeehiveWsMethodMetadata wmm = methodMap.get(tBop.getName());
if (wmm == null)
throw new RuntimeException("Invalid method name: "
+ tBop.getName());
org.xmlsoap.schemas.wsdl.soap.TOperation[] soapOperations = getSOAPOperations(tBop);
if (soapOperations != null && soapOperations.length > 0) {
wmm.setWmAction(soapOperations[0].getSoapAction());
}
TBindingOperationMessage tbMsg = tBop.getInput();
if (tbMsg == null) {
tbMsg = tBop.getOutput();
}
if (tbMsg != null) {
org.xmlsoap.schemas.wsdl.soap.TBody[] bodies = getSOAPBody(tbMsg);
if (bodies.length > 0) {
if (wsm.getWsTargetNamespace() == null) {
wsm.setWsTargetNamespace(bodies[0].getNamespace());
}
BeehiveWsSOAPBindingInfo soapInfo = wsm.getSoapBinding();
if (UseChoice.ENCODED.equals(bodies[0].getUse())) {
soapInfo.setUse(SOAPBinding.Use.ENCODED);
}
}
setSoapHeaders(wmm, tbMsg);
}
// tBop.getOutput and get the headers out of it.
setSoapHeaders(wmm, tBop.getOutput());
}
}
/**
* @param tbMsg
* @throws IllegalAccessException
* @throws NoSuchFieldException
*/
private void setSoapHeaders(BeehiveWsMethodMetadata wmm,
TBindingOperationMessage tbMsg) throws IllegalAccessException,
NoSuchFieldException {
if(null == tbMsg) return;
// get the header
org.xmlsoap.schemas.wsdl.soap.THeader[] soapHeaders = getSOAPHeader(tbMsg);
if (soapHeaders != null && soapHeaders.length > 0) { // there are method arguments that are
// in the header
for (org.xmlsoap.schemas.wsdl.soap.THeader nxtHeader : soapHeaders) {
String part = nxtHeader.getPart();
if (part == null)
throw new RuntimeException(
"Missing part attribute in soap:header method: "
+ tbMsg.getName());
BeehiveWsParameterMetadata argument = wmm.findParam(part);
if(argument == null) throw new RuntimeException ("Couldn't find part name: " + part + " in method " + wmm.getJavaMethodName());
argument.setWpHeader(true);
}
}
}
// public BeehiveWsTypeMetadata loadWebServiceMetadataFromWSDL(String wsdlLocation)
// throws Exception {
// return toWebServiceMetadata(parseWSDL(wsdlLocation));
// }
public static DefinitionsDocument parseWSDL(String wsdlLocation)
throws IOException, MalformedURLException, XmlException {
if (wsdlLocation.indexOf("://") > 2) {
return parseWSDL(new URL(wsdlLocation));
} else {
return parseWSDL(new File(wsdlLocation));
}
}
public static DefinitionsDocument parseWSDL(File wsdlFile)
throws IOException, XmlException {
return DefinitionsDocument.Factory.parse(wsdlFile);
}
public static DefinitionsDocument parseWSDL(URL wsdlURL) throws IOException,
MalformedURLException, XmlException {
return DefinitionsDocument.Factory.parse(wsdlURL);
}
public static DefinitionsDocument parseWSDL(InputStream wsdlStream)
throws IOException, MalformedURLException, XmlException {
return DefinitionsDocument.Factory.parse(wsdlStream);
}
public static org.xmlsoap.schemas.wsdl.soap.TOperation[] getSOAPOperations(
TBindingOperation bo) throws IllegalAccessException, NoSuchFieldException {
return selectChildren(bo, org.xmlsoap.schemas.wsdl.soap.TOperation.class);
}
public static org.xmlsoap.schemas.wsdl.soap.TBinding[] getSOAPBinding(
TBinding b) throws IllegalAccessException, NoSuchFieldException {
XmlObject[] kids = b.selectChildren(new QName(
"http://schemas.xmlsoap.org/wsdl/soap/", "binding"));
org.xmlsoap.schemas.wsdl.soap.TBinding[] res = new org.xmlsoap.schemas.wsdl.soap.TBinding[kids.length];
for (int i = 0; i < kids.length; i++)
res[i] = (org.xmlsoap.schemas.wsdl.soap.TBinding) kids[i];
return res;
}
public static org.xmlsoap.schemas.wsdl.soap.TBody[] getSOAPBody(
TBindingOperationMessage bom) throws IllegalAccessException,
NoSuchFieldException {
XmlObject[] kids = bom.selectChildren(new QName(
"http://schemas.xmlsoap.org/wsdl/soap/", "body"));
org.xmlsoap.schemas.wsdl.soap.TBody[] res = new org.xmlsoap.schemas.wsdl.soap.TBody[kids.length];
for (int i = 0; i < kids.length; i++)
res[i] = (org.xmlsoap.schemas.wsdl.soap.TBody) kids[i];
return res;
}
public static org.xmlsoap.schemas.wsdl.soap.THeader[] getSOAPHeader(
TBindingOperationMessage bom) throws IllegalAccessException,
NoSuchFieldException {
XmlObject[] kids = bom.selectChildren(new QName(
"http://schemas.xmlsoap.org/wsdl/soap/", "header"));
org.xmlsoap.schemas.wsdl.soap.THeader[] res = new org.xmlsoap.schemas.wsdl.soap.THeader[kids.length];
for (int i = 0; i < kids.length; i++)
res[i] = (org.xmlsoap.schemas.wsdl.soap.THeader) kids[i];
return res;
}
public static org.xmlsoap.schemas.wsdl.soap.TAddress[] getSOAPAddress(
TPort port) throws IllegalAccessException, NoSuchFieldException {
return selectChildren(port, org.xmlsoap.schemas.wsdl.soap.TAddress.class);
}
private static <T extends XmlObject> T[] selectChildren(XmlObject parent,
Class<T> childClass) throws IllegalAccessException, NoSuchFieldException {
// retrieve the SchemaType from the static type field
if(parent == null) return null;
SchemaType st = (SchemaType) childClass.getField("type").get(null);
SchemaType originalType = null;
QName element;
if (st.isAnonymousType()) {
originalType = st;
st = st.getOuterType();
}
if (st.isDocumentType()) {
element = st.getDocumentElementName();
if (originalType != null) {
st = originalType;
}
} else {
element = st.getName();
}
/*
* System.out.println("Selecting children " + element +" of class " +
* st.getJavaClass());
*/
XmlObject[] kids = parent.selectChildren(element);
T[] castKids = (T[]) Array.newInstance(childClass, kids.length);
for (int j = 0; j < castKids.length; j++) {
if (!st.getJavaClass().isAssignableFrom(kids[j].getClass())) {
// System.out.println("before typechange " +
// kids[j].getClass());
kids[j] = kids[j].changeType(st);
// System.out.println("after typechange " + kids[j].getClass());
} else {
// System.out.println("no typechange needed");
}
castKids[j] = childClass.cast(kids[j]);
}
return castKids;
}
public XmlBeanWSDLProcessor( InputStream wsdlStream) throws MalformedURLException, IOException, XmlException {
super();
this.defDoc = parseWSDL(wsdlStream);
}
private XmlBeanWSDLProcessor() {
// no default constrcutor!
}
}