Skip to content

Commit 60bf4d4

Browse files
committed
Merge branch 'hotfix-1.1.23'
2 parents 22da918 + 2957c0d commit 60bf4d4

11 files changed

Lines changed: 126 additions & 134 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.22</version>
8+
<version>1.1.23</version>
99
<inceptionYear>2003</inceptionYear>
1010
<description>
1111
<![CDATA[Data structures, math and statistics tools, and utilities that are often needed across projects.]]>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,4 @@ public String toString() {
116116
}
117117
return s;
118118
}
119-
}
119+
}

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

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
import java.util.function.Predicate;
5656
import java.util.stream.Collectors;
5757

58-
import static ubic.basecode.ontology.jena.JenaUtils.where;
58+
import static ubic.basecode.ontology.jena.JenaUtils.as;
5959

6060
/**
6161
* Base class for Jena-based ontology services.
@@ -324,7 +324,7 @@ private static boolean hasCauseMatching( Throwable t, Predicate<Throwable> predi
324324
}
325325

326326
@Override
327-
public Set<OntologySearchResult<OntologyIndividual>> findIndividuals( String search, int maxResults, boolean keepObsoletes ) throws
327+
public Collection<OntologySearchResult<OntologyIndividual>> findIndividuals( String search, int maxResults, boolean keepObsoletes ) throws
328328
OntologySearchException {
329329
State state = this.state;
330330
if ( state == null ) {
@@ -335,10 +335,13 @@ public Set<OntologySearchResult<OntologyIndividual>> findIndividuals( String sea
335335
log.warn( "Attempt to search {} when index is null, no results will be returned.", this );
336336
return Collections.emptySet();
337337
}
338-
return state.index.searchIndividuals( state.model, search, maxResults )
339-
.mapWith( i -> new OntologySearchResult<>( ( OntologyIndividual ) new OntologyIndividualImpl( i.result.as( Individual.class ), state.additionalRestrictions ), i.score ) )
340-
.filterKeep( where( ontologyTerm -> keepObsoletes || !ontologyTerm.getResult().isObsolete() ) )
341-
.toSet();
338+
return state.index.searchIndividuals( state.model, search, maxResults ).stream()
339+
.map( i -> as( i.result, Individual.class ).map( r -> new OntologySearchResult<>( ( OntologyIndividual ) new OntologyIndividualImpl( r, state.additionalRestrictions ), i.score ) ) )
340+
.filter( Optional::isPresent )
341+
.map( Optional::get )
342+
.filter( ontologyTerm -> keepObsoletes || !ontologyTerm.getResult().isObsolete() )
343+
.sorted( Comparator.comparing( OntologySearchResult::getScore, Comparator.reverseOrder() ) )
344+
.collect( Collectors.toCollection( LinkedHashSet::new ) );
342345
}
343346

344347
@Override
@@ -353,25 +356,24 @@ public Collection<OntologySearchResult<OntologyResource>> findResources( String
353356
log.warn( "Attempt to search {} when index is null, no results will be returned.", this );
354357
return Collections.emptySet();
355358
}
356-
return state.index.search( state.model, searchString, maxResults )
357-
.filterKeep( where( r -> r.result.canAs( OntClass.class ) || r.result.canAs( Individual.class ) ) )
358-
.mapWith( r -> {
359-
try {
360-
if ( r.result.canAs( OntClass.class ) ) {
361-
return new OntologySearchResult<>( ( OntologyResource ) new OntologyTermImpl( r.result.as( OntClass.class ), state.additionalRestrictions ), r.score );
362-
} else if ( r.result.canAs( Individual.class ) ) {
363-
return new OntologySearchResult<>( ( OntologyResource ) new OntologyIndividualImpl( r.result.as( Individual.class ), state.additionalRestrictions ), r.score );
364-
} else {
365-
return null;
366-
}
367-
} catch ( ConversionException e ) {
368-
log.warn( "Conversion failed for {}", r, e );
369-
return null;
359+
return state.index.search( state.model, searchString, maxResults ).stream()
360+
.filter( ( r -> r.result.canAs( OntClass.class ) || r.result.canAs( Individual.class ) ) )
361+
.map( r -> {
362+
if ( r.result.canAs( OntClass.class ) ) {
363+
return as( r.result, OntClass.class )
364+
.map( r2 -> new OntologySearchResult<>( ( OntologyResource ) new OntologyTermImpl( r2, state.additionalRestrictions ), r.score ) );
365+
} else if ( r.result.canAs( Individual.class ) ) {
366+
return as( r.result, Individual.class )
367+
.map( r2 -> new OntologySearchResult<>( ( OntologyResource ) new OntologyIndividualImpl( r2, state.additionalRestrictions ), r.score ) );
368+
} else {
369+
return Optional.<OntologySearchResult<OntologyResource>>empty();
370370
}
371371
} )
372-
.filterKeep( where( Objects::nonNull ) )
373-
.filterKeep( where( ontologyTerm -> keepObsoletes || !ontologyTerm.getResult().isObsolete() ) )
374-
.toSet();
372+
.filter( Optional::isPresent )
373+
.map( Optional::get )
374+
.filter( ontologyTerm -> keepObsoletes || !ontologyTerm.getResult().isObsolete() )
375+
.sorted( Comparator.comparing( OntologySearchResult::getScore, Comparator.reverseOrder() ) )
376+
.collect( Collectors.toCollection( LinkedHashSet::new ) );
375377
}
376378

377379
@Override
@@ -385,10 +387,13 @@ public Collection<OntologySearchResult<OntologyTerm>> findTerm( String search, i
385387
log.warn( "Attempt to search {} when index is null, no results will be returned.", this );
386388
return Collections.emptySet();
387389
}
388-
return state.index.searchClasses( state.model, search, maxResults )
389-
.mapWith( r -> new OntologySearchResult<>( ( OntologyTerm ) new OntologyTermImpl( r.result.as( OntClass.class ), state.additionalRestrictions ), r.score ) )
390-
.filterKeep( where( ontologyTerm -> keepObsoletes || !ontologyTerm.getResult().isObsolete() ) )
391-
.toSet();
390+
return state.index.searchClasses( state.model, search, maxResults ).stream()
391+
.map( r -> as( r.result, OntClass.class ).map( s -> new OntologySearchResult<>( ( OntologyTerm ) new OntologyTermImpl( s, state.additionalRestrictions ), r.score ) ) )
392+
.filter( Optional::isPresent )
393+
.map( Optional::get )
394+
.filter( ontologyTerm -> keepObsoletes || !ontologyTerm.getResult().isObsolete() )
395+
.sorted( Comparator.comparing( OntologySearchResult::getScore, Comparator.reverseOrder() ) )
396+
.collect( Collectors.toCollection( LinkedHashSet::new ) );
392397
}
393398

394399
@Override

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
*/
1919
package ubic.basecode.ontology.jena;
2020

