📄 umlmodel.java
字号:
package edu.stanford.db.rdf.uml;import org.w3c.rdf.model.*;import org.w3c.rdf.implementation.model.NodeFactoryImpl;import org.w3c.rdf.util.*;import java.util.*;import org.w3c.rdf.vocabulary.rdf_syntax_19990222.RDF;import org.w3c.rdf.vocabulary.rdf_schema_19990303.RDFS;import edu.stanford.db.rdf.uml.vocabulary.uml_core_20000422.UMLCore;import edu.stanford.db.rdf.uml.vocabulary.uml_datatypes_20000507.DataTypes;import edu.stanford.db.rdf.schema.InvalidModelException;import edu.stanford.db.rdf.schema.RDFSchemaModel;/** * A UML model supports inverse properties and generalization and validates UML schemas. * For example, the following sets of objects/subjects are equivalent: * <p><tt>find(X, UMLCore.Feature_owner, null)</tt> or * <p><tt>find(null, UMLCore.Classifier_feature, X)</tt> * <p>To determine whether X is a class, one can use: * <p><tt>find(X, RDF.type, UMLCore.Class)</tt> * Validation supports typing and cardinality constraints. Currently, we do not check * for ordered relationships. */public class UMLModel implements VirtualModel { NodeFactory nodeFactory; Model instances, schema; Hashtable inverse; // may be shared between different UMLModels private UMLModel(NodeFactory f, Hashtable inverse) { this.inverse = inverse; this.nodeFactory = f; } public UMLModel(NodeFactory f) { this(f, new Hashtable()); } public UMLModel() { this(new NodeFactoryImpl()); } public UMLModel(Model instances, Model schema) { this(); this.instances = instances; this.schema = schema; } public UMLModel(NodeFactory f, Model instances, Model schema) { this(f); this.instances = instances; this.schema = schema; } private UMLModel(NodeFactory f, Model instances, Model schema, Hashtable inverse) { this(f, inverse); this.instances = instances; this.schema = schema; } /** returns "A subClassOf B" instead of "R parent A & R child B" * schema should be UMLModel (must not if generalization and specialization are not used) */ public static Model getRDFSClassHierarchy(Model m) throws ModelException { Model res = m.create(); NodeFactory nodeFactory = m.getNodeFactory(); // find all generalizations Model gen = m.find(null, RDF.type, UMLCore.Generalization); // System.err.println("Generalizations in the schema: " + gen.size()); for(Enumeration en = gen.elements(); en.hasMoreElements();) { Resource g = ((Statement)en.nextElement()).subject(); // find parent and child using UMLModel (i.e. inverse relationships would work, too) Resource parent = RDFUtil.getObjectResource(m, g, UMLCore.Generalization_parent); Resource child = RDFUtil.getObjectResource(m, g, UMLCore.Generalization_child); if(parent == null) throw new InvalidModelException("[UMLModel] no parent in Generalization " + g); else if(child == null) throw new InvalidModelException("[UMLModel] no child in Generalization " + g); else { // System.out.println("SUBCLASSOF: " + child + " --> " + parent); res.add(nodeFactory.createStatement(child, RDFS.subClassOf, parent)); } } return res; } // precondition: inverse is an empty Hashtable private Hashtable getInverse() throws ModelException { synchronized(inverse) { if(inverse.isEmpty()) inverse = computeInverse(schema); return inverse; } } /** Computes hashtable containing the names of the inverse relationships */ public static Hashtable computeInverse(Model schema) throws ModelException { Hashtable inverse = new Hashtable(); Model ass = schema.find(null, RDF.type, UMLCore.Association); // System.err.println("Associations in the schema " + this + ": " + ass.size()); // new Exception().printStackTrace(System.err); for(Enumeration en = ass.elements(); en.hasMoreElements();) { Resource a = ((Statement)en.nextElement()).subject(); Model seq = schema.find(a, UMLCore.Association_connection, null); if(seq.size() != 2) throw new InvalidModelException("[UMLModel] cardinality violation: " + seq.size() + " instead of 2 objects for property " + UMLCore.Association_connection + " found for " + a); // FIXME: order is not really needed here... Otherwise could use org.w3c.rdf.util.OrderUtil Enumeration seqEn = seq.elements(); Resource first = (Resource)((Statement)seqEn.nextElement()).object(); Resource second = (Resource)((Statement)seqEn.nextElement()).object(); // System.out.println("INVERSE: " + first + " <--> " + second); inverse.put(first, second); inverse.put(second, first); /* if(seq != null) { Resource first = RDFUtil.getObjectResource(schema, seq, schema.getNodeFactory().createOrdinal(1)); Resource second = RDFUtil.getObjectResource(schema, seq, schema.getNodeFactory().createOrdinal(2)); if(first == null) throw new InvalidModelException("[UMLModel] no first element from " + seq); else if(second == null) throw new InvalidModelException("[UMLModel] no second element from " + seq); else { inverse.put(first, second); inverse.put(second, first); } } else throw new InvalidModelException("[UMLModel] no Association.connection from " + a); */ } // System.err.println("Total inverse elements: " + inverse.size() / 2); return inverse; } public String getLabel() throws ModelException { return instances.getLabel(); } public String getURI() throws ModelException { return instances.getURI(); } public String getLocalName() throws ModelException { return instances.getLocalName(); } public String getNamespace() throws ModelException { return instances.getNamespace(); } /** * @return model contains the fact basis of this model */ public Model getGroundModel() throws ModelException { return instances; } /** * Set a base URI for the model. * Affects creating of new resources and serialization syntax. * Inherited method getURI returns the URI set in this method */ public void setSourceURI(String uri) throws ModelException { instances.setSourceURI(uri); } /** * Returns current base URI setting. */ public String getSourceURI() throws ModelException { return instances.getSourceURI(); } // Model access /** * Number of triples in the model * * @return number of triples, -1 if unknown * * @seeAlso org.w3c.rdf.model.VirtualModel */ public int size() throws ModelException { return -1; } /** * true if the model contains no triples */ public boolean isEmpty() throws ModelException { return instances.isEmpty(); } /** * Enumerate triples */ public Enumeration elements() throws ModelException { return find(null, null, null).elements(); } /** * Tests if the model contains the given triple. * * @return <code>true</code> if the triple belongs to the model; * <code>false</code> otherwise. */ public boolean contains(Statement t) throws ModelException { // FIXME: efficiency? return !find(t.subject(), t.predicate(), t.object()).isEmpty(); } // Model manipulation: add, remove, find /** * Adds a new triple to the model. */ public void add(Statement t) throws ModelException { instances.add(t); } /** * Removes the triple from the model. */ public void remove(Statement t) throws ModelException { instances.remove(t); } public boolean isMutable() throws ModelException { return instances.isMutable(); } /** * General method to search for triples. */ public Model find( Resource subject, Resource predicate, RDFNode object ) throws ModelException { getInverse(); // we need it anyway Model res = instances.find(subject, predicate, object); Model derived = res.create(); if(predicate != null) { collectInverse(derived, subject, predicate, object); } else { // go through all found triples and add reversed one for(Enumeration en = res.elements(); en.hasMoreElements();) { Statement s = (Statement)en.nextElement(); Resource inv = (Resource)inverse.get(s.predicate()); if(inv != null && s.object() instanceof Resource) derived.add(nodeFactory.createStatement((Resource)s.object(), inv, s.subject())); } } SetOperations.unite(res, derived); return res; } private void collectInverse(Model res, Resource subject, Resource predicate, RDFNode object) throws ModelException { // check inverse relationships Resource inv = (Resource)inverse.get(predicate); if(inv != null) { Model res2 = instances.find((Resource)object, inv, subject); for(Enumeration en = res2.elements(); en.hasMoreElements();) { Statement s = (Statement)en.nextElement(); if(s.object() instanceof Resource) res.add(nodeFactory.createStatement((Resource)s.object(), predicate, s.subject())); } } // System.out.println("COLLECTING inverse for " + subject + " " + predicate + " " + object + ": " + res.size()); } /** * Search for a single triple. * <code>null</code> input for any parameter will match anything.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -