package au.com.langdale.kena;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import au.com.langdale.kena.filters.ListIterator;
import au.com.langdale.kena.filters.ListResourceIterator;
import au.com.langdale.kena.filters.ObjectsExcluding;
import au.com.langdale.kena.filters.SubjectsExcluding;
import au.com.langdale.kena.filters.TransitiveIterator;
import au.com.langdale.kena.filters.Wrapper;
import com.hp.hpl.jena.graph.FrontsNode;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.vocabulary.OWL2;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.vocabulary.ReasonerVocabulary;
public class OntResource extends Resource {
protected final OntModel model;
OntResource(Node node, OntModel model) {
super( node );
this.model = model;
}
public OntModel getOntModel() {
return model;
}
public OntResource inModel(OntModel model) {
if( this.model == model)
return this;
return new OntResource(node, model);
}
public boolean isList() {
return isEmpty() || (hasProperty(RDF.first) && hasProperty(RDF.rest));
}
public boolean isEmpty() {
return node.equals(RDF.nil.asNode());
}
public NodeIterator listElements() {
return new ListIterator(this);
}
public Node[] toElementArray() {
ArrayList buffer = new ArrayList();
NodeIterator it = listElements();
while( it.hasNext()) {
buffer.add(it.next());
}
Node[] result = new Node[buffer.size()];
for(int ix = 0; ix < result.length; ix ++) {
result[ix] = (Node) buffer.get(ix);
}
return result;
}
public ResIterator listResourceElements() {
return new Wrapper( model, new ListResourceIterator(this));
}
public OntResource getFirstResource() {
return getResource(RDF.first);
}
public Node getFirst() {
return getNode(RDF.first);
}
public OntResource getRest() {
return getResource(RDF.rest);
}
public boolean contains(FrontsNode element) {
return contains(element.asNode());
}
public boolean contains(Node element) {
for (NodeIterator it = listElements(); it.hasNext();) {
if( element.equals(it.nextNode()))
return true;
}
return false;
}
public String describe() {
StringBuilder sb = new StringBuilder();
sb.append(node);
Iterator it = model.getGraph().find(node, Node.ANY, Node.ANY);
if( it.hasNext()) {
do {
Triple t = (Triple) it.next();
sb.append("\n ");
sb.append(t.getPredicate());
sb.append(" = ");
sb.append( t.getObject());
} while( it.hasNext());
}
else {
sb.append(" has no properties.");
}
return sb.toString();
}
public boolean isClass() {
return hasRDFType(OWL2.Class) || hasRDFType(OWL2.Restriction);
}
public boolean isProperty() {
return hasRDFType(RDF.Property)
|| hasRDFType(OWL2.ObjectProperty)
|| hasRDFType(OWL2.DatatypeProperty)
|| hasRDFType(OWL2.AnnotationProperty)
|| hasRDFType(OWL2.OntologyProperty);
}
public boolean isObjectProperty() {
return hasRDFType(OWL2.ObjectProperty);
}
public boolean isDatatypeProperty() {
return hasRDFType(OWL2.DatatypeProperty);
}
public boolean isDatatype() {
return hasRDFType(RDFS.Datatype);
}
public boolean isFunctionalProperty() {
return hasRDFType(OWL2.FunctionalProperty);
}
public boolean isInverseFunctionalProperty() {
return hasRDFType(OWL2.InverseFunctionalProperty);
}
public boolean isRestriction() {
return hasRDFType(OWL2.Restriction);
}
public boolean isAllValuesFromRestriction() {
return hasProperty(OWL2.allValuesFrom);
}
public boolean isSomeValuesFromRestriction() {
return hasProperty(OWL2.someValuesFrom);
}
public boolean isCardinalityRestriction() {
return hasProperty(OWL2.cardinality);
}
public boolean isMaxCardinalityRestriction() {
return hasProperty(OWL2.maxCardinality);
}
public boolean isMinCardinalityRestriction() {
return hasProperty(OWL2.minCardinality);
}
public OntResource getOnProperty() {
return getResource(OWL2.onProperty);
}
public OntResource getSomeValuesFrom() {
return getResource(OWL2.someValuesFrom);
}
public OntResource getAllValuesFrom() {
return getResource(OWL2.allValuesFrom);
}
public int getCardinality() {
return getInteger(OWL2.cardinality).intValue();
}
public int getMaxCardinality() {
return getInteger(OWL2.maxCardinality).intValue();
}
public int getMinCardinality() {
return getInteger(OWL2.minCardinality).intValue();
}
public OntResource getIsDefinedBy() {
return getResource(RDFS.isDefinedBy);
}
public OntResource getInverseOf() {
return getResource(OWL2.inverseOf);
}
public OntResource getInverse() {
return getSubject(OWL2.inverseOf);
}
public void addProperty(FrontsNode prop, Node value) {
model.add(this, prop, value);
}
public void addProperty(FrontsNode prop, FrontsNode value) {
model.add(this, prop, value);
}
public void addProperty(FrontsNode prop, String value) {
model.add(this, prop, value);
}
public void setProperty(FrontsNode prop, String value, String lang) {
model.remove(this, prop);
model.add(this, prop, value, lang);
}
public void setProperty(FrontsNode prop, FrontsNode value) {
model.remove(this, prop);
model.add(this, prop, value);
}
public void setProperty(FrontsNode prop, Node value) {
model.remove(this, prop);
model.add(this, prop, value);
}
public OntResource cons(FrontsNode element) {
return cons(element.asNode());
}
public OntResource cons(Node element) {
OntResource cell = model.createResource();
cell.addProperty(RDF.first, element);
cell.addProperty(RDF.rest, this);
return cell;
}
public void removeList() {
OntResource cell = this;
while( cell != null && ! cell.isEmpty()) {
OntResource old = cell;
cell = cell.getRest();
old.remove();
}
}
public OntResource remove(Node element) {
LinkedList stack = new LinkedList();
OntResource cell = this;
while( cell != null && ! cell.isEmpty()) {
Node cand = cell.getFirst();
OntResource old = cell;
cell = cell.getRest();
old.remove();
if(element.equals(cand))
break;
if(cand != null)
stack.add(cand);
}
if( cell == null )
cell = model.createList();
while( stack.size() > 0 ) {
cell = cell.cons((Node)stack.remove(stack.size()-1));
}
return cell;
}
public void removeRecursive() {
ResIterator it = new TransitiveIterator(this) {
@Override
protected ResIterator traverse(OntResource subject) {
return model.listUnnamedObjects(subject);
}
};
Iterator jt = it.toSet().iterator();
while( jt.hasNext()) {
OntResource obj = (OntResource) jt.next();
obj.removeProperties();
}
remove();
}
public OntResource remove(FrontsNode element) {
return remove(element.asNode());
}
public void addProperty(FrontsNode prop, String value, String lang) {
model.add(this, prop, value, lang);
}
public void addComment(String value, String lang) {
model.add(this, RDFS.comment, value, lang);
}
public void setComment(String value, String lang) {
setProperty(RDFS.comment, value, lang);
}
public String getComment() {
return getString(RDFS.comment);
}
public String getComment(String lang) {
return getString(RDFS.comment, lang);
}
public void addLabel(String value, String lang) {
model.add(this, RDFS.label, value, lang);
}
public void setLabel(String value, String lang) {
setProperty(RDFS.label, value, lang);
}
public String getLabel() {
return getString(RDFS.label);
}
public String getLabel(String lang) {
return getString(RDFS.label, lang);
}
public void addIsDefinedBy(FrontsNode value) {
model.add(this, RDFS.isDefinedBy, value);
}
public void addDomain(FrontsNode value) {
model.add(this, RDFS.domain, value);
}
public OntResource getDomain() {
return getResource(RDFS.domain);
}
public OntResource getSameAs() {
return getResource(OWL2.sameAs);
}
public OntResource getEquivalentClass() {
return getResource(OWL2.equivalentClass);
}
public void addRange(FrontsNode value) {
model.add(this, RDFS.range, value);
}
public OntResource getRange() {
return getResource(RDFS.range);
}
public void addSubClass(FrontsNode value) {
model.add(value, RDFS.subClassOf, this);
}
public void addSuperClass(FrontsNode value) {
model.add(this, RDFS.subClassOf, value);
}
public void addInverseOf(FrontsNode value) {
model.add(this, OWL2.inverseOf, value);
}
public void setOnProperty(FrontsNode prop) {
setProperty(OWL2.onProperty, prop);
}
public void addRDFType(FrontsNode type) {
model.add(this, RDF.type, type);
}
public void convertToFunctionalProperty() {
addRDFType(OWL2.FunctionalProperty);
}
public void convertToInverseFunctionalProperty() {
addRDFType(OWL2.InverseFunctionalProperty);
}
public void convertToDatatypeProperty() {
addRDFType(OWL2.DatatypeProperty);
}
public void removeSubClass(FrontsNode value) {
model.remove(value, RDFS.subClassOf, this);
}
public void removeSuperClass(FrontsNode value) {
model.remove(this, RDFS.subClassOf, value);
}
public void remove() {
model.removeSubject(this);
model.removeObject(this);
}
public void removeProperties() {
model.removeSubject(this);
}
public void removeProperty(FrontsNode prop, Node value) {
model.remove(this, prop, value);
}
public void removeProperty(FrontsNode prop, FrontsNode value) {
model.remove(this, prop, value);
}
public void removeAll(FrontsNode prop) {
model.remove(this, prop);
}
public OntResource getResource(FrontsNode prop) {
ResIterator it = model.listResourceObjectsOfProperty(this, prop);
if( it.hasNext())
return it.nextResource();
else
return null;
}
public Node getNode(FrontsNode prop) {
NodeIterator it = model.listObjectsOfProperty(this, prop);
if( it.hasNext())
return it.nextNode();
else
return null;
}
public String getString(FrontsNode prop) {
NodeIterator it = model.listLiteralObjectsOfProperty(this, prop);
if( it.hasNext())
return it.nextNode().getLiteralLexicalForm();
else
return null;
}
public String getString(FrontsNode prop, String lang) {
NodeIterator it = model.listLiteralObjectsOfProperty(this, prop);
while( it.hasNext()) {
Node value = it.nextNode();
if( lang == null || value.getLiteralLanguage().equals(lang))
return value.getLiteralLexicalForm();
}
return null;
}
public boolean hasProperty(FrontsNode prop, FrontsNode value) {
return model.contains(this, prop, value);
}
public boolean hasProperty(FrontsNode prop) {
return model.contains(this, prop, Node.ANY);
}
public ResIterator listProperties(FrontsNode prop) {
return model.listResourceObjectsOfProperty(this, prop);
}
public NodeIterator listObjects(FrontsNode prop) {
return model.listObjectsOfProperty(this, prop);
}
public NodeIterator listLiteralProperties(FrontsNode prop) {
return model.listLiteralObjectsOfProperty(this, prop);
}
public ResIterator listRDFTypes(boolean direct) {
assert ! direct;
return model.listResourceObjectsOfProperty(this, RDF.type);
}
public ResIterator listIsDefinedBy() {
return model.listResourceObjectsOfProperty(this, RDFS.isDefinedBy);
}
public boolean hasRDFType(FrontsNode type) {
return model.contains(this, RDF.type, type);
}
public boolean hasRDFType() {
return model.contains(this, RDF.type);
}
public boolean hasSuperClass(FrontsNode type, boolean direct) {
if(direct)
return !node.equals(type.asNode()) && hasProperty(ReasonerVocabulary.directSubClassOf, type);
else
return hasProperty(RDFS.subClassOf, type);
}
public boolean hasSubClass(FrontsNode type, boolean direct) {
if(direct)
return !node.equals(type.asNode()) && model.contains(type, ReasonerVocabulary.directSubClassOf, this);
else
return model.contains(type, RDFS.subClassOf, this);
}
public boolean hasSuperClass( FrontsNode cls ) {
return hasSuperClass( cls, false );
}
public boolean hasSubClass( FrontsNode cls ) {
return hasSubClass( cls, false );
}
public ResIterator listSuperClasses(boolean direct) {
if(direct)
return listDirectObjects(ReasonerVocabulary.directSubClassOf);
else
return model.listResourceObjectsOfProperty(this, RDFS.subClassOf);
}
private ResIterator listDirectObjects(FrontsNode prop) {
return new Wrapper(model, new ObjectsExcluding(node, model.getGraph().find(node, prop.asNode(), Node.ANY)));
}
public ResIterator listSubClasses(boolean direct) {
if(direct)
return listDirectSubjects(ReasonerVocabulary.directSubClassOf);
else
return model.listSubjectsWithProperty(RDFS.subClassOf, this);
}
private ResIterator listDirectSubjects(Property prop) {
return new Wrapper( model, new SubjectsExcluding(node, model.getGraph().find(Node.ANY, prop.asNode(), node)));
}
public ResIterator listInstances() {
return model.listIndividuals(this);
}
public void addProperty(FrontsNode prop, int value) {
model.add(this, prop, value);
}
public void setProperty(FrontsNode prop, int value) {
model.remove(this, prop);
model.add(this, prop, value);
}
public OntResource getSubject(FrontsNode prop) {
ResIterator it = model.listSubjectsWithProperty(prop, this);
if( it.hasNext())
return it.nextResource();
else
return null;
}
public Integer getInteger(FrontsNode prop) {
NodeIterator it = model.listLiteralObjectsOfProperty(this, prop);
while( it.hasNext()) {
Object result = it.nextNode().getLiteralValue();
if( result instanceof Integer)
return (Integer) result;
}
return null;
}
public boolean isEnumeratedClass() {
return hasProperty(OWL2.oneOf);
}
public OntResource getOneOf() {
return getResource(OWL2.oneOf);
}
public void setOneOf(OntResource list) {
setProperty(OWL2.oneOf, list);
}
public OntResource getWithRestrictions() {
return getResource(OWL2.withRestrictions);
}
public void setWithRestrictions(OntResource list) {
setProperty(OWL2.withRestrictions, list);
}
}