[MOBY-guts] biomoby commit
Paul Gordon
gordonp at dev.open-bio.org
Thu Feb 7 20:03:27 UTC 2008
gordonp
Thu Feb 7 15:03:26 EST 2008
Update of /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util
In directory dev.open-bio.org:/tmp/cvs-serv8915/src/main/ca/ucalgary/services/util
Modified Files:
XHTMLForm.java
Log Message:
Version of XHTMLForm and unit tests that pass parsing, meta-data and logic tests
moby-live/Java/src/main/ca/ucalgary/services/util XHTMLForm.java,1.2,1.3
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/XHTMLForm.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/XHTMLForm.java 2008/02/06 16:00:57 1.2
+++ /home/repository/moby/moby-live/Java/src/main/ca/ucalgary/services/util/XHTMLForm.java 2008/02/07 20:03:26 1.3
@@ -34,7 +34,7 @@
private Map<String,String> serviceDescs;
private Map<String,String> providerURIs;
private Map<String,String> centralEndpoints;
- private Map<String,String> contactEmails;
+ private String contactEmail;
private Map<String,Map<String,String>> serviceInputs;
private Map<String,Map<String,String>> serviceSecondaries;
@@ -65,7 +65,7 @@
private final String MOBY_PREFIX_PLACEHOLDER = "%MOBYPREFIX%";
- private final String META_AUTHOR_XPATH = "/xhtml:html/xhtml:head/xhtml:meta[@name = \""+MOBY_PREFIX_PLACEHOLDER+":author\"]";
+ private final String META_CONTACT_XPATH = "/xhtml:html/xhtml:head/xhtml:meta[@name = \""+MOBY_PREFIX_PLACEHOLDER+":contact\"]";
private final String META_SERVICE_XPATH = "/xhtml:html/xhtml:head/xhtml:meta[@name = \""+MOBY_PREFIX_PLACEHOLDER+":service\"]";
private final String SERVICE_SCHEME_ATTR = "scheme";
private final String SERVICE_SPEC_ATTR = "content";
@@ -107,7 +107,6 @@
serviceDescs = new HashMap<String,String>();
providerURIs = new HashMap<String,String>();
centralEndpoints = new HashMap<String,String>();
- contactEmails = new HashMap<String,String>();
fixedParams = new HashMap<String,Map<String,String>>();
serviceInputs = new HashMap<String,Map<String,String>>();
serviceSecondaries = new HashMap<String,Map<String,String>>();
@@ -150,12 +149,46 @@
}
- protected List<String> parseMetaData(String mobyPrefix) throws Exception{
- // Find the author info (email contact, or md5 hash of an address for privacy reasons)
- String authorInfo = xPath.evaluate(META_AUTHOR_XPATH.replaceAll(MOBY_PREFIX_PLACEHOLDER, mobyPrefix),
- xhtmlDoc);
+ protected String parseAuthorData(String mobyPrefix) throws Exception{
+ String contactXPathString = META_CONTACT_XPATH.replaceAll(MOBY_PREFIX_PLACEHOLDER, mobyPrefix);
+ // Find the contact info (email contact, or md5 hash of an address for privacy reasons)
+ NodeList contactTags = (NodeList) xPath.evaluate(contactXPathString,
+ xhtmlDoc,
+ XPathConstants.NODESET);
+ if(contactTags.getLength() == 0){
+ throw new Exception("Could not find any service author tags of the required form '" +
+ contactXPathString + "'");
+ }
+ if(contactTags.getLength() > 1){
+ throw new Exception("Found multiple (hence ambiguous) service author tags of the form '" +
+ contactXPathString + "'");
+ }
+ Node contactElement = contactTags.item(0);
+ if(!(contactElement instanceof Element)){
+ throw new Exception("The XPath to retrieve the service contact info '" +
+ contactXPathString + "' did not return an element as expected (" +
+ "got a " + contactElement.getClass().getName() + " instead)");
+ }
+
+ String contactInfo = ((Element) contactElement).getAttribute(SERVICE_SPEC_ATTR);
+ if(contactInfo == null || contactInfo.trim().length() == 0){
+ throw new Exception("The service contact info is missing or blank in the HTML meta data headers" +
+ " (the XPath used was " +
+ contactXPathString + ")");
+ }
+ contactInfo = contactInfo.trim();
+ // Make sure it's an MD5 hash, or a real (probably qualified) SMTP e-mail format
+ if(!contactInfo.matches("[0-9a-f]{40}") &&
+ !contactInfo.matches("\\S+@\\S+\\.\\S{2,}")){
+ throw new Exception("The value of the service contact info (" + contactInfo +
+ " appears to be neither a qualified email address (e.g." +
+ " foo at bar.tld), nor an md5 hash of one");
+ }
+ return contactInfo;
+ }
+ protected List<String> parseMetaData(String mobyPrefix) throws Exception{
List<String> serviceNames = new Vector<String>();
NodeList serviceTags = (NodeList) xPath.evaluate(META_SERVICE_XPATH.replaceAll(MOBY_PREFIX_PLACEHOLDER, mobyPrefix),
xhtmlDoc,
@@ -173,6 +206,10 @@
}
serviceNames.add(parseServiceTag((Element) serviceTag));
}
+
+ // There can be only one contact email for the form, so this call is not in the loop
+ setContactEmail(parseAuthorData(mobyPrefix));
+
return serviceNames;
}
@@ -220,7 +257,7 @@
throw new Exception(errorPrefix + " (serviceName was blank)");
}
serviceName = serviceName.trim();
- String serviceDesc = firstColonIndex < spec.length()-1 ? spec.substring(firstColonIndex+1) : "";
+ String serviceDesc = firstColonIndex < spec.length()-1 ? spec.substring(firstColonIndex+1).trim() : "";
currentService = serviceName;
setCentralEndpoint(scheme);
@@ -289,9 +326,6 @@
for(int i = 0; i < formParams.getLength(); i++){
Element input = (Element) formParams.item(i);
String mobySpec = parseMobySpec(input, mobyPrefix);
- if(mobySpec != null && mobySpec.length() > mobyPrefix.length()+1){
- mobySpec = mobySpec.substring(mobyPrefix.length()+1);
- }
parseFormField(input, serviceName, mobySpec, inputSpecs, secondarySpecs, fixed, submits, images);
}
Map<String,String> inputSpecsAsStrings = new HashMap<String,String>();
@@ -304,7 +338,7 @@
}
for(Map.Entry<String,String[]> spec: secondarySpecs.entrySet()){
String[] value = spec.getValue();
- if(value[3] != null && !value[3].matches("\\[.*\\]")){
+ if(value[3] != null && value[3].length() > 0 && !value[3].matches("\\[.*\\]")){
value[3] = "["+value[3]+"]";
}
secondarySpecsAsStrings.put(spec.getKey(), join(":", value));
@@ -361,6 +395,8 @@
// if spec says to ignore the value as a Moby parameter
if(specFields.length == 1 && specFields[0].equals(NULL_NAME)){
// don't send this value, nor make it part of the moby params
+ // If it is a file type input, remove it from the form file list
+ removeFormFile(defaultSpec[0]);
return;
}
else if(specFields.length != 3 && specFields.length != 4){
@@ -379,7 +415,7 @@
specFields[0]+"\" specifies an allowable data range of \"" +
specFields[3]+"\", but submission parameters are only allowed " +
"fixed values (in this case \"" + specFields[2] + "\"). Please " +
- "remove the data range parameter in order top avoid a " +
+ "remove the data range parameter in order to avoid a " +
"conflicting specification.");
}
if(specFields[1] != null && specFields[1].length() > 0 &&
@@ -475,7 +511,7 @@
}
// else: ignore any other radio value, we're sticking with the fixed value
}
- // Did the user manually set a fixed value for the readio button?
+ // Did the user manually set a fixed value for the radio button?
else if(specFields[2] != null && specFields[2].length() > 0 &&
!specFields[2].equals(defaultSpec[2])){
// first time we're fixing the radio param value to send
@@ -495,11 +531,12 @@
"Moby specs as \"" + existingSpec[0] +
"\" and \"" + specFields[0]);
}
- // otherwise it's the default name maintained,
// or we're renaming for the first time
- if(!existingSpec[0].equals(specFields[0])){
+ else if(existingSpec[0].equals(defaultSpec[0]) && !existingSpec[0].equals(specFields[0])){
existingSpec[0] = specFields[0];
}
+ // otherwise it's the default name maintained
+
if(isRadioDefault){ //we've been told this item is the default value
existingSpec[2] = specFields[2];
}
@@ -558,6 +595,8 @@
if(SUBMIT_DATATYPE.equals(defaultSpec[1])){
if(defaultSpec[2].equals(submits.get(defaultSpec[0]))){
// TODO: how do we handle multiple submits with the same name but different values??
+ System.err.println("Overriding submit with same name but with new different value: " +
+ defaultSpec[0] + ", " + defaultSpec[2]);
}
submits.put(defaultSpec[0], defaultSpec[2]);
}
@@ -607,8 +646,26 @@
// The output datatype of the service is also declared in the form tag
List<String> outputSpecs = parseMobySpecs(serviceFormElement, mobyPrefix);
+ String[] cleanOutputSpecs = new String[outputSpecs.size()];
+ for(int i = 0; i < outputSpecs.size(); i++){
+ String spec = outputSpecs.get(i);
+ if(!outputSpecs.get(i).startsWith(serviceName+":")){
+ throw new Exception("The form for service '" + serviceName +
+ "' also contains moby specs (" + spec +
+ ") not of the required form '"+mobyPrefix+":"+
+ serviceName+":paramName:DataType'. " +
+ "You can only specify one service per form.");
+ }
+ if(spec.length() < serviceName.length()+4){
+ throw new Exception("The form for service '" + serviceName +
+ "' contains moby specs (" + spec +
+ ") not of the required form '"+mobyPrefix+":"+
+ serviceName+":paramName:DataType'");
+ }
+ cleanOutputSpecs[i] = spec.substring(serviceName.length()+1);
+ }
- setPrimaryOutputs(outputSpecs.toArray(new String[outputSpecs.size()]));
+ setPrimaryOutputs(cleanOutputSpecs);
String encType = URLENCODED; // This is the default XHTML value
setFormEncodingType(encType);
@@ -670,8 +727,8 @@
}
for(String classSpec: classSpecs.split("\\s")){
String[] classParts = classSpec.split(":");
- if(classParts[0].equals(mobyPrefix)){
- mobySpecs.add(classSpec);
+ if(classParts.length > 1 && classParts[0].equals(mobyPrefix)){
+ mobySpecs.add(classSpec.substring(mobyPrefix.length()+1));
}
}
@@ -807,20 +864,24 @@
addFormFile(nameAttr);
}
- // Try to parse the default value multiple ways
- dataType = MobyTags.MOBYINTEGER;
-
- try{new BigInteger(valueAttr);
- }catch(Exception e){
- dataType = MobyTags.MOBYFLOAT;}
-
- try{new BigDecimal(valueAttr);
- }catch(Exception e){
- dataType = MobyTags.MOBYDATETIME;}
-
- try{MobyDataDateTime.parseISO8601(valueAttr);
- }catch(Exception e){
- dataType = MobyTags.MOBYSTRING;}
+ if(valueAttr != null && valueAttr.length() > 0){
+
+ // Try to parse the default value multiple ways
+ dataType = MobyTags.MOBYINTEGER;
+
+ try{new BigInteger(valueAttr);
+ }catch(Exception e){
+ dataType = MobyTags.MOBYFLOAT;}
+
+ try{new BigDecimal(valueAttr);
+ }catch(Exception e){
+ dataType = MobyTags.MOBYDATETIME;}
+
+ try{MobyDataDateTime.parseISO8601(valueAttr);
+ }catch(Exception e){
+ dataType = MobyTags.MOBYSTRING;}
+ }
+ //else we keep the default of MobyTags.MOBYSTRING
}
return new String[]{nameAttr, dataType, valueAttr, range};
@@ -861,7 +922,7 @@
}
String selAttr = option.getAttributeNS(MobyPrefixResolver.XHTML_NAMESPACE, "selected");
- if(selAttr == null){
+ if(selAttr == null || selAttr.length() == 0){
selAttr = option.getAttribute("selected");
}
if(selAttr != null && selAttr.length() > 0 && !"0".equals(selAttr) && !"false".equals(selAttr)){
@@ -919,11 +980,11 @@
}
public void setContactEmail(String email){
- contactEmails.put(currentService, email);
+ contactEmail = email;
}
public String getContactEmail(){
- return contactEmails.get(currentService);
+ return contactEmail;
}
/**
@@ -981,7 +1042,7 @@
// Note that the map is not cloned...
public void setImageOptions(Map<String,String> options){
- formSubmitOptions.put(currentService, options);
+ formImageOptions.put(currentService, options);
}
/**
@@ -1036,6 +1097,12 @@
formFiles.get(currentService).add(paramName);
}
+ public void removeFormFile(String paramName){
+ if(currentService != null && formFiles.containsKey(currentService)){
+ formFiles.get(currentService).remove(paramName);
+ }
+ }
+
/**
* @return the list of input parameters (primary and/or secondary) that should be submitted in "file" style
*/
More information about the MOBY-guts
mailing list