You are viewing a plain text version of this content. The canonical link for it is here.
Posted to muse-commits@ws.apache.org by da...@apache.org on 2006/06/26 06:15:15 UTC

svn commit: r417124 - in /webservices/muse/trunk/modules/muse-tools: ./ src/ src/org/ src/org/apache/ src/org/apache/muse/ src/org/apache/muse/tools/ src/org/apache/muse/tools/inspector/

Author: danj
Date: Sun Jun 25 21:15:13 2006
New Revision: 417124

URL: http://svn.apache.org/viewvc?rev=417124&view=rev
Log:
This is the resource inspector component that is part of the client 
generation code contributed in JIRA (that includes a resource 
inspector and a proxy generator - this is just the inspector). The 
role of this component is to analyze a WSDL and allow clients to 
invoke new operations at runtime, as well as to reason about a resource's 
properties and metadata.

In the future, code generation tools will go in this module as well. 
The client generation, in particular, can use this component to do all 
of the hard work before printing out Java code.


Added:
    webservices/muse/trunk/modules/muse-tools/
    webservices/muse/trunk/modules/muse-tools/pom.xml
    webservices/muse/trunk/modules/muse-tools/src/
    webservices/muse/trunk/modules/muse-tools/src/org/
    webservices/muse/trunk/modules/muse-tools/src/org/apache/
    webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/
    webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/
    webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/
    webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/JavaMethod.java
    webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/Messages.properties
    webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/ResourceInspector.java

