[MOBY-guts] biomoby commit

Paul Gordon gordonp at dev.open-bio.org
Thu Dec 7 16:37:36 UTC 2006


gordonp
Thu Dec  7 11:37:36 EST 2006
Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/service
In directory dev.open-bio.org:/tmp/cvs-serv29629/src/main/org/biomoby/service

Modified Files:
	MobyServlet.java 
Log Message:
Updates to secondary article handling
moby-live/Java/src/main/org/biomoby/service MobyServlet.java,1.3,1.4
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/MobyServlet.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/MobyServlet.java	2006/12/06 16:07:10	1.3
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/service/MobyServlet.java	2006/12/07 16:37:36	1.4
@@ -31,6 +31,7 @@
 import javax.xml.soap.*;
 import java.util.StringTokenizer;
 import java.util.Vector;
+import java.math.*;
 
 @mobyService(name="MobyServlet",
 	     type="Testing", 
@@ -49,7 +50,7 @@
     public static final String MOBY_SERVICETYPE_PARAM = "mobyServiceType";
     public static final String MOBY_SERVICENAME_PARAM = "mobyServiceName";
     public static final String MOBY_INPUT_PARAM = "mobyInput";
-    public static final String MOBY_SECONDARY_PARAM = "mobySecondaryInput";
+    public static final String MOBY_SECONDARYINPUT_PARAM = "mobySecondaryInput";
     public static final String MOBY_OUTPUT_PARAM = "mobyOutput";
     public static final String MODE_HTTP_PARAM = "mode";
     public static final String RDF_MODE = "rdf";
@@ -279,7 +280,9 @@
 	return mobyRequestContents;
     }
 
-    // throws an exception if the data is not as expected
+    /**
+     * Throws an exception if the data in the job does not match the input spec of the service
+     */
     public static void validateArguments(MobyDataJob job, 
 					 MobyService service, 
 					 String errMessagePrefix) throws Exception{
@@ -362,6 +365,98 @@
 						   " does not have one of the required namespaces"); 
 	    }
 	}
+
+	// Check for secondary parameters, and fill in missing ones with the default values
+	MobySecondaryData[] template2 = service.getSecondaryInputs();
+	MobyDataSecondaryInstance[] values2 = job.getSecondaryData();
+
+	for(MobySecondaryData param: template2){
+	    MobyDataSecondaryInstance matchingValue = null;
+	    for(MobyDataSecondaryInstance value: values2){
+		if(value.getName().equals(param.getName())){
+		    matchingValue = value;
+		    break;
+		}
+	    }
+
+	    if(matchingValue != null){
+		String dataType = param.getDataType();
+		// This is the first point at which we have enough info to assign
+		// a data type to the secondary parameter in the job (it is string by default
+		// when parsing the XML).
+		try{
+		    matchingValue.setDataType(dataType);
+		} catch(Exception e){
+		    e.printStackTrace();  // will default to String if unrecognized
+		}
+		// Check that the value given is valid
+		if(dataType.equals(MobySecondaryData.INTEGER_TYPE)){
+		    BigInteger val = matchingValue.asInteger();
+		    if(param.getMinValue() != null && param.getMinValue().length() > 0){
+			BigInteger min = new BigInteger(param.getMinValue());
+			if(min.compareTo(val) > 0){
+			    // Out of range (too small), reset the value
+			    matchingValue.setValue(min.toString());
+			}
+		    }
+		    if(param.getMaxValue() != null && param.getMaxValue().length() > 0){
+			BigInteger max = new BigInteger(param.getMaxValue());
+			if(max.compareTo(val) < 0){
+			    // Out of range (too big), reset the value
+			    matchingValue.setValue(max.toString());
+			}
+		    }
+		}
+		else if(dataType.equals(MobySecondaryData.FLOAT_TYPE)){
+		    BigDecimal val = matchingValue.asFloat();
+		    if(param.getMinValue() != null && param.getMinValue().length() > 0){
+			BigDecimal min = new BigDecimal(param.getMinValue());
+			if(min.compareTo(val) > 0){
+			    // Out of range (too small), reset the value
+			    matchingValue.setValue(min.toString());
+			}
+		    }
+		    if(param.getMaxValue() != null && param.getMaxValue().length() > 0){
+			BigDecimal max = new BigDecimal(param.getMaxValue());
+			if(max.compareTo(val) < 0){
+			    // Out of range (too big), reset the value
+			    matchingValue.setValue(max.toString());
+			}
+		    }
+		}
+		else if(dataType.equals(MobySecondaryData.STRING_TYPE)){
+		    // Enumerated?
+		    String val = matchingValue.asString();
+		    String[] allowedVals = param.getAllowedValues();
+		    if(allowedVals != null && allowedVals.length > 0){
+			boolean isInList = false;
+			for(String allowedVal: allowedVals){
+			    if(allowedVal != null && allowedVal.equals(val)){
+				isInList = true;
+				break;
+			    }			    
+			}
+			if(!isInList){
+			    // Illegal value given, use the default instead
+			    matchingValue.setValue(param.getDefaultValue());
+			}
+		    }
+		}
+		else if(dataType.equals(MobySecondaryData.DATETIME_TYPE)){
+		    // TODO
+		}
+		else if(dataType.equals(MobySecondaryData.BOOLEAN_TYPE)){
+		    // no issues here...
+		}
+		else{
+		    // what type is this ???
+		}
+	    }
+	    else{
+		// Missing value, fill it in with the default
+		job.put(param.getName(), new MobyDataSecondaryInstance(param, param.getDefaultValue()));
+	    }
+	}
     }
 
     private void writeResponse(HttpServletResponse response, MobyContentInstance mobyResults){
@@ -548,7 +643,7 @@
     public synchronized MobyService createServiceFromConfig(HttpServletRequest request) throws Exception{
 	MobyService service = new MobyService(getServiceName());
 
-	Vector<MobyPrimaryData> inputTypes = new Vector<MobyPrimaryData>();
+	Vector<MobyData> inputTypes = new Vector<MobyData>();
 	Vector<MobyPrimaryData> outputTypes = new Vector<MobyPrimaryData>();
 
 	mobyService ann = 
@@ -602,6 +697,16 @@
 	    }
 	}
 
+	String[] secondaries = ann.secondaryParams();
+	if(config != null && config.getInitParameter(MOBY_SECONDARYINPUT_PARAM) != null){
+	    secondaries = config.getInitParameter(MOBY_SECONDARYINPUT_PARAM).split(",");
+	}
+	if(secondaries != null && secondaries.length > 0){
+	    for(String secondary: secondaries){
+		inputTypes.add(stringToSecondaryDataTemplate(secondary));
+	    }
+	}
+
 	service.setInputs(inputTypes.toArray(new MobyData[inputTypes.size()]));
 	service.setOutputs(outputTypes.toArray(new MobyData[outputTypes.size()]));
 
@@ -746,6 +851,144 @@
     }
 
     /**
+     * Strings have the form name:paramType:default:spec where spec depends on the parameter type.
+     * Currently, these are the valid paramTypes and their specs:
+     *
+     *   <ul><li>Integer: blank or [,max] or [min,] or [min,max]</li>
+     *       <li>Float: blank or [,max] or [min,] or [min,max]</li>
+     *       <li>String: blank or [choice1,choice2,...]</li>
+     *       <li>DateTime: blank or [,max] or [min,] or [min,max]</li>
+     *       <li>Boolean: blank</li></ul>
+     * 
+     * e.g. <code>db:String:nr:[nr,nt,est,swissprot]</code>
+     *
+     * e.g. <code>filter:Boolean:true</code>
+     *
+     * e.g. <code>hits:Integer:100:[0,]</code>
+     */
+    public static MobySecondaryData stringToSecondaryDataTemplate(String template) throws Exception{
+	String[] fields = template.split(":");
+	if(fields.length < 3){
+	    throw new Exception("The parameter specification (" + 
+				template + ") must have the minimal form " +
+				"\"name:paramType:defaultValue\", aborting!");
+	}
+	if(fields[0].length() < 1){
+	    throw new Exception("The parameter specification (" + 
+				template + ") has a blank parameter name, this is not allowed");
+	}
+	if(fields[1].length() < 1){
+	    throw new Exception("The parameter specification (" + 
+				template + ") has a blank parameter type, this is not allowed");
+	}
+	MobySecondaryData dataTemplate = new MobySecondaryData(fields[0]);
+	String dataType = fields[1];
+	try{
+	    dataTemplate.setDataType(dataType);  // should throw an exception if invalid param type
+	} catch(Exception e){
+	    e.printStackTrace();
+	    throw new Exception("Error in parameter type (" + dataType + "') of secondary " +
+				"parameters specification '" + template + "': " + e);
+	}
+
+	String defaultValue = fields[2];
+	dataTemplate.setDefaultValue(defaultValue);
+
+	String spec = "";
+	int i = 3;
+	for(; i < fields.length-1; i++){
+	    spec = spec + fields[i] + ":";
+	}
+	if(i == fields.length-1){
+	    spec = spec + fields[i];
+	}
+
+	// Ensure the [] are there, and strip them
+	if(spec.length() > 0){
+	    if(spec.indexOf('[') != 1 || spec.lastIndexOf(']') != spec.length()){
+		throw new Exception("Parameter options specification (4th field of '" + 
+				    template + "') " +
+				    "does not have the required form '[...]', but rather: " + spec);
+	    }
+	    spec = spec.substring(1, spec.length());
+	}
+	String[] specValues = new String[0];
+	if(spec.length() > 0){
+	    specValues = spec.split(",");
+	}
+
+	if(dataType.equals(MobySecondaryData.INTEGER_TYPE) ||
+	   dataType.equals(MobySecondaryData.FLOAT_TYPE)){
+	    if(specValues.length > 0){
+		if(specValues.length != 2){
+		    throw new Exception("Numeric parameter options specification (4th field of " +
+					template + "') " +
+					"does not have on of the required forms [min,] or [,max] or [min,max]");
+		}
+		BigDecimal min = null;
+		BigDecimal max = null;
+		if(specValues[0].length() != 0){
+		    min = new BigDecimal(specValues[0]);  // will throw exception if not a number
+		}
+		if(specValues[1].length() != 0){
+		    max = new BigDecimal(specValues[1]);  // will throw exception if not a number
+		}
+		// We will actually accept [,] as an unlimited range
+		if(min != null && max != null && min.compareTo(max) > 0){
+		    throw new Exception("Numeric parameter range (4th field of " + template + "') " +
+					"has a minimum value greater than the maximum value");
+		}
+		BigDecimal defaultNumber = new BigDecimal(defaultValue); // will throw exception if not a number
+		if(min != null){
+		    if(min.compareTo(defaultNumber) > 0){
+			throw new Exception("Numeric parameter default (3rd field of " + template + "') " +
+					    "is less than the minimum value specified");
+		    }
+		}
+		if(min != null){
+		    if(max.compareTo(defaultNumber) < 0){
+			throw new Exception("Numeric parameter default (3rd field of " + template + "') " +
+					    "is greater than the maximum value specified");
+		    }
+		}
+	    }
+	}
+	else if(dataType.equals(MobySecondaryData.STRING_TYPE)){
+	    if(specValues.length > 0){  // an enumeration
+		boolean defaultListed = false;
+		for(String value: specValues){
+		    if(defaultValue.equals(value)){
+			defaultListed = true;
+			break;
+		    }
+		}
+		if(!defaultListed){
+		    throw new Exception("The default value (" + defaultValue + 
+					") was not listed in the enumeration (" + 
+					spec + ")");
+		}
+
+		dataTemplate.setAllowedValues(specValues);
+	    }
+	    // otherwise it's a freeform string
+	}
+	else if(dataType.equals(MobySecondaryData.BOOLEAN_TYPE)){
+	    if(specValues.length > 0){
+		throw new Exception("Boolean secondary parameter specification provided " +
+				    "superfluous fields (only 3 needed): " + spec);
+	    }
+	}
+	else if(dataType.equals(MobySecondaryData.DATETIME_TYPE)){
+	    // TODO
+	}
+	else{
+	    throw new Exception("Unrecognized secondary data type encountered: " + dataType);
+	}
+
+	return dataTemplate;
+    }
+
+    /**
      * Strings have the form name:objectType:namespace, with ":namespace" optional
      * If the input is expected to be a Collection, then the syntax is name:Collection(objectType):namespace
      */
