package org.mindswap.swoop.renderer.ontology; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.apache.log4j.Logger; import org.semanticweb.owl.model.OWLAnd; import org.semanticweb.owl.model.OWLDataCardinalityRestriction; import org.semanticweb.owl.model.OWLDataEnumeration; import org.semanticweb.owl.model.OWLDataPropertyInstance; import org.semanticweb.owl.model.OWLDataPropertyRangeAxiom; import org.semanticweb.owl.model.OWLDataValueRestriction; import org.semanticweb.owl.model.OWLDescription; import org.semanticweb.owl.model.OWLEnumeration; import org.semanticweb.owl.model.OWLException; import org.semanticweb.owl.model.OWLFunctionalPropertyAxiom; import org.semanticweb.owl.model.OWLIndividualTypeAssertion; import org.semanticweb.owl.model.OWLInverseFunctionalPropertyAxiom; import org.semanticweb.owl.model.OWLInversePropertyAxiom; import org.semanticweb.owl.model.OWLNot; import org.semanticweb.owl.model.OWLObject; import org.semanticweb.owl.model.OWLObjectAllRestriction; import org.semanticweb.owl.model.OWLObjectCardinalityRestriction; import org.semanticweb.owl.model.OWLObjectPropertyInstance; import org.semanticweb.owl.model.OWLObjectPropertyRangeAxiom; import org.semanticweb.owl.model.OWLObjectSomeRestriction; import org.semanticweb.owl.model.OWLObjectValueRestriction; import org.semanticweb.owl.model.OWLOr; import org.semanticweb.owl.model.OWLPropertyDomainAxiom; import org.semanticweb.owl.model.OWLSymmetricPropertyAxiom; import org.semanticweb.owl.model.OWLTransitivePropertyAxiom; import org.semanticweb.owl.model.helper.OWLObjectVisitorAdapter; import org.semanticweb.owl.validation.OWLValidationConstants; import org.semanticweb.owl.io.RendererException; import org.semanticweb.owl.io.abstract_syntax.ObjectRenderer; import uk.ac.man.cs.img.owl.validation.ClassOrRestrictionIdentifier; /** * @author Dave * * Basically a copy of uk.ac.man.cs.img.owl.validation.ExpressionVisitor. * This is needed because 1) uk.ac.man.cs.img.owl.validation.ExpressionVisitor is not * extendable outside of its package * 2) SwoopSpeciesValidatorVisitor requires a ExpressionVisitor * This class is fitted for SwoopSpeciesValidatorVisitor. * */ public class SwoopExpressionValidatorVisitor extends OWLObjectVisitorAdapter implements OWLValidationConstants { private int level; /* A flag that indicates whether we're at the top level of an equivalence description. In this particular case, it *is* ok to have an intersection */ private boolean topLevelDescription = false; private Set complexProperties; static Logger logger = Logger.getLogger(SwoopExpressionValidatorVisitor.class); private SwoopSpeciesValidator parent; private ObjectRenderer objectRenderer; public int getLevel() { return level; } public Set getComplexProperties() { return complexProperties; } public void setTopLevelDescription( boolean b ) { topLevelDescription = b; } public SwoopExpressionValidatorVisitor( SwoopSpeciesValidator parent, ObjectRenderer renderer) { this.level = LITE; this.parent = parent; this.objectRenderer = renderer; this.complexProperties = new HashSet(); } public void reset() { this.level = LITE; this.topLevelDescription = false; } /* If it's one of: * or * not * oneof * individualValueRestriction * cardinality with anything other than 0, 1 * then we're in DL. */ public void visit( OWLOr node ) { explain( DL, UNION, "Or: " + renderNode( node ) ); level = level | DL; } public void visit( OWLNot node ) { explain( DL, COMPLEMENT, "Not: " + renderNode( node ) ); level = level | DL; } public void visit( OWLEnumeration node ) { explain( DL, ONEOF, "Enumeration: " + renderNode( node ) ); level = level | DL; } public void visit( OWLDataEnumeration node ) { explain( DL, ONEOF, /* DATARANGE?? */ "Data Enumeration: " + renderNode( node ) ); level = level | DL; } public void visit( OWLObjectValueRestriction node ) { explain( DL, ONEOF, "Individual Value: " + renderNode( node ) ); level = level | DL; } public void visit( OWLObjectCardinalityRestriction node ) throws OWLException { /* The property is complex. */ complexProperties.add( node.getProperty() ); if ( (node.isAtLeast() && node.getAtLeast() > 1) || (node.isAtMost() && node.getAtMost() > 1) ) { explain( DL, CARDINALITY, "Cardinality with > 1: " + renderNode( node ) ); level = level | DL; } } public void visit( OWLDataCardinalityRestriction node ) throws OWLException { if ( (node.isAtLeast() && node.getAtLeast() > 1) || (node.isAtMost() && node.getAtMost() > 1) ) { explain( DL, CARDINALITY, "Cardinality with > 1: " + renderNode( node ) ); level = level | DL; } } public void visit( OWLDataValueRestriction node ) { explain( DL, ONEOF, "Data Value: " + renderNode( node ) ); level = level | DL; } /* It it's an and, and we're at a top level equivalence, we need * to check that the operands are all either classes or * restrictions. If they are restrictions, we then need to check * that the restrictions are themselves ok. */ /* This is very unpleasant, and would be the kind of situation * where OWLFrame would be useful as it would allow intersection * at the top level....*/ public void visit ( OWLAnd node ) throws OWLException { if ( topLevelDescription ) { topLevelDescription = false; ClassOrRestrictionIdentifier cori = new ClassOrRestrictionIdentifier(); for ( Iterator it = node.getOperands().iterator(); it.hasNext(); ) { OWLDescription description = (OWLDescription) it.next(); cori.reset(); description.accept( cori ); if ( !cori.isClassOrRestriction() ) { /* If it's not a class or restriction, we're DL */ explain( DL, INTERSECTION, "And with non-class or restriction: " + renderNode( node ) ); level = level | DL; } else { /* Now need to check the expression itself too. */ if ( cori.isRestriction() ) { /* Recurse down and check the restriction */ description.accept( this ); } } } } else { explain( DL, INTERSECTION, "And: " + renderNode( node ) ); level = level | DL; } } /* If it's an object restriction, then if the filler is anything * other than a class, we're in at least DL. */ public void visit ( OWLObjectSomeRestriction node ) throws OWLException { topLevelDescription = false; SwoopClassIdentifierVisitor civ = new SwoopClassIdentifierVisitor(); node.getDescription().accept( civ ); if ( !civ.isClass() ) { explain( DL, EXPRESSIONINRESTRICTION, "Object restriction with non classID filler: " + renderNode( node ) ); level = level | DL; } node.getDescription().accept( this ); } public void visit ( OWLObjectAllRestriction node ) throws OWLException { topLevelDescription = false; SwoopClassIdentifierVisitor civ = new SwoopClassIdentifierVisitor(); node.getDescription().accept( civ ); if ( !civ.isClass() ) { explain( DL, EXPRESSIONINRESTRICTION, "Object restriction with non classID filler: " + renderNode( node ) ); level = level | DL; } node.getDescription().accept( this ); } private String renderNode( OWLObject node ) { try { if ( objectRenderer!=null ) { return objectRenderer.renderObject( node ); } } catch (RendererException ex) { } return node.toString(); } private void explain( int level, int code, String str ) { if ( parent!=null ) { parent.explain( level, code, str ); } } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLFunctionalPropertyAxiom) */ public void visit(OWLFunctionalPropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLInverseFunctionalPropertyAxiom) */ public void visit(OWLInverseFunctionalPropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLTransitivePropertyAxiom) */ public void visit(OWLTransitivePropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLSymmetricPropertyAxiom) */ public void visit(OWLSymmetricPropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLInversePropertyAxiom) */ public void visit(OWLInversePropertyAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLPropertyDomainAxiom) */ public void visit(OWLPropertyDomainAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLObjectPropertyRangeAxiom) */ public void visit(OWLObjectPropertyRangeAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLDataPropertyRangeAxiom) */ public void visit(OWLDataPropertyRangeAxiom node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLObjectPropertyInstance) */ public void visit(OWLObjectPropertyInstance node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLDataPropertyInstance) */ public void visit(OWLDataPropertyInstance node) throws OWLException { // TODO Auto-generated method stub } /* (non-Javadoc) * @see org.semanticweb.owl.model.OWLObjectVisitor#visit(org.semanticweb.owl.model.OWLIndividualTypeAssertion) */ public void visit(OWLIndividualTypeAssertion node) throws OWLException { // TODO Auto-generated method stub } } // ExpressionValidatorVisitor