Added: webservices/muse/trunk/modules/muse-tools/pom.xml
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-tools/pom.xml?rev=417124&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-tools/pom.xml (added)
+++ webservices/muse/trunk/modules/muse-tools/pom.xml Sun Jun 25 21:15:13 2006
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" 
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>muse</groupId>
+  <artifactId>muse-tools</artifactId>
+  <packaging>jar</packaging>
+  <version>2.0.0-M1-SNAPSHOT</version>
+  <name>Apache Muse - CLI Tools</name>
+  <url>http://ws.apache.org/muse</url>
+  <dependencies>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-util</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-util-qname</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-util-xml</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-wsa-soap</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-core</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-wsrf-api</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-wsrf-impl</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-wsn-api</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>muse</groupId>
+      <artifactId>muse-wsn-impl</artifactId>
+      <version>2.0.0-M1-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>wsdl4j</groupId>
+      <artifactId>wsdl4j</artifactId>
+      <version>1.5.1</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <sourceDirectory>src</sourceDirectory>
+    <outputDirectory>build/classes</outputDirectory>
+    <directory>build/jars</directory>
+    <resources>
+      <resource>
+        <directory>src</directory>
+        <includes>
+        	<include>**/*.properties</include>
+        </includes>
+      </resource>
+    </resources>
+    
+    <!-- 
+    
+        This feature can be used when Maven 2.1 is released 
+         
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <addMavenDescriptor>false</addMavenDescriptor>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+    
+    -->
+    
+  </build>
+</project>

Added: webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/JavaMethod.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/JavaMethod.java?rev=417124&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/JavaMethod.java (added)
+++ webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/JavaMethod.java Sun Jun 25 21:15:13 2006
@@ -0,0 +1,91 @@
+package org.apache.muse.tools.inspector;
+
+import javax.xml.namespace.QName;
+
+/**
+ * 
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+class JavaMethod
+{
+    private QName _name = null;
+    
+    private QName[] _parameterTypeNames = null;   
+    private QName[] _parameterSchemaTypes = null;
+    private Class[] _parameterTypes = null;
+    
+    private QName _returnName = null;
+    private QName _returnSchemaType = null;
+    private Class _returnType = null;
+    
+    public QName getName()
+    {
+        return _name;
+    }
+    
+    public void setName(QName name)
+    {
+        _name = name;
+    }
+    
+    public QName[] getParameterSchemaTypes()
+    {
+        return _parameterSchemaTypes;
+    }
+    
+    public void setParameterSchemaTypes(QName[] parameterSchemaTypes)
+    {
+        _parameterSchemaTypes = parameterSchemaTypes;
+    }
+    
+    public QName[] getParameterTypeNames()
+    {
+        return _parameterTypeNames;
+    }
+    
+    public void setParameterTypeNames(QName[] parameterTypeNames)
+    {
+        _parameterTypeNames = parameterTypeNames;
+    }
+    
+    public Class[] getParameterTypes()
+    {
+        return _parameterTypes;
+    }
+    public void setParameterTypes(Class[] parameterTypes)
+    {
+        _parameterTypes = parameterTypes;
+    }
+    
+    public QName getReturnName()
+    {
+        return _returnName;
+    }
+    
+    public void setReturnName(QName returnName)
+    {
+        _returnName = returnName;
+    }
+    
+    public QName getReturnSchemaType()
+    {
+        return _returnSchemaType;
+    }
+    
+    public void setReturnSchemaType(QName returnSchemaType)
+    {
+        _returnSchemaType = returnSchemaType;
+    }
+    
+    public Class getReturnType()
+    {
+        return _returnType;
+    }
+    
+    public void setReturnType(Class returnType)
+    {
+        _returnType = returnType;
+    }
+}

Added: webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/Messages.properties
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/Messages.properties?rev=417124&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/Messages.properties (added)
+++ webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/Messages.properties Sun Jun 25 21:15:13 2006
@@ -0,0 +1,13 @@
+CreateFile = Creating source file XXX.
+StartCodeGen = Starting code generation for XXX.
+FinishCodeGen = Finished code generation for XXX.
+MethodGen = Generating method 'XXX'.
+NumberOfOps = The WSDL portType 'XXX' has XXX operations defined.
+PortTypeNotFound = The portType 'XXX' was not found in the WSDL provided.
+NotDocLiteral = The WSDL operation 'XXX' is not doc-literal because it defines a message with more than one message part for its SOAP Body. The SOAP Body of a doc-literal message should contain one root request element (with the operation name) with zero or more child elements (the parameters).
+Extending = Class XXX is extending Muse client class XXX.
+NoTypeDef = No type definition found for 'XXX'.
+PropertiesGen = Generating XXX resource properties found in WSDL's WS-RP definition.
+OperationUndefined = There is no operation for the Java method 'XXX' - you can only invoke operations that are defined in the resource's WSDL (remote interface).
+OneServicePerWSDL = The resource inspector can only process WSDLs with one service element.
+OnePortPerWSDL = The resource inspector can only process WSDLs with one port element. The WSDL can have multiple portTypes, but only one concrete service and port.

Added: webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/ResourceInspector.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/ResourceInspector.java?rev=417124&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/ResourceInspector.java (added)
+++ webservices/muse/trunk/modules/muse-tools/src/org/apache/muse/tools/inspector/ResourceInspector.java Sun Jun 25 21:15:13 2006
@@ -0,0 +1,798 @@
+// ========================================================================
+//
+// Licensed Materials - Property of IBM
+//
+// PRODUCT_NO
+//
+// (c) Copyright IBM Corp. 2005.    All Rights Reserved.
+//
+// US Government Users Restricted Rights - Use, duplication or
+// disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
+//
+// =========================================================================
+
+package org.apache.muse.tools.inspector;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Operation;
+import javax.wsdl.Output;
+import javax.wsdl.Part;
+import javax.wsdl.Port;
+import javax.wsdl.PortType;
+import javax.wsdl.Service;
+import javax.wsdl.factory.WSDLFactory;
+import javax.wsdl.xml.WSDLReader;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.proxy.ProxyHandler;
+import org.apache.muse.core.proxy.ReflectionProxyHandler;
+import org.apache.muse.util.ReflectUtils;
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.util.xml.XsdUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.WsaConstants;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.notification.WsnConstants;
+import org.apache.muse.ws.notification.remote.NotificationConsumerClient;
+import org.apache.muse.ws.notification.remote.NotificationProducerClient;
+import org.apache.muse.ws.resource.lifetime.WsrlConstants;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.OpenMetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.impl.SimpleMetadataDescriptor;
+import org.apache.muse.ws.resource.properties.WsrpConstants;
+import org.apache.muse.ws.resource.properties.impl.WsrpUtils;
+import org.apache.muse.ws.resource.properties.schema.ResourcePropertiesSchema;
+import org.apache.muse.ws.resource.properties.schema.impl.SimpleResourcePropertiesSchema;
+import org.apache.muse.ws.resource.remote.WsResourceClient;
+import org.apache.muse.ws.wsdl.WsdlUtils;
+
+/**
+ *
+ * This tool allows a client to dynamically discover the properties and operations 
+ * of a resource by parsing its WSDL. The inspector provides all of the data 
+ * structures necessary to invoke operations with the proper SOAP messages and 
+ * to reason about properties and their metadata. Its chief use is as the data 
+ * model to the client generator that converts WSDL to a Java interface/class.
+ * 
+ * @author Dan Jemiolo (danj)
+ * @author Andrew Eberbach
+ *
+ */
+
+public class ResourceInspector
+{
+    private static final Set _BASIC_RESOURCE_METHODS = new HashSet();
+    
+    //
+    // Used to lookup all exception messages
+    //
+    private static Messages _MESSAGES = MessagesFactory.get(ResourceInspector.class);
+    
+    static
+    {
+        _BASIC_RESOURCE_METHODS.add(WsrpConstants.GET_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsrpConstants.GET_MULTIPLE_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsrpConstants.QUERY_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsrpConstants.SET_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsrlConstants.DESTROY_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsrlConstants.SET_TERMINATION_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsnConstants.NOTIFY_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsnConstants.SUBSCRIBE_QNAME);
+        _BASIC_RESOURCE_METHODS.add(WsnConstants.GET_CURRENT_QNAME);
+    }
+    
+    //
+    // The proxy type that will handle the core WS-* operations
+    //
+    private Class _baseProxyClass = null;
+        
+    //
+    // Map[operation _name, ProxyHandler] for invoking services
+    //
+    private Map _handlersByName = null;
+    
+    //
+    // A WSDL might have multiple port types, but it should only have one 
+    // concrete service, which maps to one port type
+    //
+    private QName _portType = null;
+    
+    //
+    // The (optional) RMD that supplements the WS-RP definition in the WSDL. 
+    // The default is the "empty" RMD, which allows all operations.
+    //
+    private MetadataDescriptor _rmd = OpenMetadataDescriptor.getInstance();
+    
+    //
+    // The service's WS-RP doc
+    //
+    private ResourcePropertiesSchema _wsrpSchema = null;
+    
+    private Object createBaseProxy(WsResourceClient resource)
+        throws Exception
+    {
+        EndpointReference src = resource.getSource();
+        EndpointReference dest = resource.getDestination();
+        
+        Class[] paramTypes = new Class[]{
+                EndpointReference.class, EndpointReference.class 
+        };
+        Constructor ctor = getBaseProxyClass().getConstructor(paramTypes);
+        return ctor.newInstance(new Object[]{ dest, src });
+    }
+    
+    private JavaMethod createJavaMethod(Element wsdl, Operation op)
+    {
+        JavaMethod method = new JavaMethod();
+        
+        method.setName(getInputName(op));
+        method.setReturnName(getOutputName(op));
+        
+        Element inputElement = WsdlUtils.getTypeDeclaration(wsdl, method.getName());
+        
+        if (inputElement == null)
+        {
+            Object[] filler = { method.getName() };
+            throw new RuntimeException(_MESSAGES.get("NoTypeDef", filler));
+        }
+        
+        Element outputElement = null;
+        
+        if (method.getReturnName() != null)
+            outputElement = WsdlUtils.getTypeDeclaration(wsdl, method.getReturnName());
+                
+        method.setReturnSchemaType(getSchemaType(outputElement));
+        method.setReturnType(getJavaType(method.getReturnSchemaType()));
+        
+        Element[] paramXML = XmlUtils.findInSubTree(inputElement, XsdUtils.ELEMENT_QNAME);
+        Element schema = (Element)inputElement.getParentNode();
+        String targetNS = schema.getAttribute(XmlUtils.TARGET_NS);
+        
+        Class[] parameterTypes = new Class[paramXML.length];
+        QName[] parameterSchemaTypes = new QName[paramXML.length];
+        QName[] parameterTypeNames = new QName[paramXML.length];
+        
+        for (int n = 0; n < paramXML.length; ++n)
+        {
+            String localName = paramXML[n].getAttribute(XsdUtils.NAME);
+            parameterTypeNames[n] = new QName(targetNS, localName, "pfx");
+            parameterSchemaTypes[n] = getSchemaType(paramXML[n]);
+            parameterTypes[n] = getJavaType(method.getParameterSchemaTypes()[n]);
+        }
+        
+        method.setParameterTypes(parameterTypes);
+        method.setParameterSchemaTypes(parameterSchemaTypes);
+        method.setParameterTypeNames(parameterTypeNames);
+        
+        return method;
+    }
+
+    private QName getSchemaType(Element element)
+    {
+        if (element == null)
+            return null;
+        
+        String typeName = element.getAttribute(XsdUtils.TYPE);
+        
+        if (typeName == null || typeName.length() == 0)
+            return XsdUtils.ANY_TYPE_QNAME;
+        
+        return XmlUtils.parseQName(typeName, element);
+    }
+    
+    private ProxyHandler createReflectionHandler(JavaMethod method)
+    {
+        ProxyHandler handler = new ReflectionProxyHandler();
+        String action = method.getName().getNamespaceURI();
+        
+        if (!action.endsWith("/"))
+            action += '/';
+        
+        action += method.getName().getLocalPart();
+        handler.setAction(URI.create(action));
+        
+        handler.setRequestName(method.getName());
+        handler.setRequestParameterNames(method.getParameterTypeNames());
+        handler.setRequestParameterSchemaTypes(method.getParameterSchemaTypes());
+        handler.setRequestParameterTypes(method.getParameterTypes());
+        handler.setResponseName(method.getReturnName());
+        handler.setReturnSchemaType(method.getReturnSchemaType());
+        handler.setReturnType(method.getReturnType());
+        
+        return handler;
+    }
+    
+    public URI getAction(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return handler.getAction();
+        
+        return null;        
+    }
+    
+    public Class getBaseProxyClass()
+    {
+        return _baseProxyClass;
+    }
+    
+    private Method getBaseProxyMethod(String operation)
+    {
+        Method[] methods = getBaseProxyClass().getMethods();
+        
+        if (!isBasicResourceOperation(operation))
+        {
+            Object[] filler = { operation };
+            throw new RuntimeException(_MESSAGES.get("OperationUndefined", filler));
+        }
+            
+        for (int n = 0; n < methods.length; ++n)
+            if (methods[n].getName().equals(operation))
+                return methods[n];
+        
+        Object[] filler = { operation };
+        throw new RuntimeException(_MESSAGES.get("OperationUndefined", filler));
+    }
+    
+    private ProxyHandler getHandler(String operation)
+    {
+        return (ProxyHandler)_handlersByName.get(operation);
+    }
+    
+    private Map getHandlers(Map operations)
+    {
+        _baseProxyClass = getProxyExtends(operations);
+        Iterator i = operations.keySet().iterator();
+        Map handlers = new HashMap();
+        
+        while (i.hasNext())
+        {
+            JavaMethod method = (JavaMethod)operations.get(i.next());
+            
+            if (isBasicResourceOperation(method.getName()))
+                continue;
+            
+            ProxyHandler handler = createReflectionHandler(method);
+            
+            String javaName = getMethodName(method.getName().getLocalPart());
+            handlers.put(javaName, handler);
+        }
+        
+        return handlers;
+    }
+    
+    public static String getMethodName(String operationName)
+    {
+        if (operationName == null)
+            throw new NullPointerException(_MESSAGES.get("NullOperationName"));
+        
+        System.out.println("OperationName " + operationName);
+        
+        char first = operationName.charAt(0);
+        return Character.toLowerCase(first) + operationName.substring(1);
+    }
+    
+    private QName getInputName(Operation op)
+    {
+        Map parts = op.getInput().getMessage().getParts();
+        
+        if (parts.size() != 1)
+        {
+            Object[] filler = { op.getName() };
+            throw new RuntimeException(_MESSAGES.get("NotDocLiteral", filler));
+        }
+        
+        Part docLiteralPart = (Part)parts.values().iterator().next();
+        return docLiteralPart.getElementName();
+    }
+    
+    private Class getJavaType(QName schemaType)
+    {
+        if (schemaType == null)
+            return Void.TYPE;
+        
+        Class type = getXsdJavaType(schemaType);
+        return type == null ? Element.class : type;
+    }
+    
+    public Collection getOperations()
+    {
+        Collection ops = new HashSet(_handlersByName.keySet());
+        
+        Method[] baseOps = getBaseProxyClass().getMethods();
+        
+        for (int n = 0; n < baseOps.length; ++n)
+            if (isBasicResourceOperation(baseOps[n].getName()))
+                ops.add(baseOps[n].getName());
+        
+        return ops;
+    }
+     
+    private Map getOperations(Definition wsdlDef, Element wsdlXML, QName portTypeName)
+    {
+        PortType portType = wsdlDef.getPortType(portTypeName);
+        
+        List operations = portType.getOperations();
+        
+        Map javaMethodsByName = new LinkedHashMap();
+        Iterator i = operations.iterator();
+        
+        while (i.hasNext())
+        {
+            Operation next = (Operation)i.next();            
+            JavaMethod method = createJavaMethod(wsdlXML, next);            
+            javaMethodsByName.put(method.getName(), method);
+        }
+        
+        return getHandlers(javaMethodsByName);
+    }
+
+	private QName getOutputName(Operation op)
+    {
+        Output output = op.getOutput();
+        
+        if (output == null)
+            return null;
+        
+        Map parts = output.getMessage().getParts();
+        
+        if (parts.size() != 1)
+        {
+            Object[] filler = { op.getName() };
+            throw new RuntimeException(_MESSAGES.get("NotDocLiteral", filler));
+        }
+        
+        Part docLiteralPart = (Part)parts.values().iterator().next();
+        return docLiteralPart.getElementName();
+    }
+    
+    public String[] getParameterNames(String operation)
+    {
+    	
+    	System.out.println("Examining operation = " + operation);
+        QName[] qnames = getParameterQNames(operation);
+        String[] names = new String[qnames.length];
+        
+        for (int n = 0; n < qnames.length; ++n) {
+            names[n] = getMethodName(qnames[n].getLocalPart());
+        }
+        
+        return names;
+    }
+    
+    public QName[] getParameterQNames(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        System.out.println("handler from ["+operation+"] is null? " + (handler == null));
+        
+        if (handler != null)
+            return handler.getRequestParameterNames();
+        
+        return new QName[0];
+    }
+    
+    public QName[] getParameterSchemaTypes(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return handler.getRequestParameterSchemaTypes();
+        
+        Method method = getBaseProxyMethod(operation);
+        Class[] types = method.getParameterTypes();
+        QName[] qnames = new QName[types.length];
+        
+        for (int n = 0; n < types.length; ++n)
+            qnames[n] = getSchemaType(types[n]);
+        
+        return qnames;
+    }
+    
+    public Class[] getParameterTypes(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return handler.getRequestParameterTypes();
+        
+        Method method = getBaseProxyMethod(operation);
+        return method.getParameterTypes();
+    }
+    
+    public QName getPortType()
+    {
+        return _portType;
+    }
+    
+    private QName getPortType(Definition wsdl)
+    {
+        Map services = wsdl.getServices();
+        
+        if (services.size() != 1)
+            throw new RuntimeException(_MESSAGES.get("OneServicePerWSDL"));
+        
+        Service service = (Service)services.values().iterator().next();
+        Map ports = service.getPorts();
+        
+        if (ports.size() != 1)
+            throw new RuntimeException(_MESSAGES.get("OnePortPerWSDL"));
+        
+        Port port = (Port)ports.values().iterator().next();
+        PortType portType = port.getBinding().getPortType();        
+        return portType.getQName();
+    }
+    
+    public Collection getProperties()
+    {
+        return _wsrpSchema.getPropertyNames();
+    }
+        
+    public Class getPropertyType(QName property)
+    {
+        QName type = _wsrpSchema.getPropertyTypeName(property);
+        Class javaType = getXsdJavaType(type);
+        
+        if (isPropertyMultiple(property))
+            javaType = ReflectUtils.getArrayClassFromClass(javaType);
+        
+        return javaType;            
+    }
+    
+    private Class getProxyExtends(Map operations)
+    {
+        if (operations.keySet().contains(WsnConstants.SUBSCRIBE_QNAME))
+            return NotificationProducerClient.class;
+        
+        else if (operations.keySet().contains(WsnConstants.NOTIFY_QNAME))
+            return NotificationConsumerClient.class;
+        
+        return WsResourceClient.class;
+    }
+    
+    public QName getRequestName(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return handler.getRequestName();
+        
+        return null;        
+    }
+    
+    public QName getReturnName(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return handler.getResponseName();
+        
+        return null;
+    }
+    
+    public Class getReturnType(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return handler.getReturnType();
+        
+        Method method = getBaseProxyMethod(operation);
+        return method.getReturnType();        
+    }
+    
+    public QName getReturnSchemaType(String operation)
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return handler.getReturnSchemaType();
+        
+        Method method = getBaseProxyMethod(operation);
+        Class type = method.getReturnType();
+        return getSchemaType(type);
+    }
+    
+    private ResourcePropertiesSchema getWsrpSchema(Element wsdl, QName portType)
+    {
+        Element wsrp = WsrpUtils.getPropertiesDefinition(wsdl, portType);
+        return new SimpleResourcePropertiesSchema(wsrp);
+    }
+    
+    /**
+     * 
+     * This method will invoke form the proper SOAP request for the given 
+     * operation and parameters and send it to the resource represented by 
+     * the given client. The response is the content of the SOAP response's 
+     * Body, deserialized into POJO form.
+     *
+     */
+    public Object invoke(WsResourceClient resource, String operation, Object[] parameters)
+        throws SoapFault
+    {
+        ProxyHandler handler = getHandler(operation);
+        
+        if (handler != null)
+            return resource.invoke(handler, parameters);
+        
+        Object proxy = null;
+        
+        try
+        {
+            proxy = createBaseProxy(resource);
+        }
+        
+        catch (Exception error)
+        {
+            throw new RuntimeException(error.getMessage(), error);
+        }
+        
+        Method method = getBaseProxyMethod(operation);
+        
+        try
+        {
+            return method.invoke(proxy, parameters);
+        }
+        
+        catch (Exception error)
+        {
+            throw new SoapFault(error);
+        }
+    }
+    
+    public boolean isBasicResourceOperation(QName name)
+    {
+        return _BASIC_RESOURCE_METHODS.contains(name);
+    }
+    
+    public boolean isBasicResourceOperation(String name)
+    {
+        Iterator i = _BASIC_RESOURCE_METHODS.iterator();
+        
+        while (i.hasNext())
+        {
+            QName qname = (QName)i.next();
+            
+            if (name.equalsIgnoreCase(qname.getLocalPart()))
+                return true;
+        }
+            
+        return false;
+    }
+    
+    public boolean isPropertyAppendable(QName property)
+    {
+        return !_rmd.isReadOnlyExternal(property) && _rmd.canInsert(property);
+    }
+    
+    public boolean isPropertyMultiple(QName property)
+    {
+        return _wsrpSchema.getMaxOccurs(property) > 1;
+    }
+    
+    public boolean isPropertyMutable(QName property)
+    {
+        return !_rmd.isReadOnlyExternal(property) && _rmd.canUpdate(property);
+    }
+    
+    public void run(Element wsdl)
+    {
+        run(wsdl, null);
+    }
+    
+    public void run(Element wsdl, Environment env)
+    {
+        Definition def = null;
+        String path = null;
+        
+        if (env != null)
+            path = env.getRealDirectory().getAbsolutePath();
+        
+        try
+        {
+            WSDLFactory factory = WSDLFactory.newInstance();
+            WSDLReader reader = factory.newWSDLReader();
+            def = reader.readWSDL(path, wsdl);
+        }
+        
+        catch (Exception error)
+        {
+            throw new RuntimeException(error);
+        }
+        
+        _portType = getPortType(def);
+        _wsrpSchema = getWsrpSchema(wsdl, _portType);
+        _handlersByName = getOperations(def, wsdl, _portType);
+    }
+    
+    public void setMetadata(Element rmdXML)
+    {
+        rmdXML = XmlUtils.getFirstElement(rmdXML);
+        _rmd = new SimpleMetadataDescriptor(rmdXML);
+    }
+    
+    
+    //
+    // A Map between XSD built-in types and JDK types
+    //
+    private static Map _JAVA_TYPES = new HashMap();
+    
+    /**
+     * 
+     * @param type
+     *        A Class representing the Java type that maps to the XSD type.
+     * 
+     * @return The QName of the XSD type representing the given Java type, 
+     *         or ANY_TYPE_QNAME if no such mapping exists.
+     *
+     */
+    public static QName getSchemaType(Class type)
+    {
+        Iterator i = _JAVA_TYPES.entrySet().iterator();
+        
+        while (i.hasNext())
+        {
+            Map.Entry next = (Map.Entry)i.next();
+            Class nextType = (Class)next.getValue();
+            
+            if (type.equals(nextType))
+                return (QName)next.getKey();
+        }
+        
+        return null;
+    }
+    
+    /**
+     * 
+     * @param typeName
+     *        The _name of an XSD built-in type (or WS-A EndpointReference).
+     * 
+     * @return A Class representing the Java type that maps to the XSD 
+     *         type, or null if no mapping exists.
+     *
+     */
+    public static Class getXsdJavaType(QName typeName)
+    {
+        return (Class)_JAVA_TYPES.get(typeName);
+    }
+    
+    //
+    // below are the names for some XSD built-in types
+    //
+    
+    
+    //
+    // The XMLSchema namespace URI
+    //
+    public static final String NAMESPACE_URI = 
+        "http://www.w3.org/2001/XMLSchema";
+    
+    public static final String PREFIX = "xsd";
+    
+    public static final QName ANY_TYPE_QNAME = 
+        new QName(NAMESPACE_URI, "anyType", PREFIX);
+    
+    public static final QName ANY_URI_QNAME = 
+        new QName(NAMESPACE_URI, "anyURI", PREFIX);
+
+    public static final QName BOOLEAN_QNAME = 
+        new QName(NAMESPACE_URI, "boolean", PREFIX);
+
+    public static final QName DATE_QNAME = 
+        new QName(NAMESPACE_URI, "date", PREFIX);
+
+    public static final QName DATE_TIME_QNAME = 
+        new QName(NAMESPACE_URI, "dateTime", PREFIX);
+
+    public static final QName DOUBLE_QNAME = 
+        new QName(NAMESPACE_URI, "double", PREFIX);
+
+    public static final QName DURATION_QNAME = 
+        new QName(NAMESPACE_URI, "duration", PREFIX);
+
+    public static final QName FLOAT_QNAME = 
+        new QName(NAMESPACE_URI, "float", PREFIX);
+
+    public static final QName INT_QNAME = 
+        new QName(NAMESPACE_URI, "int", PREFIX);
+
+    public static final QName INTEGER_QNAME = 
+        new QName(NAMESPACE_URI, "integer", PREFIX);
+
+    public static final QName LONG_QNAME = 
+        new QName(NAMESPACE_URI, "long", PREFIX);
+
+    public static final QName QNAME_QNAME = 
+        new QName(NAMESPACE_URI, "QName", PREFIX);
+
+    public static final QName SHORT_QNAME = 
+        new QName(NAMESPACE_URI, "short", PREFIX);
+
+    public static final QName STRING_QNAME = 
+        new QName(NAMESPACE_URI, "string", PREFIX);
+    
+    //
+    // below are the common names for XSD tags
+    //
+
+    
+    
+    public static final QName ATTRIBUTE_QNAME = 
+        new QName(NAMESPACE_URI, "attribute", PREFIX);
+
+    public static final QName ATTRIBUTE_GROUP_QNAME = 
+        new QName(NAMESPACE_URI, "attributeGroup", PREFIX);
+    
+    public static final QName COMPLEX_TYPE_QNAME = 
+        new QName(NAMESPACE_URI, "complexType", PREFIX);
+    
+    public static final QName ELEMENT_QNAME = 
+        new QName(NAMESPACE_URI, "element", PREFIX);
+    
+    public static final QName IMPORT_QNAME = 
+        new QName(NAMESPACE_URI, "import", PREFIX);
+    
+    public static final QName INCLUDE_QNAME = 
+        new QName(NAMESPACE_URI, "include", PREFIX);
+    
+    public static final QName NC_NAME_QNAME = 
+        new QName(NAMESPACE_URI, "NCName", PREFIX);
+    
+    public static final QName SCHEMA_QNAME = 
+        new QName(NAMESPACE_URI, "schema", PREFIX);
+    
+    public static final QName SEQUENCE_QNAME = 
+        new QName(NAMESPACE_URI, "sequence", PREFIX);
+    
+    public static final QName SIMPLE_TYPE_QNAME = 
+        new QName(NAMESPACE_URI, "simpleType", PREFIX);
+    
+    static
+    {
+        //
+        // create the XSD -> JDK mapping for all supported types
+        //
+        
+        _JAVA_TYPES.put(ANY_TYPE_QNAME, Element.class);
+        _JAVA_TYPES.put(ANY_URI_QNAME, URI.class);
+        _JAVA_TYPES.put(STRING_QNAME, String.class);
+        _JAVA_TYPES.put(NC_NAME_QNAME, String.class);
+        _JAVA_TYPES.put(QNAME_QNAME, QName.class);
+        _JAVA_TYPES.put(BOOLEAN_QNAME, boolean.class);
+        _JAVA_TYPES.put(INT_QNAME, int.class);
+        _JAVA_TYPES.put(INTEGER_QNAME, int.class);
+        _JAVA_TYPES.put(SHORT_QNAME, short.class);
+        _JAVA_TYPES.put(LONG_QNAME, long.class);
+        _JAVA_TYPES.put(FLOAT_QNAME, float.class);
+        _JAVA_TYPES.put(DOUBLE_QNAME, double.class);
+        _JAVA_TYPES.put(DATE_QNAME, Date.class);
+        _JAVA_TYPES.put(DATE_TIME_QNAME, Date.class);
+        _JAVA_TYPES.put(DURATION_QNAME, String.class);
+        
+        //
+        // this isn't a XSD type, but it's common to all WS-* services
+        //
+        _JAVA_TYPES.put(WsaConstants.EPR_QNAME, EndpointReference.class);
+        _JAVA_TYPES.put(WsaConstants.EPR_TYPE_QNAME, EndpointReference.class);
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: muse-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-commits-help@ws.apache.org