package org.drools.semantics.builder.model;
import org.drools.semantics.util.area.AreaTxn;
import org.drools.util.CodedHierarchy;
import org.drools.util.HierarchyEncoder;
import org.drools.util.HierarchyEncoderImpl;
import org.drools.util.HierarchySorter;
import org.semanticweb.owlapi.model.OWLOntology;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class GenericModelImpl implements OntoModel, Cloneable {
private String defaultPackage;
private String defaultNamespace;
private OWLOntology ontology;
private String name;
private Mode mode;
private Set<Individual> individuals = new HashSet<Individual>();
private LinkedHashMap<String, Concept> concepts = new LinkedHashMap<String, Concept>();
private Set<SubConceptOf> subConcepts = new HashSet<SubConceptOf>();
private Map<String, Set<PropertyRelation>> properties = new HashMap<String, Set<PropertyRelation>>();
private Set<String> packageNames = new HashSet<String>();
private ClassLoader classLoader;
private HierarchyEncoder<Concept> hierarchyEncoder = new HierarchyEncoderImpl<Concept>();
private ConceptAreaTxn areaTxn;
protected GenericModelImpl newInstance() {
return new GenericModelImpl();
}
public Object clone() {
GenericModelImpl twin = newInstance();
twin.setDefaultPackage( defaultPackage );
twin.setOntology( ontology );
twin.setName( name );
twin.setMode(mode);
twin.setConcepts( new LinkedHashMap<String, Concept>( concepts ) );
twin.setSubConcepts( new HashSet<SubConceptOf>( subConcepts ) );
twin.setProperties( new HashMap<String, Set<PropertyRelation>>( properties ) );
return twin;
}
public OWLOntology getOntology() {
return ontology;
}
public void setOntology( OWLOntology ontology ) {
this.ontology = ontology;
}
public String getDefaultPackage() {
return defaultPackage;
}
public void setDefaultPackage( String pack ) {
this.defaultPackage = pack;
}
public Set<String> getAllPackageNames() {
return packageNames;
}
public String getDefaultNamespace() {
return defaultNamespace;
}
public void setDefaultNamespace(String namespace) {
this.defaultNamespace = namespace;
}
public String getDefaultPackagee() {
return defaultPackage;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Concept> getConcepts() {
return new ArrayList<Concept>( concepts.values() );
}
public Concept getConcept( String id ) {
return concepts.get( id );
}
public void addConcept( Concept con ) {
try {
Class klass;
if ( getClassLoader() != null ) {
klass = Class.forName( con.getFullyQualifiedName(), true, getClassLoader() );
} else {
klass = Class.forName( con.getFullyQualifiedName() );
}
con.setResolved( true );
if ( klass.isInterface() ) {
con.setResolvedAs( Concept.Resolution.IFACE );
} else if ( klass.isEnum() ) {
con.setResolvedAs( Concept.Resolution.ENUM );
} else {
con.setResolvedAs( Concept.Resolution.CLASS );
}
} catch ( ClassNotFoundException e ) {
con.setResolved( false );
con.setResolvedAs( Concept.Resolution.NONE );
}
concepts.put( con.getIri(), con );
packageNames.add( con.getPackage() );
}
public Concept removeConcept( Concept con ) {
return concepts.remove( con.getIri() );
}
public Set<Individual> getIndividuals() {
return individuals;
}
public void addIndividual( Individual i ) {
individuals.add( i );
}
public Individual removeIndividual( Individual i ) {
return individuals.remove( i ) ? i : null;
}
protected void setConcepts(LinkedHashMap<String, Concept> concepts) {
this.concepts = concepts;
}
public Set<SubConceptOf> getSubConcepts() {
return subConcepts;
}
public void addSubConceptOf( SubConceptOf sub ) {
subConcepts.add( sub );
}
public boolean removeSubConceptOf( SubConceptOf sub ) {
return subConcepts.remove( sub );
}
public SubConceptOf getSubConceptOf( String sub, String sup ) {
for ( SubConceptOf rel : subConcepts ) {
if ( rel.getSubject().equals( sub ) ) {
if ( rel.getObject().equals( sup ) ) {
return rel;
}
}
}
return null;
}
protected void setSubConcepts(Set<SubConceptOf> subConcepts) {
this.subConcepts = subConcepts;
}
public Set<PropertyRelation> getProperties( String domainIri ) {
return properties.get( domainIri );
}
public Set<PropertyRelation> getProperties() {
HashSet<PropertyRelation> set = new HashSet<PropertyRelation>();
for ( Set<PropertyRelation> subset : properties.values() ) {
set.addAll( subset );
}
return set;
}
public void addProperty( PropertyRelation rel ) {
Set<PropertyRelation> set = properties.get( rel.getProperty() );
if ( set == null ) {
set = new HashSet<PropertyRelation>();
properties.put( rel.getProperty(), set );
}
set.add( rel );
}
public PropertyRelation removeProperty( PropertyRelation rel ) {
Set<PropertyRelation> set = properties.get( rel.getProperty() );
if ( set != null ) {
set.remove( rel );
return rel;
}
return null;
}
public PropertyRelation getProperty( String iri ) {
Collection<PropertyRelation> props = properties.get( iri );
return props != null ? props.iterator().next() : null;
}
protected void setProperties(Map<String, Set<PropertyRelation>> properties) {
this.properties = properties;
}
@Override
public String toString() {
return "Model{\n" +
"\n\n concepts=\n" + conceptsToString() +
"\n\n subConcepts=\n" + subConceptsToString() +
"\n\n properties=\n" + propertiesToString() +
'}';
}
private String propertiesToString() {
StringBuilder sb = new StringBuilder();
for ( PropertyRelation prop : getProperties() ) {
sb.append("\t").append(prop.toFullString()).append("\n");
}
return sb.toString();
}
private String subConceptsToString() {
StringBuilder sb = new StringBuilder();
for ( SubConceptOf sub : subConcepts ) {
sb.append("\t").append(sub.toFullString()).append("\n");
}
return sb.toString();
}
private String conceptsToString() {
StringBuilder sb = new StringBuilder();
for ( Concept con : getConcepts() ) {
sb.append("\t").append( con.toFullString() ).append("\n");
}
return sb.toString();
}
public CodedHierarchy<Concept> getConceptHierarchy() {
return hierarchyEncoder;
}
public Mode getMode() {
return mode;
}
public void setMode(Mode mode) {
this.mode = mode;
}
public boolean isHierarchyConsistent() {
for ( Concept con : getConcepts() ) {
for ( PropertyRelation rel : con.getProperties().values() ) {
// System.out.println( "Looking for property " + rel.getName() + " starting from " + con.getName() );
if ( ! isPropertyAvailableToImpl( rel, con ) ) {
return false;
}
}
}
return true;
}
private boolean isPropertyAvailableToImpl( PropertyRelation rel, Concept con ) {
if ( con == null ) {
return false;
}
if ( con.getChosenProperties().containsKey( rel.getProperty() ) ) {
return true;
} else {
if ( con.getChosenSuperConcept() != con ) {
return isPropertyAvailableToImpl( rel, con.getChosenSuperConcept() );
} else {
// System.err.print( "Topp reached looking fir " + rel.getProperty() + " in " + con.getIri() );
return false;
}
}
}
public void reassignConceptCodes() {
hierarchyEncoder.clear();
for ( Concept con : getConcepts() ) {
con.setTypeCode( hierarchyEncoder.encode( con, con.getSuperConcepts() ) );
}
if ( hierarchyEncoder.size() != getConcepts().size() ) {
StringBuilder sb = new StringBuilder();
sb.append( " Not all concepts were coded correctly, or some code has been overwritten : \n" );
for ( Concept con : getConcepts() ) {
if ( hierarchyEncoder.getCode( con ) == null ) {
sb.append( "Unable to find concept code : " ).append( con ).append( "\n" );
}
}
sb.append( " Encoder size " ).append( hierarchyEncoder.size() ).append( " vs expected " ).append( getConcepts().size() );
throw new IllegalStateException( sb.toString() );
}
}
public ClassLoader getClassLoader() {
return classLoader;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
public void sort() {
Map<Concept,Collection<Concept>> hier = new HashMap<Concept, Collection<Concept>>();
for ( Concept c : concepts.values() ) {
hier.put( c, c.getSuperConcepts() );
}
concepts.clear();
List<Concept> sorted = new HierarchySorter<Concept>().sort( hier );
for ( Concept c : sorted ) {
concepts.put( c.getIri(), c );
}
}
public void buildAreaTaxonomy() {
areaTxn = new ConceptAreaTxn( this );
}
public AreaTxn<Concept,PropertyRelation> getAreaTaxonomy() {
if ( areaTxn == null ) {
buildAreaTaxonomy();
}
return areaTxn;
}
}