Modified: incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/model/wsdl/XmlBeanWSDLProcessor.java URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/model/wsdl/XmlBeanWSDLProcessor.java?view=diff&r1=158823&r2=158824 ============================================================================== --- incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/model/wsdl/XmlBeanWSDLProcessor.java (original) +++ incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/jsr181/model/wsdl/XmlBeanWSDLProcessor.java Wed Mar 23 11:57:57 2005 @@ -66,6 +66,7 @@ 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; @@ -158,31 +159,6 @@ return wsm; } - /* - * public static DefinitionsDocument fromWebServiceMetadata - * (WebServiceTYPEMetadata wsm) throws Exception { String ns = - * wsm.getWsTargetNamespace(); DefinitionsDocument defDoc = - * DefinitionsDocument.Factory.newInstance(); TDefinitions tDefs = - * defDoc.addNewDefinitions(); TPortType tPT = tDefs.addNewPortType(); - * tPT.setName(wsm.getWsName()); TBinding tBind = tDefs.addNewBinding(); - * tBind.setName(tPT.getName() + "Binding"); tBind.setType(new QName(ns, - * tPT.getName())); org.xmlsoap.schemas.wsdl.soap.BindingDocument bindDoc = - * org.xmlsoap.schemas.wsdl.soap.BindingDocument.Factory.newInstance(); - * org.xmlsoap.schemas.wsdl.soap.TBinding tSoapBind = bindDoc - * .addNewBinding(); if - * (SOAPBinding.Style.DOCUMENT.equals(wsm.getSoapBinding().getStyle())) { - * tSoapBind.setStyle(TStyleChoice.DOCUMENT); } else { - * tSoapBind.setStyle(TStyleChoice.RPC); } tSoapBind.setTransport(TRANSPORT); - * insertChild(tBind, bindDoc); processMethodMetadata(wsm.getMethods(), tDefs, - * tPT, tBind, ns); TService tServ = tDefs.addNewService(); - * tServ.setName(wsm.getWsServiceName()); TPort tPort = tServ.addNewPort(); - * tPort.setName(wsm.getWsName()); tPort.setBinding(new QName(ns, - * tBind.getName())); org.xmlsoap.schemas.wsdl.soap.AddressDocument addrDoc = - * org.xmlsoap.schemas.wsdl.soap.AddressDocument.Factory.newInstance(); - * org.xmlsoap.schemas.wsdl.soap.TAddress tAddr = addrDoc.addNewAddress(); - * tAddr.setLocation("fake://FAKEURL"); insertChild(tPort, tAddr); return - * defDoc; } - */ private void processTOperation(TOperation op, BeehiveWsTypeMetadata wsm, Map<String, BeehiveWsMethodMetadata> methodMap, @@ -248,29 +224,21 @@ BeehiveWsParameterMetadata[] params = processParameters(inputParam, types, messageMap, wsm); - if (paramOrder != null) { // walk the parameters according to - // order - // if they exist. - // note that the Jsr181MethodMetadata - // needs correct order of the parameters - // (simnilar reflection of method). - - // TODO: Paramorder is only used for rpc. This code should be - // modified so that in/out parameters are all handled in one - // place. - // if there is a paramoder then order the parameters, then all - // the parameters and look at in/out flag. + 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())) { - - wpm.setWpMode(WebParam.Mode.IN); // THIUS MAY BE - // BUG... WE NEED - // TO MAKE SURE TO - // HANDLE THE OUT - // PARAMTERS ALSO - // (like the code - // for below) + 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; } @@ -312,8 +280,9 @@ } } - List<BeehiveWsParameterMetadata> params = wmm.getParams(); + /* + * Collection<BeehiveWsParameterMetadata> params = wmm.getParams(); * System.out.println("adding method " + wmm.getWmOperationName() + " * returning " + wmm.getJavaReturnType() + " with the following " + * params.size() + " parameters"); @@ -328,6 +297,13 @@ private BeehiveWsParameterMetadata[] processParameters(TParam parameter, TTypes types, Map<String, TPart[]> messageMap, BeehiveWsTypeMetadata wsm) { + // When there you have parts of the message in the header, you would have multiple wsdl:part. In case of + // wrapped we would have 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. + boolean paramStyleIsSet = false; + if (parameter != null) { TPart[] messageParts = messageMap.get(parameter.getMessage() .getLocalPart()); @@ -354,7 +330,10 @@ // if name is "parameters" then we need to unwrap the type // and the service is doc/literal wrapped./ if (0 == "parameters".compareTo(name) ) { - if (types != null) { // if there are some type + 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 @@ -412,14 +391,14 @@ // that there are xml-aware classes that can decode // the xml we let them do the // processing. - - wsm.getSoapBinding().setParameterStyle( - SOAPBinding.ParameterStyle.BARE); + 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(element.getLocalPart()); + wpm.setWpName(name); // NAME SHOULD BE THE NAME OF THE MESSAGE PART. element.getLocalPart()); wpm.setXmlType(element); wpm.setJavaType(javaType); paramList.add(wpm); @@ -518,111 +497,76 @@ } } - 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) { - 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()); + 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()); } - BeehiveWsSOAPBindingInfo soapInfo = wsm.getSoapBinding(); - if (UseChoice.ENCODED.equals(bodies[0].getUse())) { - soapInfo.setUse(SOAPBinding.Use.ENCODED); + 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()); + } - } } - } - /* - * private static void processMethodMetadata (Collection - * <WebServiceMETHODMetadata> methods, TDefinitions defs, TPortType portType, - * TBinding bind, String namespace) { for (WebServiceMETHODMetadata op : - * methods) { String operationName = op.getWmOperationName(); String request = - * operationName + "Request"; String response = operationName + "Response"; - * TMessage tMsg = defs.addNewMessage(); tMsg.setName(request); List <String> - * paramOrder = new ArrayList <String>(); - * processParameterMetadata(op.getParams(), paramOrder, tMsg); if - * (!op.isOneWay()) { tMsg = defs.addNewMessage(); tMsg.setName(response); - * TPart tPart = tMsg.addNewPart(); tPart.setName(op.getWrName()); - * tPart.setType(class2QName(op.getJavaReturnType())); //tPart.setElement(new - * QName("some", "element"); } TOperation tOp = portType.addNewOperation(); - * tOp.setName(operationName); tOp.setParameterOrder(paramOrder); TParam input = - * tOp.addNewInput(); TParam output = tOp.addNewOutput(); - * input.setName(request); input.setMessage(new QName(namespace, request)); if - * (!op.isOneWay()) { output.setName(response); output.setMessage(new - * QName(namespace, response)); } - * processBindingOperationMetadata(bind.addNewOperation(), op, namespace, - * operationName, request, response); } } - * - * private static void processParameterMetadata (Collection - * <WebServicePARAMETERMetadata> params, List <String> paramOrder, TMessage - * msg) { for (WebServicePARAMETERMetadata param : params) { TPart tPart = - * msg.addNewPart(); tPart.setName(param.getWpName()); - * tPart.setType(class2QName(param.getJavaType())); - * paramOrder.add(param.getWpName()); } } - * - * private static void processBindingOperationMetadata(TBindingOperation tBop, - * WebServiceMETHODMetadata op, String namespace, String operationName, String - * request, String response) { tBop.setName(operationName); - * org.xmlsoap.schemas.wsdl.soap.OperationDocument opDoc = - * org.xmlsoap.schemas.wsdl.soap.OperationDocument.Factory .newInstance(); - * org.xmlsoap.schemas.wsdl.soap.TOperation tSoapOperation = - * opDoc.addNewOperation(); tSoapOperation.setSoapAction(op.getWmAction()); // - * SOAPBindingInfo sb = op.getSoapBinding(); // if (sb != null && - * SOAPBinding.Style.DOCUMENT.equals(sb.getStyle())) { // - * tSoapOperation.setStyle(TStyleChoice.DOCUMENT); // } // else { // - * tSoapOperation.setStyle(TStyleChoice.RPC); // } insertChild(tBop, opDoc); - * TBindingOperationMessage inBom = tBop.addNewInput(); - * TBindingOperationMessage outBom = tBop.addNewOutput(); - * inBom.setName(request); outBom.setName(response); - */ - /* - * NOTE [EMAIL PROTECTED] 2004-Aug-31 -- Using the same body for both the input - * and output, this may need to be changed. - */ - /* - * org.xmlsoap.schemas.wsdl.soap.BodyDocument bodDoc = - * org.xmlsoap.schemas.wsdl.soap.BodyDocument.Factory.newInstance(); - * org.xmlsoap.schemas.wsdl.soap.TBody tBod = bodDoc.addNewBody(); // if (sb != - * null && SOAPBinding.Use.LITERAL.equals(sb.getUse())) { // - * tBod.setUse(UseChoice.LITERAL); // } // else { // - * tBod.setUse(UseChoice.ENCODED); // } - */ - /* - * NOTE [EMAIL PROTECTED] 2004-Aug-31 -- not sure what parts get set here. - */ - // tBod.setParts(?); - /* - * tBod.setNamespace(namespace); List <String> encodingStyles = new ArrayList - * <String>(); encodingStyles.add(SOAPENCODING); - * tBod.setEncodingStyle(encodingStyles); insertChild(inBom, bodDoc); - * insertChild(outBom, bodDoc); } - * - * - * public static boolean insertChild(XmlObject parent, XmlObject child) { // - * might need to use copyXmlContents() instead if copyXml copies too much - * XmlCursor kidCursor = child.newCursor(); XmlCursor parentCursor = - * parent.newCursor(); parentCursor.toFirstContentToken(); - * //parentCursor.toNextToken(); kidCursor.toNextToken(); return - * kidCursor.copyXml(parentCursor); } - */ + /** + * @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 { @@ -673,8 +617,29 @@ public static org.xmlsoap.schemas.wsdl.soap.TBody[] getSOAPBody( TBindingOperationMessage bom) throws IllegalAccessException, NoSuchFieldException { - return selectChildren(bom, org.xmlsoap.schemas.wsdl.soap.TBody.class); - } + 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 { @@ -684,6 +649,7 @@ 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;
Modified: incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/registration/TypeRegistrar.java URL: http://svn.apache.org/viewcvs/incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/registration/TypeRegistrar.java?view=diff&r1=158823&r2=158824 ============================================================================== --- incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/registration/TypeRegistrar.java (original) +++ incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/registration/TypeRegistrar.java Wed Mar 23 11:57:57 2005 @@ -19,244 +19,242 @@ */ package org.apache.beehive.wsm.registration; - import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.rmi.Remote; +import java.util.HashMap; +import java.util.Map; + import org.apache.log4j.*; import javax.xml.namespace.QName; import javax.xml.rpc.encoding.TypeMapping; import javax.xml.rpc.holders.Holder; + import org.apache.beehive.wsm.databinding.BindingLookupService; import org.apache.beehive.wsm.databinding.GenericHolder; - public abstract class TypeRegistrar { - static Logger logger = Logger.getLogger(TypeRegistrar.class); - protected TypeMapping mTypeMapping; - protected BindingLookupService lookupService; - -/** - * @param typeMapping - * @param lookupService - */ - public TypeRegistrar(TypeMapping typeMapping, - BindingLookupService lookupService) { - super(); - mTypeMapping = typeMapping; - this.lookupService = lookupService; - } - - /** - * @param cls - * @return - */ - protected abstract QName getRegisteredQName(Class cls); - - /** - * @param cls - * @param q - */ - abstract protected void registerClassAsWithDefaultSearialization(Class cls, QName q); - - /** - * @param cls - * @param q - */ - abstract protected void registerClassAsXMLBeans(Class cls, QName q); - - /** - * @param cls - * @param q - * @throws ClassNotFoundException - * @throws NoSuchMethodException - * @throws InstantiationException - * @throws IllegalAccessException - * @throws InvocationTargetException - */ - abstract protected void registerClassAsDataHandler(Class cls, QName q) - throws ClassNotFoundException, NoSuchMethodException, - InstantiationException, IllegalAccessException, - InvocationTargetException; - - /** - * @param cls - * @param q - */ - abstract protected void registerClassAsArray(Class cls, QName q); - - /** - * @param cls - * @param q - * @return - */ - abstract protected boolean classIsRegistered(Class cls, QName q); - - - /** - * @return - */ - abstract public QName getVoidType(); - - public QName registerType(Class cls) { - return registerType(cls, lookupService.class2qname(cls)); - } - - public QName registerType(Class cls, QName q) { - logger.debug("Register class: " + cls.getCanonicalName() + " qName: " - + q); - - QName currentQName = getRegisteredQName(cls); - logger.debug("Got a q from typemapping: " + currentQName); - - if (currentQName != null ) { // && currentQName.equals(q)) { - logger.debug("Type is already registered."); - return q; // Already registered. - } - -// // IF generic holders are used, just register the type of the -// // underlying object. -// if (GenericHolder.class.isAssignableFrom(cls)) { -// Type[] typeArgs = cls.getGenericInterfaces(); -// return registerType((Class) typeArgs[0]); -// } -// // for other holders get the underlying class -// if(Holder.class.isAssignableFrom(cls)) { -// registerType(getUnderlyingType(cls)); -// } - // if (q == null || (expectedType != null && - // !expectedType.equals(q))) { - // - // if (expectedType == null) { - // q = generateQName(cls, "http://no.namespace.specified"); - // } else { - // q = expectedType; - // } - - if (cls.isArray()) { - if (!classIsRegistered(cls, q)) { - registerClassAsArray(cls, q); - } - q = registerType(cls.getComponentType()); - // TODO: fix the expected type thing for arrays. - // if (expectedType != null) { - // q = expectedType; - // } - } else if (q == null || !classIsRegistered(cls, q)) { // WHY - // IS - // THIS - // NEEDED? - if (org.apache.xmlbeans.XmlObject.class.isAssignableFrom(cls)) { - registerClassAsXMLBeans(cls, q); - } - /* - * NOTE [EMAIL PROTECTED] 2004-Oct-11 -- these datahandler using - * classes are generally already registered but just in case... - */ - else if (isActivationEnabled() - && (java.awt.Image.class.isAssignableFrom(cls) - || getMultipartClass().isAssignableFrom(cls) || getDataHandlerClass() - .isAssignableFrom(cls))) { - try { - registerClassAsDataHandler(cls, q); - } catch (Exception e) { - /* - * FIXME [EMAIL PROTECTED] 2004-Oct-08 -- log this properly - */ - e.printStackTrace(); - } - } else if (!Remote.class.isAssignableFrom(cls) - /* - * NOTE [EMAIL PROTECTED] 2004-Oct-11 -- java.rmi.Remote is - * prohibited by the jax-rpc spec. - */ - - /* - * NOTE [EMAIL PROTECTED] 2004-Oct-11 -- restricting against File - * since, it doesn't make sense to serialize as a bean. That and it - * causes an infinite loop as it keeps returning itself from the - * getAbsoluteFile and getCanonicalFile calls - */ - && !File.class.isAssignableFrom(cls)) { - registerClassAsWithDefaultSearialization(cls, q); - } else { - throw new RuntimeException("failed to register " - + cls.getName() + " as a valid web service datatype," - + " consider using a custom type mapping"); - } - } - // } - // } - return q; - } // public Class q2Class(QName qType) { // - - - - - private boolean isActivationEnabled() { - return null != getDataHandlerClass() && null != getMultipartClass(); - } - - private Class getDataHandlerClass() { - try { - return getClass().getClassLoader().loadClass( - "javax.activation.DataHandler"); - } catch (Exception e) { - } - return null; - } - - private Class getMultipartClass() { - try { - return getClass().getClassLoader().loadClass( - "javax.mail.internet.MimeMultipart"); - } catch (Exception e) { - } - return null; - } - - - - /** - * @param t - * @throws Exception - */ - static public Class getUnderlyingType(Type t) { - Class nxtType = null; - if (t instanceof Class) { - // for holder class we need to get the value field type - if( Holder.class.isAssignableFrom((Class)t)) { - Field[] publicFields = ((Class) t).getFields(); - for (int i = 0; i < publicFields.length; i++) { - if( 0 == "value".compareTo(publicFields[i].getName())) { - nxtType= publicFields[i].getType(); - System.out.println("******************************class : " + t.getClass().getCanonicalName() + " is converted to: " + nxtType.getCanonicalName()); - break; - } - } - } else { // if it is not a holder just use the type as is - nxtType = (Class) t; - } - } else if (t instanceof java.lang.reflect.ParameterizedType) { - java.lang.reflect.ParameterizedType pt = ((java.lang.reflect.ParameterizedType) t); - Type[] typeArgs = pt.getActualTypeArguments(); - Type raw = pt.getRawType(); - if (GenericHolder.class.isAssignableFrom((Class) raw) - && typeArgs.length == 1) { - nxtType = (Class) typeArgs[0]; - } else { - throw new RuntimeException(raw + " ~ " + typeArgs[0]); - } - } else { - throw new RuntimeException("Only Classes and ParameterizedTypes" - + " are currently handled, support for " + t.getClass() - + " should be added."); - } - return nxtType; - } + static Logger logger = Logger.getLogger(TypeRegistrar.class); + + protected TypeMapping mTypeMapping; + + protected BindingLookupService lookupService; + + + /** + * @param typeMapping + * @param lookupService + */ + public TypeRegistrar(TypeMapping typeMapping, + BindingLookupService lookupService) { + super(); + mTypeMapping = typeMapping; + this.lookupService = lookupService; + } + + + /** + * @param cls + * @return + */ + protected abstract QName getRegisteredQName(Class cls); + + /** + * @param cls + * @param q + */ + abstract protected void registerClassAsWithDefaultSearialization(Class cls, + QName q); + + /** + * @param cls + * @param q + */ + abstract protected void registerClassAsXMLBeans(Class cls, QName q); + + /** + * @param cls + * @param q + * @throws ClassNotFoundException + * @throws NoSuchMethodException + * @throws InstantiationException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + abstract protected void registerClassAsDataHandler(Class cls, QName q) + throws ClassNotFoundException, NoSuchMethodException, + InstantiationException, IllegalAccessException, + InvocationTargetException; + + /** + * @param cls + * @param q + */ + abstract protected void registerClassAsArray(Class cls, QName q); + + /** + * @param cls + * @param q + * @return + */ + abstract protected boolean classIsRegistered(Class cls, QName q); + + /** + * @return + */ + abstract public QName getVoidType(); + + abstract protected boolean isBuiltInType(Class cls); + abstract protected QName getBuiltInTypeQname(Class cls); + + + public QName registerType(Class cls) { + return registerType(cls, lookupService.class2qname(cls)); + } + + public QName registerType(Class cls, QName q) { + try { + logger.debug("Register class: " + cls.getCanonicalName() + + " qName: " + q); + if (q == null) + throw new RuntimeException( + "Invalid registeration requestion qname is null"); + if (isBuiltInType(cls)) + return getBuiltInTypeQname(cls); + if (cls.isArray()) { + if (!classIsRegistered(cls, q)) { + registerClassAsArray(cls, q); + } + q = registerType(cls.getComponentType()); + // TODO: fix the expected type thing for arrays. + // if (expectedType != null) { + // q = expectedType; + // } + } else if (!classIsRegistered(cls, q)) { // WHY + // IS + // THIS + // NEEDED? + if (org.apache.xmlbeans.XmlObject.class.isAssignableFrom(cls)) { + registerClassAsXMLBeans(cls, q); + } + /* + * NOTE [EMAIL PROTECTED] 2004-Oct-11 -- these datahandler using + * classes are generally already registered but just in case... + */ + else if (isActivationEnabled() + && (java.awt.Image.class.isAssignableFrom(cls) + || getMultipartClass().isAssignableFrom(cls) || getDataHandlerClass() + .isAssignableFrom(cls))) { + try { + registerClassAsDataHandler(cls, q); + } catch (Exception e) { + /* + * FIXME [EMAIL PROTECTED] 2004-Oct-08 -- log this + * properly + */ + e.printStackTrace(); + } + } else if (!Remote.class.isAssignableFrom(cls) + /* + * NOTE [EMAIL PROTECTED] 2004-Oct-11 -- java.rmi.Remote is + * prohibited by the jax-rpc spec. + */ + + /* + * NOTE [EMAIL PROTECTED] 2004-Oct-11 -- restricting against File + * since, it doesn't make sense to serialize as a bean. That and + * it causes an infinite loop as it keeps returning itself from + * the getAbsoluteFile and getCanonicalFile calls + */ + && !File.class.isAssignableFrom(cls)) { + registerClassAsWithDefaultSearialization(cls, q); + } else { + throw new RuntimeException("failed to register " + + cls.getName() + + " as a valid web service datatype," + + " consider using a custom type mapping"); + } + } + // } + // } + logger.info("Registered class: " + cls.getCanonicalName() + + " qName: " + q); + return q; + } catch (RuntimeException e) { + logger.error("Failed to register class: " + cls.getCanonicalName() + + " type: " + q.getNamespaceURI() + ":" + q.getLocalPart()); + + e.printStackTrace(); + throw e; + } + } // public Class q2Class(QName qType) { // + + + private boolean isActivationEnabled() { + return null != getDataHandlerClass() && null != getMultipartClass(); + } + + private Class getDataHandlerClass() { + try { + return getClass().getClassLoader().loadClass( + "javax.activation.DataHandler"); + } catch (Exception e) { + } + return null; + } + + private Class getMultipartClass() { + try { + return getClass().getClassLoader().loadClass( + "javax.mail.internet.MimeMultipart"); + } catch (Exception e) { + } + return null; + } + + /** + * @param t + * @throws Exception + */ + static public Class getUnderlyingType(Type t) { + Class nxtType = null; + if (t instanceof Class) { + // for holder class we need to get the value field type + if (Holder.class.isAssignableFrom((Class) t)) { + Field[] publicFields = ((Class) t).getFields(); + for (int i = 0; i < publicFields.length; i++) { + if (0 == "value".compareTo(publicFields[i].getName())) { + nxtType = publicFields[i].getType(); + System.out + .println("******************************class : " + + t.getClass().getCanonicalName() + + " is converted to: " + + nxtType.getCanonicalName()); + break; + } + } + } else { // if it is not a holder just use the type as is + nxtType = (Class) t; + } + } else if (t instanceof java.lang.reflect.ParameterizedType) { + java.lang.reflect.ParameterizedType pt = ((java.lang.reflect.ParameterizedType) t); + Type[] typeArgs = pt.getActualTypeArguments(); + Type raw = pt.getRawType(); + if (GenericHolder.class.isAssignableFrom((Class) raw) + && typeArgs.length == 1) { + nxtType = (Class) typeArgs[0]; + } else { + throw new RuntimeException(raw + " ~ " + typeArgs[0]); + } + } else { + throw new RuntimeException("Only Classes and ParameterizedTypes" + + " are currently handled, support for " + t.getClass() + + " should be added."); + } + return nxtType; + } } -