@@ -753,21 +996,18 @@
 	StringTokenizer st = new StringTokenizer(spec, ":");
 	String name = st.nextToken();
 	if(name == null || name.length() == 0){
-	    System.err.println("Anonymous parameters are not allowed in service calls (" + 
-			       spec + "), aborting!");
-	    System.exit(1);
+	    throw new Exception("Anonymous parameters are not allowed in service calls (" + 
+				spec + "), aborting!");
 	}
         if(!st.hasMoreTokens()){
-	    System.err.println("The parameter specification (" + 
-			       spec + ") must have the minimal form " +
-			       "\"name:objectType\", aborting!");
-	    System.exit(1);
+	    throw new Exception("The parameter specification (" + 
+				spec + ") must have the minimal form " +
+				"\"name:objectType\", aborting!");
 	}
 	String objectType = st.nextToken();
 	if(objectType == null || objectType.length() == 0){
-	    System.err.println("The parameter specification (" + 
+	    throw new Exception("The parameter specification (" + 
 			       spec + ") has a blank object type, aborting!");
-	    System.exit(1);
 	}
 
 	MobyPrimaryData dataTemplate = null;
@@ -785,11 +1025,10 @@
 
 	MobyDataType type = MobyDataType.getDataType(objectType);
 	if(type == null){
-	    System.err.println("The parameter specification (" + 
-			       spec + ") has a data type not found in the " +
-			       "MOBY registry, aborting! (Either correct the type," +
-			       " or register it as a new type in MOBY Central");
-	    System.exit(1);
+	    throw new Exception("The parameter specification (" + 
+				spec + ") has a data type not found in the " +
+				"MOBY registry, aborting! (Either correct the type," +
+				" or register it as a new type in MOBY Central");
 	}
 	dataTemplate.setDataType(type);
 	if(isCollection){




More information about the MOBY-guts mailing list