Skip to content

Commit a9f1d3d

Browse files
committed
Merge branch 'hotfix-1.1.17'
2 parents af27f36 + faa4af7 commit a9f1d3d

17 files changed

Lines changed: 284 additions & 163 deletions

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<name>baseCode</name>
66
<groupId>baseCode</groupId>
77
<artifactId>baseCode</artifactId>
8-
<version>1.1.16</version>
8+
<version>1.1.17</version>
99
<inceptionYear>2003</inceptionYear>
1010
<description>
1111
<![CDATA[Data structures, math and statistics tools, and utilities that are often needed across projects.]]>

src/ontology.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ load.mouseDevelOntology=false
88
load.mammalPhenotypeOntology=false
99
load.humanPhenotypeOntology=false
1010
load.obiOntology=false
11-
load.soOntology=false
11+
load.seqOntology=false
1212
load.nifstdOntology=false
1313
load.experimentalFactorOntology=false
1414
load.uberonOntology=false

src/ubic/basecode/ontology/jena/AbstractOntologyMemoryBackedService.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
package ubic.basecode.ontology.jena;
1616

1717
import com.hp.hpl.jena.ontology.OntModel;
18+
import com.hp.hpl.jena.ontology.OntModelSpec;
19+
import ubic.basecode.util.Configuration;
1820

21+
import java.io.IOException;
1922
import java.io.InputStream;
2023

