You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by re...@apache.org on 2015/03/19 14:43:37 UTC

[09/35] incubator-taverna-common-activities git commit: package names changed to org.apache.taverna.*

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java
new file mode 100644
index 0000000..f9af843
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/SOAPResponsePrimitiveParser.java
@@ -0,0 +1,149 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPElement;
+import org.apache.taverna.wsdl.parser.ArrayTypeDescriptor;
+import org.apache.taverna.wsdl.parser.BaseTypeDescriptor;
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+import org.apache.taverna.wsdl.parser.WSDL11Parser;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+
+/**
+ * SOAPResponseParser responsible for parsing soap responses that map to outputs
+ * that can be directly represented with Primitive types (i.e. int, String,
+ * String[]).
+ * 
+ * @author sowen
+ * 
+ */
+@SuppressWarnings("unchecked")
+public class SOAPResponsePrimitiveParser implements SOAPResponseParser {
+
+    private Unmarshaller u;
+    private Map<String, TypeDescriptor> descriptors;
+
+    private static final Logger logger = Logger.getLogger(WSDL11Parser.class.getName());
+    
+    public SOAPResponsePrimitiveParser(List<TypeDescriptor> outputDescriptors) {
+        
+        descriptors = new TreeMap<String, TypeDescriptor>();
+        
+        for (TypeDescriptor desc : outputDescriptors) {
+            descriptors.put(desc.getName(), desc);
+        }
+        
+        try {
+            u  = JAXBContext.newInstance().createUnmarshaller();
+        }
+        catch(JAXBException ex) {}
+    }
+
+    /**
+     * Parses each SOAPBodyElement for the primitive type, and places it in the
+     * output Map
+     */
+    @Override
+    public Map parse(List<SOAPElement> response) throws Exception {
+        Map result = new HashMap();
+
+        SOAPElement responseElement = response.get(0); 
+        
+        for (Iterator<SOAPElement> paramIterator = responseElement.getChildElements(); paramIterator.hasNext();) {
+            SOAPElement param = paramIterator.next();
+            
+            TypeDescriptor typeDesc = descriptors.get(param.getLocalName());
+            if (typeDesc != null) {
+                if (typeDesc instanceof ArrayTypeDescriptor) {
+                    ArrayTypeDescriptor arrayDesc = (ArrayTypeDescriptor)typeDesc;
+                    typeDesc = arrayDesc.getElementType(); // do we need to know a type here?
+                    List elements = new ArrayList();
+                    for (Iterator<Element> iter = param.getChildElements(); iter.hasNext();) {
+                        Element element = iter.next();
+                        Object value = getNodeObject(element, typeDesc.getQname());
+                        elements.add(value);
+                    }
+                    
+                    result.put(param.getElementName().getLocalName(), ObjectConverter.convertObject(elements));
+                }
+                else if (typeDesc instanceof BaseTypeDescriptor) {
+                    Object value = getNodeObject(param, typeDesc.getQname());
+                    result.put(param.getElementName().getLocalName(), ObjectConverter.convertObject(value));
+                }
+            }
+        }
+
+        return result;
+    }
+    
+    private Object getNodeObject(Element element, QName type) throws JAXBException {
+        Attr attr = (Attr)element.getAttributes().getNamedItemNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+        if (attr != null) {
+            String xsiType = attr.getValue();
+            int idx = xsiType.indexOf(':');
+            if (idx > 0) {
+                String prefix = xsiType.substring(0, idx);
+                String namespace = element.lookupNamespaceURI(prefix);
+                if (namespace != null) {
+                    String localName = xsiType.substring(idx + 1);
+                    QName typeName = new QName(namespace, localName);
+                    if (typeName.equals(type)) {
+                        return u.unmarshal(element, Object.class).getValue();
+                    }
+                    logger.log(Level.WARNING, "different types in parameter {0}defined: {1}, expected: {2}", new Object[]{element.getLocalName(), typeName, type});
+                } else {
+                    logger.log(Level.WARNING, "no xsi:type namespace found: {0}", xsiType);
+                }
+            } else {
+                logger.log(Level.WARNING, "missing parameter xsi:type namespace {0} xsi:type='{1}'", new Object[]{element.getLocalName(), xsiType});
+            }
+        }
+
+        // this is a safeguard code where there is no xsi:type specified, so using provided type
+        attr = element.getOwnerDocument().createAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+        
+        String prefix = element.lookupPrefix(type.getNamespaceURI());
+        if (prefix == null) {
+            // it is supposed that elements are of primitive types...
+            element.setAttribute(XMLConstants.XML_NS_PREFIX + ":xsd", type.getNamespaceURI());
+            prefix = "xsd";
+        }
+        attr.setValue(prefix + ":" + type.getLocalPart());
+        
+        element.getAttributes().setNamedItemNS(attr);
+
+        return u.unmarshal(element, Object.class).getValue();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSDLSOAPInvoker.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSDLSOAPInvoker.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSDLSOAPInvoker.java
new file mode 100644
index 0000000..319cc70
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSDLSOAPInvoker.java
@@ -0,0 +1,288 @@
+/*
+* 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.taverna.wsdl.soap;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.activation.DataHandler;
+import javax.wsdl.WSDLException;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.soap.AttachmentPart;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+import org.apache.taverna.wsdl.parser.UnknownOperationException;
+import org.apache.taverna.wsdl.parser.WSDLParser;
+import org.apache.log4j.Logger;
+import org.xml.sax.SAXException;
+
+/**
+ * Invoke SOAP based webservices
+ * 
+ * @author Stuart Owen
+ * 
+ */
+@SuppressWarnings("unchecked")
+public class WSDLSOAPInvoker {
+
+	private static final String ATTACHMENT_LIST = "attachmentList";
+	
+	private static Logger logger = Logger.getLogger(WSDLSOAPInvoker.class);
+
+	private BodyBuilderFactory bodyBuilderFactory = BodyBuilderFactory.instance();
+	private WSDLParser parser;
+	private String operationName;
+	private List<String> outputNames;
+        
+        private JaxWSInvoker invoker;
+        
+	public WSDLSOAPInvoker(WSDLParser parser, String operationName,
+			List<String> outputNames) {
+            this.parser = parser;
+            this.operationName = operationName;
+            this.outputNames = outputNames;
+    
+            invoker = new JaxWSInvoker(parser, null, operationName);
+            invoker.setTimeout(getTimeout());
+	}
+	
+        public void setCredentials(String username, String password) {
+            invoker.setCredentials(username, password);
+        }
+        
+        public void setWSSSecurity(WSSTokenProfile token) {
+            invoker.setWSSSecurity(token);
+        }
+        
+	protected String getOperationName() {
+            return operationName;
+	}
+	
+	protected WSDLParser getParser() {
+            return parser;
+	}
+
+	protected List<String> getOutputNames() {
+            return outputNames;
+	}
+	
+
+	/**
+	 * Invokes the webservice with the supplied input Map, and returns a Map
+	 * containing the outputs, mapped against their output names.
+	 * 
+	 * @param inputMap
+	 * @return
+	 * @throws Exception
+	 */
+	public Map<String, Object> invoke(Map inputMap) throws Exception {
+
+            SOAPMessage message = makeRequestEnvelope(inputMap);
+                
+            return invoke(message);
+	}
+
+	public SOAPMessage call(SOAPMessage message) throws Exception
+        {
+            return invoker.call(message);
+            
+//            String endpoint = parser.getOperationEndpointLocations(operationName).get(0);
+//            URL endpointURL = new URL(endpoint);
+//
+//            String soapAction = parser.getSOAPActionURI(operationName);
+//            if (soapAction != null) {
+//                MimeHeaders headers = message.getMimeHeaders();
+//                headers.setHeader("SOAPAction", soapAction);
+//            }
+//
+//            logger.info("Invoking service with SOAP envelope:\n" + message.getSOAPPart().getEnvelope());
+//            
+//            SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
+//            SOAPConnection connection = factory.createConnection();  
+//
+////		call.setTimeout(getTimeout());
+//            return connection.call(message, endpointURL);
+        }
+        
+	/**
+	 * Invokes the webservice with the supplied input Map and preconfigured axis call, 
+	 * and returns a Map containing the outputs, mapped against their output names.
+	 */
+	public Map<String, Object> invoke(SOAPMessage message)
+			throws Exception {
+
+                SOAPMessage response = call(message);
+		
+                List<SOAPElement> responseElements = new ArrayList();
+                for (Iterator<SOAPElement> iter = response.getSOAPBody().getChildElements(); iter.hasNext();)
+                {
+                    responseElements.add(iter.next());
+                }
+		logger.info("Received SOAP response:\n"+response);
+                
+                Map<String, Object> result;
+                if (responseElements.isEmpty()) {
+			if (outputNames.size() == 1
+					&& outputNames.get(0).equals(ATTACHMENT_LIST)) {
+				// Could be axis 2 service with no output (TAV-617)
+				result = new HashMap<String, Object>();
+			} else {
+				throw new IllegalStateException(
+						"Missing expected outputs from service");
+			}                    
+		} else {
+			logger.info("SOAP response was:" + response);
+			SOAPResponseParser responseParser = 
+                                SOAPResponseParserFactory.instance().create(responseElements,
+                                                                            getUse(),
+							                    getStyle(),
+							                    parser.getOperationOutputParameters(operationName));
+			result = responseParser.parse(responseElements);
+		}
+
+		result.put(ATTACHMENT_LIST, extractAttachments(message));
+
+		return result;
+	}
+
+	protected SOAPMessage makeRequestEnvelope(Map inputMap)
+			throws UnknownOperationException, IOException, WSDLException,
+			ParserConfigurationException, SOAPException, SAXException {
+	
+            MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); // TODO: SOAP version
+            SOAPMessage message = factory.createMessage();
+//            
+//            String soapAction = parser.getSOAPActionURI(operationName);
+//            if (soapAction != null) {
+//                MimeHeaders headers = message.getMimeHeaders();
+//                headers.addHeader("SOAPAction", soapAction);
+//            }
+//
+//            if (username != null && username.length() > 0 && 
+//                password != null && password.length() > 0) {
+//                String authorization = DatatypeConverter.printBase64Binary((username+":"+password).getBytes());
+//                MimeHeaders headers = message.getMimeHeaders();
+//                headers.addHeader("Authorization", "Basic " + authorization);
+//            }
+            
+            SOAPEnvelope requestEnv = message.getSOAPPart().getEnvelope();
+                
+            addSoapHeader(requestEnv);
+                
+            requestEnv.getBody().addChildElement(makeSoapBody(inputMap));
+
+            return message;
+	}
+
+        protected void addSoapHeader(SOAPEnvelope envelope) throws SOAPException
+        {
+        }
+
+	protected SOAPElement makeSoapBody(Map inputMap)
+			throws UnknownOperationException, IOException, WSDLException,
+			ParserConfigurationException, SOAPException, SAXException {
+		
+            BodyBuilder builder = 
+                    bodyBuilderFactory.create(parser, operationName, parser.getOperationInputParameters(operationName));
+                
+            return builder.build(inputMap);
+	}
+
+	/**
+	 * Reads the property taverna.wsdl.timeout, default to 5 minutes if missing.
+	 * 
+	 * @return
+	 */
+	protected Integer getTimeout() {
+		int result = 300000;
+		String minutesStr = System.getProperty("taverna.wsdl.timeout");
+
+		if (minutesStr == null) {
+			// using default of 5 minutes
+			return result;
+		}
+		try {
+			int minutes = Integer.parseInt(minutesStr.trim());
+			result = minutes * 1000 * 60;
+		} catch (NumberFormatException e) {
+			logger.error("Non-integer timeout", e);
+			return result;
+		}
+		return result;
+	}
+
+	protected String getStyle() throws UnknownOperationException {
+		return parser.getStyle(operationName);
+	}
+
+	protected String getUse() throws UnknownOperationException {
+		return parser.getUse(operationName);
+	}	
+
+	/**
+	 * Exctracts any attachments that result from invoking the service, and
+	 * returns them as a List wrapped within a DataThing
+	 * 
+	 * @param message
+	 * @return
+	 * @throws SOAPException
+	 * @throws IOException
+	 */
+	protected List extractAttachments(SOAPMessage message)
+			throws SOAPException, IOException {
+		List attachmentList = new ArrayList();
+		if (message.countAttachments() > 0) {
+			for (Iterator i = message.getAttachments(); i
+					.hasNext();) {
+				AttachmentPart ap = (AttachmentPart) i.next();
+				DataHandler dh = ap.getDataHandler();
+				BufferedInputStream bis = new BufferedInputStream(dh
+						.getInputStream());
+				ByteArrayOutputStream bos = new ByteArrayOutputStream();
+				int c;
+				while ((c = bis.read()) != -1) {
+					bos.write(c);
+				}
+				bis.close();
+				bos.close();
+				String mimeType = dh.getContentType();
+				if (mimeType.matches(".*image.*")
+						|| mimeType.matches(".*octet.*")
+						|| mimeType.matches(".*audio.*")
+						|| mimeType.matches(".*application/zip.*")) {
+					attachmentList.add(bos.toByteArray());
+				} else {
+					attachmentList.add(new String(bos.toByteArray()));
+				}
+			}
+		}
+
+		return attachmentList;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSSTokenProfile.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSSTokenProfile.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSSTokenProfile.java
new file mode 100644
index 0000000..90f675d
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/WSSTokenProfile.java
@@ -0,0 +1,39 @@
+/*
+* 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.taverna.wsdl.soap;
+
+/**
+ * @author Dmitry Repchevsky
+ */
+
+public enum WSSTokenProfile {
+    
+    PasswordDigest("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"),
+    PasswordText("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"),
+    UsernameToken("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken"),
+    Base64Binary("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soapmessage-security-1.0#Base64Binary"),
+    X509v3("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
+    
+    public final String TOKEN;
+     
+    private WSSTokenProfile(String token) {
+        TOKEN = token;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/package.html
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/package.html b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/package.html
new file mode 100644
index 0000000..5fd36e5
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/soap/package.html
@@ -0,0 +1,5 @@
+<body>
+Contains classes required to invoke an endpoint for a SOAP based web-service described by a WSDL.<br>
+These classes are derived heavily from the original parsing classes from the Taverna 1 WSDLBasedProcessor and have been refactored<br>
+to remove references to to Taverna 1 
+</body>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLInputSplitter.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLInputSplitter.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLInputSplitter.java
new file mode 100644
index 0000000..5f93f9d
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLInputSplitter.java
@@ -0,0 +1,286 @@
+/*
+* 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.taverna.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.DatatypeConverter;
+import org.apache.taverna.wsdl.parser.ArrayTypeDescriptor;
+import org.apache.taverna.wsdl.parser.BaseTypeDescriptor;
+import org.apache.taverna.wsdl.parser.ComplexTypeDescriptor;
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+
+public class XMLInputSplitter {
+
+	private TypeDescriptor typeDescriptor;
+	private String[] outputNames;
+	private String[] inputNames;
+	private String[] inputTypes;
+
+	public XMLInputSplitter(TypeDescriptor typeDescriptor, String inputNames[],
+			String inputTypes[], String[] outputNames) {
+		this.typeDescriptor = typeDescriptor;
+		this.outputNames = outputNames;
+		this.inputTypes = inputTypes;
+		this.inputNames = inputNames;
+	}
+
+	public Map<String, String> execute(Map<String, Object> inputMap)
+			throws JDOMException, IOException {
+		Map<String, String> result = new HashMap<String, String>();
+		Element outputElement = (this.typeDescriptor.getName().length() > 0 ? new Element(
+				this.typeDescriptor.getName())
+				: new Element(this.typeDescriptor.getType()));
+
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			executeForComplexType(inputMap, result, outputElement);
+
+		} else {
+			for (String key : inputMap.keySet()) {
+				Object dataObject = inputMap.get(key);
+
+				if (dataObject instanceof List) {
+					Element dataElement = buildElementFromObject(key, "");
+					for (Object dataItem : ((List<?>) dataObject)) {
+						Element itemElement = buildElementFromObject(key,
+								dataItem);
+						dataElement.addContent(itemElement);
+					}
+
+					XMLOutputter outputter = new XMLOutputter();
+					String xmlText = outputter.outputString(dataElement);
+
+					result.put(outputNames[0], xmlText);
+				} else {
+					Element dataElement = buildElementFromObject(key,
+							dataObject);
+					outputElement.addContent(dataElement);
+					XMLOutputter outputter = new XMLOutputter();
+					String xmlText = outputter.outputString(outputElement);
+					result.put(outputNames[0], xmlText);
+				}
+
+			}
+		}
+
+		return result;
+
+	}
+
+	private void executeForComplexType(Map<String, Object> inputMap,
+			Map<String, String> result, Element outputElement)
+			throws JDOMException, IOException {
+		ComplexTypeDescriptor complexDescriptor = (ComplexTypeDescriptor) typeDescriptor;
+		for (TypeDescriptor elementType : complexDescriptor.getElements()) {
+			String key = elementType.getName();
+			Object dataObject = inputMap.get(key);			
+			if (dataObject==null) {
+				if (elementType.isOptional()) {
+					continue;
+				} if (elementType.isNillable()) {
+					dataObject = "xsi:nil";
+				} else {
+					dataObject="";
+				}
+			}
+
+			if (dataObject instanceof List) {
+				Element arrayElement = buildElementFromObject(key, "");
+
+				String itemkey = "item";
+				boolean wrapped = false;
+				if (elementType instanceof ArrayTypeDescriptor) {
+					wrapped = ((ArrayTypeDescriptor) elementType).isWrapped();
+					TypeDescriptor arrayElementType = ((ArrayTypeDescriptor) elementType)
+							.getElementType();
+					if (!wrapped) {
+						itemkey = elementType.getName();
+					} else {
+						if (arrayElementType.getName() != null
+								&& arrayElementType.getName().length() > 0) {
+							itemkey = arrayElementType.getName();
+						} else {
+							itemkey = arrayElementType.getType();
+						}
+					}
+
+				}
+
+				for (Object itemObject : ((List<?>)dataObject)) {
+
+					Element dataElement = buildElementFromObject(itemkey,
+							itemObject);
+					dataElement.setNamespace(Namespace.getNamespace(elementType
+							.getNamespaceURI()));
+					if (!wrapped) {
+						dataElement.setName(itemkey);
+						outputElement.addContent(dataElement);
+					} else {
+						arrayElement.addContent(dataElement);
+					}
+				}
+				if (wrapped)
+					outputElement.addContent(arrayElement);
+			} else {
+				Element dataElement = buildElementFromObject(key, dataObject);
+				outputElement.addContent(dataElement);
+			}
+		}
+		for (TypeDescriptor attribute : complexDescriptor.getAttributes()) {
+			String key = attribute.getName();
+			Object dataObject = inputMap.get("1" + key);
+			if (dataObject == null) {
+				dataObject = inputMap.get(key);
+			}
+			if (dataObject != null) {
+				outputElement.setAttribute(key, dataObject.toString(), Namespace
+						.getNamespace(attribute.getQname().getPrefix(), attribute.getNamespaceURI()));
+			}
+		}
+		
+		outputElement.setNamespace(Namespace.getNamespace(typeDescriptor
+				.getNamespaceURI()));
+		XMLOutputter outputter = new XMLOutputter();
+		String xmlText = outputter.outputString(outputElement);
+		result.put(outputNames[0], xmlText);
+	}
+
+	private Element buildElementFromObject(String key, Object dataObject)
+			throws JDOMException, IOException {
+
+		Element dataElement = null;
+
+		if (isXMLInput(key)) {
+			dataElement = createDataElementForXMLInput(dataObject, key);
+		} else {
+			dataElement = new Element(key);
+			setDataElementNamespace(key, dataElement);
+			Namespace xsiNs = org.jdom.Namespace
+				.getNamespace("xsi",
+						"http://www.w3.org/2001/XMLSchema-instance");
+			if (dataObject.toString().equals("xsi:nil")) {
+				dataElement.setAttribute("nil", "true", xsiNs); // changes nil value
+			} else {
+				if (dataObject instanceof byte[]) {
+				
+					dataElement
+							.setAttribute(
+									"type",
+									"xsd:base64Binary",
+									xsiNs);
+					dataObject = DatatypeConverter.printBase64Binary((byte[]) dataObject);
+				}
+				dataElement.setText(dataObject.toString());
+			}
+
+		}
+		return dataElement;
+	}
+
+	private Element createDataElementForXMLInput(Object dataObject, String key)
+			throws JDOMException, IOException {
+		Element dataElement = null;
+		String xml = dataObject.toString();
+		if (xml.length() > 0) {
+			Document doc = new SAXBuilder().build(new StringReader(xml));
+			dataElement = doc.getRootElement();
+			dataElement.detach();
+		} else {
+			dataElement = new Element(key);
+		}
+
+		setDataElementNamespace(key, dataElement);
+		return dataElement;
+	}
+
+	// set the namespace if it can be determined from the element TypeDescriptor
+	// by the key
+	private void setDataElementNamespace(String key, Element dataElement) {
+		if (typeDescriptor instanceof ComplexTypeDescriptor) {
+			TypeDescriptor elementTypeDescriptor = ((ComplexTypeDescriptor) typeDescriptor)
+					.elementForName(key);
+			if (elementTypeDescriptor != null) {
+				String nsURI = null;
+				if (elementTypeDescriptor instanceof BaseTypeDescriptor) {
+					nsURI = elementTypeDescriptor.getNamespaceURI();
+					// this is some protective code against old workflows that
+					// had the base element namespace incorrectly
+					// declared (it was using the type NS, rather than the
+					// element NS.
+					if (nsURI.contains("XMLSchema")
+							&& nsURI.contains("http://www.w3.org")) {
+						nsURI = typeDescriptor.getNamespaceURI();
+					}
+				} else {
+					nsURI = elementTypeDescriptor.getNamespaceURI();
+				}
+				if (nsURI != null && nsURI.length() > 0) {
+					updateElementNamespace(dataElement, nsURI);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Updates the element namespace, and also iterates all descendant elements.
+	 * If these elements have no default namespace, or is blank then it is also
+	 * set to namespaceURI (JDOM by default will not set the child elements to
+	 * the same namespace as the element modified but will override them with
+	 * blank namespaces).
+	 * 
+	 * @param dataElement
+	 * @param namespaceURI
+	 */
+	private void updateElementNamespace(Element dataElement, String namespaceURI) {
+		dataElement.setNamespace(Namespace.getNamespace(namespaceURI));
+		Iterator<?> iterator = dataElement.getDescendants();
+		while (iterator.hasNext()) {
+			Object descendantObject = iterator.next();
+			if (descendantObject instanceof Element) {
+				Element childElement = (Element) descendantObject;
+				if (childElement.getNamespaceURI() == null) {
+					childElement.setNamespace(Namespace
+							.getNamespace(namespaceURI));
+				}
+			}
+		}
+	}
+
+	private boolean isXMLInput(String key) {
+		boolean result = false;
+		for (int i = 0; i < inputNames.length; i++) {
+			if (inputNames[i].equals(key)) {
+				result = inputTypes[i].indexOf("'text/xml'") != -1;
+			}
+		}
+		return result;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java
new file mode 100644
index 0000000..fdb8cc1
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLOutputSplitter.java
@@ -0,0 +1,198 @@
+/*
+* 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.taverna.wsdl.xmlsplitter;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.taverna.wsdl.parser.ArrayTypeDescriptor;
+import org.apache.taverna.wsdl.parser.BaseTypeDescriptor;
+import org.apache.taverna.wsdl.parser.ComplexTypeDescriptor;
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+
+import javax.xml.bind.DatatypeConverter;
+
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.XMLOutputter;
+
+public class XMLOutputSplitter {
+
+	private TypeDescriptor typeDescriptor;
+	private String[] outputNames;
+	private String[] inputNames;
+	private String[] outputTypes;
+
+	public XMLOutputSplitter(TypeDescriptor typeDescriptor,
+			String[] outputNames, String[] outputTypes,String[] inputNames) {
+		this.typeDescriptor = typeDescriptor;
+		this.outputNames = outputNames;
+		this.inputNames = inputNames;
+		this.outputTypes = outputTypes;
+	}
+
+	@SuppressWarnings("unchecked")
+	public Map<String, Object> execute(Map<String, String> inputMap)
+			throws XMLSplitterExecutionException {
+
+		Map<String, Object> result = new HashMap<String, Object>();
+		List<String> outputNameList = Arrays.asList(outputNames);
+
+		String xml = inputMap.get(inputNames[0]);
+		try {
+			Document doc = new SAXBuilder().build(new StringReader(xml));
+			List<Element> children = doc.getRootElement().getChildren();
+			if (typeDescriptor instanceof ArrayTypeDescriptor) {
+				if (outputNames.length > 1)
+					throw new XMLSplitterExecutionException(
+							"Unexpected, multiple output names for ArrayType");
+				executeForArrayType(result, children);
+			} else {
+				executeForComplexType(result, outputNameList, children, doc.getRootElement().getAttributes());
+			}
+
+			// populate missing outputs with empty strings for basic types,
+			// empty elements for complex/array types.
+			for (int i = 0; i < outputNames.length; i++) {
+				if (result.get(outputNames[i]) == null) {
+					if (outputTypes[i].equals("'text/xml'")) {
+						result
+								.put(outputNames[i], "<" + outputNames[i]
+										+ " />");
+					} else if (outputTypes[i].startsWith("l('")) {
+						result.put(outputNames[i], new ArrayList<Object>());
+					} else {
+						result.put(outputNames[i], "");
+					}
+
+				}
+			}
+		} catch (JDOMException e) {
+			throw new XMLSplitterExecutionException("Unable to parse XML: " + xml, e);
+		} catch (IOException e) {
+			throw new XMLSplitterExecutionException("IOException parsing XML: " + xml,
+					e);
+		}
+
+		return result;
+	}
+
+	private void executeForArrayType(Map<String, Object> result,
+			List<Element> children) {
+		ArrayTypeDescriptor arrayDescriptor = (ArrayTypeDescriptor) typeDescriptor;
+		List<String> values = new ArrayList<String>();
+		XMLOutputter outputter = new XMLOutputter();
+
+		boolean isInnerBaseType = arrayDescriptor.getElementType() instanceof BaseTypeDescriptor;
+		if (isInnerBaseType) {
+			values = extractBaseTypeArrayFromChildren(children);
+		} else {
+			for (Element child : children) {
+				values.add(outputter.outputString(child));
+			}
+		}
+		result.put(outputNames[0], values);
+	}
+
+	@SuppressWarnings({ "unchecked" })
+	private void executeForComplexType(Map<String, Object> result,
+			List<String> outputNameList, List<Element> children, List<Attribute> list)
+			throws IOException {               
+
+		XMLOutputter outputter = new XMLOutputter();
+		for (Element child : children) {
+			
+			if (outputNameList.contains(child.getName())) {
+				int i = outputNameList.indexOf(child.getName());
+				TypeDescriptor descriptorForChild = ((ComplexTypeDescriptor) typeDescriptor)
+						.elementForName(outputNames[i]);
+				if (outputTypes[i].startsWith("l(")
+						&& descriptorForChild instanceof ArrayTypeDescriptor
+						&& !((ArrayTypeDescriptor) descriptorForChild)
+								.isWrapped()) {
+					boolean isXMLContent = outputTypes[i].contains("text/xml");
+					result.put(child.getName(), extractDataListFromChildList(
+							children, isXMLContent));
+                    break;
+				} else {
+					if (outputTypes[i].equals("'text/xml'")
+							|| outputTypes[i].equals("l('text/xml')")) {
+						String xmlText = outputter.outputString(child);
+						result.put(child.getName(), xmlText);
+					} else if (outputTypes[i]
+							.equals("'application/octet-stream'")) { // base64Binary
+						
+						byte[] data = DatatypeConverter.parseBase64Binary(child.getText());
+						result.put(child.getName(), data);
+					} else if (outputTypes[i].equals("l('text/plain')")) { // an
+																			// inner
+																			// element
+																			// containing
+																			// a
+																			// list
+						result.put(child.getName(),
+								extractBaseTypeArrayFromChildren(child
+										.getChildren()));
+					} else {
+						result.put(child.getName(), child.getText());
+					}
+				}
+			}
+		}
+		for (Attribute attribute : list) {
+			if (outputNameList.contains("1" + attribute.getName())) {
+				result.put("1" + attribute.getName(), attribute.getValue());
+			} else if (outputNameList.contains(attribute.getName())) {
+				result.put(attribute.getName(), attribute.getValue());
+			}
+		}
+	}
+
+	private List<String> extractDataListFromChildList(List<Element> children,
+			boolean isXMLContent) {
+		List<String> result = new ArrayList<String>();
+		XMLOutputter outputter = new XMLOutputter();
+		for (Element child : children) {
+			if (!isXMLContent) {
+				result.add(child.getTextTrim());
+			} else {
+				result.add(outputter.outputString(child));
+			}
+		}
+		return result;
+	}
+
+	private List<String> extractBaseTypeArrayFromChildren(List<Element> children) {
+		List<String> result = new ArrayList<String>();
+		for (Element child : children) {
+			result.add(child.getTextTrim());
+		}
+		return result;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java
new file mode 100644
index 0000000..18c19d1
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterExecutionException.java
@@ -0,0 +1,33 @@
+/*
+* 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.taverna.wsdl.xmlsplitter;
+
+public class XMLSplitterExecutionException extends Exception {
+
+	private static final long serialVersionUID = 5623707293500493612L;
+
+	public XMLSplitterExecutionException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+
+	public XMLSplitterExecutionException(String msg) {
+		super(msg);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterSerialisationHelper.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterSerialisationHelper.java b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterSerialisationHelper.java
new file mode 100644
index 0000000..4c5e5bc
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/java/org/apache/taverna/wsdl/xmlsplitter/XMLSplitterSerialisationHelper.java
@@ -0,0 +1,341 @@
+/*
+* 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.taverna.wsdl.xmlsplitter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.taverna.wsdl.parser.ArrayTypeDescriptor;
+import org.apache.taverna.wsdl.parser.AttributeTypeDescriptor;
+import org.apache.taverna.wsdl.parser.BaseTypeDescriptor;
+import org.apache.taverna.wsdl.parser.ComplexTypeDescriptor;
+import org.apache.taverna.wsdl.parser.TypeDescriptor;
+
+import org.apache.log4j.Logger;
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * A helper class that supports the XMLOutputSplitter and XMLInputSplitter,
+ * providing the ability for each to be serialised/deserialised to and from the
+ * extensions XML for the ScuflModel XML when storing a workflow. This XML
+ * describes the TypeDescriptor tree that the Splitter wraps.
+ * 
+ * @author Stuart Owen
+ * @author Asger Askov-Bleking
+ * 
+ */
+
+public class XMLSplitterSerialisationHelper {
+
+	public final static Namespace XScuflNS = Namespace.getNamespace("s",
+			"http://org.embl.ebi.escience/xscufl/0.1alpha");
+
+	private static Logger logger = Logger
+			.getLogger(XMLSplitterSerialisationHelper.class);
+
+	/**
+	 * Generates the extensions XML that describes the TypeDescriptor to allow
+	 * an XMLInputSplitter or XMLOutputSplitter to be reconstructed using
+	 * consumeXML.
+	 */
+	public static Element typeDescriptorToExtensionXML(TypeDescriptor descriptor) {
+		Element result = new Element("extensions", XScuflNS);
+		Element type = null;
+		if (descriptor instanceof ComplexTypeDescriptor) {
+			type = constructElementForComplexType(
+					(ComplexTypeDescriptor) descriptor, new ArrayList<String>());
+		}
+		else if (descriptor instanceof ArrayTypeDescriptor) {
+			type = constructElementForArrayType(
+					(ArrayTypeDescriptor) descriptor, new ArrayList<String>());
+		}
+		result.addContent(type);
+		return result;
+	}
+
+	/**
+	 * Generates the TypeDescriptor structurefrom the extensions XML element
+	 * provided. This assumes that the root of the structure is <complextype/>.
+	 * This will be the same xml generated by provideXML.
+	 */
+	public static TypeDescriptor extensionXMLToTypeDescriptor(Element element) {
+		Element child = (Element) element.getChildren().get(0);
+		return buildTypeDescriptorFromElement(child,
+				new HashMap<String, TypeDescriptor>());
+	}
+
+	private static Element constructElementForArrayType(
+			ArrayTypeDescriptor descriptor, List<String> existingsTypes) {
+		Element result = new Element("arraytype", XScuflNS);
+		if (existingsTypes.contains(descriptor.getQname().toString())) {
+			result.setAttribute("id", descriptor.getQname().toString());
+			populateElement(result, descriptor);
+			result.removeAttribute("qname");
+		} else {
+			existingsTypes.add(descriptor.getQname().toString());
+			populateElement(result, descriptor);
+			Element elementType = new Element("elementtype", XScuflNS);
+			if (descriptor.getElementType() instanceof ComplexTypeDescriptor) {
+				elementType.addContent(constructElementForComplexType(
+						(ComplexTypeDescriptor) descriptor.getElementType(),
+						existingsTypes));
+			} else if (descriptor.getElementType() instanceof ArrayTypeDescriptor) {
+				elementType.addContent(constructElementForArrayType(
+						(ArrayTypeDescriptor) descriptor.getElementType(),
+						existingsTypes));
+			} else if (descriptor.getElementType() instanceof BaseTypeDescriptor) {
+				Element element = new Element("basetype", XScuflNS);
+				populateElement(element, descriptor.getElementType());
+				elementType.addContent(element);
+			}
+			result.addContent(elementType);
+		}
+		return result;
+	}
+
+	private static Element constructElementForComplexType(
+			ComplexTypeDescriptor descriptor, List<String> existingsTypes) {
+		Element result = new Element("complextype", XScuflNS);
+		if (existingsTypes.contains(descriptor.getQname().toString())) {
+			result.setAttribute("id", descriptor.getQname().toString());
+			populateElement(result, descriptor);
+			result.removeAttribute("qname");
+		} else {
+			existingsTypes.add(descriptor.getQname().toString());
+			populateElement(result, descriptor);
+			Element elements = new Element("elements", XScuflNS);
+			for (TypeDescriptor desc : descriptor.getElements()) {
+				Element element = null;
+				if (desc instanceof ComplexTypeDescriptor) {
+					element = constructElementForComplexType(
+							(ComplexTypeDescriptor) desc, existingsTypes);
+				} else if (desc instanceof ArrayTypeDescriptor) {
+					element = constructElementForArrayType(
+							(ArrayTypeDescriptor) desc, existingsTypes);
+				} else if (desc instanceof BaseTypeDescriptor) {
+					element = new Element("basetype", XScuflNS);
+					populateElement(element, desc);
+				}
+				if (element != null)
+					elements.addContent(element);
+			}
+			result.addContent(elements);
+			List<TypeDescriptor> attributeDescriptors = descriptor.getAttributes();
+			if (attributeDescriptors != null && attributeDescriptors.size() > 0) {
+				Element attributes = new Element("attributes", XScuflNS);
+				for (TypeDescriptor desc : attributeDescriptors) {
+					Element attribute = new Element("attribute", XScuflNS);
+					populateElement(attribute, desc);
+					attributes.addContent(attribute);
+				}
+				result.addContent(attributes);
+			}
+		}
+		return result;
+	}
+
+	private static void populateElement(Element element,
+			TypeDescriptor descriptor) {
+		element.setAttribute("optional", String
+				.valueOf(descriptor.isOptional()));
+		element.setAttribute("unbounded", String.valueOf(descriptor
+				.isUnbounded()));
+		if (descriptor instanceof ArrayTypeDescriptor) {
+			element.setAttribute("wrapped", String
+					.valueOf(((ArrayTypeDescriptor) descriptor).isWrapped()));
+		}
+		element.setAttribute("typename", descriptor.getType());
+		element.setAttribute("name", descriptor.getName() == null ? ""
+				: descriptor.getName());
+		element.setAttribute("qname", descriptor.getQname().toString());
+		if (descriptor.getDocumentation() != null){
+           Element annotationElement =
+                   new Element("annotation", Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema"));
+           Element documentationElemenet =
+                    new Element("documentation", Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema"));
+            documentationElemenet.setText(descriptor.getDocumentation());
+            annotationElement.addContent(documentationElemenet);
+            element.addContent(annotationElement);
+		}
+
+	}
+
+	private static TypeDescriptor buildTypeDescriptorFromElement(
+			Element element, HashMap<String, TypeDescriptor> existingsTypes) {
+		TypeDescriptor result = null;
+		if (element.getAttributeValue("id") != null) {
+			TypeDescriptor stored = existingsTypes.get(element
+					.getAttributeValue("id"));
+			if (stored == null)
+				logger.fatal("Missing reference to parent type with id="
+						+ element.getAttributeValue("id"));
+			else {
+				result = createFromCache(stored, element);
+			}
+		}
+
+		if (result == null) {
+			if (element.getName().equalsIgnoreCase("complextype")) {
+				result = new ComplexTypeDescriptor();
+				populateDescriptor(element, result);
+				existingsTypes.put(result.getQname().toString(), result);
+				Element elements = element.getChild("elements", XScuflNS);
+				for (Iterator<?> iterator = elements.getChildren().iterator(); iterator
+						.hasNext();) {
+					Element childElement = (Element) iterator.next();
+					((ComplexTypeDescriptor) result).getElements().add(
+							buildTypeDescriptorFromElement(childElement,
+									existingsTypes));
+				}
+				Element attributes = element.getChild("attributes", XScuflNS);
+				if (attributes != null) {
+					for (Iterator<?> iterator = attributes.getChildren().iterator(); iterator
+					.hasNext();) {
+						Element childElement = (Element) iterator.next();
+						((ComplexTypeDescriptor) result).getAttributes().add(
+								buildTypeDescriptorFromElement(childElement,
+										existingsTypes));
+					}
+				}
+
+			} else if (element.getName().equalsIgnoreCase("arraytype")) {
+
+				result = new ArrayTypeDescriptor();
+				populateDescriptor(element, result);
+				existingsTypes.put(result.getQname().toString(), result);
+				Element elementType = element.getChild("elementtype", XScuflNS);
+				((ArrayTypeDescriptor) result)
+						.setElementType(buildTypeDescriptorFromElement(
+								(Element) elementType.getChildren().get(0),
+								existingsTypes));
+				if (element.getAttribute("wrapped") != null) {
+					((ArrayTypeDescriptor) result).setWrapped(element
+							.getAttributeValue("wrapped").equalsIgnoreCase(
+									"true"));
+				} else {
+					// prior to the addition of the wrapped attribute, in the
+					// majority of cases an array
+					// would not be wrapped if it was flagged as unbounded.
+					((ArrayTypeDescriptor) result).setWrapped(!result
+							.isUnbounded());
+				}
+
+			} else if (element.getName().equalsIgnoreCase("basetype")) {
+				result = new BaseTypeDescriptor();
+				populateDescriptor(element, result);
+			} else if (element.getName().equalsIgnoreCase("attribute")) {
+				result = new AttributeTypeDescriptor();
+				populateDescriptor(element, result);
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * Performs a shallow copy of the descriptor stored, but updates its name,
+	 * isbounded and optional This means that descriptors of the same type do
+	 * not need to be repeated throught the stored XML but also takes into
+	 * account parameters of the same type may have different name and
+	 * attributes to that stored
+	 * 
+	 * @param descriptor
+	 * @param element
+	 * @return
+	 */
+	private static TypeDescriptor createFromCache(TypeDescriptor descriptor,
+			Element element) {
+		TypeDescriptor result = null;
+		if (descriptor instanceof ArrayTypeDescriptor) {
+			ArrayTypeDescriptor array = new ArrayTypeDescriptor();
+			array.setQname(descriptor.getQname());
+			array.setElementType(((ArrayTypeDescriptor) descriptor)
+					.getElementType());
+			array.setWrapped(((ArrayTypeDescriptor) descriptor).isWrapped());
+			result = array;
+		} else if (descriptor instanceof ComplexTypeDescriptor) {
+			ComplexTypeDescriptor complex = new ComplexTypeDescriptor();
+			complex.setQname(descriptor.getQname());
+			complex.setElements(((ComplexTypeDescriptor) descriptor)
+					.getElements());
+			result = complex;
+		} else {
+			throw new IllegalArgumentException("Unexpected type descriptor: "
+					+ descriptor);
+		}
+		result.setType(descriptor.getType());
+
+		String name = element.getAttributeValue("name");
+		result.setName(name != null ? name : descriptor.getName());
+
+		String optional = element.getAttributeValue("optional");
+		if (optional != null) {
+			result.setOptional(optional.equalsIgnoreCase("true"));
+		} else {
+			result.setOptional(descriptor.isOptional());
+		}
+
+		String unbounded = element.getAttributeValue("unbounded");
+		if (unbounded != null) {
+			result.setUnbounded(unbounded.equalsIgnoreCase("true"));
+		} else {
+			result.setUnbounded(descriptor.isUnbounded());
+		}
+
+		return result;
+	}
+
+	private static void populateDescriptor(Element element,
+			TypeDescriptor result) {
+		result.setName(element.getAttributeValue("name"));
+		result.setType(element.getAttributeValue("typename"));
+		result.setOptional(element.getAttributeValue("optional")
+				.equalsIgnoreCase("true"));
+		result.setUnbounded(element.getAttributeValue("unbounded")
+				.equalsIgnoreCase("true"));
+
+		Element annotationChild =
+               element.getChild("annotation", Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema"));
+        if (annotationChild != null){
+           List documentationChildren = annotationChild
+                    .getChildren("documentation", Namespace.getNamespace("xsd", "http://www.w3.org/2001/XMLSchema"));
+			 
+           String documentation = "";
+            for (Object documentationChild : documentationChildren) {
+                documentation += ((Element)documentationChild).getText();
+            }
+            if (!documentation.isEmpty()){
+               result.setDocumentation(documentation);
+            }
+        }
+
+		// qname has been added since 1.3.2-RC1 so need to test if missing for
+		// older workflows
+		// if missing it is resolved to an empty namespace and typename:
+		// {}typename
+		String qname = element.getAttributeValue("qname");
+		if (qname != null)
+			result.setQnameFromString(qname);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/main/resources/META-INF/soap-encoding.xsd
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/main/resources/META-INF/soap-encoding.xsd b/taverna-wsdl-generic/src/main/resources/META-INF/soap-encoding.xsd
new file mode 100644
index 0000000..fcf5f4c
--- /dev/null
+++ b/taverna-wsdl-generic/src/main/resources/META-INF/soap-encoding.xsd
@@ -0,0 +1,536 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+
+<!-- Schema for the SOAP/1.1 encoding
+
+Portions © 2001 DevelopMentor. 
+© 2001 W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved.  
+ 
+This document is governed by the W3C Software License [1] as described in the FAQ [2].
+[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD 
+By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:
+
+Permission to use, copy, modify, and distribute this software and its documentation, with or without modification,  for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make:
+
+1.  The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. 
+
+2.  Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: "Copyright © 2001 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/" 
+
+3.  Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.)   
+
+Original W3C files; http://www.w3.org/2001/06/soap-encoding
+Changes made: 
+     - reverted namespace to http://schemas.xmlsoap.org/soap/encoding/
+     - reverted root to only allow 0 and 1 as lexical values
+	 - removed default value from root attribute declaration
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.
+
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+           xmlns:tns="http://schemas.xmlsoap.org/soap/encoding/"
+           targetNamespace="http://schemas.xmlsoap.org/soap/encoding/" >
+        
+ <xs:attribute name="root" >
+   <xs:annotation>
+     <xs:documentation>
+	   'root' can be used to distinguish serialization roots from other
+       elements that are present in a serialization but are not roots of
+       a serialized value graph 
+	 </xs:documentation>
+   </xs:annotation>
+   <xs:simpleType>
+     <xs:restriction base='xs:boolean'>
+	   <xs:pattern value='0|1' />
+	 </xs:restriction>
+   </xs:simpleType>
+ </xs:attribute>
+
+  <xs:attributeGroup name="commonAttributes" >
+    <xs:annotation>
+	  <xs:documentation>
+	    Attributes common to all elements that function as accessors or 
+        represent independent (multi-ref) values.  The href attribute is
+        intended to be used in a manner like CONREF.  That is, the element
+        content should be empty iff the href attribute appears
+	  </xs:documentation>
+	</xs:annotation>
+    <xs:attribute name="id" type="xs:ID" />
+    <xs:attribute name="href" type="xs:anyURI" />
+    <xs:anyAttribute namespace="##other" processContents="lax" />
+  </xs:attributeGroup>
+
+  <!-- Global Attributes.  The following attributes are intended to be usable via qualified attribute names on any complex type referencing them. -->
+       
+  <!-- Array attributes. Needed to give the type and dimensions of an array's contents, and the offset for partially-transmitted arrays. -->
+   
+  <xs:simpleType name="arrayCoordinate" >
+    <xs:restriction base="xs:string" />
+  </xs:simpleType>
+          
+  <xs:attribute name="arrayType" type="xs:string" />
+  <xs:attribute name="offset" type="tns:arrayCoordinate" />
+  
+  <xs:attributeGroup name="arrayAttributes" >
+    <xs:attribute ref="tns:arrayType" />
+    <xs:attribute ref="tns:offset" />
+  </xs:attributeGroup>    
+  
+  <xs:attribute name="position" type="tns:arrayCoordinate" /> 
+  
+  <xs:attributeGroup name="arrayMemberAttributes" >
+    <xs:attribute ref="tns:position" />
+  </xs:attributeGroup>    
+
+  <xs:group name="Array" >
+    <xs:sequence>
+      <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+	</xs:sequence>
+  </xs:group>
+
+  <xs:element name="Array" type="tns:Array" />
+  <xs:complexType name="Array" >
+    <xs:annotation>
+	  <xs:documentation>
+	   'Array' is a complex type for accessors identified by position 
+	  </xs:documentation>
+	</xs:annotation>
+    <xs:group ref="tns:Array" minOccurs="0" />
+    <xs:attributeGroup ref="tns:arrayAttributes" />
+    <xs:attributeGroup ref="tns:commonAttributes" />
+  </xs:complexType> 
+
+  <!-- 'Struct' is a complex type for accessors identified by name. 
+       Constraint: No element may be have the same name as any other,
+       nor may any element have a maxOccurs > 1. -->
+   
+  <xs:element name="Struct" type="tns:Struct" />
+
+  <xs:group name="Struct" >
+    <xs:sequence>
+      <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
+	</xs:sequence>
+  </xs:group>
+
+  <xs:complexType name="Struct" >
+    <xs:group ref="tns:Struct" minOccurs="0" />
+    <xs:attributeGroup ref="tns:commonAttributes"/>
+  </xs:complexType> 
+
+  <!-- 'Base64' can be used to serialize binary data using base64 encoding
+       as defined in RFC2045 but without the MIME line length limitation. -->
+
+  <xs:simpleType name="base64" >
+    <xs:restriction base="xs:base64Binary" />
+  </xs:simpleType>
+
+ <!-- Element declarations corresponding to each of the simple types in the 
+      XML Schemas Specification. -->
+
+  <xs:element name="duration" type="tns:duration" />
+  <xs:complexType name="duration" >
+    <xs:simpleContent>
+      <xs:extension base="xs:duration" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="dateTime" type="tns:dateTime" />
+  <xs:complexType name="dateTime" >
+    <xs:simpleContent>
+      <xs:extension base="xs:dateTime" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+
+
+  <xs:element name="NOTATION" type="tns:NOTATION" />
+  <xs:complexType name="NOTATION" >
+    <xs:simpleContent>
+      <xs:extension base="xs:QName" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+  
+
+  <xs:element name="time" type="tns:time" />
+  <xs:complexType name="time" >
+    <xs:simpleContent>
+      <xs:extension base="xs:time" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="date" type="tns:date" />
+  <xs:complexType name="date" >
+    <xs:simpleContent>
+      <xs:extension base="xs:date" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="gYearMonth" type="tns:gYearMonth" />
+  <xs:complexType name="gYearMonth" >
+    <xs:simpleContent>
+      <xs:extension base="xs:gYearMonth" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="gYear" type="tns:gYear" />
+  <xs:complexType name="gYear" >
+    <xs:simpleContent>
+      <xs:extension base="xs:gYear" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="gMonthDay" type="tns:gMonthDay" />
+  <xs:complexType name="gMonthDay" >
+    <xs:simpleContent>
+      <xs:extension base="xs:gMonthDay" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="gDay" type="tns:gDay" />
+  <xs:complexType name="gDay" >
+    <xs:simpleContent>
+      <xs:extension base="xs:gDay" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="gMonth" type="tns:gMonth" />
+  <xs:complexType name="gMonth" >
+    <xs:simpleContent>
+      <xs:extension base="xs:gMonth" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+  
+  <xs:element name="boolean" type="tns:boolean" />
+  <xs:complexType name="boolean" >
+    <xs:simpleContent>
+      <xs:extension base="xs:boolean" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="base64Binary" type="tns:base64Binary" />
+  <xs:complexType name="base64Binary" >
+    <xs:simpleContent>
+      <xs:extension base="xs:base64Binary" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="hexBinary" type="tns:hexBinary" />
+  <xs:complexType name="hexBinary" >
+    <xs:simpleContent>
+     <xs:extension base="xs:hexBinary" >
+       <xs:attributeGroup ref="tns:commonAttributes" />
+     </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="float" type="tns:float" />
+  <xs:complexType name="float" >
+    <xs:simpleContent>
+      <xs:extension base="xs:float" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="double" type="tns:double" />
+  <xs:complexType name="double" >
+    <xs:simpleContent>
+      <xs:extension base="xs:double" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="anyURI" type="tns:anyURI" />
+  <xs:complexType name="anyURI" >
+    <xs:simpleContent>
+      <xs:extension base="xs:anyURI" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="QName" type="tns:QName" />
+  <xs:complexType name="QName" >
+    <xs:simpleContent>
+      <xs:extension base="xs:QName" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  
+  <xs:element name="string" type="tns:string" />
+  <xs:complexType name="string" >
+    <xs:simpleContent>
+      <xs:extension base="xs:string" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="normalizedString" type="tns:normalizedString" />
+  <xs:complexType name="normalizedString" >
+    <xs:simpleContent>
+      <xs:extension base="xs:normalizedString" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="token" type="tns:token" />
+  <xs:complexType name="token" >
+    <xs:simpleContent>
+      <xs:extension base="xs:token" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="language" type="tns:language" />
+  <xs:complexType name="language" >
+    <xs:simpleContent>
+      <xs:extension base="xs:language" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="Name" type="tns:Name" />
+  <xs:complexType name="Name" >
+    <xs:simpleContent>
+      <xs:extension base="xs:Name" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="NMTOKEN" type="tns:NMTOKEN" />
+  <xs:complexType name="NMTOKEN" >
+    <xs:simpleContent>
+      <xs:extension base="xs:NMTOKEN" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="NCName" type="tns:NCName" />
+  <xs:complexType name="NCName" >
+    <xs:simpleContent>
+      <xs:extension base="xs:NCName" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="NMTOKENS" type="tns:NMTOKENS" />
+  <xs:complexType name="NMTOKENS" >
+    <xs:simpleContent>
+      <xs:extension base="xs:NMTOKENS" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="ID" type="tns:ID" />
+  <xs:complexType name="ID" >
+    <xs:simpleContent>
+      <xs:extension base="xs:ID" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="IDREF" type="tns:IDREF" />
+  <xs:complexType name="IDREF" >
+    <xs:simpleContent>
+      <xs:extension base="xs:IDREF" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="ENTITY" type="tns:ENTITY" />
+  <xs:complexType name="ENTITY" >
+    <xs:simpleContent>
+      <xs:extension base="xs:ENTITY" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="IDREFS" type="tns:IDREFS" />
+  <xs:complexType name="IDREFS" >
+    <xs:simpleContent>
+      <xs:extension base="xs:IDREFS" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="ENTITIES" type="tns:ENTITIES" />
+  <xs:complexType name="ENTITIES" >
+    <xs:simpleContent>
+      <xs:extension base="xs:ENTITIES" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="decimal" type="tns:decimal" />
+  <xs:complexType name="decimal" >
+    <xs:simpleContent>
+      <xs:extension base="xs:decimal" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="integer" type="tns:integer" />
+  <xs:complexType name="integer" >
+    <xs:simpleContent>
+      <xs:extension base="xs:integer" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="nonPositiveInteger" type="tns:nonPositiveInteger" />
+  <xs:complexType name="nonPositiveInteger" >
+    <xs:simpleContent>
+      <xs:extension base="xs:nonPositiveInteger" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="negativeInteger" type="tns:negativeInteger" />
+  <xs:complexType name="negativeInteger" >
+    <xs:simpleContent>
+      <xs:extension base="xs:negativeInteger" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="long" type="tns:long" />
+  <xs:complexType name="long" >
+    <xs:simpleContent>
+      <xs:extension base="xs:long" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="int" type="tns:int" />
+  <xs:complexType name="int" >
+    <xs:simpleContent>
+      <xs:extension base="xs:int" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="short" type="tns:short" />
+  <xs:complexType name="short" >
+    <xs:simpleContent>
+      <xs:extension base="xs:short" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="byte" type="tns:byte" />
+  <xs:complexType name="byte" >
+    <xs:simpleContent>
+      <xs:extension base="xs:byte" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="nonNegativeInteger" type="tns:nonNegativeInteger" />
+  <xs:complexType name="nonNegativeInteger" >
+    <xs:simpleContent>
+      <xs:extension base="xs:nonNegativeInteger" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="unsignedLong" type="tns:unsignedLong" />
+  <xs:complexType name="unsignedLong" >
+    <xs:simpleContent>
+      <xs:extension base="xs:unsignedLong" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="unsignedInt" type="tns:unsignedInt" />
+  <xs:complexType name="unsignedInt" >
+    <xs:simpleContent>
+      <xs:extension base="xs:unsignedInt" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="unsignedShort" type="tns:unsignedShort" />
+  <xs:complexType name="unsignedShort" >
+    <xs:simpleContent>
+      <xs:extension base="xs:unsignedShort" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="unsignedByte" type="tns:unsignedByte" />
+  <xs:complexType name="unsignedByte" >
+    <xs:simpleContent>
+      <xs:extension base="xs:unsignedByte" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="positiveInteger" type="tns:positiveInteger" />
+  <xs:complexType name="positiveInteger" >
+    <xs:simpleContent>
+      <xs:extension base="xs:positiveInteger" >
+        <xs:attributeGroup ref="tns:commonAttributes" />
+      </xs:extension>
+    </xs:simpleContent>
+  </xs:complexType>
+
+  <xs:element name="anyType" />
+</xs:schema>
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-common-activities/blob/433612be/taverna-wsdl-generic/src/test/java/net/sf/taverna/wsdl/parser/TypeDescriptorTest.java
----------------------------------------------------------------------
diff --git a/taverna-wsdl-generic/src/test/java/net/sf/taverna/wsdl/parser/TypeDescriptorTest.java b/taverna-wsdl-generic/src/test/java/net/sf/taverna/wsdl/parser/TypeDescriptorTest.java
deleted file mode 100644
index c7be469..0000000
--- a/taverna-wsdl-generic/src/test/java/net/sf/taverna/wsdl/parser/TypeDescriptorTest.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2003 The University of Manchester 
- *
- * Modifications to the initial code base are copyright of their
- * respective authors, or their employers as appropriate.  Authorship
- * of the modifications may be determined from the ChangeLog placed at
- * the end of this file.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA.
- *
- ****************************************************************
- * Source code information
- * -----------------------
- * Filename           $RCSfile: TypeDescriptorTest.java,v $
- * Revision           $Revision: 1.2 $
- * Release status     $State: Exp $
- * Last modified on   $Date: 2007/11/30 12:13:38 $
- *               by   $Author: sowen70 $
- * Created on 17-May-2006
- *****************************************************************/
-package net.sf.taverna.wsdl.parser;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-public class TypeDescriptorTest extends TestCase {
-
-	// array of strings
-	public void testRetrieveSignitureForArrayDescriptor() {
-		ArrayTypeDescriptor desc = new ArrayTypeDescriptor();
-		desc.setName("AnArray");
-		desc.setType("arrayofstring");
-
-		BaseTypeDescriptor base = new BaseTypeDescriptor();
-		base.setName("");
-		base.setType("string");
-
-		desc.setElementType(base);
-
-		String[] names = new String[1];
-		Class<?>[] types = new Class[1];
-
-		List<TypeDescriptor> params = new ArrayList<TypeDescriptor>();
-		params.add(desc);
-		TypeDescriptor.retrieveSignature(params, names, types);
-
-		assertEquals("AnArray", names[0]);
-		assertEquals(String[].class, types[0]);
-	}
-
-	// array of strings, but type for array is defined as string
-	// (which is logically warped, but some wsdl's describe their string arrays
-	// this way).
-	public void testRetrieveSignitureForArrayDescriptor3() {
-		ArrayTypeDescriptor desc = new ArrayTypeDescriptor();
-		desc.setName("AnArray");
-		desc.setType("string");
-
-		BaseTypeDescriptor base = new BaseTypeDescriptor();
-		base.setName("");
-		base.setType("string");
-
-		desc.setElementType(base);
-
-		String[] names = new String[1];
-		Class<?>[] types = new Class[1];
-
-		List<TypeDescriptor> params = new ArrayList<TypeDescriptor>();
-		params.add(desc);
-		TypeDescriptor.retrieveSignature(params, names, types);
-
-		assertEquals("AnArray", names[0]);
-		assertEquals(String[].class, types[0]);
-	}
-
-	// array of complex types
-	public void testRetrieveSignitureForArrayDescriptor2() {
-		ArrayTypeDescriptor desc = new ArrayTypeDescriptor();
-		desc.setName("AnArray");
-		desc.setType("complextype");
-
-		ComplexTypeDescriptor complex = new ComplexTypeDescriptor();
-		complex.setName("complex");
-		complex.setType("complextype");
-
-		desc.setElementType(complex);
-
-		String[] names = new String[1];
-		Class<?>[] types = new Class[1];
-
-		List<TypeDescriptor> params = new ArrayList<TypeDescriptor>();
-		params.add(desc);
-		TypeDescriptor.retrieveSignature(params, names, types);
-
-		assertEquals("AnArray", names[0]);
-		assertEquals(org.w3c.dom.Element.class, types[0]);
-	}
-
-	public void testForCyclicTrue() {
-		ComplexTypeDescriptor a = new ComplexTypeDescriptor();
-		a.setName("a");
-		a.setType("outertype");
-
-		ComplexTypeDescriptor b = new ComplexTypeDescriptor();
-		b.setName("b");
-		b.setType("middletype");
-
-		ComplexTypeDescriptor c = new ComplexTypeDescriptor();
-		c.setName("c");
-		c.setType("innertype");
-
-		a.getElements().add(b);
-		b.getElements().add(c);
-		c.getElements().add(a);
-
-		assertTrue("should be identified as cyclic", TypeDescriptor.isCyclic(a));
-	}
-
-	public void testForCyclicTrueWithArray() {
-		ComplexTypeDescriptor a = new ComplexTypeDescriptor();
-		a.setName("a");
-		a.setType("outertype");
-
-		ArrayTypeDescriptor b = new ArrayTypeDescriptor();
-		b.setName("b");
-		b.setType("arraytype");
-
-		ComplexTypeDescriptor c = new ComplexTypeDescriptor();
-		c.setName("c");
-		c.setType("innertype");
-
-		a.getElements().add(b);
-		b.setElementType(c);
-		c.getElements().add(a);
-
-		assertTrue("should be identified as cyclic", TypeDescriptor.isCyclic(a));
-	}
-
-	public void testForCyclicFalse() {
-		ComplexTypeDescriptor a = new ComplexTypeDescriptor();
-		a.setName("a");
-		a.setType("person");
-
-		ComplexTypeDescriptor b = new ComplexTypeDescriptor();
-		b.setName("b");
-		b.setType("name");
-
-		ComplexTypeDescriptor c = new ComplexTypeDescriptor();
-		c.setName("c");
-		c.setType("age");
-
-		a.getElements().add(b);
-		a.getElements().add(c);
-
-		assertFalse("should be not identified as cyclic", TypeDescriptor
-				.isCyclic(a));
-	}
-
-	public void testQNameAsString() {
-		ComplexTypeDescriptor a = new ComplexTypeDescriptor();
-		a.setQnameFromString("{URI}localPart");
-		assertEquals("URI", a.getQname().getNamespaceURI());
-		assertEquals("localPart", a.getQname().getLocalPart());
-
-		a = new ComplexTypeDescriptor();
-		a.setQnameFromString("{}localPart");
-		assertEquals("", a.getQname().getNamespaceURI());
-		assertEquals("localPart", a.getQname().getLocalPart());
-	}
-	
-	public void testBaseTypeKnownSigniture() {
-		TypeDescriptor decimal=new BaseTypeDescriptor();
-		decimal.setName("adecimal");
-		decimal.setType("decimal");
-		
-		List<TypeDescriptor> params=new ArrayList<TypeDescriptor>();
-		String [] names=new String[1];
-		Class<?> [] types=new Class[1];
-		params.add(decimal);
-		TypeDescriptor.retrieveSignature(params, names, types);
-		
-		assertEquals("should only be 1 type",1,types.length);
-		assertEquals("should only be 1 name",1,names.length);
-		
-		assertEquals("name should be adecimal","adecimal",names[0]);
-		assertEquals("type should be double",Double.TYPE,types[0]);
-	}
-	
-	public void testBaseTypeUnrecognisedSigniture() {
-		TypeDescriptor date=new BaseTypeDescriptor();
-		date.setName("adate");
-		date.setType("date");
-		
-		List<TypeDescriptor> params=new ArrayList<TypeDescriptor>();
-		String [] names=new String[1];
-		Class<?> [] types=new Class[1];
-		params.add(date);
-		TypeDescriptor.retrieveSignature(params, names, types);
-		
-		assertEquals("should only be 1 type",1,types.length);
-		assertEquals("should only be 1 name",1,names.length);
-		
-		assertEquals("name should be adecimal","adate",names[0]);
-		assertEquals("type should be string",String.class,types[0]);
-	}
-	
-	public void testComplex() {
-		TypeDescriptor complex=new ComplexTypeDescriptor();
-		complex.setName("acomplex");
-		complex.setType("complextype");
-		
-		List<TypeDescriptor> params=new ArrayList<TypeDescriptor>();
-		String [] names=new String[1];
-		Class<?> [] types=new Class[1];
-		params.add(complex);
-		TypeDescriptor.retrieveSignature(params, names, types);
-		
-		assertEquals("should only be 1 type",1,types.length);
-		assertEquals("should only be 1 name",1,names.length);
-		
-		assertEquals("name should be adecimal","acomplex",names[0]);
-		assertEquals("type should be string",org.w3c.dom.Element.class,types[0]);
-	}
-
-}