4646import javax .annotation .Nullable ;
4747import java .io .IOException ;
4848import java .io .InputStream ;
49+ import java .io .InterruptedIOException ;
50+ import java .nio .channels .ClosedByInterruptException ;
4951import java .util .*;
5052import java .util .concurrent .locks .Lock ;
5153import java .util .concurrent .locks .ReadWriteLock ;
5254import java .util .concurrent .locks .ReentrantReadWriteLock ;
55+ import java .util .function .Predicate ;
5356import java .util .stream .Collectors ;
5457
5558import static ubic .basecode .ontology .jena .JenaUtils .where ;
@@ -138,8 +141,15 @@ private void initialize( @Nullable InputStream stream, boolean forceLoad, boolea
138141 if ( checkIfInterrupted () )
139142 return ;
140143
141- model = stream != null ? loadModelFromStream ( stream ) : loadModel (); // can take a while.
142- assert model != null ;
144+ try {
145+ model = stream != null ? loadModelFromStream ( stream ) : loadModel (); // can take a while.
146+ } catch ( Exception e ) {
147+ if ( isCausedByInterrupt ( e ) ) {
148+ return ;
149+ } else {
150+ throw new RuntimeException ( String .format ( "Failed to load ontology model for %s." , this ), e );
151+ }
152+ }
143153
144154 // retrieving restrictions is lengthy
145155 if ( checkIfInterrupted () )
@@ -160,8 +170,16 @@ private void initialize( @Nullable InputStream stream, boolean forceLoad, boolea
160170 boolean indexExists = OntologyIndexer .getSubjectIndex ( cacheName ) != null ;
161171 boolean forceReindexing = forceLoad && forceIndexing ;
162172 // indexing is slow, don't do it if we don't have to.
163- index = OntologyIndexer .indexOntology ( cacheName , model ,
164- forceReindexing || changed || !indexExists );
173+ try {
174+ index = OntologyIndexer .indexOntology ( cacheName , model ,
175+ forceReindexing || changed || !indexExists );
176+ } catch ( Exception e ) {
177+ if ( isCausedByInterrupt ( e ) ) {
178+ return ;
179+ } else {
180+ throw new RuntimeException ( String .format ( "Failed to generate index for %s." , this ), e );
181+ }
182+ }
165183 } else {
166184 index = null ;
167185 }
@@ -202,6 +220,21 @@ private boolean checkIfInterrupted() {
202220 return false ;
203221 }
204222
223+ private static boolean isCausedByInterrupt ( Exception e ) {
224+ return hasCauseMatching ( e , cause -> ( ( cause instanceof ParseException ) && ( ( ParseException ) cause ).getErrorNumber () == ARPErrorNumbers .ERR_INTERRUPTED ) ) ||
225+ hasCause ( e , InterruptedException .class ) ||
226+ hasCause ( e , InterruptedIOException .class ) ||
227+ hasCause ( e , ClosedByInterruptException .class );
228+ }
229+
230+ private static boolean hasCause ( Throwable t , Class <? extends Throwable > clazz ) {
231+ return hasCauseMatching ( t , clazz ::isInstance );
232+ }
233+
234+ private static boolean hasCauseMatching ( Throwable t , Predicate <Throwable > predicate ) {
235+ return predicate .test ( t ) || ( t .getCause () != null && hasCauseMatching ( t .getCause (), predicate ) );
236+ }
237+
205238 /**
206239 * Do not do this except before re-indexing.
207240 */
@@ -211,7 +244,8 @@ public void closeIndex() {
211244 }
212245
213246 @ Override
214- public Collection <OntologyIndividual > findIndividuals ( String search , boolean keepObsoletes ) throws OntologySearchException {
247+ public Collection <OntologyIndividual > findIndividuals ( String search , boolean keepObsoletes ) throws
248+ OntologySearchException {
215249 Lock lock = rwLock .readLock ();
216250 try {
217251 lock .lock ();
@@ -233,7 +267,8 @@ public Collection<OntologyIndividual> findIndividuals( String search, boolean ke
233267 }
234268
235269 @ Override
236- public Collection <OntologyResource > findResources ( String searchString , boolean keepObsoletes ) throws OntologySearchException {
270+ public Collection <OntologyResource > findResources ( String searchString , boolean keepObsoletes ) throws
271+ OntologySearchException {
237272 Lock lock = rwLock .readLock ();
238273 try {
239274 lock .lock ();
@@ -393,7 +428,8 @@ public Collection<OntologyIndividual> getTermIndividuals( String uri ) {
393428 }
394429
395430 @ Override
396- public Set <OntologyTerm > getParents ( Collection <OntologyTerm > terms , boolean direct , boolean includeAdditionalProperties , boolean keepObsoletes ) {
431+ public Set <OntologyTerm > getParents ( Collection <OntologyTerm > terms , boolean direct ,
432+ boolean includeAdditionalProperties , boolean keepObsoletes ) {
397433 Lock lock = rwLock .readLock ();
398434 try {
399435 lock .lock ();
@@ -411,7 +447,8 @@ public Set<OntologyTerm> getParents( Collection<OntologyTerm> terms, boolean dir
411447 }
412448
413449 @ Override
414- public Set <OntologyTerm > getChildren ( Collection <OntologyTerm > terms , boolean direct , boolean includeAdditionalProperties , boolean keepObsoletes ) {
450+ public Set <OntologyTerm > getChildren ( Collection <OntologyTerm > terms , boolean direct ,
451+ boolean includeAdditionalProperties , boolean keepObsoletes ) {
415452 Lock lock = rwLock .readLock ();
416453 try {
417454 lock .lock ();
@@ -463,13 +500,8 @@ public synchronized void startInitializationThread( boolean forceLoad, boolean f
463500 initializationThread = new Thread ( () -> {
464501 try {
465502 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- }
470503 } catch ( Exception e ) {
471- log .error ( e .getMessage (), e );
472- this .isInitialized = false ;
504+ log .error ( "Initialization for %s failed." , e );
473505 }
474506 }, getOntologyName () + "_load_thread_" + RandomStringUtils .randomAlphanumeric ( 5 ) );
475507 // To prevent VM from waiting on this thread to shut down (if shutting down).
@@ -521,13 +553,13 @@ public void waitForInitializationThread() throws InterruptedException {
521553 * Delegates the call as to load the model into memory or leave it on disk. Simply delegates to either
522554 * OntologyLoader.loadMemoryModel( url ); OR OntologyLoader.loadPersistentModel( url, spec );
523555 */
524- protected abstract OntModel loadModel ();
556+ protected abstract OntModel loadModel () throws JenaException , IOException ;
525557
526558
527559 /**
528560 * Load a model from a given input stream.
529561 */
530- protected abstract OntModel loadModelFromStream ( InputStream stream );
562+ protected abstract OntModel loadModelFromStream ( InputStream stream ) throws JenaException , IOException ;
531563
532564 /**
533565 * A name for caching this ontology, or null to disable caching.
@@ -555,6 +587,9 @@ public void index( boolean force ) {
555587 return ;
556588 }
557589 index = OntologyIndexer .indexOntology ( getCacheName (), model , force );
590+ } catch ( IOException e ) {
591+ log .error ( "Failed to generate index for {}." , this , e );
592+ return ;
558593 } finally {
559594 lock .unlock ();
560595 }
0 commit comments