21-
import com.hp.hpl.jena.rdf.model.RDFNode;
22-
import com.hp.hpl.jena.rdf.model.Resource;
23-
import com.hp.hpl.jena.rdf.model.Statement;
21+
import com.hp.hpl.jena.rdf.model.*;
2422
import com.hp.hpl.jena.vocabulary.RDFS;
2523
import ubic.basecode.ontology.model.AnnotationProperty;
2624

@@ -73,7 +71,23 @@ public String getContents() {
7371
return null;
7472
}
7573
} else {
76-
return JenaUtils.asString( object );
74+
return ( String ) object.visitWith( new RDFVisitor() {
75+
76+
@Override
77+
public Object visitBlank( Resource r, AnonId id ) {
78+
return r.getLocalName();
79+
}
80+
81+
@Override
82+
public Object visitLiteral( Literal l ) {
83+
return l.toString().replaceAll( "\\^\\^.+", "" );
84+
}
85+
86+
@Override
87+
public Object visitURI( Resource r, String uri ) {
88+
return r.getLocalName();
89+
}
90+
} );
7791
}
7892
}
7993

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

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package ubic.basecode.ontology.jena;
22

33
import com.hp.hpl.jena.ontology.*;
4-
import com.hp.hpl.jena.rdf.model.*;
4+
import com.hp.hpl.jena.rdf.model.Property;
5+
import com.hp.hpl.jena.rdf.model.RDFNode;
6+
import com.hp.hpl.jena.rdf.model.Resource;
7+
import com.hp.hpl.jena.rdf.model.ResourceFactory;
58
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
6-
import com.hp.hpl.jena.util.iterator.Filter;
79
import com.hp.hpl.jena.util.iterator.UniqueExtendedIterator;
810
import org.apache.commons.lang3.time.StopWatch;
911
import org.slf4j.Logger;
1012
import org.slf4j.LoggerFactory;
1113

