[MOBY-guts] biomoby commit

Gary Schiltz gss at pub.open-bio.org
Wed Sep 14 22:06:11 UTC 2005


gss
Wed Sep 14 18:06:10 EDT 2005
Update of /home/repository/moby/moby-live/S-MOBY/ref-impl/core/src/org/semanticmoby/parser
In directory pub.open-bio.org:/tmp/cvs-serv17011/src/org/semanticmoby/parser

Modified Files:
	Parser.java 
Added Files:
	NamespaceBasedPropertyDetector.java MOBYPropertyDetector.java 
Log Message:
Major API overhaul

moby-live/S-MOBY/ref-impl/core/src/org/semanticmoby/parser NamespaceBasedPropertyDetector.java,NONE,1.1 MOBYPropertyDetector.java,NONE,1.1 Parser.java,1.2,1.3
===================================================================
RCS file: /home/repository/moby/moby-live/S-MOBY/ref-impl/core/src/org/semanticmoby/parser/Parser.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- /home/repository/moby/moby-live/S-MOBY/ref-impl/core/src/org/semanticmoby/parser/Parser.java	2005/03/21 21:32:38	1.2
+++ /home/repository/moby/moby-live/S-MOBY/ref-impl/core/src/org/semanticmoby/parser/Parser.java	2005/09/14 22:06:10	1.3
@@ -12,9 +12,9 @@
 import com.hp.hpl.jena.vocabulary.*;
 
 /**
- * This class is used to parse RDF models, stored as Jena2 models, into
- * objects that implement interfaces from the org.semanticmoby.graph
- * package.
+ * This class is used to parse RDF models, stored as Jena2 Model objects,
+ * into API wrapper objects that insulate the programmer from the details
+ * of RDF.
  */
 public class Parser
 {
@@ -28,6 +28,9 @@
      */
     public final static String LANGUAGE_N3 = "N3";
     
+    private MOBYPropertyDetector propDetector =
+        new NamespaceBasedPropertyDetector();
+    
     /**
      * Since models are stored in a single Jena model, we
      * segregate the single model into multiple sub-models,
@@ -35,12 +38,6 @@
      * plus all statements that are reachable from it.
      */
     private List subModels = new ArrayList();
-    
-    /**
-     * A map relating a property's URI to an Inference model derived from
-     * its base model
-     */
-    private Map cachedPropertyModels = new HashMap();
 
     /**
      * Create and return a parser for parsing an N3 file
@@ -130,7 +127,7 @@
      */
     public Parser(Model model)
     {
-    	StmtIterator it = model.listStatements(null, RDF.type, MOBY.Provider);
+    	StmtIterator it = model.listStatements(null, RDF.type, MOBY.Service);
         while (it.hasNext())
         {
         	Statement stmt = it.nextStatement();
@@ -143,84 +140,86 @@
     }
 
     /**
-     * Parse a provider from the model. If the model contains
-     * multiple providers, only one will be returned (at random). If
-     * the model is expected to contain multiple providers, then call
-     * parseProviders() instead to get all the providers in a
+     * Parse a MOBYService from the model. If the model contains multiple
+     * services, only one will be returned (at random), so if the model is
+     * expected to contain multiple services, then call parseServices() instead to get all the providers in a
      * MOBYCollection.
      */
-    public MOBYProvider parseProvider()
+    public MOBYService parseService()
+        throws NonCanonicalException
     {
-    	MOBYUnorderedCollection providers = parseProviders();
+    	List services = parseServices();
     	
-    	if (providers.size() == 0) {
+    	if (services.size() == 0) {
     		return null;
     	} else {
-    		return (MOBYProvider) providers.iterator().next();
+    		return (MOBYService) services.iterator().next();
     	}
     }
     
     /**
-     * Parse and return an unordered collection of providers
+     * Parse and return an list of MOBYService objects
      */
-    public MOBYUnorderedCollection parseProviders()
+    public List parseServices()
+        throws NonCanonicalException
     {
-        ArrayList providers = new ArrayList();
+        ArrayList services = new ArrayList();
         
-        // Parse each provider
-        //
         Iterator it = subModels.iterator();
         while (it.hasNext())
         {
         	Model model = (Model) it.next();
-        	StmtIterator it2 = model.listStatements(null, RDF.type, MOBY.Provider);
+        	StmtIterator it2 = model.listStatements(null, RDF.type, MOBY.Service);
         	
         	if (it2 != null)
         	{
         		Statement stmt = it2.nextStatement();
-	            Resource provider = stmt.getSubject();
-	            providers.add(parseProvider(provider));
+                services.add(parseService(stmt));
         	}
         }
-        
-        // Create and return an unordered collection of the parsed providers
-        //
-        return new MOBYUnorderedCollection(providers, null, null);
+        return services;
     }
     
     /**
-     * Parse a provider starting from the given resource (i.e. a resource that
-     * is the subject of an rdf:type statement with object of moby:Provider)
+     * Parse a service starting from the given resource (i.e. a resource that
+     * is the subject of an rdf:type statement with object of moby:Service)
      */
-    public MOBYProvider parseProvider(Resource provider)
+    public MOBYService parseService(Statement typeStmt)
+        throws NonCanonicalException
     {
-    	Model model = provider.getModel();
+        Resource headResource = typeStmt.getSubject();
+        
+    	Model model = headResource.getModel();
     	
-        // First parse the scalar properties name, oneLineDescription, and aboutURI
-        //
-        Statement nameStmt = model.getProperty(provider, MOBY.name);
-        Statement oneLineDescriptionStmt = model.getProperty(provider, MOBY.oneLineDescription);
-        Statement aboutURIStmt = model.getProperty(provider, MOBY.aboutURI);
+        // First parse the scalar properties
+        
+        Statement nameStmt =
+            model.getProperty(headResource, MOBY.name);
         
-        // A provider can have multiple operatesOn properties, each of
+        Statement oneLineDescriptionStmt =
+            model.getProperty(headResource, MOBY.oneLineDescription);
+        
+        Statement aboutURIStmt =
+            model.getProperty(headResource, MOBY.aboutURI);
+        
+        // A service can have multiple operatesOn properties, each of
         // which leads to a subgraph. Parse each of these subgraphs.
-        //
-        List operatesOn = new ArrayList();
-        StmtIterator it = model.listStatements(provider, MOBY.operatesOn, (RDFNode) null);
+        Map operatesOn = new HashMap();
+        StmtIterator it =
+            model.listStatements(headResource, MOBY.operatesOn, (RDFNode) null);
         while (it.hasNext())
         {
-            Statement stmt = it.nextStatement();
-            Resource r = (Resource) stmt.getObject();
-            operatesOn.add(parseOperatesOn(r));
+            Statement operatesOnStmt = it.nextStatement();
+            Resource r = (Resource) operatesOnStmt.getObject();
+            operatesOn.put(operatesOnStmt, parseOperatesOn(r));
         }
         
-        // Create and return a new Provider object using the provider URI, name,
+        // Create and return a new Service object using the service URI, name,
         // oneLineDescription, aboutURI, and collection of operatesOn subgraphs
         //
-        return new MOBYProvider(
-            provider, nameStmt, oneLineDescriptionStmt, aboutURIStmt,
-            new MOBYUnorderedCollection(operatesOn, provider, model),
-            model);
+        return new MOBYService(model, typeStmt, nameStmt,
+                               oneLineDescriptionStmt,
+                               aboutURIStmt, operatesOn);
     }
     
     /**
@@ -231,25 +230,48 @@
      * each element of the data structure should be a mapping subgraph.
      */
     private MOBYGraphNode parseOperatesOn(Resource res)
+        throws NonCanonicalException
     {
     	Model model = res.getModel();
     	
         if (isGraph(res))
         {
-            // The resource is a MOBY Graph, so should have exactly one
+            // Throw an exception if it is also a data structure
+            if (isDataStructure(res))
+            {
+                throw new NonCanonicalException(
+                    "A resource was found to be both a Graph " +
+                    "and Data Structure", model);
+            }
+            
+            // The defining statement for the MOBYGraph instance
+            Statement typeStmt = model.listStatements(
+                res, RDF.type, MOBY.Graph).nextStatement();
+            
+            // The statement that asserts the hasMapping property
+            Statement hasMappingStmt = model.listStatements(
+                res, MOBY.hasMapping, (RDFNode) null).nextStatement();
+            
+            // Since the resource is a MOBY Graph, it should have exactly one
             // hasMapping property that leads to its mapping subgraph.
-            //
             Resource hasMapping = getResourcePropertyValue(res, MOBY.hasMapping);
-            return new MOBYGraph(res, parseHasMapping(hasMapping), model);
+            return new MOBYGraph(model, typeStmt, hasMappingStmt,
+                                 parseHasMapping(hasMapping));
         }
         else
         {
+            // Throw an exception if it is also a graph
+            if (isGraph(res))
+            {
+                throw new NonCanonicalException(
+                    "A resource was found to be both a Graph " +
+                    "and Data Structure", model);
+            }
             // The resource is a data structure, so has multiple mapping
             // subgraphs, each of which is headed by an element in the
             // data structure. Iterate through the data structure elements,
             // parsing a mapping subgraph from each by recursively calling
             // this method.
-            //
             Iterator it = iteratorFor(res);
             List subgraphs = new ArrayList();
             while (it.hasNext())
@@ -260,7 +282,6 @@
             
             // Create and return a collection of the subgraphs; the type
             // of the collection depends on the type of the passed resource
-            //
             return collectionFor(res, subgraphs);
         }
     }
@@ -273,37 +294,52 @@
      * each element of the data structure should be a mapped subgraph.
      */
     private MOBYSubject parseHasMapping(Resource res)
+        throws NonCanonicalException
     {
-    	Model model = res.getModel();
-    	
-        // Collect the properties of this subject resource that are
-        // subproperties of moby:Property, and create MOBY statements
-        // for each.
-        //
-        List statements = mobyPropertyStatementsOf(res);
+        Model model = res.getModel();
+        
+        // It is *not* legal for the object of a hasMapping to be *neither*
+        // a Subject nor a data structure, so throw an exception if this is
+        // the case.
+        if ((! isSubject(res)) && (! isDataStructure(res)))
+        {
+            throw new NonCanonicalException(
+                "A hasMapping property was found to have a value that " +
+                "is neither a Subject nor a data structure", model);
+        }
+
+        // Collect the properties of this subject that are
+        // meant to be filled in by the client
+        List propValStmts = mobyPropertyStatementsOf(res);
         
         // List of direct mappings, i.e. those related through hasMapping
         // properties.
-        //
-        List directMappings = new ArrayList();
+        Map directMappings = new HashMap();
         
         // List of nested hasMapping subgraphs
-        //
         List nestedMappings = new ArrayList();
         
+        // The statement that asserts this to be of rdf:type moby:Subject.
+        // Since it is legal for this to not be a Subject, then the statement
+        // can be null
+        Statement typeStmt = null;
+        
         if (isSubject(res))
         {
+            typeStmt = model.listStatements(
+                res, RDF.type, MOBY.Subject).nextStatement();
+            
             // The resource is a MOBY Subject, so should have one or more
             // mapsTo properties that lead to its mapped subgraphs.
-            //
             List mapsTo = new ArrayList();
-            StmtIterator it = model.listStatements(res, MOBY.mapsTo, (RDFNode) null);
+            StmtIterator it =
+                model.listStatements(res, MOBY.mapsTo, (RDFNode) null);
             while (it.hasNext())
             {
-                Statement stmt = it.nextStatement();
-                Resource mapsToSubject = stmt.getResource();
+                Statement mapsToStmt = it.nextStatement();
+                Resource mapsToSubject = mapsToStmt.getResource();
                 MOBYGraphNode object = parseMapsTo(mapsToSubject);
-                directMappings.add(object);
+                directMappings.put(object, mapsToStmt);
             }
         }
         
@@ -313,7 +349,6 @@
             // nested in each element. For each element in the data structure,
             // recursively call this method to create a mapping subgraph, an
             // save the parsed object in the nestedMappings list.
-            //
             Iterator it = iteratorFor(res);
             while (it.hasNext())
             {
@@ -322,13 +357,66 @@
             }
         }
         
-        // Create and return a Subject to describe this hasMapping subgraph
-        //
-        return new MOBYSubject(res,
-            new MOBYFixedCollection(statements, res, model),
-            new MOBYUnorderedCollection(directMappings, res, model),
-            collectionFor(res, nestedMappings),
-            model);
+        return new MOBYSubject(model, typeStmt, propValStmts, directMappings,
+                               collectionFor(res, nestedMappings));
+    }
+    
+    /**
+     * Parse the object of an mapsTo statement, which should be a
+     * Subject, a data structure, or both. If the object is a Subject,
+     * then it should be connected to one or more mapped subgraphs through
+     * mapsTo properties. If the object is a data structure, then
+     * each element of the data structure should be a mapped subgraph.
+     */
+    private MOBYObject parseMapsTo(Resource res)
+        throws NonCanonicalException
+    {
+        Model model = res.getModel();
+        
+        // It is *not* legal for the object of a mapsTo to be *neither*
+        // an Object nor a data structure, so throw an exception if this is
+        // the case.
+        if ((! isObject(res)) && (! isDataStructure(res)))
+        {
+            throw new NonCanonicalException(
+                "A mapsTo property was found to have a value " +
+                "is neither an Object nor a data structure", model);
+        }
+
+        // Collect the properties of this subject that are
+        // meant to be filled in by the client
+        List propValStmts = mobyPropertyStatementsOf(res);
+        
+        // List of nested Object subgraphs
+        List nestedObjects = new ArrayList();
+        
+        // The statement that asserts this to be of rdf:type moby:Object.
+        // Since it is legal for this to not be an Object, then the statement
+        // can be null
+        Statement typeStmt = null;
+        
+        if (isObject(res))
+        {
+            typeStmt = model.listStatements(
+                res, RDF.type, MOBY.Object).nextStatement();
+        }
+        
+        if (isDataStructure(res))
+        {
+            // The resource is a data structure, so has a mapping subgraph
+            // nested in each element. For each element in the data structure,
+            // recursively call this method to create a mapping subgraph, an
+            // save the parsed object in the nestedMappings list.
+            Iterator it = iteratorFor(res);
+            while (it.hasNext())
+            {
+                Resource r = (Resource) it.next(); 
+                nestedObjects.add(parseMapsTo(r));
+            }
+        }
+        
+        return new MOBYObject(model, typeStmt, propValStmts,
+                              collectionFor(res, nestedObjects));
     }
 
     
@@ -336,14 +424,15 @@
      * Parse the object of a mapsTo statement, which should be an
      * Object, a data structure, or both. If the object is a data
      * structure, then each element of the data structure should
-     * be a mapped subgraph.
+     * in turn be an Object, a data structure, or both.
      */
+    /*
     private MOBYObject parseMapsTo(Resource res)
     {
-        // Collect the properties of this subject resource that are
-        // subproperties of moby:Property, and create MOBY statements
-        // for each.
-        //
+        Model model = res.getModel();
+        
+        // Collect the properties of this object that are
+        // meant to be filled in by the service
         List statements = mobyPropertyStatementsOf(res);
         
         // List of nested mapsTo statements
@@ -364,14 +453,11 @@
                 nested.add(parseMapsTo(r));
             }
         }
-        
-        // Create and return a new MOBYObject
-        //
-        Model model = res.getModel();
         return new MOBYObject(res,
             new MOBYFixedCollection(statements, res, model),
             collectionFor(res, nested), model);
     }
+    */
     
     /**
      * Return a list of statements for whom the subject is a given resource,
@@ -381,86 +467,22 @@
     private List mobyPropertyStatementsOf(Resource res)
     {
     	// The statements to return
-    	//
         List stmts = new ArrayList();
         
         // Iterate over the statements whose subjects are the resource
-        //
         StmtIterator it = res.listProperties();
         while (it.hasNext())
         {
             Statement stmt = it.nextStatement();
-            Property p = stmt.getPredicate();
-            RDFNode pval = stmt.getObject();
-            
-            // Try to retrieve a description of the property at
-            // its URI.
-            //
-            InfModel model = getPropertyModel(p);
-            
-            if (isMobyProperty(p, model))
+            if (stmt.getObject().isAnon() &&
+                !propDetector.isMOBYProperty(stmt.getPredicate()))
             {
-                MOBYPropertyValueStatement pvalStmt =
-                    new MOBYPropertyValueStatement(stmt, model);
-                
-                Statement s = p.getProperty(RDFS.range);
-                
-                if ((s != null) && (s.getObject().canAs(Resource.class)))
-                {
-                    Resource range = (Resource) s.getObject();
-                    if (range.equals(XSD.date)) {
-                        pvalStmt.setConstraint(new MOBYDateConstraint());
-                    } else if (range.equals(XSD.integer)) {
-                        pvalStmt.setConstraint(new MOBYIntegerConstraint());
-                    } else if (range.equals(XSD.nonNegativeInteger)) {
-                        pvalStmt.setConstraint(
-                            new MOBYNonNegativeIntegerConstraint());
-                    } else if (range.equals(XSD.nonPositiveInteger)) {
-                        pvalStmt.setConstraint(
-                            new MOBYNonPositiveIntegerConstraint());
-                    }
-                }
-                
-                stmts.add(pvalStmt);
+                stmts.add(stmt);
             }
         }
         return stmts;
     }
     
-    /**
-     * Get the model describing a given property by doing a GET
-     * on its URI, and creating an inference model from it.
-     */
-    private InfModel getPropertyModel(Property p)
-    {
-    	InfModel cachedModel = (InfModel)
-			cachedPropertyModels.get(p.getURI());
-    	
-    	if (cachedModel == null)
-    	{
-	    	Model model = ModelRetriever.retrieveModel(p.getURI());
-	    	
-	    	if (model != null)
-	    	{
-	    		cachedModel = ModelFactory.createRDFSModel(model);
-	    		cachedPropertyModels.put(p.getURI(), cachedModel);
-	    	}
-    	}
-    	return cachedModel;
-    }
-    
-    /**
-     * Return whether or not the given property is a MOBY property.
-     * This will be true if there is a statement in the model saying
-     * that the property is an rdfs:subPropertyOf moby:Property.
-     */
-    private boolean isMobyProperty(Property p, InfModel model)
-    {
-    	return
-		    model != null &&
-			model.contains(p, RDFS.subPropertyOf, MOBY.Property);
-    }
-    
     private Resource getResourcePropertyValue(Resource subject, Property property)
     {
         Statement s = subject.getModel().getProperty(subject, property);
@@ -490,21 +512,31 @@
      * an RDF:Seq yields a MOBYOrderedCollection; an RDF Alt yields a
      * MOBYEnumeration.
      */
-    private MOBYCollection collectionFor(Resource res, List elements)
+    private MOBYCollection collectionFor(Resource res, List items)
     {
+        Model model = res.getModel();
         if (isList(res)) {
-            return new MOBYFixedCollection(elements, res, res.getModel());
+            return new MOBYFixedCollection(
+                model, typeStatement(res, RDF.List), items);
         } else if (isBag(res)) {
-            return new MOBYUnorderedCollection(elements, res, res.getModel());
+            return new MOBYUnorderedCollection(
+                    model, typeStatement(res, RDF.Bag), items);
         } else if (isSeq(res)) {
-            return new MOBYOrderedCollection(elements, res, res.getModel());
+            return new MOBYOrderedCollection(
+                    model, typeStatement(res, RDF.Seq), items);
         } else if (isAlt(res)) {
-            return new MOBYEnumeration(elements, res, res.getModel());
+            return new MOBYEnumeration(
+                    model, typeStatement(res, RDF.Alt), items);
         } else {
             return null;
         }
     }
     
+    private Statement typeStatement(Resource subject, Resource objectType) {
+        return subject.getModel().listStatements(
+            subject, RDF.type, objectType).nextStatement();
+    }
+    
     /**
      * Return whether or not the given resource is an RDF List
      */




More information about the MOBY-guts mailing list