[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