indiIt = model.listIndividuals();
- count = 0;
- log.debug( "Reading individuals..." );
- while ( indiIt.hasNext() ) {
- Individual element = indiIt.next();
- if ( element.isAnon() ) continue;
- OntologyIndividual ontologyTerm = new OntologyIndividualImpl( element );
- result.add( ontologyTerm );
- if ( ++count % 1000 == 0 ) {
- log.debug( "Loaded " + count + " individuals, last was " + ontologyTerm );
- }
- }
- log.debug( "Loaded " + count + " individuals" );
- return result;
- }
-
/**
* Load an ontology into memory. Use this type of model when fast access is critical and memory is available.
- *
- * @param is
- * @param url, used as a key
- * @param spec
- * @return
*/
- public static OntModel loadMemoryModel( InputStream is, String url, OntModelSpec spec ) {
- OntModel model = getMemoryModel( url, spec );
+ public static OntModel loadMemoryModel( InputStream is, String url ) {
+ OntModel model = getMemoryModel( url );
model.read( is, null );
return model;
}
- /**
- * Load an ontology into memory. Use this type of model when fast access is critical and memory is available. Uses
- * OWL_MEM_TRANS_INF
- *
- * @param url
- * @return
- */
- public static OntModel loadMemoryModel( String url ) {
- return loadMemoryModel( url, OntModelSpec.OWL_MEM_TRANS_INF );
- }
-
- /**
- * Load an ontology into memory. Use this type of model when fast access is critical and memory is available. Uses
- * OWL_MEM_TRANS_INF
- * If load from URL fails, attempt to load from disk cache under @cacheName.
- *
- * @param url
- * @return
- */
- public static OntModel loadMemoryModel( String url, String cacheName ) {
- return loadMemoryModel( url, OntModelSpec.OWL_MEM_TRANS_INF, cacheName );
- }
-
/**
* Load an ontology into memory. Use this type of model when fast access is critical and memory is available.
- *
- * @param url
- * @return
+ *
+ * @see #loadMemoryModel(String, String)
*/
- public static OntModel loadMemoryModel( String url, OntModelSpec spec ) {
- return loadMemoryModel( url, spec, null );
+ public static OntModel loadMemoryModel( String url ) {
+ return loadMemoryModel( url, null );
}
/**
* Load an ontology into memory. Use this type of model when fast access is critical and memory is available.
* If load from URL fails, attempt to load from disk cache under @cacheName.
- *
- * @param url
- * @param spec e.g. OWL_MEM_TRANS_INF
- * @param cacheName unique name of this ontology, will be used to load from disk in case of failed url connection
- * @return
+ *
+ * Uses {@link OntModelSpec#OWL_MEM_TRANS_INF}.
+ *
+ * @param url a URL where the OWL file is stored
+ * @param cacheName unique name of this ontology, will be used to load from disk in case of failed url connection
*/
- public static OntModel loadMemoryModel( String url, OntModelSpec spec, String cacheName ) {
+ public static OntModel loadMemoryModel( String url, String cacheName ) {
StopWatch timer = new StopWatch();
timer.start();
- OntModel model = getMemoryModel( url, spec );
+ OntModel model = getMemoryModel( url );
URLConnection urlc = null;
int tries = 0;
@@ -242,7 +126,7 @@ public static OntModel loadMemoryModel( String url, OntModelSpec spec, String ca
}
if ( urlc != null ) {
- try (InputStream in = urlc.getInputStream();) {
+ try ( InputStream in = urlc.getInputStream(); ) {
Reader reader;
if ( cacheName != null ) {
// write tmp to disk
@@ -261,7 +145,7 @@ public static OntModel loadMemoryModel( String url, OntModelSpec spec, String ca
}
assert reader != null;
- try (BufferedReader buf = new BufferedReader( reader );) {
+ try ( BufferedReader buf = new BufferedReader( reader ); ) {
model.read( buf, url );
}
@@ -286,7 +170,7 @@ public static OntModel loadMemoryModel( String url, OntModelSpec spec, String ca
}
if ( f.exists() && !f.isDirectory() ) {
- try (BufferedReader buf = new BufferedReader( new FileReader( f ) );) {
+ try ( BufferedReader buf = new BufferedReader( new FileReader( f ) ); ) {
model.read( buf, url );
// We successfully loaded the cached ontology. Copy the loaded ontology to oldFile
// so that we don't recreate indices during initialization based on a false change in
@@ -359,25 +243,14 @@ public static boolean deleteOldCache( String cacheName ) {
return false;
}
- /**
- * Get model that is entirely in memory with default OntModelSpec.OWL_MEM_RDFS_INF.
- *
- * @param url
- * @return
- */
- static OntModel getMemoryModel( String url ) {
- return getMemoryModel( url, OntModelSpec.OWL_MEM_RDFS_INF );
- }
-
/**
* Get model that is entirely in memory.
- *
- * @param url
- * @param specification
+ *
+ * @param url
* @return
*/
- static OntModel getMemoryModel( String url, OntModelSpec specification ) {
- OntModelSpec spec = new OntModelSpec( specification );
+ private static OntModel getMemoryModel( String url ) {
+ OntModelSpec spec = new OntModelSpec( OntModelSpec.OWL_MEM_TRANS_INF );
ModelMaker maker = ModelFactory.createMemModelMaker();
Model base = maker.createModel( url, false );
spec.setImportModelMaker( maker );
@@ -389,7 +262,7 @@ static OntModel getMemoryModel( String url, OntModelSpec specification ) {
}
/**
- * @param name
+ * @param name
* @return
*/
public static File getDiskCachePath( String name ) {
diff --git a/src/ubic/basecode/ontology/model/OntologyTerm.java b/src/ubic/basecode/ontology/model/OntologyTerm.java
index 4717fc57..d31b38bf 100644
--- a/src/ubic/basecode/ontology/model/OntologyTerm.java
+++ b/src/ubic/basecode/ontology/model/OntologyTerm.java
@@ -1,8 +1,8 @@
/*
* The basecode project
- *
+ *
* Copyright (c) 2007-2019 Columbia University
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -22,48 +22,53 @@
/**
* @author Paul
- *
*/
public interface OntologyTerm extends OntologyResource {
- public Collection getAlternativeIds();
+ Collection getAlternativeIds();
- public Collection getAnnotations();
+ Collection getAnnotations();
+
+ Collection getChildren( boolean direct );
/**
* @param direct return only the immediate children; if false, return all of them down to the leaves.
+ * @param includePartOf include terms matched via
* @return
*/
- public Collection getChildren( boolean direct );
+ Collection getChildren( boolean direct, boolean includePartOf );
- public String getComment();
+ String getComment();
- public Collection getIndividuals();
+ Collection getIndividuals();
- public Collection getIndividuals( boolean direct );
+ Collection getIndividuals( boolean direct );
- public String getLocalName();
+ String getLocalName();
- public Object getModel();
+ Object getModel();
/**
* Note that any restriction superclasses are not returned, unless they are has_proper_part
- *
+ *
* @param direct
* @return
*/
- public Collection getParents( boolean direct );
+ Collection getParents( boolean direct );
- public Collection getRestrictions();
+ Collection getParents( boolean direct, boolean includePartOf );
- public String getTerm();
+ Collection getRestrictions();
- @Override
- public String getUri();
+ String getTerm();
- public boolean isRoot();
+ @Override
+ String getUri();
- /** check to see if the term is obsolete, if it is it should not be used */
- public boolean isTermObsolete();
+ boolean isRoot();
+ /**
+ * check to see if the term is obsolete, if it is it should not be used
+ */
+ boolean isTermObsolete();
}
diff --git a/src/ubic/basecode/ontology/model/OntologyTermImpl.java b/src/ubic/basecode/ontology/model/OntologyTermImpl.java
index 0d5186a1..6ce80a76 100644
--- a/src/ubic/basecode/ontology/model/OntologyTermImpl.java
+++ b/src/ubic/basecode/ontology/model/OntologyTermImpl.java
@@ -14,27 +14,14 @@
*/
package ubic.basecode.ontology.model;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.commons.lang3.ObjectUtils;
-
-import com.hp.hpl.jena.ontology.AllValuesFromRestriction;
-import com.hp.hpl.jena.ontology.ConversionException;
-import com.hp.hpl.jena.ontology.Individual;
-import com.hp.hpl.jena.ontology.OntClass;
-import com.hp.hpl.jena.ontology.OntProperty;
-import com.hp.hpl.jena.ontology.OntResource;
-import com.hp.hpl.jena.ontology.Restriction;
-import com.hp.hpl.jena.ontology.SomeValuesFromRestriction;
-import com.hp.hpl.jena.rdf.model.Property;
-import com.hp.hpl.jena.rdf.model.RDFNode;
-import com.hp.hpl.jena.rdf.model.Resource;
-import com.hp.hpl.jena.rdf.model.ResourceFactory;
-import com.hp.hpl.jena.rdf.model.Statement;
-import com.hp.hpl.jena.rdf.model.StmtIterator;
+import com.hp.hpl.jena.ontology.*;
+import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+import com.hp.hpl.jena.util.iterator.Filter;
+import org.apache.commons.collections4.CollectionUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
/**
* Represents a class in an ontology
@@ -45,30 +32,44 @@ public class OntologyTermImpl extends AbstractOntologyResource implements Ontolo
private static final String HAS_ALTERNATE_ID = "http://www.geneontology.org/formats/oboInOwl#hasAlternativeId";
private static final String NOTHING = "http://www.w3.org/2002/07/owl#Nothing";
- private static Set REJECT_PARENT_URI = new HashSet<>();
/**
- *
+ * Properties through which propagation is allowed for {@link #getParents(boolean)}
*/
- private static final long serialVersionUID = 1L;
+ private static final Set PROPAGATE_PARENT_URIS = new HashSet<>();
+
+ private static final Set REJECT_PARENT_URIS = new HashSet<>();
/**
- * Should has_proper_part be used to indicate additional parent/child relations.
+ *
*/
- private static final boolean USE_PROPER_PART_RESTRICTIONS = true;
- static {
- REJECT_PARENT_URI.add( "http://www.ifomis.org/bfo/1.1/snap#IndependentContinuant" );
- REJECT_PARENT_URI.add( "http://www.ifomis.org/bfo/1.1/snap#Continuant" );
- REJECT_PARENT_URI.add( "http://www.ifomis.org/bfo/1.1/snap#MaterialEntity" );
+ private static final long serialVersionUID = 1L;
- // anatomical entity
- REJECT_PARENT_URI.add( "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_6" );
+ static {
+ CollectionUtils.addAll( PROPAGATE_PARENT_URIS,
+ "http://www.obofoundry.org/ro/ro.owl#proper_part_of",
+ "http://purl.obolibrary.org/obo/BFO_0000050" // part of
+ );
+ CollectionUtils.addAll( REJECT_PARENT_URIS,
+ "http://www.ifomis.org/bfo/1.1/snap#IndependentContinuant",
+ "http://www.ifomis.org/bfo/1.1/snap#Continuant",
+ "http://www.ifomis.org/bfo/1.1/snap#MaterialEntity",
+ // anatomical entity
+ "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_6" );
}
private String label = null;
private String localName = null;
- private transient OntClass ontResource = null;
+ /**
+ * Ontology class underlying this term.
+ */
+ private final transient OntClass ontResource;
+
+ /**
+ * Extra sets of properties to use when navigating parents and children of a term.
+ */
+ private final transient Set propagateParentsProperties;
public OntologyTermImpl( OntClass resource ) {
this.ontResource = resource;
@@ -76,6 +77,12 @@ public OntologyTermImpl( OntClass resource ) {
this.label = ontResource.getLabel( "EN" );
if ( this.label == null ) this.label = ontResource.getLabel( null );
this.localName = ontResource.getLocalName();
+ this.propagateParentsProperties = PROPAGATE_PARENT_URIS.stream()
+ .map( uri -> resource.getModel().getProperty( uri ) )
+ .filter( Objects::nonNull )
+ .collect( Collectors.toSet() );
+ } else {
+ this.propagateParentsProperties = Collections.emptySet();
}
}
@@ -88,9 +95,9 @@ public boolean equals( Object obj ) {
final OntologyTermImpl that = ( OntologyTermImpl ) obj;
if ( this.getUri() != null ) {
- return ObjectUtils.equals( this.getUri(), that.getUri() );
+ return Objects.equals( this.getUri(), that.getUri() );
}
- return ObjectUtils.equals( this.getTerm(), that.getTerm() );
+ return Objects.equals( this.getTerm(), that.getTerm() );
}
@Override
@@ -98,7 +105,8 @@ public Collection getAlternativeIds() {
Collection results = new HashSet<>();
Property alternate = ResourceFactory.createProperty( HAS_ALTERNATE_ID );
- for ( StmtIterator it = this.ontResource.listProperties( alternate ); it.hasNext(); ) {
+ StmtIterator it = this.ontResource.listProperties( alternate );
+ while ( it.hasNext() ) {
Statement statement = it.next();
results.add( statement.asTriple().getMatchObject().getLiteralLexicalForm() );
}
@@ -126,9 +134,80 @@ public Collection getAnnotations() {
@Override
public Collection getChildren( boolean direct ) {
- Collection result = new HashSet<>();
- getChildren( direct, result );
- return result;
+ return getChildren( direct, true );
+ }
+
+ @Override
+ public Collection getChildren( boolean direct, boolean includePartOf ) {
+ Collection result = new HashSet<>();
+ ExtendedIterator iterator = ontResource.listSubClasses( direct )
+ .filterDrop( new EqualityByUriFilter( NOTHING ) );
+ OntModel model = ontResource.getOntModel();
+
+ while ( iterator.hasNext() ) {
+ OntClass c = iterator.next();
+
+ // bnode
+ if ( c.getURI() == null )
+ continue;
+
+ result.add( c );
+ }
+
+ if ( includePartOf ) {
+ Property subClassOf = model.getProfile().SUB_CLASS_OF();
+ ExtendedIterator restrictionsIterator = model.listRestrictions()
+ .filterKeep( new RestrictionWithPropertyAndValueFilter( propagateParentsProperties, ontResource ) );
+ while ( restrictionsIterator.hasNext() ) {
+ Restriction r = restrictionsIterator.next();
+ ResIterator ss = model.listResourcesWithProperty( subClassOf, r );
+ while ( ss.hasNext() ) {
+ Resource s = ss.next();
+ if ( s.getURI() != null ) {
+ OntClass o = model.getOntClass( s.getURI() );
+ if ( o != null ) {
+ result.add( o );
+ }
+ }
+ }
+ }
+ }
+
+ return result.stream().map( OntologyTermImpl::new ).collect( Collectors.toSet() );
+ }
+
+ /**
+ * Filter that retain resources with the given URI.
+ */
+ private static class EqualityByUriFilter extends Filter {
+ private final String uri;
+
+ private EqualityByUriFilter( String uri ) {
+ this.uri = uri;
+ }
+
+ @Override
+ public boolean accept( OntClass o ) {
+ return uri.equals( o.getURI() );
+ }
+ }
+
+ /**
+ * Filter that retain only the restrictions with any of the given properties and resource as value.
+ */
+ private static class RestrictionWithPropertyAndValueFilter extends Filter {
+ private final Set properties;
+ private final Resource resource;
+
+ private RestrictionWithPropertyAndValueFilter( Set properties, OntClass resource ) {
+ this.properties = properties;
+ this.resource = resource;
+ }
+
+ @Override
+ public boolean accept( Restriction o ) {
+ return hasRestrictionValue( o, resource ) && properties.stream().anyMatch( o::onProperty );
+ }
}
/*
@@ -152,17 +231,15 @@ public Collection getIndividuals() {
return getIndividuals( true );
}
- /**
- * @param direct
- * @return
- */
@Override
public Collection getIndividuals( boolean direct ) {
Collection inds = new HashSet<>();
ExtendedIterator extends OntResource> iterator = this.ontResource.listInstances( direct );
while ( iterator.hasNext() ) {
- Individual i = ( Individual ) iterator.next();
- inds.add( new OntologyIndividualImpl( i ) );
+ OntResource r = iterator.next();
+ if ( r.isIndividual() ) {
+ inds.add( new OntologyIndividualImpl( r.asIndividual() ) );
+ }
}
return inds;
}
@@ -184,9 +261,49 @@ public Object getModel() {
@Override
public Collection getParents( boolean direct ) {
- Collection result = new HashSet<>();
- this.getParents( direct, result );
- return result;
+ return getParents( direct, true );
+ }
+
+ @Override
+ public Collection getParents( boolean direct, boolean includePartOf ) {
+ Collection result = new HashSet<>();
+ ExtendedIterator iterator;
+ Set excludeProperties;
+ iterator = ontResource.listSuperClasses( direct );
+ excludeProperties = REJECT_PARENT_URIS;
+
+ while ( iterator.hasNext() ) {
+ OntClass c = iterator.next();
+
+ // handles part of some {parent container} or part of all {parent container}
+ if ( includePartOf && c.isRestriction() ) {
+ Restriction r = c.asRestriction();
+ if ( propagateParentsProperties.contains( r.getOnProperty() ) ) {
+ Resource value = getRestrictionValue( c.asRestriction() );
+ if ( value instanceof OntClass ) {
+ c = ( OntClass ) value;
+ } else {
+ continue;
+ }
+ }
+ }
+
+ // bnode
+ if ( c.getURI() == null )
+ continue;
+
+ // excluded terms
+ if ( excludeProperties.contains( c.getURI() ) )
+ continue;
+
+ // already visited
+ if ( result.contains( c ) )
+ continue;
+
+ result.add( c );
+ }
+
+ return result.stream().map( OntologyTermImpl::new ).collect( Collectors.toSet() );
}
/**
@@ -201,14 +318,9 @@ public Collection getRestrictions() {
ExtendedIterator iterator = ontResource.listSuperClasses( false );
while ( iterator.hasNext() ) {
OntClass c = iterator.next();
- Restriction r = null;
- try {
- r = c.asRestriction();
- result.add( RestrictionFactory.asRestriction( r ) );
- } catch ( Exception e ) {
-
+ if ( c.isRestriction() ) {
+ result.add( RestrictionFactory.asRestriction( c.asRestriction() ) );
}
-
}
// Check superclasses for any ADDITIONAL restrictions.
@@ -221,9 +333,10 @@ public Collection getRestrictions() {
} catch ( Exception e ) {
// not a restriction, but a superclass that might have restrictions
ExtendedIterator supClassesIt = c.listSuperClasses( false );
- loop: while ( supClassesIt.hasNext() ) {
+ loop:
+ while ( supClassesIt.hasNext() ) {
OntClass sc = supClassesIt.next();
- Restriction sr = null;
+ Restriction sr;
try {
sr = sc.asRestriction();
@@ -253,7 +366,7 @@ public Collection getRestrictions() {
*/
@Override
public String getTerm() {
- String res = null;
+ String res;
if ( this.label != null ) {
res = this.label;
} else if ( this.localName != null ) {
@@ -322,11 +435,11 @@ public boolean isTermObsolete() {
if ( parentOntologyTerm.getUri() != null
&& parentOntologyTerm.getUri().equalsIgnoreCase(
- "http://bioontology.org/projects/ontologies/birnlex#_birnlex_retired_class" )
+ "http://bioontology.org/projects/ontologies/birnlex#_birnlex_retired_class" )
|| parentOntologyTerm
- .getUri()
- .equalsIgnoreCase(
- "http://ontology.neuinfo.org/NIF/Backend/BIRNLex_annotation_properties.owl#_birnlex_retired_class" ) ) {
+ .getUri()
+ .equalsIgnoreCase(
+ "http://ontology.neuinfo.org/NIF/Backend/BIRNLex_annotation_properties.owl#_birnlex_retired_class" ) ) {
return true;
}
}
@@ -343,7 +456,7 @@ public boolean isTermObsolete() {
RDFNode n = state.getObject();
if ( p.getLocalName().equalsIgnoreCase( "deprecated" ) ) {
- if ( n.toString().indexOf( "true" ) != -1 ) {
+ if ( n.toString().contains( "true" ) ) {
return true;
}
break;
@@ -371,169 +484,23 @@ public String toString() {
return res;
}
- protected OntologyTerm fromOntClass( OntClass ontClass ) {
- return new OntologyTermImpl( ontClass );
- }
-
- /**
- * @param direct
- * @param work
- */
- private void getChildren( boolean direct, Collection work ) {
-
- // get children by recursion, don't rely on the jena api.
- ExtendedIterator iterator = ontResource.listSubClasses( true );
- while ( iterator.hasNext() ) {
- OntClass c = iterator.next();
- // URI can be null if the ont is a bnode (no idea what it is, but we have to handle this)
- // some reasoners will infer owl#Nothing as a subclass of everything
- if ( c.getURI() == null || c.getURI().equals( NOTHING ) ) continue;
-
- if ( USE_PROPER_PART_RESTRICTIONS && c.isRestriction() ) {
-
- Restriction restriction = c.asRestriction();
-
- OntProperty onProperty = restriction.getOnProperty();
-
- if ( !onProperty.getURI().equals( "http://www.obofoundry.org/ro/ro.owl#has_proper_part" ) ) {
- continue;
- }
-
- Resource r = getRestrictionValue( restriction );
- if ( r == null ) continue;
-
- OntologyTerm child = fromOntClass( ( OntClass ) r );
-
- // avoid risk of endless regression.
- if ( !work.contains( child ) ) {
- work.add( child );
- if ( !direct ) ( ( OntologyTermImpl ) child ).getChildren( false, work );
- }
- } else {
- OntologyTerm child = this.fromOntClass( c );
- work.add( child );
- if ( !direct ) ( ( OntologyTermImpl ) child ).getChildren( false, work );
- }
- // log.info( c );
- }
-
- if ( USE_PROPER_PART_RESTRICTIONS ) {
- ExtendedIterator sciterator = this.ontResource.listSuperClasses( true );
- while ( sciterator.hasNext() ) {
- OntClass c = sciterator.next();
- if ( !c.isRestriction() ) {
- continue;
- }
-
- Restriction restriction = c.asRestriction();
-
- try {
- OntProperty onProperty = restriction.getOnProperty();
- if ( !onProperty.getURI().equals( "http://www.obofoundry.org/ro/ro.owl#has_proper_part" ) ) {
- continue;
- }
- } catch ( ConversionException e ) {
- continue;
- }
-
- Resource r = getRestrictionValue( restriction );
- if ( r == null ) continue;
-
- // if ( !( r instanceof OntClass ) ) {
- // // means our owl file is incomplete, is in tests.
- // log.info( r );
- // continue;
- // }
-
- OntologyTerm child = fromOntClass( ( OntClass ) r );
- if ( !work.contains( child ) ) {
- work.add( child );
- if ( !direct ) ( ( OntologyTermImpl ) child ).getChildren( false, work );
- }
-
- }
- }
- }
-
- /**
- * @param direct
- * @param work
- */
- private void getParents( boolean direct, Collection work ) {
- assert work != null;
- if ( !ontResource.isClass() ) {
- return;
- }
-
- ExtendedIterator iterator = ontResource.listSuperClasses( true );
-
- while ( iterator.hasNext() ) {
-
- try {
- OntClass c = iterator.next();
-
- if ( USE_PROPER_PART_RESTRICTIONS && c.isRestriction() ) {
- Restriction restriction = c.asRestriction();
-
- OntProperty onProperty = restriction.getOnProperty();
-
- assert onProperty != null;
-
- // We ignore this... hack.
- if ( !onProperty.getURI().equals( "http://www.obofoundry.org/ro/ro.owl#proper_part_of" ) ) {
- continue;
- }
-
- Resource r = getRestrictionValue( restriction );
-
- if ( r == null ) continue;
-
- assert r != null;
- if ( log.isDebugEnabled() ) log.debug( " Some from:" + r + " " + onProperty.getURI() );
-
- OntologyTerm parent = fromOntClass( ( OntClass ) r );
-
- if ( REJECT_PARENT_URI.contains( parent.getUri() ) ) continue;
-
- // avoid endless regression
- if ( !work.contains( parent ) ) {
- work.add( parent );
- if ( !direct ) ( ( OntologyTermImpl ) parent ).getParents( direct, work );
- }
-
- } else {
- // not a restriction.
- OntologyTerm parent = this.fromOntClass( c );
-
- if ( REJECT_PARENT_URI.contains( parent.getUri() ) ) continue;
-
- if ( !work.contains( parent ) ) {
- work.add( parent );
- if ( !direct ) {
- // recurse.
- ( ( OntologyTermImpl ) parent ).getParents( direct, work );
- }
- }
- }
- } catch ( ConversionException e ) {
- if ( log.isDebugEnabled() ) log.debug( e.getMessage() );
- continue;
- }
-
+ private static Resource getRestrictionValue( Restriction r ) {
+ if ( r.isSomeValuesFromRestriction() ) {
+ return r.asSomeValuesFromRestriction().getSomeValuesFrom();
+ } else if ( r.isAllValuesFromRestriction() ) {
+ return r.asAllValuesFromRestriction().getAllValuesFrom();
+ } else {
+ return null;
}
}
- private Resource getRestrictionValue( Restriction restriction ) {
- Resource r = null;
-
- if ( restriction.isSomeValuesFromRestriction() ) {
- SomeValuesFromRestriction some = restriction.asSomeValuesFromRestriction();
- r = some.getSomeValuesFrom();
- } else if ( restriction.isAllValuesFromRestriction() ) {
- AllValuesFromRestriction allValues = restriction.asAllValuesFromRestriction();
- r = allValues.getAllValuesFrom();
+ private static boolean hasRestrictionValue( Restriction r, Resource value ) {
+ if ( r.isSomeValuesFromRestriction() ) {
+ return r.asSomeValuesFromRestriction().hasSomeValuesFrom( value );
+ } else if ( r.isAllValuesFromRestriction() ) {
+ return r.asAllValuesFromRestriction().hasAllValuesFrom( value );
+ } else {
+ return false;
}
- return r;
}
-
}
diff --git a/src/ubic/basecode/ontology/providers/AbstractOntologyMemoryBackedService.java b/src/ubic/basecode/ontology/providers/AbstractOntologyMemoryBackedService.java
index 34bc3acf..2470d05b 100644
--- a/src/ubic/basecode/ontology/providers/AbstractOntologyMemoryBackedService.java
+++ b/src/ubic/basecode/ontology/providers/AbstractOntologyMemoryBackedService.java
@@ -1,97 +1,30 @@
/*
* The baseCode project
- *
+ *
* Copyright (c) 2013 University of British Columbia
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package ubic.basecode.ontology.providers;
-import java.io.IOException;
-import java.io.InputStream;
-
-import ubic.basecode.ontology.OntologyLoader;
-import ubic.basecode.ontology.search.OntologyIndexer;
-
import com.hp.hpl.jena.ontology.OntModel;
-import com.hp.hpl.jena.ontology.OntModelSpec;
+import ubic.basecode.ontology.OntologyLoader;
/**
* This class has some stuff that's specific to in-memory ontologies. Unlike database backed ontologies we don't use a
* pool keeping only one instance of model in memory.
- *
+ *
* @author paul
*/
public abstract class AbstractOntologyMemoryBackedService extends AbstractOntologyService {
- /**
- * For testing! Overrides normal way of loading the ontology. This does not index the ontology unless 'force' is
- * true (if there is an existing index, it will be used)
- *
- * @param is
- * @param forceIndex initialize the index. Otherwise it will only be initialized if it doesn't exist.
- * @throws IOException
- */
- public synchronized void loadTermsInNameSpace( InputStream is, boolean forceIndex ) {
- synchronized ( isInitialized ) {
- this.indexReady.set( false );
- this.modelReady.set( false );
- this.isInitialized.set( false );
- this.cacheReady.set( false );
- }
-
- if ( initializationThread.isAlive() ) {
- log.warn( this.getOntologyName() + " initialization is already running, trying to cancel ..." );
- initializationThread.cancel();
-
- // wait for the thread to die.
- int maxWait = 10;
- int wait = 0;
- while ( initializationThread.isAlive() ) {
- try {
- Thread.sleep( 5000 );
- log.warn( "Waiting for auto-initialization to stop so manual initialization can begin ..." );
- } catch ( InterruptedException e ) {
- // no-op.
- }
- if ( ++wait >= maxWait ) {
- log.error( "Got tired of waiting" );
- break;
- }
- if ( initializationThread.isInterrupted() ) {
- log.warn( "Got interrupt." );
- break;
- }
- }
- }
-
- if ( this.terms != null ) this.terms.clear();
- if ( this.individuals != null ) this.individuals.clear();
-
- this.model = OntologyLoader.loadMemoryModel( is, this.getOntologyUrl(), OntModelSpec.OWL_MEM );
- this.index = OntologyIndexer.getSubjectIndex( getOntologyName() );
- if ( index == null || forceIndex ) {
- this.index = OntologyIndexer.indexOntology( getOntologyName(), model, true /* force */ );
- }
-
- addTerms( OntologyLoader.initialize( this.getOntologyUrl(), model ) );
-
- synchronized ( isInitialized ) {
- indexReady.set( this.index != null );
- cacheReady.set( true );
- modelReady.set( true );
- isInitialized.set( true );
- }
- log.info( this.getClass().getSimpleName() + " ready" );
- }
-
@Override
protected synchronized OntModel loadModel() {
return OntologyLoader.loadMemoryModel( this.getOntologyUrl(), this.getOntologyName() );
diff --git a/src/ubic/basecode/ontology/providers/AbstractOntologyService.java b/src/ubic/basecode/ontology/providers/AbstractOntologyService.java
index c31566bf..42ae11c5 100644
--- a/src/ubic/basecode/ontology/providers/AbstractOntologyService.java
+++ b/src/ubic/basecode/ontology/providers/AbstractOntologyService.java
@@ -19,166 +19,132 @@
package ubic.basecode.ontology.providers;
-import java.io.IOException;
-import java.lang.Thread.State;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
+import com.hp.hpl.jena.ontology.ObjectProperty;
+import com.hp.hpl.jena.ontology.*;
+import com.hp.hpl.jena.rdf.arp.ARPErrorNumbers;
+import com.hp.hpl.jena.rdf.arp.ParseException;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.shared.JenaException;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import com.hp.hpl.jena.ontology.OntModel;
-
import ubic.basecode.ontology.OntologyLoader;
-import ubic.basecode.ontology.model.OntologyIndividual;
-import ubic.basecode.ontology.model.OntologyResource;
-import ubic.basecode.ontology.model.OntologyTerm;
+import ubic.basecode.ontology.model.*;
import ubic.basecode.ontology.search.OntologyIndexer;
import ubic.basecode.ontology.search.OntologySearch;
import ubic.basecode.ontology.search.OntologySearchException;
import ubic.basecode.ontology.search.SearchIndex;
import ubic.basecode.util.Configuration;
+import java.io.InputStream;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
/**
* @author kelsey
*/
-public abstract class AbstractOntologyService {
+@SuppressWarnings("unused")
+public abstract class AbstractOntologyService implements OntologyService {
- protected class OntologyInitializationThread extends Thread {
+ protected static Logger log = LoggerFactory.getLogger( AbstractOntologyService.class );
- AtomicBoolean cancel = new AtomicBoolean( false );
+ /**
+ * Lock used to prevent reads while the ontology is being initialized.
+ */
+ private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
- private boolean forceReindexing = false;
+ /* internal state protected by rwLock */
+ private OntModel model;
+ private Map alternativeIDs;
+ private final Map termCache = new ConcurrentHashMap<>( 1024 );
+ private SearchIndex index;
- public OntologyInitializationThread( boolean forceRefresh ) {
- super();
- this.forceReindexing = forceRefresh;
- }
+ private boolean isInitialized = false;
- public void cancel() {
- this.cancel.set( true );
- this.interrupt();
+ @Override
+ public void initialize( boolean forceLoad, boolean forceIndexing ) {
+ if ( !forceLoad && isInitialized ) {
+ log.warn( getOntologyName() + " is already loaded, and force=false, not restarting" );
+ return;
}
- public boolean isCancelled() {
- return cancel.get();
- }
+ boolean loadOntology = isEnabled();
- public boolean isForceReindexing() {
- return forceReindexing;
+ // If loading ontologies is disabled in the configuration, return
+ if ( !forceLoad && !loadOntology ) {
+ log.debug( "Loading " + getOntologyName() + " is disabled (force=" + forceLoad + ", " + "Configuration load." + getOntologyName() + "=" + loadOntology + ")" );
+ return;
}
- @Override
- public void run() {
-
- terms = new HashMap<>();
- individuals = new HashMap<>();
-
- if ( isCancelled() ) {
- log.warn( "Cancelled initialization" );
- return;
- }
-
- log.info( "Loading ontology: " + getOntologyName() + " from " + getOntologyUrl() + " ..." );
- StopWatch loadTime = new StopWatch();
- loadTime.start();
-
- model = getModel(); // can take a while.
- assert model != null;
-
- try {
-
- //Checks if the current ontology has changed since it was last loaded.
- boolean changed = OntologyLoader.hasChanged( getOntologyName() );
- boolean indexExists = OntologyIndexer.getSubjectIndex( getOntologyName() ) != null;
-
- /*
- * Indexing is slow, don't do it if we don't have to.
- */
- index( forceReindexing || changed || !indexExists );
-
- indexReady.set( true );
-
- if ( isCancelled() ) {
- log.error( "Cancelled initialization" );
- return;
- }
-
- /*
- * This creates a cache of URI (String) --> OntologyTerms. ?? Does Jena provide an easier way to do
- * this?
- */
-
- loadTermsInNameSpace( getOntologyUrl(), model );
-
- cleanup();
-
- cacheReady.set( true );
-
- isInitialized.set( true );
- loadTime.stop();
-
- log.info( "Finished loading " + getOntologyName() + " in " + String.format( "%.2f", loadTime.getTime() / 1000.0 )
- + "s" );
-
- } catch ( Exception e ) {
- log.error( e.getMessage(), e );
- isInitialized.set( false );
- } finally {
- // no-op
- }
+ // Detect configuration problems.
+ if ( StringUtils.isBlank( this.getOntologyUrl() ) ) {
+ throw new IllegalStateException( "URL not defined, ontology cannot be loaded (" + this.getClass().getSimpleName() + ")" );
}
- public void setForceReindexing( boolean forceReindexing ) {
- this.forceReindexing = forceReindexing;
+ // This thread indexes ontology and creates local cache for uri->ontology terms mappings.
+ if ( !forceIndexing ) {
+ log.info( getOntologyName() + " index will *not* be refreshed unless the ontology " + "has changed or the index is misssing" );
}
- private void cleanup() {
- OntologyLoader.deleteOldCache( getOntologyName() );
- }
- }
+ log.info( "Loading ontology: " + getOntologyName() + " from " + getOntologyUrl() + " ..." );
+ StopWatch loadTime = StopWatch.createStarted();
- protected static Logger log = LoggerFactory.getLogger( AbstractOntologyService.class );
+ // use temporary variables so we can minimize the critical region for replacing the service's state
+ Map terms = new HashMap<>();
+ Map individuals = new HashMap<>();
+ OntModel model;
+ SearchIndex index;
- protected AtomicBoolean cacheReady = new AtomicBoolean( false );
+ if ( Thread.currentThread().isInterrupted() ) {
+ log.warn( String.format( "The current thread is interrupted, initialization of %s will be stop.", getOntologyName() ) );
+ return;
+ }
- protected SearchIndex index;
+ model = loadModel(); // can take a while.
+ assert model != null;
- protected AtomicBoolean indexReady = new AtomicBoolean( false );
- protected Map individuals;
+ //Checks if the current ontology has changed since it was last loaded.
+ boolean changed = OntologyLoader.hasChanged( getOntologyName() );
+ boolean indexExists = OntologyIndexer.getSubjectIndex( getOntologyName() ) != null;
+ boolean forceReindexing = forceLoad && forceIndexing;
- protected OntologyInitializationThread initializationThread;
- protected AtomicBoolean isInitialized = new AtomicBoolean( false );
- protected OntModel model = null;
+ /*
+ * Indexing is slow, don't do it if we don't have to.
+ */
+ boolean force = forceReindexing || changed || !indexExists;
- protected AtomicBoolean modelReady = new AtomicBoolean( false );
+ index = OntologyIndexer.indexOntology( getOntologyName(), model, force );
- protected Map terms = null;
+ if ( Thread.currentThread().isInterrupted() ) {
+ log.warn( String.format( "The current thread is interrupted, initialization of %s will be stop.", getOntologyName() ) );
+ return;
+ }
- private Map alternativeIDs = new HashMap<>();
+ Lock lock = rwLock.writeLock();
+ try {
+ lock.lock();
+ this.model = model;
+ this.termCache.clear();
+ this.index = index;
+ this.isInitialized = true;
+ } finally {
+ lock.unlock();
+ }
- /**
- *
- */
- public AbstractOntologyService() {
- super();
+ // now that the terms have been replaced, we can clear old caches
+ OntologyLoader.deleteOldCache( getOntologyName() );
- initializationThread = new OntologyInitializationThread( false );
- initializationThread.setName( getOntologyName() + "_load_thread_" + RandomStringUtils.randomAlphanumeric( 5 ) );
- // To prevent VM from waiting on this thread to shutdown (if shutting down).
- initializationThread.setDaemon( true );
+ loadTime.stop();
+ log.info( String.format( "Finished loading %s in %ss", getOntologyName(), String.format( "%.2f", loadTime.getTime() / 1000.0 ) ) );
}
- // private boolean enabled = false;
-
/**
* Do not do this except before re-indexing.
*/
@@ -187,348 +153,368 @@ public void closeIndex() {
index.close();
}
- /**
- * Looks for any OntologyIndividuals that match the given search string.
- *
- * @param search
- * @return
- */
+ @Override
public Collection findIndividuals( String search ) throws OntologySearchException {
-
- if ( !isOntologyLoaded() ) return null;
-
- if ( index == null ) {
- log.warn( "attempt to search " + this.getOntologyName() + " when index is null" );
- return null;
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ log.warn( String.format( "Ontology %s is not ready, no individuals will be returned.", getOntologyName() ) );
+ return Collections.emptySet();
+ }
+ if ( index == null ) {
+ log.warn( "attempt to search " + this.getOntologyName() + " when index is null" );
+ return Collections.emptySet();
+ }
+ return OntologySearch.matchIndividuals( model, index, search );
+ } finally {
+ lock.unlock();
}
-
- OntModel m = getModel();
-
- Collection indis = OntologySearch.matchIndividuals( m, index, search );
-
- return indis;
}
- /**
- * Looks for any OntologyIndividuals or ontologyTerms that match the given search string
- *
- * @param search
- * @return results, or an empty collection if the results are empty OR the ontology is not available to be
- * searched.
- */
+ @Override
public Collection findResources( String searchString ) throws OntologySearchException {
-
- if ( !isOntologyLoaded() ) {
- log.warn( "Ontology is not ready: " + this.getClass() );
- return new HashSet<>();
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ log.warn( String.format( "Ontology %s is not ready, no resources will be returned.", getOntologyName() ) );
+ return Collections.emptySet();
+ }
+ if ( index == null ) {
+ log.warn( "attempt to search " + this.getOntologyName() + " when index is null" );
+ return Collections.emptySet();
+ }
+ return OntologySearch.matchResources( model, index, searchString );
+ } finally {
+ lock.unlock();
}
-
- assert index != null : "attempt to search " + this.getOntologyName() + " when index is null";
-
- OntModel m = getModel();
-
- Collection results = OntologySearch.matchResources( m, index, searchString );
-
- return results;
}
- /**
- * Looks for any ontologyTerms that match the given search string. Obsolete terms are filtered out.
- *
- * @param search
- * @return
- */
+ @Override
public Collection findTerm( String search ) throws OntologySearchException {
-
- if ( !isOntologyLoaded() ) return new HashSet<>();
-
- if ( log.isDebugEnabled() ) log.debug( "Searching " + this.getOntologyName() + " for '" + search + "'" );
-
- assert index != null : "attempt to search " + this.getOntologyName() + " when index is null";
-
- OntModel m = getModel();
-
- Collection matches = OntologySearch.matchClasses( m, index, search );
-
- return matches;
+ if ( log.isDebugEnabled() ) log.debug( "Searching " + getOntologyName() + " for '" + search + "'" );
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ log.warn( String.format( "Ontology %s is not ready, no terms will be returned.", getOntologyName() ) );
+ return Collections.emptySet();
+ }
+ if ( index == null ) {
+ log.warn( "attempt to search " + this.getOntologyName() + " when index is null" );
+ return Collections.emptySet();
+ }
+ return OntologySearch.matchClasses( model, index, search );
+ } finally {
+ lock.unlock();
+ }
}
+ @Override
public OntologyTerm findUsingAlternativeId( String alternativeId ) {
-
- if ( alternativeIDs.isEmpty() ) {
- log.info( "init search by alternativeID" );
- initSearchByAlternativeId();
- }
-
- if ( alternativeIDs.get( alternativeId ) != null ) {
- return alternativeIDs.get( alternativeId );
+ Lock lock = alternativeIDs != null ? rwLock.readLock() : rwLock.writeLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ log.warn( String.format( "Ontology %s is not ready, null will be returned for alternative ID match.", getOntologyName() ) );
+ return null;
+ }
+ if ( alternativeIDs == null ) {
+ log.info( "init search by alternativeID" );
+ initSearchByAlternativeId();
+ }
+ String termUri = alternativeIDs.get( alternativeId );
+ return termUri != null ? getTerm( termUri ) : null;
+ } finally {
+ lock.unlock();
}
-
- return null;
}
+ @Override
public Set getAllURIs() {
- if ( terms == null ) return null;
- return new HashSet<>( terms.keySet() );
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ log.warn( String.format( "Ontology %s is not ready, no term URIs will be returned.", getOntologyName() ) );
+ return Collections.emptySet();
+ }
+ Set allUris = new HashSet<>();
+ ExtendedIterator iterator = model.listClasses();
+ while ( iterator.hasNext() ) {
+ allUris.add( iterator.next().getURI() );
+ }
+ ExtendedIterator it2 = model.listIndividuals();
+ while ( it2.hasNext() ) {
+ allUris.add( it2.next().getURI() );
+ }
+ return allUris;
+ } finally {
+ lock.unlock();
+ }
}
- /**
- * Looks through both Terms and Individuals for a OntologyResource that has a uri matching the uri given. If no
- * OntologyTerm is found only then will ontologyIndividuals be searched. returns null if nothing is found.
- *
- * @param uri
- * @return
- */
+ @Override
public OntologyResource getResource( String uri ) {
-
- if ( ( uri == null ) || ( !isInitialized.get() ) ) return null;
-
- OntologyResource resource = terms.get( uri );
-
- if ( resource == null ) resource = individuals.get( uri );
-
- return resource;
+ if ( uri == null ) return null;
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ return null;
+ }
+ OntologyResource res;
+ Resource resource = model.getResource( uri );
+ if ( resource.getURI() == null ) {
+ return null;
+ }
+ if ( resource instanceof OntClass ) {
+ // use the cached term
+ res = getTermInternal( uri );
+ } else if ( resource instanceof Individual ) {
+ res = new OntologyIndividualImpl( ( Individual ) resource );
+ } else if ( resource instanceof OntProperty ) {
+ res = PropertyFactory.asProperty( ( ObjectProperty ) resource );
+ } else {
+ res = null;
+ }
+ return res;
+ } finally {
+ lock.unlock();
+ }
}
- /**
- * Looks for a OntologyTerm that has the match in URI given
- *
- * @param uri
- * @return
- */
+ @Override
public OntologyTerm getTerm( String uri ) {
-
- if ( !isInitialized.get() || terms == null ) return null;
-
if ( uri == null ) throw new IllegalArgumentException( "URI cannot be null" );
-
- OntologyTerm term = terms.get( uri );
-
- return term;
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) return null;
+ return getTermInternal( uri );
+ } finally {
+ lock.unlock();
+ }
}
- /**
- * @param uri
- * @return
- */
+ @Override
public Collection getTermIndividuals( String uri ) {
-
- if ( terms == null ) {
- log.warn( "No term for URI=" + uri + " in " + this.getOntologyName()
- + " no terms loaded; make sure ontology is loaded and uri is valid" );
- return new HashSet<>();
- }
-
- OntologyTerm term = terms.get( uri );
- if ( term == null ) {
- /*
- * Either the ontology hasn't been loaded, or the id was not valid.
- */
- log.warn( "No term for URI=" + uri + " in " + this.getOntologyName()
- + "; make sure ontology is loaded and uri is valid" );
- return new HashSet<>();
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ return Collections.emptySet();
+ }
+ OntologyTerm term = getTermInternal( uri );
+ if ( term == null ) {
+ /*
+ * Either the ontology hasn't been loaded, or the id was not valid.
+ */
+ log.warn( "No term for URI=" + uri + " in " + this.getOntologyName() + "; make sure ontology is loaded and uri is valid" );
+ return new HashSet<>();
+ }
+ return term.getIndividuals( true );
+ } finally {
+ lock.unlock();
}
- return term.getIndividuals( true );
-
}
- /**
- * Create the search index.
- *
- * @param force
- */
- public void index( boolean force ) {
- StopWatch timer = new StopWatch();
- timer.start();
- OntModel m = getModel();
- assert m != null;
-
- index = OntologyIndexer.indexOntology( getOntologyName(), m, force );
-
- }
-
- /**
- * @return
- */
+ @Override
public boolean isEnabled() {
- if ( isOntologyLoaded() ) return true; // could have forced, without setting config
+ // quick path: just lookup the configuration
String configParameter = "load." + getOntologyName();
- return Configuration.getBoolean( configParameter );
- }
-
- public boolean isInitializationThreadAlive() {
- return initializationThread.isAlive();
+ if ( Configuration.getBoolean( configParameter ) ) {
+ return true;
+ }
+ // could have forced, without setting config
+ Lock lock = rwLock.readLock();
+ try {
+ lock.lock();
+ return isInitialized;
+ } finally {
+ lock.unlock();
+ }
}
- /**
- * Used for determining if the Ontology has finished loading into memory. Although calls like getParents,
- * getChildren will still work (its much faster once the ontologies have been preloaded into memory.)
- *
- * @returns boolean
- */
+ @Override
public boolean isOntologyLoaded() {
- return isInitialized.get();
+ // it's fine not to use the read lock here
+ return isInitialized;
}
- /**
- *
- * @param forceLoad
- * @param forceIndexing If forceLoad is also true, indexing will be performed. If you know the index is
- * up to date, there's no need to do it again. Normally indexing is only done if there is no
- * index, or if the ontology has changed since last loaded.
- */
- public void startInitializationThread( boolean forceLoad, boolean forceIndexing ) {
- assert initializationThread != null;
- synchronized ( initializationThread ) {
- if ( initializationThread.isAlive() ) {
- log.warn( getOntologyName() + " initialization is already running, not restarting." );
- return;
- } else if ( initializationThread.isInterrupted() ) {
- log.warn( getOntologyName() + " initialization was interrupted, not restarting." );
- return;
- } else if ( !initializationThread.getState().equals( State.NEW ) ) {
- log.warn( getOntologyName() + " initialization was not ready to run: state="
- + initializationThread.getState() + ", not restarting." );
- return;
- }
-
- if ( !forceLoad && this.isOntologyLoaded() ) {
- log.warn( getOntologyName() + " is already loaded, and force=false, not restarting" );
- return;
- }
-
- boolean loadOntology = isEnabled();
+ private Thread initializationThread = null;
- // If loading ontologies is disabled in the configuration, return
- if ( !forceLoad && !loadOntology ) {
- log.debug( "Loading " + getOntologyName() + " is disabled (force=" + forceLoad + ", "
- + "Configuration load." + getOntologyName() + "=" + loadOntology + ")" );
- return;
+ @Override
+ public synchronized void startInitializationThread( boolean forceLoad, boolean forceIndexing ) {
+ if ( initializationThread != null && initializationThread.isAlive() ) {
+ log.warn( String.format( " Initialization thread for %s is currently running, not restarting.", getOntologyName() ) );
+ return;
+ }
+ // create and start the initialization thread
+ initializationThread = new Thread( () -> {
+ try {
+ this.initialize( forceLoad, forceIndexing );
+ } catch ( JenaException e ) {
+ if ( !( e.getCause() instanceof ParseException ) || ( ( ParseException ) e.getCause() ).getErrorNumber() != ARPErrorNumbers.ERR_INTERRUPTED ) {
+ throw e;
+ }
+ } catch ( Exception e ) {
+ log.error( e.getMessage(), e );
+ this.isInitialized = false;
}
+ }, getOntologyName() + "_load_thread_" + RandomStringUtils.randomAlphanumeric( 5 ) );
+ // To prevent VM from waiting on this thread to shutdown (if shutting down).
+ initializationThread.setDaemon( true );
+ initializationThread.start();
+ }
- // Detect configuration problems.
- if ( StringUtils.isBlank( this.getOntologyUrl() ) ) {
- throw new IllegalStateException( "URL not defined, ontology cannot be loaded ("
- + this.getClass().getSimpleName() + ")" );
- }
+ @Override
+ public boolean isInitializationThreadAlive() {
+ return initializationThread != null && initializationThread.isAlive();
+ }
- // This thread indexes ontology and creates local cache for uri->ontology terms mappings.
- if ( !forceIndexing ) {
- log.info( getOntologyName() + " index will *not* be refreshed unless the ontology "
- + "has changed or the index is misssing" );
- }
- initializationThread.setForceReindexing( forceLoad && forceIndexing );
- initializationThread.start();
- }
+ @Override
+ public boolean isInitializationThreadCancelled() {
+ return initializationThread != null && initializationThread.isInterrupted();
}
/**
* Cancel the initialization thread.
*/
+ @Override
public void cancelInitializationThread() {
- initializationThread.cancel();
- }
-
- /**
- * @param newTerms
- */
- protected void addTerms( Collection newTerms ) {
-
- if ( newTerms == null || newTerms.isEmpty() ) {
- log.warn( "No terms!" );
- return;
- }
-
- if ( terms == null ) terms = new HashMap<>();
- if ( individuals == null ) individuals = new HashMap<>();
-
- int i = 0;
- for ( OntologyResource term : newTerms ) {
- if ( term.getUri() == null ) continue;
- if ( term instanceof OntologyTerm ) terms.put( term.getUri(), ( OntologyTerm ) term );
- if ( term instanceof OntologyIndividual ) individuals.put( term.getUri(), ( OntologyIndividual ) term );
-
- if ( ++i % 1000 == 0 && initializationThread.isCancelled() ) {
- log.error( "Cancelled initialization" );
- this.isInitialized.set( false );
- return;
- }
+ if ( initializationThread == null ) {
+ throw new IllegalStateException( "The initialization thread has not started. Invoke startInitializationThread() first." );
}
+ initializationThread.interrupt();
}
- protected synchronized OntModel getModel() {
- if ( model == null ) {
- model = loadModel();
+ @Override
+ public void waitForInitializationThread() throws InterruptedException {
+ if ( initializationThread == null ) {
+ throw new IllegalStateException( "The initialization thread has not started. Invoke startInitializationThread() first." );
}
- return model;
+ initializationThread.join();
}
/**
- * The simple name of the ontology. Used for indexing purposes. (ie this will determine the name of the underlying
+ * The simple getOntologyName() of the ontology. Used for indexing purposes. (ie this will determine the getOntologyName() of the underlying
* index for searching the ontology)
- *
- * @return
*/
protected abstract String getOntologyName();
/**
- * Defines the location of the ontology eg: http://mged.sourceforge.net/ontologies/MGEDOntology.owl
- *
- * @return
+ * Defines the location of the ontology eg: MGED
*/
protected abstract String getOntologyUrl();
/**
* Delegates the call as to load the model into memory or leave it on disk. Simply delegates to either
* OntologyLoader.loadMemoryModel( url ); OR OntologyLoader.loadPersistentModel( url, spec );
- *
- * @param url
- * @return
- * @throws IOException
*/
protected abstract OntModel loadModel();
- /**
- * @param url
- * @param m
- * @throws IOException
- */
- protected void loadTermsInNameSpace( String url, OntModel m ) {
- Collection t = OntologyLoader.initialize( url, m );
- addTerms( t );
+ @Override
+ public void index( boolean force ) {
+ Lock lock = rwLock.writeLock();
+ try {
+ lock.lock();
+ if ( !isInitialized ) {
+ log.warn( String.format( "Ontology %s is not initialized, cannot index it.", getOntologyName() ) );
+ return;
+ }
+ index = OntologyIndexer.indexOntology( getOntologyName(), model, force );
+ } finally {
+ lock.unlock();
+ }
}
- /*
+ /**
+ * Initialize alternative IDs mapping.
+ *
* this add alternative id in 2 ways
- *
+ *
* Example :
- *
- * http://purl.obolibrary.org/obo/HP_0000005 with alternative id : HP:0001453
- *
- * by default way use in file 1- HP:0001453 -----> http://purl.obolibrary.org/obo/HP_0000005
- *
- * trying to use the value uri 2- http://purl.obolibrary.org/obo/HP_0001453 ----->
- * http://purl.obolibrary.org/obo/HP_0000005
+ *
+ * HP_0000005 with alternative id : HP:0001453
+ *
+ * by default way use in file 1- HP:0001453 -----> HP_0000005
+ *
+ * trying HP_0001453ibrary.org/obo/HP_0001453 ----->
+ * HP_0000005
*/
private void initSearchByAlternativeId() {
-
- // lets find the baseUrl, to change to valueUri
- String randomUri = terms.values().iterator().next().getUri();
- String baseOntologyUri = randomUri.substring( 0, randomUri.lastIndexOf( "/" ) + 1 );
-
+ alternativeIDs = new HashMap<>();
// for all Ontology terms that exist in the tree
- for ( OntologyTerm ontologyTerm : terms.values() ) {
-
+ ExtendedIterator iterator = model.listClasses();
+ while ( iterator.hasNext() ) {
+ OntClass ind = iterator.next();
+ OntologyTerm ontologyTerm = new OntologyTermImpl( ind );
+ // lets find the baseUri, to change to valueUri
+ String baseOntologyUri = ontologyTerm.getUri().substring( 0, ontologyTerm.getUri().lastIndexOf( "/" ) + 1 );
for ( String alternativeId : ontologyTerm.getAlternativeIds() ) {
// first way
- alternativeIDs.put( alternativeId, ontologyTerm );
-
- String alternativeIdModified = alternativeId.replace( ':', '_' );
-
+ alternativeIDs.put( alternativeId, ontologyTerm.getUri() );
// second way
- alternativeIDs.put( baseOntologyUri + alternativeIdModified, ontologyTerm );
+ String alternativeIdModified = alternativeId.replace( ':', '_' );
+ alternativeIDs.put( baseOntologyUri + alternativeIdModified, ontologyTerm.getUri() );
}
}
}
+ private OntologyTerm getTermInternal( String uri ) {
+ return termCache.computeIfAbsent( uri, u -> {
+ OntClass ontCls = model.getOntClass( u );
+ // bnode
+ if ( ontCls.getURI() == null ) {
+ return null;
+ }
+ return new OntologyTermImpl( ontCls );
+ } );
+ }
+
+ @Override
+ public void loadTermsInNameSpace( InputStream is, boolean forceIndex ) {
+ Lock lock = rwLock.writeLock();
+ try {
+ lock.lock();
+ this.isInitialized = false;
+
+ if ( initializationThread != null && initializationThread.isAlive() ) {
+ log.warn( this.getOntologyName() + " initialization is already running, trying to cancel ..." );
+ initializationThread.interrupt();
+ // wait for the thread to die.
+ int maxWait = 10;
+ int wait = 0;
+ while ( initializationThread.isAlive() ) {
+ try {
+ initializationThread.join( 5000 );
+ log.warn( "Waiting for auto-initialization to stop so manual initialization can begin ..." );
+ } catch ( InterruptedException e ) {
+ Thread.currentThread().interrupt();
+ log.warn( String.format( "Got interrupted while waiting for the initialization thread of %s to finish.", getOntologyName() ) );
+ return;
+ }
+ ++wait;
+ if ( wait >= maxWait && !initializationThread.isAlive() ) {
+ throw new RuntimeException( String.format( "Got tired of waiting for %s's initialization thread.", getOntologyName() ) );
+ }
+ }
+ }
+
+ this.model = OntologyLoader.loadMemoryModel( is, this.getOntologyUrl() );
+ this.termCache.clear();
+ this.index = OntologyIndexer.getSubjectIndex( getOntologyName() );
+ if ( index == null || forceIndex ) {
+ this.index = OntologyIndexer.indexOntology( getOntologyName(), model, true /* force */ );
+ }
+
+ isInitialized = true;
+ } finally {
+ lock.unlock();
+ }
+
+ log.info( this.getClass().getSimpleName() + " ready" );
+ }
}
\ No newline at end of file
diff --git a/src/ubic/basecode/ontology/providers/OntologyService.java b/src/ubic/basecode/ontology/providers/OntologyService.java
new file mode 100644
index 00000000..f50f2405
--- /dev/null
+++ b/src/ubic/basecode/ontology/providers/OntologyService.java
@@ -0,0 +1,103 @@
+package ubic.basecode.ontology.providers;
+
+import ubic.basecode.ontology.model.OntologyIndividual;
+import ubic.basecode.ontology.model.OntologyResource;
+import ubic.basecode.ontology.model.OntologyTerm;
+import ubic.basecode.ontology.search.OntologySearchException;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Set;
+
+public interface OntologyService {
+
+ /**
+ * Initialize this ontology service.
+ */
+ void initialize( boolean forceLoad, boolean forceIndexing );
+
+ /**
+ * Looks for any OntologyIndividuals that match the given search string.
+ */
+ Collection findIndividuals( String search ) throws OntologySearchException;
+
+ /**
+ * Looks for any OntologyIndividuals or ontologyTerms that match the given search string
+ *
+ * @return results, or an empty collection if the results are empty OR the ontology is not available to be
+ * searched.
+ */
+ Collection findResources( String searchString ) throws OntologySearchException;
+
+ /**
+ * Looks for any ontologyTerms that match the given search string. Obsolete terms are filtered out.
+ */
+ Collection findTerm( String search ) throws OntologySearchException;
+
+ OntologyTerm findUsingAlternativeId( String alternativeId );
+
+ Set getAllURIs();
+
+ /**
+ * Looks through both Terms and Individuals for a OntologyResource that has a uri matching the uri given. If no
+ * OntologyTerm is found only then will ontologyIndividuals be searched. returns null if nothing is found.
+ */
+ OntologyResource getResource( String uri );
+
+ /**
+ * Looks for a OntologyTerm that has the match in URI given
+ */
+ OntologyTerm getTerm( String uri );
+
+ Collection getTermIndividuals( String uri );
+
+ boolean isEnabled();
+
+ /**
+ * Used for determining if the Ontology has finished loading into memory. Although calls like getParents,
+ * getChildren will still work (its much faster once the ontologies have been preloaded into memory.)
+ */
+ boolean isOntologyLoaded();
+
+ /**
+ * Start the initialization thread.
+ *
+ * If the initialization thread is already running, this method does nothing. If the initialization thread
+ * previously completed, the ontology will be reinitialized.
+ *
+ * @param forceLoad Force loading of ontology, even if it is already loaded
+ * @param forceIndexing If forceLoad is also true, indexing will be performed. If you know the index is
+ * up to date, there's no need to do it again. Normally indexing is only done if there is no
+ * index, or if the ontology has changed since last loaded.
+ */
+ void startInitializationThread( boolean forceLoad, boolean forceIndexing );
+
+ boolean isInitializationThreadAlive();
+
+ boolean isInitializationThreadCancelled();
+
+ void cancelInitializationThread();
+
+ /**
+ * Wait for the initialization thread to finish.
+ */
+ void waitForInitializationThread() throws InterruptedException;
+
+ /**
+ * Index the ontology for performing full-text searches.
+ *
+ * @see #findIndividuals(String)
+ * @see #findTerm(String)
+ * @see #findResources(String)
+ */
+ void index( boolean force );
+
+ /**
+ * For testing! Overrides normal way of loading the ontology. This does not index the ontology unless 'force' is
+ * true (if there is an existing index, it will be used)
+ *
+ * @param is input stream from which the ontology model is loaded
+ * @param forceIndex initialize the index. Otherwise it will only be initialized if it doesn't exist.
+ */
+ void loadTermsInNameSpace( InputStream is, boolean forceIndex );
+}
diff --git a/test/data/uberon.owl.gz b/test/data/uberon.owl.gz
new file mode 100644
index 00000000..34e4a6f7
Binary files /dev/null and b/test/data/uberon.owl.gz differ
diff --git a/test/log4j2-test.xml b/test/log4j2-test.xml
index d130a10c..b275c446 100644
--- a/test/log4j2-test.xml
+++ b/test/log4j2-test.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/test/ubic/basecode/ontology/OntologyTermTest.java b/test/ubic/basecode/ontology/OntologyTermTest.java
index cc891809..ed0fe4bf 100644
--- a/test/ubic/basecode/ontology/OntologyTermTest.java
+++ b/test/ubic/basecode/ontology/OntologyTermTest.java
@@ -1,36 +1,34 @@
/*
* The baseCode project
- *
+ *
* Copyright (c) 2012 University of British Columbia
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package ubic.basecode.ontology;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.zip.GZIPInputStream;
-
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import ubic.basecode.ontology.model.OntologyTerm;
import ubic.basecode.ontology.providers.CellLineOntologyService;
import ubic.basecode.ontology.providers.DiseaseOntologyService;
import ubic.basecode.ontology.providers.NIFSTDOntologyService;
+import ubic.basecode.ontology.providers.UberonOntologyService;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.zip.GZIPInputStream;
+
+import static org.junit.Assert.*;
/**
* @author Paul
@@ -82,7 +80,7 @@ public void testGetChildren() throws Exception {
/**
* FIXME this uses NIF, which we are no longer using actively - not a big deal since this just tests mechanics
- *
+ *
* @throws Exception
*/
@Test
@@ -92,13 +90,11 @@ public void testGetChildrenHasProperPart() throws Exception {
"/data/NIF-GrossAnatomy.small.owl.xml.gz" ) );
s.loadTermsInNameSpace( is, false );
- OntologyTerm t = s
- .getTerm( "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_734" );
-
+ OntologyTerm t = s.getTerm( "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_734" );
assertNotNull( t );
Collection c = t.getChildren( true );
- assertEquals( 9, c.size() );
+ assertEquals( 6, c.size() );
// Dorsal hypothalamic area [birnlex_777]
// Lateral hypothalamic area [birnlex_4037]
// Medial forebrain bundle [birnlex_908]
@@ -108,36 +104,15 @@ public void testGetChildrenHasProperPart() throws Exception {
// Anterior hypothalamic region [birnlex_1005]
// Intermediate hypothalamic region [birnlex_1015]
// Regional part of hypothalamus [birnlex_995]
- boolean found = false;
- for ( OntologyTerm o : c ) {
- // System.err.println( o );
- if ( o.getUri().equals(
- "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_898" ) ) {
- found = true;
- }
- }
- assertTrue( found );
+ OntologyTerm t1 = s.getTerm( "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_898" );
+ assertNotNull( t1 );
+ assertTrue( c.contains( t1 ) );
Collection c2 = t.getChildren( false );
- assertEquals( 11, c2.size() );
- found = false;
- for ( OntologyTerm o : c2 ) {
- System.err.println( o );
- if ( o.getUri().equals(
- "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_4037" ) ) {
- found = true;
- }
-
- // exercise other things.
- log.info( "Annotations: " + StringUtils.join( o.getAnnotations(), "," ) );
- log.info( "Comment: " + o.getComment() );
- log.info( "Individuals: " + StringUtils.join( o.getIndividuals(), "," ) );
- log.info( "Individuals: " + StringUtils.join( o.getIndividuals( true ), "," ) );
- log.info( "Individuals: " + StringUtils.join( o.getIndividuals( false ), "," ) );
- // Log.info( "Restrictions: "+ StringUtils.join( o.getRestrictions(), "," ) );
- log.info( "AlternativeIDs: " + StringUtils.join( o.getAlternativeIds(), "," ) );
- }
- assertTrue( found );
+ assertEquals( 6, c2.size() );
+ OntologyTerm t2 = s.getTerm( "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_4037" );
+ assertNotNull( t2 );
+ assertTrue( c.contains( t2 ) );
}
@Test
@@ -219,27 +194,16 @@ public void testGetParentsHasProperPart() throws Exception {
// Diencephalon [birnlex_1503] x
Collection parents2 = t.getParents( false );
- assertEquals( 12, parents2.size() );
+ assertEquals( 5, parents2.size() );
// does not includes 'continuant' and 'independent continuant' or parents of those terms.
- found = false;
- for ( OntologyTerm p : parents2 ) {
- // System.err.println( p + " " + p.getUri() );
-
- if ( p.getUri().equals(
- "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_1503" ) ) {
- found = true;
- }
-
- assertTrue( !p.getUri().equals( "http://www.ifomis.org/bfo/1.1/snap#Continuant" ) );
-
- }
- assertTrue( found );
+ // assertTrue( parents2.contains( s.getTerm( "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_1503" ) ) );
+ assertFalse( parents2.contains( s.getResource( "http://www.ifomis.org/bfo/1.1/snap#Continuant" ) ) );
}
-
+
@Test
public void testRejectNonEnglish() throws Exception {
- CellLineOntologyService s = new CellLineOntologyService();
+ CellLineOntologyService s = new CellLineOntologyService();
InputStream is = new GZIPInputStream( this.getClass().getResourceAsStream( "/data/clo_merged.sample.owl.xml.gz" ) );
s.loadTermsInNameSpace( is, false );
@@ -247,4 +211,41 @@ public void testRejectNonEnglish() throws Exception {
assertEquals( "immortal larynx-derived cell line cell", t.getLabel() );
}
+
+ @Test
+ public void testGetParentsHasPart() throws Exception {
+ UberonOntologyService s = new UberonOntologyService();
+ try ( InputStream is = new GZIPInputStream( getClass().getResourceAsStream( "/data/uberon.owl.gz" ) ) ) {
+ s.loadTermsInNameSpace( is, false );
+ }
+ OntologyTerm t = s.getTerm( "http://purl.obolibrary.org/obo/UBERON_0000955" );
+ assertNotNull( t );
+ Collection parents = t.getParents( true );
+ assertEquals( 3, parents.size() );
+ // does not contain itself
+ assertFalse( parents.contains( t ) );
+ // via subclass
+ assertTrue( parents.contains( s.getTerm( "http://purl.obolibrary.org/obo/UBERON_0004121" ) ) );
+ assertTrue( parents.contains( s.getTerm( "http://purl.obolibrary.org/obo/UBERON_0000062" ) ) );
+ // via part of, central nervous system
+ assertTrue( parents.contains( s.getTerm( "http://purl.obolibrary.org/obo/UBERON_0001017" ) ) );
+ }
+
+ @Test
+ public void testGetChildrenHasPart() throws Exception {
+ UberonOntologyService s = new UberonOntologyService();
+ try ( InputStream is = new GZIPInputStream( getClass().getResourceAsStream( "/data/uberon.owl.gz" ) ) ) {
+ s.loadTermsInNameSpace( is, false );
+ }
+ OntologyTerm t = s.getTerm( "http://purl.obolibrary.org/obo/UBERON_0000955" );
+ assertNotNull( t );
+ Collection children = t.getChildren( false );
+ assertEquals( 1496, children.size() );
+ // via subclass of, insect adult brain
+ assertTrue( children.contains( s.getTerm( "http://purl.obolibrary.org/obo/UBERON_6003624" ) ) );
+ // via part of, nucleus of brain
+ assertTrue( children.contains( s.getTerm( "http://purl.obolibrary.org/obo/UBERON_0002308" ) ) );
+ // does not contain owl:Nothing
+ assertFalse( children.contains( s.getTerm( "http://www.w3.org/2002/07/owl#Nothing" ) ) );
+ }
}
diff --git a/test/ubic/basecode/ontology/providers/AbstractOntologyServiceTest.java b/test/ubic/basecode/ontology/providers/AbstractOntologyServiceTest.java
index 50a0aea9..ef8f91ad 100644
--- a/test/ubic/basecode/ontology/providers/AbstractOntologyServiceTest.java
+++ b/test/ubic/basecode/ontology/providers/AbstractOntologyServiceTest.java
@@ -1,8 +1,8 @@
/*
* The baseCode project
- *
+ *
* Copyright (c) 2017 University of British Columbia
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -19,22 +19,22 @@
package ubic.basecode.ontology.providers;
-import static org.junit.Assert.assertTrue;
-
import java.io.File;
import java.net.URL;
import java.util.Collection;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import ubic.basecode.ontology.OntologyLoader;
import ubic.basecode.ontology.model.OntologyTerm;
import ubic.basecode.util.Configuration;
+import static org.junit.Assert.*;
+
/**
- *
* @author mjacobson
*/
public class AbstractOntologyServiceTest {
@@ -54,6 +54,7 @@ public static void tearDown() throws Exception {
}
@Test
+ @Ignore("This test was always broken, but the failure was obscured in a thread.")
public void testCacheOntologyToDisk() throws Exception {
String name = "fooTEST1234";
@@ -104,19 +105,22 @@ public void testReindexOnInitialize() throws Exception {
}
- private GenericOntologyService createService( String name, String resourceURL, boolean cache ) throws Exception {
-
- GenericOntologyService s = new GenericOntologyService( name, resourceURL, cache );
-
+ @Test
+ public void testInitializeInBackgroundThread() throws InterruptedException {
+ URL resource = this.getClass().getResource( dataResource );
+ assertNotNull( resource );
+ GenericOntologyService s = new GenericOntologyService( "foo", resource.toString(), false );
s.startInitializationThread( true, false );
- int i = 0;
- while ( s.isInitializationThreadAlive() && !s.isOntologyLoaded() ) {
- Thread.sleep( 1000 );
- if ( ++i > 100 ) {
- break;
- }
- }
+ assertTrue( s.isInitializationThreadAlive() );
+ s.cancelInitializationThread();
+ assertTrue( s.isInitializationThreadCancelled() );
+ s.waitForInitializationThread();
+ assertFalse( s.isInitializationThreadAlive() );
+ }
+ private GenericOntologyService createService( String name, String resourceURL, boolean cache ) throws Exception {
+ GenericOntologyService s = new GenericOntologyService( name, resourceURL, cache );
+ s.initialize( true, false );
return s;
}
}
diff --git a/test/ubic/basecode/ontology/providers/ObiServiceTest.java b/test/ubic/basecode/ontology/providers/ObiServiceTest.java
index 54518e10..5eaa2c4e 100644
--- a/test/ubic/basecode/ontology/providers/ObiServiceTest.java
+++ b/test/ubic/basecode/ontology/providers/ObiServiceTest.java
@@ -1,13 +1,13 @@
/*
* The baseCode project
- *
+ *
* Copyright (c) 2012 University of British Columbia
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
@@ -37,18 +37,7 @@ public class ObiServiceTest {
@Test
public void testLoadAndSearch() throws Exception {
ObiService m = new ObiService();
- m.startInitializationThread( true, false );
- m.startInitializationThread( true, false );
- m.startInitializationThread( true, false );
- int i = 0;
- while ( !m.isOntologyLoaded() ) {
-
- Thread.sleep( 3000 );
- i++;
- log.info( "Waiting for OBI to load ... " + i );
-
- if ( i > 20 ) fail( "OBI Ontology didn't load in time" );
- }
+ m.initialize( true, false );
assertTrue( m.isOntologyLoaded() );
diff --git a/test/ubic/basecode/ontology/search/OntologySearchTest.java b/test/ubic/basecode/ontology/search/OntologySearchTest.java
index f8a7b1b7..1fb1caf5 100644
--- a/test/ubic/basecode/ontology/search/OntologySearchTest.java
+++ b/test/ubic/basecode/ontology/search/OntologySearchTest.java
@@ -14,36 +14,31 @@
*/
package ubic.basecode.ontology.search;
-import static org.junit.Assert.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.*;
+import com.hp.hpl.jena.ontology.OntModel;
+import com.hp.hpl.jena.shared.JenaException;
+import org.junit.Test;
+import ubic.basecode.ontology.OntologyLoader;
+import ubic.basecode.ontology.model.OntologyTerm;
import java.io.InputStream;
import java.util.Collection;
import java.util.zip.GZIPInputStream;
-import com.hp.hpl.jena.shared.JenaException;
-import org.junit.Test;
-
-import com.hp.hpl.jena.ontology.OntModel;
-import com.hp.hpl.jena.ontology.OntModelSpec;
-
-import ubic.basecode.ontology.OntologyLoader;
-import ubic.basecode.ontology.model.OntologyTerm;
+import static org.junit.Assert.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
/**
* Most of these tests were moved over from Gemma.
*
* @author Paul
- *
*/
public class OntologySearchTest {
@Test
public final void testIndexing() throws Exception {
InputStream is = new GZIPInputStream( this.getClass().getResourceAsStream( "/data/mged.owl.gz" ) );
- OntModel model = OntologyLoader.loadMemoryModel( is, "owl-test", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "owl-test" );
SearchIndex index = OntologyIndexer.indexOntology( "MGEDTEST", model, true );
@@ -68,7 +63,7 @@ public final void testIndexing() throws Exception {
public final void testOmitBadPredicates() throws Exception {
InputStream is = this.getClass().getResourceAsStream( "/data/niforgantest.owl.xml" );
- OntModel model = OntologyLoader.loadMemoryModel( is, "NIFTEST", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "NIFTEST" );
is.close();
SearchIndex index = OntologyIndexer.indexOntology( "NIFTEST", model, true );
@@ -105,7 +100,7 @@ public final void testOmitBadPredicates() throws Exception {
@Test
public final void testOmitBadPredicates2() throws Exception {
InputStream is = this.getClass().getResourceAsStream( "/data/eftest.owl.xml" );
- OntModel model = OntologyLoader.loadMemoryModel( is, "EFTEST", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "EFTEST" );
is.close();
SearchIndex index = OntologyIndexer.indexOntology( "EFTEST", model, true );
@@ -128,7 +123,7 @@ public final void testOmitBadPredicates2() throws Exception {
@Test
public final void testOmitDefinitions() throws Exception {
InputStream is = this.getClass().getResourceAsStream( "/data/dotest.owl.xml" );
- OntModel model = OntologyLoader.loadMemoryModel( is, "DO_TEST", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "DO_TEST" );
is.close();
SearchIndex index = OntologyIndexer.indexOntology( "DO_TEST", model, true );
@@ -150,7 +145,7 @@ public final void testOmitDefinitions() throws Exception {
@Test
public final void testOmitDefinitions2() throws Exception {
InputStream is = this.getClass().getResourceAsStream( "/data/nif.organism.test.owl.xml" );
- OntModel model = OntologyLoader.loadMemoryModel( is, "NIFORG_TEST", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "NIFORG_TEST" );
is.close();
SearchIndex index = OntologyIndexer.indexOntology( "NIFORG_TEST", model, true );
@@ -190,7 +185,7 @@ public final void testOmitDefinitions2() throws Exception {
@Test
public final void testOmitDefinitions3() throws Exception {
InputStream is = this.getClass().getResourceAsStream( "/data/obi.test.owl.xml" );
- OntModel model = OntologyLoader.loadMemoryModel( is, "OBI_TEST", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "OBI_TEST" );
SearchIndex index = OntologyIndexer.indexOntology( "OBI_TEST", model, true );
@@ -213,7 +208,7 @@ public final void testOmitDefinitions3() throws Exception {
public final void testOmitDefinitions4() throws Exception {
InputStream is = new GZIPInputStream( this.getClass().getResourceAsStream( "/data/NIF-GrossAnatomy.owl.gz" ) );
- OntModel model = OntologyLoader.loadMemoryModel( is, "NIFAN_TEST2", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "NIFAN_TEST2" );
is.close();
SearchIndex index = OntologyIndexer.indexOntology( "NIFAN_TEST2", model, true );
@@ -238,7 +233,7 @@ public final void testOmitDefinitions4() throws Exception {
@Test
public final void testPersistence() throws Exception {
InputStream is = new GZIPInputStream( this.getClass().getResourceAsStream( "/data/mged.owl.gz" ) );
- OntModel model = OntologyLoader.loadMemoryModel( is, "owl-test", OntModelSpec.OWL_MEM_TRANS_INF );
+ OntModel model = OntologyLoader.loadMemoryModel( is, "owl-test" );
SearchIndex index = OntologyIndexer.indexOntology( "MGEDTEST", model, false );
index.close();