1214
import javax.annotation.Nullable;
1315
import java.util.*;
14-
import java.util.function.Predicate;
1516
import java.util.stream.Collectors;
1617

1718
import static com.hp.hpl.jena.reasoner.ReasonerRegistry.makeDirect;
@@ -20,6 +21,21 @@ class JenaUtils {
2021

2122
protected static final Logger log = LoggerFactory.getLogger( JenaUtils.class );
2223

24+
/**
25+
* Safely convert a {@link RDFNode} to a target class.
26+
*/
27+
public static <T extends RDFNode> Optional<T> as( RDFNode resource, Class<T> clazz ) {
28+
if ( !resource.canAs( clazz ) ) {
29+
return Optional.empty();
30+
}
31+
try {
32+
return Optional.of( resource.as( clazz ) );
33+
} catch ( ConversionException e ) {
34+
log.warn( "Conversion of {} to {} failed.", resource, clazz.getName() );
35+
return Optional.empty();
36+
}
37+
}
38+
2339
public static Collection<OntClass> getParents( OntModel model, Collection<OntClass> ontClasses, boolean direct, @Nullable Set<Restriction> additionalRestrictions ) {
2440
Collection<OntClass> parents = getParentsInternal( model, ontClasses, direct, additionalRestrictions );
2541
if ( shouldRevisit( parents, direct, model, additionalRestrictions ) ) {
@@ -135,7 +151,7 @@ public static Collection<OntClass> getChildrenInternal( OntModel model, Collecti
135151
result.addAll( model.listResourcesWithProperty( subClassOf, r )
136152
.filterDrop( new BnodeFilter<>() )
137153
.mapWith( r2 -> as( r2, OntClass.class ) )
138-
.filterKeep( where( Optional::isPresent ) )
154+
.filterKeep( new PredicateFilter<Optional<OntClass>>( Optional::isPresent ) )
139155
.mapWith( Optional::get )
140156
.toSet() );
141157
}
@@ -190,45 +206,6 @@ public static Resource getRestrictionValue( Restriction r ) {
190206
}
191207
}
192208

193-
/**
194-
* Use to pretty-print a RDFNode
195-
*/
196-
public static String asString( RDFNode object ) {
197-
return ( String ) object.visitWith( new RDFVisitor() {
198-
199-
@Override
200-
public Object visitBlank( Resource r, AnonId id ) {
201-
return r.getLocalName();
202-
}
203-
204-
@Override
205-
public Object visitLiteral( Literal l ) {
206-
return l.toString().replaceAll( "\\^\\^.+", "" );
207-
}
208-
209-
@Override
210-
public Object visitURI( Resource r, String uri ) {
211-
return r.getLocalName();
212-
}
213-
} );
214-
}
215-
216-
public static <T> Filter<T> where( Predicate<T> predicate ) {
217-
return new PredicateFilter<>( predicate );
218-
}
219-
220-
public static <T extends RDFNode> Optional<T> as( RDFNode resource, Class<T> clazz ) {
221-
if ( !resource.canAs( clazz ) ) {
222-
return Optional.empty();
223-
}
224-
try {
225-
return Optional.of( resource.as( clazz ) );
226-
} catch ( ConversionException e ) {
227-
log.warn( "Conversion of {} to {} failed.", resource, clazz.getName() );
228-
return Optional.empty();
229-
}
230-
}
231-
232209
/**
233210
* List all restrictions in the given model on any of the given properties.
234211
*/
@@ -238,14 +215,13 @@ public static ExtendedIterator<Restriction> listRestrictionsOnProperties( OntMod
238215
for ( Property p : props ) {
239216
Property property = p.inModel( model );
240217
// include sub-properties for inference
241-
if ( property.canAs( OntProperty.class ) ) {
242-
OntProperty op = property.as( OntProperty.class );
218+
as( property, OntProperty.class ).ifPresent( op -> {
243219
ExtendedIterator<? extends OntProperty> it = op.listSubProperties( false );
244220
while ( it.hasNext() ) {
245221
OntProperty sp = it.next();
246222
allProps.add( sp );
247223
}
248-
}
224+
} );
249225
}
250226
props = allProps;
251227
}

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

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.hp.hpl.jena.rdf.model.*;
2626
import com.hp.hpl.jena.shared.JenaException;
2727
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
28-
import com.hp.hpl.jena.util.iterator.WrappedIterator;
2928
import com.hp.hpl.jena.vocabulary.RDFS;
3029
import org.apache.commons.lang3.StringUtils;
3130
import org.apache.commons.lang3.time.StopWatch;
@@ -59,6 +58,8 @@
5958
import java.util.stream.Collectors;
6059
import java.util.stream.Stream;
6160

61+
import static ubic.basecode.ontology.jena.JenaUtils.as;
62+
6263
/**
6364
* A Lucene-based ontology indexer.
6465
*
@@ -206,14 +207,8 @@ private static Directory index( String name, OntModel model, Analyzer analyzer,
206207
Document doc = new Document();
207208
doc.add( new Field( ID_FIELD, id, Field.Store.YES, Field.Index.NOT_ANALYZED ) );
208209
doc.add( new Field( LOCAL_NAME_FIELD, subject.getLocalName(), Field.Store.NO, Field.Index.NOT_ANALYZED ) );
209-
boolean isClass, isIndividual;
210-
if ( subject.canAs( OntResource.class ) ) {
211-
isClass = subject.as( OntResource.class ).isClass();
212-
isIndividual = subject.as( OntResource.class ).isIndividual();
213-
} else {
214-
isClass = false;
215-
isIndividual = false;
216-
}
210+
boolean isClass = as( subject, OntResource.class ).map( OntResource::isClass ).orElse( false );
211+
boolean isIndividual = as( subject, OntResource.class ).map( OntResource::isIndividual ).orElse( false );
217212
doc.add( new NumericField( IS_CLASS_FIELD ).setIntValue( isClass ? 1 : 0 ) );
218213
doc.add( new NumericField( IS_INDIVIDUAL_FIELD ).setIntValue( isIndividual ? 1 : 0 ) );
219214
for ( IndexableProperty prop : indexableProperties ) {
@@ -300,21 +295,21 @@ public LuceneSearchIndex( String[] searchableFields, IndexReader index, Analyzer
300295
}
301296

302297
@Override
303-
public ExtendedIterator<JenaSearchResult> search( OntModel model, String queryString, int maxResults ) throws OntologySearchException {
298+
public List<JenaSearchResult> search( OntModel model, String queryString, int maxResults ) throws OntologySearchException {
304299
return search( model, queryString, null, maxResults );
305300
}
306301

307302
@Override
308-
public ExtendedIterator<JenaSearchResult> searchClasses( OntModel model, String queryString, int maxResults ) throws OntologySearchException {
303+
public List<JenaSearchResult> searchClasses( OntModel model, String queryString, int maxResults ) throws OntologySearchException {
309304
return search( model, queryString, NumericRangeFilter.newIntRange( IS_CLASS_FIELD, 1, 1, true, true ), maxResults );
310305
}
311306

312307
@Override
313-
public ExtendedIterator<JenaSearchResult> searchIndividuals( OntModel model, String queryString, int maxResults ) throws OntologySearchException {
308+
public List<JenaSearchResult> searchIndividuals( OntModel model, String queryString, int maxResults ) throws OntologySearchException {
314309
return search( model, queryString, NumericRangeFilter.newIntRange( IS_INDIVIDUAL_FIELD, 1, 1, true, true ), maxResults );
315310
}
316311

317-
private ExtendedIterator<JenaSearchResult> search( OntModel model, String queryString, @Nullable Filter filter, int maxResults ) throws OntologySearchException {
312+
private List<JenaSearchResult> search( OntModel model, String queryString, @Nullable Filter filter, int maxResults ) throws OntologySearchException {
318313
if ( StringUtils.isBlank( queryString ) ) {
319314
throw new IllegalArgumentException( "Query cannot be blank" );
320315
}
@@ -339,7 +334,7 @@ private ExtendedIterator<JenaSearchResult> search( OntModel model, String queryS
339334
break;
340335
}
341336
}
342-
return WrappedIterator.create( resources.iterator() );
337+
return resources;
343338
} catch ( ParseException e ) {
344339
throw new OntologySearchException( "Failed to parse search query.", queryString, e );
345340
} catch ( IOException e ) {

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
import java.util.Set;
3535
import java.util.stream.Collectors;
3636

37-
import static ubic.basecode.ontology.jena.JenaUtils.where;
38-
3937
/**
4038
* Represents a class in an ontology
4139
*
@@ -129,7 +127,7 @@ public String getComment() {
129127
@Override
130128
public Collection<OntologyIndividual> getIndividuals( boolean direct ) {
131129
return this.ontResource.listInstances( direct )
132-
.filterKeep( where( OntResource::isIndividual ) )
130+
.filterKeep( new PredicateFilter<>( OntResource::isIndividual ) )
133131
.mapWith( r -> ( OntologyIndividual ) new OntologyIndividualImpl( r.asIndividual(), additionalRestrictions ) )
134132
.toSet();
135133
}

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,31 @@
55
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
66
import ubic.basecode.ontology.search.OntologySearchException;
77

8+
import java.util.List;
9+
import java.util.stream.Stream;
10+
811
interface SearchIndex extends AutoCloseable {
912

1013
/**
1114
* Find RDF nodes matching the given query string.
1215
*/
13-
ExtendedIterator<JenaSearchResult> search( OntModel model, String queryString, int maxResults ) throws OntologySearchException;
16+
List<JenaSearchResult> search( OntModel model, String queryString, int maxResults ) throws OntologySearchException;
1417

1518
/**
1619
* Find classes that match the query string.
1720
*
1821
* @param model that goes with the index
1922
* @return Collection of OntologyTerm objects
2023
*/
21-
ExtendedIterator<JenaSearchResult> searchClasses( OntModel model, String queryString, int maxResults ) throws OntologySearchException;
24+
List<JenaSearchResult> searchClasses( OntModel model, String queryString, int maxResults ) throws OntologySearchException;
2225

2326
/**
2427
* Find individuals that match the query string
2528
*
2629
* @param model that goes with the index
2730
* @return Collection of OntologyTerm objects
2831
*/
29-
ExtendedIterator<JenaSearchResult> searchIndividuals( OntModel model, String queryString, int maxResults ) throws OntologySearchException;
32+
List<JenaSearchResult> searchIndividuals( OntModel model, String queryString, int maxResults ) throws OntologySearchException;
3033

3134
class JenaSearchResult {
3235

src/ubic/basecode/ontology/providers/OntologyService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ default Collection<OntologySearchResult<OntologyIndividual>> findIndividuals( St
193193
* @param search search query
194194
* @param keepObsoletes retain obsolete terms
195195
*/
196-
Set<OntologySearchResult<OntologyIndividual>> findIndividuals( String search, int maxResults, boolean keepObsoletes ) throws OntologySearchException;
196+
Collection<OntologySearchResult<OntologyIndividual>> findIndividuals( String search, int maxResults, boolean keepObsoletes ) throws OntologySearchException;
197197

198198
/**
199199
* Looks for any resources (terms or individuals) that match the given search string

0 commit comments

Comments
 (0)