[MOBY-guts] biomoby commit
Paul Gordon
gordonp at dev.open-bio.org
Thu Oct 30 02:33:25 UTC 2008
gordonp
Wed Oct 29 22:33:24 EDT 2008
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util
In directory dev.open-bio.org:/tmp/cvs-serv10500/src/main/ca/ucalgary/services/util
Modified Files:
MobySpecWrapper.java SourceMap.java WSDLConfig.java
Log Message:
Updates related to SAWSDL wrapping Web Service implementation
moby-live/Java/src/main/ca/ucalgary/services/util MobySpecWrapper.java,1.1,1.2 SourceMap.java,1.1,1.2 WSDLConfig.java,1.4,1.5
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/MobySpecWrapper.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/MobySpecWrapper.java 2008/03/13 23:05:47 1.1
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/MobySpecWrapper.java 2008/10/30 02:33:24 1.2
@@ -19,6 +19,7 @@
private Map<String,Map<String,String>> serviceInputs;
private Map<String,Map<String,String>> serviceInputFormats;
private Map<String,Map<String,String>> serviceSecondaries;
+ private Map<String,Map<String,String>> serviceSecondaryFormats;
private Map<String,Map<String,String>> serviceOutputs;
private Map<String,Map<String,String>> serviceOutputFormats;
private Map<String,Map<String,String>> fixedParams;
@@ -36,6 +37,7 @@
serviceOutputs = new HashMap<String,Map<String,String>>();
fixedParams = new HashMap<String,Map<String,String>>();
serviceInputFormats = new HashMap<String,Map<String,String>>();
+ serviceSecondaryFormats = new HashMap<String,Map<String,String>>();
serviceOutputFormats = new HashMap<String,Map<String,String>>();
}
@@ -102,10 +104,23 @@
return serviceInputs.get(currentService);
}
+ public void setSecondaryInputFormats(Map<String,String> specs){
+ serviceSecondaryFormats.put(currentService, specs);
+ }
+
+ public Map<String,String> getSecondaryInputFormats(){
+ return serviceSecondaryFormats.get(currentService);
+ }
+
public void setPrimaryInputFormats(Map<String,String> specs){
serviceInputFormats.put(currentService, specs);
}
+ /**
+ * Note that the string values for the formats are specialized for the
+ * various LegacyService child classes, as they will all have their own naming scheme for legacy
+ * formats.
+ */
public Map<String,String> getPrimaryInputFormats(){
return serviceInputFormats.get(currentService);
}
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/SourceMap.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/SourceMap.java 2008/06/30 17:42:29 1.1
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/SourceMap.java 2008/10/30 02:33:24 1.2
@@ -4,23 +4,21 @@
import java.io.*;
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
/**
* Converts a Map of Strings into a Source for the Java SOAP libraries.
* The Map should be of the form (SOAP input param name -> XML Schema Instance data).
*/
-public class SourceMap extends javax.xml.transform.stream.StreamSource implements ConcurrentMap<String,String>{
+public class SourceMap extends javax.xml.transform.stream.StreamSource implements Map<String,String>{
- private ConcurrentHashMap<String,String> members;
+ private TreeMap<String,String> members;
private QName messageName;
/**
* @param msgName the name of the operation message (WSDL 1.1) or operation element (WSDL 2.0) that is being encapsulated
*/
public SourceMap(QName msgName){
- members = new ConcurrentHashMap<String,String>();
+ members = new TreeMap<String,String>();
messageName = msgName;
}
@@ -38,7 +36,7 @@
xmlContents.append("<?xml version='1.0'?>\n");
xmlContents.append("<m:"+messageName.getLocalPart()+" xmlns:m=\""+messageName.getNamespaceURI()+"\">");
- // Serialize map members NOTE: not correct yet!
+ // Serialize map members
for(String value: values()){
xmlContents.append(value);
}
@@ -140,41 +138,5 @@
public int size(){
return members.size();
}
-
- /*
- * If the field with a given name is not yet associated with any value, associate it with the given value.
- * Note that this operation is atomic for data integrity purposes in multi-threaded apps.
- */
- public String putIfAbsent(String key, String value){
- return members.putIfAbsent(key, value);
- }
-
- /*
- * Removes the field with the given name only if it currently has the given value.
- * Note that this operation is atomic for data integrity purposes in multi-threaded apps.
- *
- * @return true if the replacement operation caused a change in the object value
- */
- public boolean remove(Object key, Object value){
- return members.remove(key, value);
- }
-
- /*
- * Replaces the field with the given name only if the field already exists in the composite.
- * Note that this operation is atomic for data integrity purposes in multi-threaded apps.
- */
- public String replace(String fieldName, String value){
- return members.replace(fieldName, value);
- }
-
- /*
- * Replaces the field with the given name only if it currently has a given value
- * Note that this operation is atomic for data integrity purposes in multi-threaded apps.
- *
- * @return true if the replacement operation caused a change in the object value
- */
- public boolean replace(String fieldName, String oldValue, String newValue){
- return members.replace(fieldName, oldValue, newValue);
- }
}
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java 2008/07/03 16:29:25 1.4
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/WSDLConfig.java 2008/10/30 02:33:24 1.5
@@ -138,6 +138,7 @@
NodeList partElements = messageElement.getElementsByTagNameNS(MobyPrefixResolver.WSDL_NAMESPACE, "part");
Map<String,String> inputs = new HashMap<String,String>();
Map<String,String> inputMappings = new HashMap<String,String>();
+ Map<String,String> secondaryMappings = new HashMap<String,String>();
Map<String,String> inputTypes = new HashMap<String,String>();
Map<String,String> secondaryInputs = new HashMap<String,String>();
Map<String,String> outputs = new HashMap<String,String>();
@@ -177,6 +178,7 @@
"' is not a properly formed Moby primary or secondary param LSID as required");
}
secondaryInputs.put(partName, mobyParam);
+ secondaryMappings.put(partName, schemaMapping);
}
else{
inputs.put(partName, mobyParam);
@@ -200,6 +202,7 @@
setPrimaryInputFormats(inputMappings);
setInputXSDTypes(inputTypes);
setSecondaryInputs(secondaryInputs);
+ setSecondaryInputFormats(secondaryMappings);
}
else{ // it's output
setPrimaryOutputs(outputs);
@@ -216,25 +219,31 @@
(!dataTypeLSIDFields[3].equals("objectclass") && !dataTypeLSIDFields[3].equals("namespacetype"))){
return null;
}
- // Special case, if the LSID is a namespace, spec out a base object in the given namespace
- if(dataTypeLSIDFields[3].equals("namespacetype")){
- return paramName+":"+MobyTags.MOBYOBJECT+":"+dataTypeLSIDFields[4];
- }
- else{
- // Deal with the case where the output XSD data type is an array:
- // implicitly make the return data type Collection(Thing)
-
- // See if the name is namespace qualified, and separate the local part if so
- String nsURI = "";
- if(paramXSDType.contains(":")){
- String nsPrefix = paramXSDType.substring(0, paramXSDType.indexOf(":")); //XML NS prefix
- paramXSDType = paramXSDType.substring(paramXSDType.indexOf(":")+1); //local part
- nsURI = element.lookupNamespaceURI(nsPrefix); //prefix->URI
+ // Deal with the case where the output XSD data type is an array:
+ // implicitly make the return data type Collection(Thing)
+
+ // See if the name is namespace qualified, and separate the local part if so
+ String nsURI = "";
+ if(paramXSDType.contains(":")){
+ String nsPrefix = paramXSDType.substring(0, paramXSDType.indexOf(":")); //XML NS prefix
+ paramXSDType = paramXSDType.substring(paramXSDType.indexOf(":")+1); //local part
+ nsURI = element.lookupNamespaceURI(nsPrefix); //prefix->URI
+ }
+ Element schemaDataTypeElement = isBasicType(paramXSDType) ? null :
+ getSchemaElement(element.getOwnerDocument(), nsURI, paramXSDType);
+ if(getArrayType(schemaDataTypeElement) != null){
+ // Special case, if the LSID is a namespace, spec out a base object in the given namespace
+ if(dataTypeLSIDFields[3].equals("namespacetype")){
+ return paramName+":Collection("+MobyTags.MOBYOBJECT+"):"+dataTypeLSIDFields[4];
}
- Element schemaDataTypeElement = getSchemaElement(element.getOwnerDocument(), nsURI, paramXSDType);
- if(getArrayType(schemaDataTypeElement) != null){
+ else{
return paramName+":Collection("+dataTypeLSIDFields[4]+")";
}
+ }
+ else{
+ if(dataTypeLSIDFields[3].equals("namespacetype")){
+ return paramName+":"+MobyTags.MOBYOBJECT+":"+dataTypeLSIDFields[4];
+ }
else{
return paramName+":"+dataTypeLSIDFields[4];
}
@@ -242,6 +251,10 @@
}
+ private boolean isBasicType(String xsdType){
+ return "string".equals(xsdType); //TODO: fill out list
+ }
+
public String wsdlParam2MobySecondaryParam(Element partElement, String paramName,
String paramXSDType, String dataTypeLSID) throws Exception{
String[] dataTypeLSIDFields = dataTypeLSID.split(":");
@@ -252,6 +265,7 @@
}
// the format for secondaries is "name:type:defaultValue:[min,max]", where [min,max] can be an enumeration as well
String restrictionsSpec = getSecondaryParamRestrictions(partElement);
+ //System.err.println("Full secondary spec is " + paramName+":"+dataTypeLSIDFields[4]+":"+restrictionsSpec);
return paramName+":"+dataTypeLSIDFields[4]+":"+restrictionsSpec;
}
@@ -478,6 +492,9 @@
// <xsd:restriction base="soapenc:Array">
// <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="typens:Thing[]"/>
// </xsd:restriction></xsd:complexContent></xsd:complexType>
+ if(schemaDefElement == null){
+ return null;
+ }
NodeList contentElements = schemaDefElement.getElementsByTagNameNS(MobyPrefixResolver.XSD_NAMESPACE,
"complexContent");
if(contentElements.getLength() == 1){
@@ -538,6 +555,31 @@
nsUri + " does not exist");
}
+ public static Element renameSoapArrayElements(Element arrayElement, String newName, Document owner){
+ NodeList arrayElements = arrayElement.getChildNodes();
+ Element renamedArray = owner.createElement("soap-array");
+ for(int j = 0; j < arrayElements.getLength(); j++){
+ if(!(arrayElements.item(j) instanceof Element)){
+ continue;
+ }
+ // For XPath rules to work properly, we need to rename the items
+ // in the array to the parent name
+ Element renamedArrayItem = owner.createElement(newName);
+ // clone the old element attributes and children into the new one
+ Element oldElement = (Element) arrayElements.item(j);
+ NamedNodeMap attrs = oldElement.getAttributes();
+ for(int k = 0; k < attrs.getLength(); k++){
+ renamedArrayItem.setAttributeNodeNS((Attr) attrs.item(k).cloneNode(true));
+ }
+ NodeList children = oldElement.getChildNodes();
+ for(int k = 0; k < children.getLength(); k++){
+ renamedArrayItem.appendChild(children.item(k).cloneNode(true));
+ }
+ renamedArray.appendChild(renamedArrayItem);
+ }
+ return renamedArray;
+ }
+
protected String convertSourceToMobySecondaryValues(Source source, URL liftingSchema, boolean arrayRule) throws Exception{
// The source will contain an XML document, lets convert it to a string of the form val1,val2,val3 using a stylesheet
TransformerFactory transformerFactory = TransformerFactory.newInstance();
@@ -560,8 +602,22 @@
if(!(source instanceof StreamSource)){
StringWriter verbatim = new StringWriter();
transformerFactory.newTransformer().transform(source, new StreamResult(verbatim));
- //System.err.println("Verbatim source is:\n" + verbatim);
- source = new StreamSource(new StringReader(verbatim.toString()));
+ // Need to compensate for the fact that some XSLT transformers don't copy over the
+ // namespace declaration properly, so declare it manually for xsi if that's the case
+ // otherwise you get a parsing error later on when trying to do the
+ // xml schema -> moby xml transformation. Ditto with soap encoding.
+ String verb = verbatim.toString();
+ if(verb.indexOf(" xmlns:xsi") == -1 &&
+ verb.indexOf(" xsi:") != -1){
+ verb = verb.replaceFirst(" xsi:",
+ " xmlns:xsi=\""+MobyPrefixResolver.XSI_NAMESPACE2001+"\" xsi:");
+ }
+ if(verb.indexOf(" xmlns:SOAP-ENC") == -1 &&
+ verb.indexOf(" SOAP-ENC:") != -1){
+ verb = verb.replaceFirst(" SOAP-ENC:",
+ " xmlns:SOAP-ENC=\""+MobyPrefixResolver.SOAP_ENC_NAMESPACE+"\" SOAP-ENC:");
+ }
+ source = new StreamSource(new StringReader(verb));
}
Document arrayDoc = null;
@@ -572,10 +628,16 @@
arrayDoc = docBuilder.parse(new org.xml.sax.InputSource(((StreamSource) source).getReader()));
}
else{
- throw new Exception("Neither the InputStream or Reader was available from " +
+ throw new Exception("Neither an InputStream nor a Reader was available from " +
"the StreamSource, cannot process the source");
}
- NodeList arrayElements = arrayDoc.getElementsByTagName("item");
+ Element arrayElement = (Element) arrayDoc.getDocumentElement().getFirstChild();
+ String dataTypeAttr = arrayElement.getAttributeNS(MobyPrefixResolver.SOAP_ENC_NAMESPACE, "arrayType");
+ String dataType = dataTypeAttr.replaceFirst("^.*:([^\\[]+).*", "$1");
+ //System.err.println("Array Data Type for secondary source is " + dataType);
+ // for RPC-encoded data, rename item tags to real data type name
+ Element renamedArray = renameSoapArrayElements(arrayElement, dataType, arrayDoc);
+ NodeList arrayElements = renamedArray.getElementsByTagName(dataType);
for(int i = 0; i < arrayElements.getLength(); i++){
if(i != 0){
stringWriter.write(','); //join values with a comma
@@ -587,7 +649,7 @@
else{
transformer.transform(source, new StreamResult(stringWriter));
}
- //System.err.println("Response payload:\n"+stringWriter.toString());
+ //System.err.println("Response payload for secondary param:\n"+stringWriter.toString());
return stringWriter.toString();
}
More information about the MOBY-guts
mailing list