[MOBY-guts] biomoby commit
Paul Gordon
gordonp at pub.open-bio.org
Sat Aug 20 01:58:13 UTC 2005
gordonp
Fri Aug 19 21:58:13 EDT 2005
Update of /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data
In directory pub.open-bio.org:/tmp/cvs-serv27410/src/main/org/biomoby/shared/data
Modified Files:
MobyContentInstance.java MobyDataObject.java
MobyDataObjectSet.java MobyDataSecondaryInstance.java
MobyDataUtils.java
Log Message:
Updates to deal with requirements for named parameters in MOBY API 0.86, and some relaxing of this rule to allow existing anonymously parameterized one-input services to still be valid
moby-live/Java/src/main/org/biomoby/shared/data MobyContentInstance.java,1.1,1.2 MobyDataObject.java,1.6,1.7 MobyDataObjectSet.java,1.3,1.4 MobyDataSecondaryInstance.java,1.4,1.5 MobyDataUtils.java,1.1,1.2
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyContentInstance.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyContentInstance.java 2005/07/22 05:11:54 1.1
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyContentInstance.java 2005/08/20 01:58:13 1.2
@@ -46,9 +46,11 @@
/**
* A convenience constructor when you want to create an envelope with just one object in it.
- * This object will be put into its own data group (mobyData tag), and automatically assigned an
- * articleName if paramName is null or an empty string.
- *MobyDataObjectSet
+ * This object will be put into its own data group (mobyData tag), and automatically assigned a
+ * queryID. If paramName is null, the parameter is assigned an empty string for articleName.
+ * For now, single parameter requests can have empty articleNames in jMOBY. This may change
+ * in the future.
+ *
* @throws MobyException if the passed in object is not a MobyDataObject or a MobyDataObjectSet or null (an empty data group)
*/
public MobyContentInstance(MobyDataInstance mdi, String paramName) throws MobyException{
@@ -59,19 +61,21 @@
throw new MobyException("The input Moby data instance class (" + mdi.getClass().getName() +
") was neither MobyDataObject nor MobyDataObjectSet as required");
}
- Vector dataGroup = new Vector();
+ HashMap queryParams = new HashMap();
if(mdi != null){
- dataGroup.add(mdi);
+ if(paramName == null){
+ paramName = ""; // Cannot have a null key in a hash
+ }
+ queryParams.put(paramName, mdi);
}
- put(((paramName == null || paramName.length() == 0) ? ""+autoID++ : paramName),
- dataGroup);
+ put(""+autoID++, queryParams);
}
/**
* Builds a MobyContentInstance (i.e. one or more MOBY queries or responses) using
* a DOM-parsed XML MOBY envelope (i.e. the mobyContent tag). This is useful if you
* want to parse a response from a server, or if you are a server and you want to parse
- * an incoming query. The resulting object can be modifed using the standard Map
+ * an incoming query. The resulting object can be modified using the standard Map
* interface methods, with queryID as key, and MobyDataInstance Vectors (mobyData) as values.
*/
public MobyContentInstance(Element objectTag) throws MobyException{
@@ -92,13 +96,13 @@
// If we got this far, we're in the clear for the single envelope
// What we need to parse now is the one or more sets of data in the envelope
- NodeList mobyData = objectTag.getElementsByTagNameNS(MobyPrefixResolver.MOBY_XML_NAMESPACE,
- INVOCABLE_ELEMENT);
+ NodeList mobyData = MobyPrefixResolver.getChildElements(objectTag,
+ INVOCABLE_ELEMENT);
if(mobyData.getLength() == 0){
throw new MobyException("The document's " + ELEMENT_NAME +
"element does not have a " + INVOCABLE_ELEMENT +
- " child. It must have one or more");
+ " child. It must have one or more according to the MOBY API");
}
// Now back to the main data
@@ -125,12 +129,12 @@
// Concatenate all serviceNotes. Because service notes often contain markup such as HTML,
// we will convert all of the subtrees into a string, not just the direct child text and CDATA elements.
- NodeList notes = objectTag.getElementsByTagNameNS(MobyPrefixResolver.MOBY_XML_NAMESPACE,
- SERVICE_NOTES_ELEMENT);
+ NodeList notes = MobyPrefixResolver.getChildElements(objectTag,
+ SERVICE_NOTES_ELEMENT);
if(notes.getLength() > 0){
StringBuffer notesText = new StringBuffer();
for(int i = 0; i < notes.getLength(); i++){
- notesText.append(((Element) notes.item(i)));
+ notesText.append(MobyObjectDecompositionImpl.getTextContent((Element) notes.item(i)));
}
setServiceNotes(notesText.toString());
}
@@ -159,7 +163,7 @@
protected void parseDataGroup(Element dataGroupTag) throws MobyException{
String groupID = null;
- Vector dataMembers = new Vector();
+ HashMap dataMembers = new HashMap();
groupID = dataGroupTag.getAttributeNS(MobyPrefixResolver.MOBY_XML_NAMESPACE, ID_ATTR);
if(groupID == null){
@@ -175,29 +179,14 @@
for(int j = 0; collections != null && j < collections.getLength(); j++){
if(debug && j == 0){
debugPS.println("There are " + collections.getLength() +
- " simples in response " + groupID +
- ", collection #" + j);
+ " collections in response " + groupID);
}
Element collectionTag = (Element) collections.item(j);
- MobyDataObjectSet collection = new MobyDataObjectSet(MobyDataObject.getName(collectionTag));
-
- // For each collection, find the simple children
- NodeList subsimples = MobyPrefixResolver.getChildElements(collectionTag, "Simple");
-
- // And add their values to the collection
- MobyDataObject[] subout = new MobyDataObject[subsimples.getLength()];
- for(int k = 0; k < subsimples.getLength(); k++){
- if(debug && k == 0){
- debugPS.println("There are " + subsimples.getLength() +
- " simples in response " + groupID +
- ", collection #" + j);
- }
- subout[k] = (MobyDataObject) MobyDataObject.createInstanceFromDOM((Element) subsimples.item(k));
- }
- collection.setElements(subout);
+ MobyDataObjectSet collection = (MobyDataObjectSet) (MobyDataObject.createInstanceFromDOM(collectionTag));
// Add completed collection to the output list
- dataMembers.add(collection);
+ dataMembers.put(collection.getName(), collection);
+
} // Done fetching collections
// Take all the top level simples and add them to the list
@@ -210,16 +199,33 @@
if(debug && j == 0){
debugPS.println("There are " + simples.getLength() + " simples in the response");
}
- dataMembers.add(MobyDataObject.createInstanceFromDOM((Element) simples.item(j)));
+ String name = MobyPrefixResolver.getAttr((Element) simples.item(j), "articleName");
+ // A named member. Die if there is more than one with the same name
+ if(name != null){
+ if(dataMembers.containsKey(name)){
+ throw new MobyException("Illegal XML: there is more than one tag in the response " +
+ groupID + " with the articleName " + name);
+ }
+ dataMembers.put(name, MobyDataObject.createInstanceFromDOM((Element) simples.item(j)));
+ }
+ // No anonymous data member yet
+ else if(!dataMembers.containsKey("")){
+ dataMembers.put("", MobyDataObject.createInstanceFromDOM((Element) simples.item(j)));
+ }
+ else{
+ debugPS.println("More than one anonymous member, ignoring simple #" + j);
+ }
}
- // Now add the parameter
+ // Now add the secondary parameters
NodeList parameters = MobyPrefixResolver.getChildElements(dataGroupTag, "Parameter");
for(int j = 0; parameters != null && j < parameters.getLength(); j++){
if(debug && j == 0){
- debugPS.println("There are " + parameters.getLength() + " simples in the response");
+ debugPS.println("There are " + parameters.getLength() + " parameters in the response");
}
- dataMembers.add(MobyDataObject.createInstanceFromDOM((Element) parameters.item(j)));
+ MobyDataSecondaryInstance paramObject = (MobyDataSecondaryInstance)
+ MobyDataObject.createInstanceFromDOM((Element) parameters.item(j));
+ dataMembers.put(paramObject.getName(), paramObject);
}
put(groupID, dataMembers);
@@ -271,7 +277,55 @@
}
public String toXML(){
- return "stuff here";
+ StringBuffer xml = new StringBuffer(" <moby:mobyContent" +
+ (serviceAuthURI == null ? "" : " moby:authority=\"" +serviceAuthURI + "\"") +
+ ">\n");
+ if(serviceNotes != null){
+ // Note: we should escape the service notes, in case they contain bad markup -> TODO
+ xml.append(" <moby:serviceNotes>" + serviceNotes + "</moby:serviceNotes>");
+ }
+
+ // print each query (or response as it may be)
+ Iterator queryIter = keySet().iterator();
+ while(queryIter.hasNext()){
+ // What's in the mobyData tag?
+ String queryName = (String) queryIter.next();
+ xml.append(" <moby:mobyData queryID=\""+queryName+"\">");
+
+ AbstractMap queryParams = (AbstractMap) get(queryName);
+ // Print each parameter (the order is random)
+ Iterator paramIter = queryParams.keySet().iterator();
+
+ while(paramIter.hasNext()){
+ String paramName = ((String) paramIter.next());
+ MobyDataInstance dataObject = ((MobyDataInstance) queryParams.get(paramName));
+
+ int oldXmlMode = dataObject.getXmlMode();
+ if(oldXmlMode != MobyDataInstance.SERVICE_XML_MODE){
+ dataObject.setXmlMode(MobyDataInstance.SERVICE_XML_MODE);
+ }
+
+ if(dataObject instanceof MobyDataObject){
+ // This line should be replaced with a named field
+ xml.append(" <Simple articleName='" + paramName + "'>"+
+ dataObject.toXML()+
+ "</Simple>");
+ }
+ else{
+ xml.append(dataObject.toXML());
+ }
+
+ // Restore the old XML mode setting if not service mode
+ if(oldXmlMode != MobyDataInstance.SERVICE_XML_MODE){
+ dataObject.setXmlMode(oldXmlMode);
+ }
+ }
+
+ xml.append(" </moby:mobyData>");
+ }
+
+ xml.append(" </moby:mobyContent>\n");
+ return xml.toString();
}
// Below, to the end of the class file, are the methods that must be
@@ -344,7 +398,7 @@
//public MobyDataObject put(String fieldName, MobyDataObject value){
/**
* @param queryID a unique ID for the query. If null, or not a String, or blank it will be auto-generated
- * @param value
+ * @param value an AbstractMap of <String, MobyDataInstance>, where the string is the parameter name
*/
public Object put(Object queryID, Object value){
if(queryID == null || !(queryID instanceof String) || ((String) queryID).length() == 0){
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataObject.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataObject.java 2005/08/07 23:46:12 1.6
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataObject.java 2005/08/20 01:58:13 1.7
@@ -154,12 +154,23 @@
return new MobyDataSecondaryInstance(objectTag);
}
// Must otherwise be a composite
- else{
+ else{
return new MobyDataComposite(objectTag);
}
}
/**
+ * Please note that you almost never want to call this method in a client.
+ * The articleName of a MOBY Ontology object is normally fully determined
+ * by either the parameter name in the service being called (MobyContentInstance
+ * handles this), or the member field name when included as part of a composite object
+ * (MobyDataComposite handles this).
+ */
+ public void setName(String name){
+ super.setName(name);
+ }
+
+ /**
* Similar to DOM level 3 getTextContent, but only elements are excepted as input, and text
* inside children elements is not picked up.
* Actually calls MobyObjectDecompositionImpl.getTextContent()
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataObjectSet.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/shared/data/MobyDataObjectSet.java 2005/07/22 05:11:54 1.3
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataObjectSet.java 2005/08/20 01:58:13 1.4
@@ -28,7 +28,12 @@
private int xmlMode = MobyDataInstance.SERVICE_XML_MODE;
public MobyDataObjectSet(org.w3c.dom.Element e) throws MobyException{
- this(MobyDataObject.getName(e), getChildren(e));
+ this(MobyDataObject.getName(e), getChildren(e));
+
+ if(getName() == null){
+ throw new MobyException("Anonymous collections are not allowed (need articleName), input was :\n" + e);
+ }
+
}
public static Collection getChildren(org.w3c.dom.Element e) throws MobyException{
@@ -98,7 +103,14 @@
bag.add(values[i]);
}
}
-
+
+ /**
+ * @return a Vector with the MobyDataObjects
+ */
+ public Object getObject(){
+ return bag;
+ }
+
/**
* @return the MobyDataObjects that comprise the collection
*/
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataSecondaryInstance.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataSecondaryInstance.java 2005/08/15 17:41:41 1.4
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataSecondaryInstance.java 2005/08/20 01:58:13 1.5
@@ -40,6 +40,14 @@
public MobyDataSecondaryInstance(Element objectTag) throws MobyException{
// What is the parameter name?
super(MobyDataObject.getName(objectTag));
+
+ if(getName() == null){
+ throw new MobyException("Anonymous secondary parameters are not allowed (need articleName), input was :\n" +
+ objectTag);
+ }
+ if(getName().length() == 0){
+ throw new MobyException("Secondary parameters with blank articleNames are not allowed, input was: " + objectTag);
+ }
setDataType("String");
if(objectTag == null){
===================================================================
RCS file: /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataUtils.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataUtils.java 2005/07/22 05:11:54 1.1
+++ /home/repository/moby/moby-live/Java/src/main/org/biomoby/shared/data/MobyDataUtils.java 2005/08/20 01:58:13 1.2
@@ -1,5 +1,6 @@
package org.biomoby.shared.data;
+import org.biomoby.shared.MobyPrefixResolver;
import org.biomoby.shared.*;
import org.w3c.dom.*;
import java.io.*;
@@ -14,14 +15,14 @@
public static boolean toXMLDocument(OutputStream os, MobyContentInstance mci) throws Exception{
// May want to check character encoding before doing getBytes(), implement this later
os.write("<?xml version=\"1.0\"?>\n".getBytes());
- os.write("<moby:MOBY>\n".getBytes());
+ os.write(("<moby:MOBY xmlns:moby=\"" + MobyPrefixResolver.MOBY_XML_NAMESPACE + "\">\n").getBytes());
os.write(mci.toXML().getBytes());
os.write("\n</moby:MOBY>".getBytes());
return true;
}
-
+
public static MobyContentInstance fromXMLDocument(InputStream is) throws Exception{
-
+
// Load an XML document
javax.xml.parsers.DocumentBuilder docBuilder = null;
try{
More information about the MOBY-guts
mailing list