2124
/**
@@ -26,17 +29,29 @@
2629
*/
2730
public abstract class AbstractOntologyMemoryBackedService extends AbstractOntologyService {
2831

29-
protected boolean getProcessImport() {
30-
return true;
32+
@Override
33+
protected String getOntologyUrl() {
34+
return Configuration.getString( "url." + getOntologyName() );
3135
}
3236

3337
@Override
34-
protected OntModel loadModel() {
35-
return OntologyLoader.loadMemoryModel( this.getOntologyUrl(), this.getCacheName(), this.getProcessImport() );
38+
protected OntModel loadModel( boolean processImports, InferenceMode inferenceMode ) throws IOException {
39+
return OntologyLoader.loadMemoryModel( this.getOntologyUrl(), this.getCacheName(), processImports, this.getSpec( inferenceMode ) );
3640
}
3741

3842
@Override
39-
protected OntModel loadModelFromStream( InputStream is ) {
40-
return OntologyLoader.loadMemoryModel( is, this.getOntologyUrl(), this.getProcessImport() );
43+
protected OntModel loadModelFromStream( InputStream is, boolean processImports, InferenceMode inferenceMode ) {
44+
return OntologyLoader.loadMemoryModel( is, this.getOntologyUrl(), processImports, this.getSpec( inferenceMode ) );
45+
}
46+
47+
private OntModelSpec getSpec( InferenceMode inferenceMode ) {
48+
switch ( inferenceMode ) {
49+
case TRANSITIVE:
50+
return OntModelSpec.OWL_MEM_TRANS_INF;
51+
case NONE:
52+
return OntModelSpec.OWL_MEM;
53+
default:
54+
throw new UnsupportedOperationException( String.format( "Unsupported inference level %s.", inferenceMode ) );
55+
}
4156
}
4257
}

src/ubic/basecode/ontology/jena/AbstractOntologyService.java

Lines changed: 129 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@
4646
import javax.annotation.Nullable;
4747
import java.io.IOException;
4848
import java.io.InputStream;
49+
import java.io.InterruptedIOException;
50+
import java.nio.channels.ClosedByInterruptException;
4951
import java.util.*;
5052
import java.util.concurrent.locks.Lock;
5153
import java.util.concurrent.locks.ReadWriteLock;
5254
import java.util.concurrent.locks.ReentrantReadWriteLock;
55+
import java.util.function.Predicate;
5356
import java.util.stream.Collectors;
5457

5558
import static ubic.basecode.ontology.jena.JenaUtils.where;
@@ -75,6 +78,11 @@ public abstract class AbstractOntologyService implements OntologyService {
7578
additionalProperties.add( RO.properPartOf );
7679
}
7780

81+
/* settings (applicable for next initialization) */
82+
private InferenceMode nextInferenceMode = InferenceMode.TRANSITIVE;
83+
private boolean nextProcessImports = true;
84+
private boolean nextSearchEnabled = true;
85+
7886
/**
7987
* Lock used to prevent reads while the ontology is being initialized.
8088
*/
@@ -83,13 +91,64 @@ public abstract class AbstractOntologyService implements OntologyService {
8391
/* internal state protected by rwLock */
8492
private OntModel model;
8593
private Map<String, String> alternativeIDs;
86-
8794
@Nullable
8895
private SearchIndex index;
89-
9096
private Set<Restriction> additionalRestrictions;
91-
9297
private boolean isInitialized = false;
98+
@Nullable
99+
private InferenceMode inferenceMode = null;
100+
@Nullable
101+
private Boolean processImports = null;
102+
@Nullable
103+
private Boolean searchEnabled = null;
104+
105+
@Override
106+
public InferenceMode getInferenceMode() {
107+
Lock lock = rwLock.readLock();
108+
try {
109+
lock.lock();
110+
return this.inferenceMode != null ? this.inferenceMode : nextInferenceMode;
111+
} finally {
112+
lock.unlock();
113+
}
114+
}
115+
116+
@Override
117+
public void setInferenceMode( InferenceMode inferenceMode ) {
118+
this.nextInferenceMode = inferenceMode;
119+
}
120+
121+
@Override
122+
public boolean getProcessImports() {
123+
Lock lock = rwLock.readLock();
124+
try {
125+
lock.lock();
126+
return processImports != null ? processImports : nextProcessImports;
127+
} finally {
128+
lock.unlock();
129+
}
130+
}
131+
132+
@Override
133+
public void setProcessImports( boolean processImports ) {
134+
this.nextProcessImports = processImports;
135+
}
136+
137+
@Override
138+
public boolean isSearchEnabled() {
139+
Lock lock = rwLock.readLock();
140+
try {
141+
lock.lock();
142+
return searchEnabled != null ? searchEnabled : nextSearchEnabled;
143+
} finally {
144+
lock.unlock();
145+
}
146+
}
147+
148+
@Override
149+
public void setSearchEnabled( boolean searchEnabled ) {
150+
this.nextSearchEnabled = searchEnabled;
151+
}
93152

94153
public void initialize( boolean forceLoad, boolean forceIndexing ) {
95154
initialize( null, forceLoad, forceIndexing );
@@ -108,6 +167,9 @@ private void initialize( @Nullable InputStream stream, boolean forceLoad, boolea
108167
String ontologyUrl = getOntologyUrl();
109168
String ontologyName = getOntologyName();
110169
String cacheName = getCacheName();
170+
InferenceMode inferenceMode = nextInferenceMode;
171+
boolean processImports = nextProcessImports;
172+
boolean searchEnabled = nextSearchEnabled;
111173

112174
// Detect configuration problems.
113175
if ( StringUtils.isBlank( ontologyUrl ) ) {
@@ -138,8 +200,15 @@ private void initialize( @Nullable InputStream stream, boolean forceLoad, boolea
138200
if ( checkIfInterrupted() )
139201
return;
140202

141-
model = stream != null ? loadModelFromStream( stream ) : loadModel(); // can take a while.
142-
assert model != null;
203+
try {
204+
model = stream != null ? loadModelFromStream( stream, processImports, inferenceMode ) : loadModel( processImports, inferenceMode ); // can take a while.
205+
} catch ( Exception e ) {
206+
if ( isCausedByInterrupt( e ) ) {
207+
return;
208+
} else {
209+
throw new RuntimeException( String.format( "Failed to load ontology model for %s.", this ), e );
210+
}
211+
}
143212

144213
// retrieving restrictions is lengthy
145214
if ( checkIfInterrupted() )
@@ -154,14 +223,22 @@ private void initialize( @Nullable InputStream stream, boolean forceLoad, boolea
154223
if ( checkIfInterrupted() )
155224
return;
156225

157-
if ( cacheName != null ) {
226+
if ( searchEnabled && cacheName != null ) {
158227
//Checks if the current ontology has changed since it was last loaded.
159228
boolean changed = OntologyLoader.hasChanged( cacheName );
160229
boolean indexExists = OntologyIndexer.getSubjectIndex( cacheName ) != null;
161230
boolean forceReindexing = forceLoad && forceIndexing;
162231
// indexing is slow, don't do it if we don't have to.
163-
index = OntologyIndexer.indexOntology( cacheName, model,
164-
forceReindexing || changed || !indexExists );
232+
try {
233+
index = OntologyIndexer.indexOntology( cacheName, model,
234+
forceReindexing || changed || !indexExists );
235+
} catch ( Exception e ) {
236+
if ( isCausedByInterrupt( e ) ) {
237+
return;
238+
} else {
239+
throw new RuntimeException( String.format( "Failed to generate index for %s.", this ), e );
240+
}
241+
}
165242
} else {
166243
index = null;
167244
}
@@ -177,6 +254,9 @@ private void initialize( @Nullable InputStream stream, boolean forceLoad, boolea
177254
this.additionalRestrictions = additionalRestrictions;
178255
this.index = index;
179256
this.isInitialized = true;
257+
this.inferenceMode = inferenceMode;
258+
this.processImports = processImports;
259+
this.searchEnabled = searchEnabled;
180260
if ( cacheName != null ) {
181261
// now that the terms have been replaced, we can clear old caches
182262
try {
@@ -202,6 +282,21 @@ private boolean checkIfInterrupted() {
202282
return false;
203283
}
204284

285+
private static boolean isCausedByInterrupt( Exception e ) {
286+
return hasCauseMatching( e, cause -> ( ( cause instanceof ParseException ) && ( ( ParseException ) cause ).getErrorNumber() == ARPErrorNumbers.ERR_INTERRUPTED ) ) ||
287+
hasCause( e, InterruptedException.class ) ||
288+
hasCause( e, InterruptedIOException.class ) ||
289+
hasCause( e, ClosedByInterruptException.class );
290+
}
291+
292+
private static boolean hasCause( Throwable t, Class<? extends Throwable> clazz ) {
293+
return hasCauseMatching( t, clazz::isInstance );
294+
}
295+
296+
private static boolean hasCauseMatching( Throwable t, Predicate<Throwable> predicate ) {
297+
return predicate.test( t ) || ( t.getCause() != null && hasCauseMatching( t.getCause(), predicate ) );
298+
}
299+
205300
/**
206301
* Do not do this except before re-indexing.
207302
*/
@@ -211,7 +306,8 @@ public void closeIndex() {
211306
}
212307

213308
@Override
214-
public Collection<OntologyIndividual> findIndividuals( String search, boolean keepObsoletes ) throws OntologySearchException {
309+
public Collection<OntologyIndividual> findIndividuals( String search, boolean keepObsoletes ) throws
310+
OntologySearchException {
215311
Lock lock = rwLock.readLock();
216312
try {
217313
lock.lock();
@@ -233,7 +329,8 @@ public Collection<OntologyIndividual> findIndividuals( String search, boolean ke
233329
}
234330

235331
@Override
236-
public Collection<OntologyResource> findResources( String searchString, boolean keepObsoletes ) throws OntologySearchException {
332+
public Collection<OntologyResource> findResources( String searchString, boolean keepObsoletes ) throws
333+
OntologySearchException {
237334
Lock lock = rwLock.readLock();
238335
try {
239336
lock.lock();
@@ -393,7 +490,8 @@ public Collection<OntologyIndividual> getTermIndividuals( String uri ) {
393490
}
394491

395492
@Override
396-
public Set<OntologyTerm> getParents( Collection<OntologyTerm> terms, boolean direct, boolean includeAdditionalProperties, boolean keepObsoletes ) {
493+
public Set<OntologyTerm> getParents( Collection<OntologyTerm> terms, boolean direct,
494+
boolean includeAdditionalProperties, boolean keepObsoletes ) {
397495
Lock lock = rwLock.readLock();
398496
try {
399497
lock.lock();
@@ -411,7 +509,8 @@ public Set<OntologyTerm> getParents( Collection<OntologyTerm> terms, boolean dir
411509
}
412510

413511
@Override
414-
public Set<OntologyTerm> getChildren( Collection<OntologyTerm> terms, boolean direct, boolean includeAdditionalProperties, boolean keepObsoletes ) {
512+
public Set<OntologyTerm> getChildren( Collection<OntologyTerm> terms, boolean direct,
513+
boolean includeAdditionalProperties, boolean keepObsoletes ) {
415514
Lock lock = rwLock.readLock();
416515
try {
417516
lock.lock();
@@ -463,13 +562,8 @@ public synchronized void startInitializationThread( boolean forceLoad, boolean f
463562
initializationThread = new Thread( () -> {
464563
try {
465564
this.initialize( forceLoad, forceIndexing );
466-
} catch ( JenaException e ) {
467-
if ( !( e.getCause() instanceof ParseException ) || ( ( ParseException ) e.getCause() ).getErrorNumber() != ARPErrorNumbers.ERR_INTERRUPTED ) {
468-
throw e;
469-
}
470565
} catch ( Exception e ) {
471-
log.error( e.getMessage(), e );
472-
this.isInitialized = false;
566+
log.error( "Initialization for %s failed.", e );
473567
}
474568
}, getOntologyName() + "_load_thread_" + RandomStringUtils.randomAlphanumeric( 5 ) );
475569
// To prevent VM from waiting on this thread to shut down (if shutting down).
@@ -521,13 +615,13 @@ public void waitForInitializationThread() throws InterruptedException {
521615
* Delegates the call as to load the model into memory or leave it on disk. Simply delegates to either
522616
* OntologyLoader.loadMemoryModel( url ); OR OntologyLoader.loadPersistentModel( url, spec );
523617
*/
524-
protected abstract OntModel loadModel();
618+
protected abstract OntModel loadModel( boolean processImports, InferenceMode inferenceMode ) throws JenaException, IOException;
525619

526620

527621
/**
528622
* Load a model from a given input stream.
529623
*/
530-
protected abstract OntModel loadModelFromStream( InputStream stream );
624+
protected abstract OntModel loadModelFromStream( InputStream stream, boolean processImports, InferenceMode inferenceMode ) throws JenaException, IOException;
531625

532626
/**
533627
* A name for caching this ontology, or null to disable caching.
@@ -546,6 +640,10 @@ public void index( boolean force ) {
546640
log.warn( "This ontology does not support indexing; assign a cache name to be used." );
547641
return;
548642
}
643+
if ( !nextSearchEnabled ) {
644+
log.warn( "Search is not enabled for this ontology." );
645+
return;
646+
}
549647
SearchIndex index;
550648
Lock lock = rwLock.readLock();
551649
try {
@@ -555,6 +653,9 @@ public void index( boolean force ) {
555653
return;
556654
}
557655
index = OntologyIndexer.indexOntology( getCacheName(), model, force );
656+
} catch ( IOException e ) {
657+
log.error( "Failed to generate index for {}.", this, e );
658+
return;
558659
} finally {
559660
lock.unlock();
560661
}
@@ -563,6 +664,7 @@ public void index( boolean force ) {
563664
try {
564665
lock.lock();
565666
this.index = index;
667+
this.searchEnabled = true;
566668
} finally {
567669
lock.unlock();
568670
}
@@ -635,9 +737,13 @@ public String toString() {
635737

636738
private Set<OntClass> getOntClassesFromTerms( Collection<OntologyTerm> terms ) {
637739
return terms.stream()
638-
.map( OntologyTerm::getUri )
639-
.filter( Objects::nonNull )
640-
.map( model::getOntClass )
740+
.map( o -> {
741+
if ( o instanceof OntologyTermImpl ) {
742+
return ( ( OntologyTermImpl ) o ).getOntClass();
743+
} else {
744+
return o.getUri() != null ? model.getOntClass( o.getUri() ) : null;
745+
}
746+
} )
641747
.filter( Objects::nonNull )
642748
.collect( Collectors.toSet() );
643749
}

0 commit comments

Comments
 (0)