Skip to content

Commit 9579fba

Browse files
committed
Add a mechanism for allowing certain URI prefixes
1 parent e0a9985 commit 9579fba

4 files changed

Lines changed: 75 additions & 9 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@
604604
<site>
605605
<id>pavlab</id>
606606
<name>PavLab</name>
607-
<url>scpexe://${pavlab.server}${pavlab.siteDir}/${project.groupId}/${project.artifactId}-${project.version}</url>
607+
<url>scpexe://${pavlab.server}${pavlab.siteDir}/${project.groupId}/gsec-${project.version}</url>
608608
</site>
609609
</distributionManagement>
610610
<pluginRepositories>

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

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public abstract class AbstractOntologyService implements OntologyService {
8888
private boolean searchEnabled = true;
8989
private Set<String> excludedWordsFromStemming = Collections.emptySet();
9090
private Set<String> additionalPropertyUris = DEFAULT_ADDITIONAL_PROPERTIES.stream().map( Property::getURI ).collect( Collectors.toSet() );
91+
@Nullable
92+
private Set<String> allowedUriPrefixes = null;
9193

9294
protected AbstractOntologyService( String ontologyName, String ontologyUrl, boolean ontologyEnabled, @Nullable String cacheName ) {
9395
this.ontologyName = ontologyName;
@@ -126,7 +128,7 @@ public synchronized void startInitializationThread( boolean forceLoad, boolean f
126128
try {
127129
this.initialize( forceLoad, forceIndexing );
128130
} catch ( Exception e ) {
129-
log.error( "Initialization for %s failed.", e );
131+
log.error( "Initialization of {} failed.", this, e );
130132
}
131133
}, getOntologyName() + "_load_thread_" + RandomStringUtils.randomAlphanumeric( 5 ) );
132134
// To prevent VM from waiting on this thread to shut down (if shutting down).
@@ -235,6 +237,19 @@ public void setProcessImports( boolean processImports ) {
235237
this.processImports = processImports;
236238
}
237239

240+
@Override
241+
public void setAllowedUriPrefixes( String... uriPrefixes ) {
242+
if ( uriPrefixes.length == 0 ) {
243+
throw new IllegalArgumentException( "At least one URI prefix must be supplied." );
244+
}
245+
this.allowedUriPrefixes = new HashSet<>( Arrays.asList( uriPrefixes ) );
246+
}
247+
248+
@Override
249+
public void clearAllowedUriPrefixes() {
250+
this.allowedUriPrefixes = null;
251+
}
252+
238253
@Override
239254
public boolean isSearchEnabled() {
240255
return getState().map( state -> state.index != null ).orElse( searchEnabled );
@@ -288,6 +303,7 @@ private synchronized void initialize( @Nullable InputStream stream, boolean forc
288303
boolean processImports = this.processImports;
289304
boolean searchEnabled = this.searchEnabled;
290305
Set<String> excludedWordsFromStemming = this.excludedWordsFromStemming;
306+
Set<String> allowedUriPrefixes = this.allowedUriPrefixes;
291307

292308
// Detect configuration problems.
293309
if ( StringUtils.isBlank( ontologyUrl ) ) {
@@ -379,13 +395,15 @@ private synchronized void initialize( @Nullable InputStream stream, boolean forc
379395
}
380396
}
381397

382-
this.state = new State( model, index, excludedWordsFromStemming, additionalRestrictions, languageLevel, inferenceMode, processImports, additionalProperties.stream().map( Property::getURI ).collect( Collectors.toSet() ), null );
398+
this.state = new State( model, index, excludedWordsFromStemming, additionalRestrictions, languageLevel,
399+
inferenceMode, processImports, additionalProperties.stream().map( Property::getURI ).collect( Collectors.toSet() ),
400+
allowedUriPrefixes, null );
383401
if ( cacheName != null ) {
384402
// now that the terms have been replaced, we can clear old caches
385403
try {
386404
OntologyLoader.deleteOldCache( cacheName );
387405
} catch ( IOException e ) {
388-
log.error( String.format( String.format( "Failed to delete old cache directory for %s.", this ), e ) );
406+
log.error( "Failed to delete old cache directory for {}.", this, e );
389407
}
390408
}
391409

@@ -422,6 +440,7 @@ public Collection<OntologySearchResult<OntologyIndividual>> findIndividuals( Str
422440
return Collections.emptySet();
423441
}
424442
return state.index.searchIndividuals( state.model, search, maxResults ).stream()
443+
.filter( i -> state.isUriAllowed( i.result.getURI() ) )
425444
.map( i -> as( i.result, Individual.class ).map( r -> new OntologySearchResult<>( ( OntologyIndividual ) new OntologyIndividualImpl( r, state.additionalRestrictions ), i.score ) ) )
426445
.filter( Optional::isPresent )
427446
.map( Optional::get )
@@ -443,6 +462,7 @@ public Collection<OntologySearchResult<OntologyResource>> findResources( String
443462
return Collections.emptySet();
444463
}
445464
return state.index.search( state.model, searchString, maxResults ).stream()
465+
.filter( i -> state.isUriAllowed( i.result.getURI() ) )
446466
.filter( ( r -> r.result.canAs( OntClass.class ) || r.result.canAs( Individual.class ) ) )
447467
.map( r -> {
448468
if ( r.result.canAs( OntClass.class ) ) {
@@ -474,6 +494,7 @@ public Collection<OntologySearchResult<OntologyTerm>> findTerm( String search, i
474494
return Collections.emptySet();
475495
}
476496
return state.index.searchClasses( state.model, search, maxResults ).stream()
497+
.filter( i -> state.isUriAllowed( i.result.getURI() ) )
477498
.map( r -> as( r.result, OntClass.class ).map( s -> new OntologySearchResult<>( ( OntologyTerm ) new OntologyTermImpl( s, state.additionalRestrictions ), r.score ) ) )
478499
.filter( Optional::isPresent )
479500
.map( Optional::get )
@@ -514,6 +535,9 @@ public Set<String> getAllURIs() {
514535
@Override
515536
public OntologyResource getResource( String uri ) {
516537
return getState().map( state -> {
538+
if ( !state.isUriAllowed( uri ) ) {
539+
return null;
540+
}
517541
OntologyResource res;
518542
Resource resource = state.model.getResource( uri );
519543
if ( resource.getURI() == null ) {
@@ -536,6 +560,9 @@ public OntologyResource getResource( String uri ) {
536560
@Override
537561
public OntologyTerm getTerm( String uri ) {
538562
return getState().map( state -> {
563+
if ( !state.isUriAllowed( uri ) ) {
564+
return null;
565+
}
539566
OntClass ontCls = state.model.getOntClass( uri );
540567
// null or bnode
541568
if ( ontCls == null || ontCls.getURI() == null ) {
@@ -564,6 +591,7 @@ public Set<OntologyTerm> getParents( Collection<OntologyTerm> terms, boolean dir
564591
return getState().map( state ->
565592
JenaUtils.getParents( state.model, getOntClassesFromTerms( state.model, terms ), direct, includeAdditionalProperties ? state.additionalRestrictions : null )
566593
.stream()
594+
.filter( o -> state.isUriAllowed( o.getURI() ) )
567595
.map( o -> ( OntologyTerm ) new OntologyTermImpl( o, state.additionalRestrictions ) )
568596
.filter( o -> keepObsoletes || !o.isObsolete() )
569597
.collect( Collectors.toSet() ) )
@@ -576,6 +604,7 @@ public Set<OntologyTerm> getChildren( Collection<OntologyTerm> terms, boolean di
576604
return getState().map( state ->
577605
JenaUtils.getChildren( state.model, getOntClassesFromTerms( state.model, terms ), direct, includeAdditionalProperties ? state.additionalRestrictions : null )
578606
.stream()
607+
.filter( o -> state.isUriAllowed( o.getURI() ) )
579608
.map( o -> ( OntologyTerm ) new OntologyTermImpl( o, state.additionalRestrictions ) )
580609
.filter( o -> keepObsoletes || !o.isObsolete() )
581610
.collect( Collectors.toSet() )
@@ -667,7 +696,7 @@ public synchronized void index( boolean force ) {
667696
return;
668697
}
669698
// now we replace the index
670-
this.state = new State( state.model, index, state.excludedWordsFromStemming, state.additionalRestrictions, state.languageLevel, state.inferenceMode, state.processImports, state.additionalPropertyUris, state.alternativeIDs );
699+
this.state = new State( state.model, index, state.excludedWordsFromStemming, state.additionalRestrictions, state.languageLevel, state.inferenceMode, state.processImports, state.additionalPropertyUris, state.allowedUriPrefixes, state.alternativeIDs );
671700
}
672701

673702
/**
@@ -703,7 +732,7 @@ private State initSearchByAlternativeId( State state ) {
703732
alternativeIDs.put( baseOntologyUri + alternativeIdModified, ontologyTerm.getUri() );
704733
}
705734
}
706-
return new State( state.model, state.index, state.excludedWordsFromStemming, state.additionalRestrictions, state.languageLevel, state.inferenceMode, state.processImports, state.additionalPropertyUris, alternativeIDs );
735+
return new State( state.model, state.index, state.excludedWordsFromStemming, state.additionalRestrictions, state.languageLevel, state.inferenceMode, state.processImports, state.additionalPropertyUris, state.allowedUriPrefixes, alternativeIDs );
707736
}
708737

709738
@Override
@@ -715,8 +744,8 @@ public void close() throws Exception {
715744

716745
@Override
717746
public String toString() {
718-
return String.format( "%s [url=%s] [language level=%s] [inference mode=%s] [imports=%b] [search=%b]",
719-
getOntologyName(), getOntologyUrl(), getLanguageLevel(), getInferenceMode(), getProcessImports(), isSearchEnabled() );
747+
return String.format( "%s [url=%s] [allowed prefixes=%s] [language level=%s] [inference mode=%s] [imports=%b] [search=%b]",
748+
getOntologyName(), getOntologyUrl(), allowedUriPrefixes != null ? String.join( ",", allowedUriPrefixes ) : "*", getLanguageLevel(), getInferenceMode(), getProcessImports(), isSearchEnabled() );
720749
}
721750

722751
private Optional<State> getState() {
@@ -747,9 +776,11 @@ private static class State implements AutoCloseable {
747776
private final boolean processImports;
748777
private final Set<String> additionalPropertyUris;
749778
@Nullable
779+
private final Set<String> allowedUriPrefixes;
780+
@Nullable
750781
private final Map<String, String> alternativeIDs;
751782

752-
private State( OntModel model, @Nullable SearchIndex index, Set<String> excludedWordsFromStemming, Set<Restriction> additionalRestrictions, @Nullable LanguageLevel languageLevel, InferenceMode inferenceMode, boolean processImports, Set<String> additionalPropertyUris, @Nullable Map<String, String> alternativeIDs ) {
783+
private State( OntModel model, @Nullable SearchIndex index, Set<String> excludedWordsFromStemming, Set<Restriction> additionalRestrictions, @Nullable LanguageLevel languageLevel, InferenceMode inferenceMode, boolean processImports, Set<String> additionalPropertyUris, @Nullable Set<String> allowedUriPrefixes, @Nullable Map<String, String> alternativeIDs ) {
753784
this.model = model;
754785
this.index = index;
755786
this.excludedWordsFromStemming = excludedWordsFromStemming;
@@ -758,9 +789,20 @@ private State( OntModel model, @Nullable SearchIndex index, Set<String> excluded
758789
this.inferenceMode = inferenceMode;
759790
this.processImports = processImports;
760791
this.additionalPropertyUris = additionalPropertyUris;
792+
this.allowedUriPrefixes = allowedUriPrefixes;
761793
this.alternativeIDs = alternativeIDs;
762794
}
763795

796+
/**
797+
* Check if this particular state allows a given URI from being returned by the service.
798+
*/
799+
public boolean isUriAllowed( @Nullable String uri ) {
800+
if ( allowedUriPrefixes == null ) {
801+
return true;
802+
}
803+
return uri == null || allowedUriPrefixes.stream().anyMatch( uri::startsWith );
804+
}
805+
764806
@Override
765807
public void close() throws Exception {
766808
try {

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ public void setProcessImports( boolean processImports ) {
3838
delegate.setProcessImports( processImports );
3939
}
4040

41+
@Override
42+
public void setAllowedUriPrefixes( String... uriPrefixes ) {
43+
delegate.setAllowedUriPrefixes( uriPrefixes );
44+
}
45+
46+
@Override
47+
public void clearAllowedUriPrefixes() {
48+
delegate.clearAllowedUriPrefixes();
49+
}
50+
4151
@Override
4252
public LanguageLevel getLanguageLevel() {
4353
return delegate.getLanguageLevel();

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@ public interface OntologyService extends AutoCloseable {
3939
*/
4040
void setProcessImports( boolean processImports );
4141

42+
/**
43+
* List of URI prefixes to load from the ontology.
44+
* <p>
45+
* Changes are applicable only if the service is re-initialized.
46+
*/
47+
void setAllowedUriPrefixes( String... uriPrefixes );
48+
49+
/**
50+
* Clear the list of allowed URI prefixes.
51+
* <p>
52+
* Changes are applicable only if the service is re-initialized.
53+
*/
54+
void clearAllowedUriPrefixes();
55+
4256
enum LanguageLevel {
4357
/**
4458
* The full OWL language.

0 commit comments

Comments
 (0)