1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package ubic.basecode.ontology.model;
16
17 import com.hp.hpl.jena.ontology.*;
18 import com.hp.hpl.jena.rdf.model.*;
19 import com.hp.hpl.jena.util.iterator.ExtendedIterator;
20 import com.hp.hpl.jena.util.iterator.Filter;
21 import org.apache.commons.collections4.CollectionUtils;
22
23 import java.util.*;
24 import java.util.stream.Collectors;
25
26
27
28
29
30
31 public class OntologyTermImpl extends AbstractOntologyResource implements OntologyTerm {
32
33 private static final String HAS_ALTERNATE_ID = "http://www.geneontology.org/formats/oboInOwl#hasAlternativeId";
34 private static final String NOTHING = "http://www.w3.org/2002/07/owl#Nothing";
35
36
37
38
39 private static final Set<String> PROPAGATE_PARENT_URIS = new HashSet<>();
40
41 private static final Set<String> REJECT_PARENT_URIS = new HashSet<>();
42
43
44
45
46 private static final long serialVersionUID = 1L;
47
48 static {
49 CollectionUtils.addAll( PROPAGATE_PARENT_URIS,
50 "http://www.obofoundry.org/ro/ro.owl#proper_part_of",
51 "http://purl.obolibrary.org/obo/BFO_0000050" // part of
52 );
53 CollectionUtils.addAll( REJECT_PARENT_URIS,
54 "http://www.ifomis.org/bfo/1.1/snap#IndependentContinuant",
55 "http://www.ifomis.org/bfo/1.1/snap#Continuant",
56 "http://www.ifomis.org/bfo/1.1/snap#MaterialEntity",
57
58 "http://ontology.neuinfo.org/NIF/BiomaterialEntities/NIF-GrossAnatomy.owl#birnlex_6" );
59 }
60
61 private String label = null;
62 private String localName = null;
63
64
65
66
67 private final transient OntClass ontResource;
68
69
70
71
72 private final transient Set<Property> propagateParentsProperties;
73
74 public OntologyTermImpl( OntClass resource ) {
75 this.ontResource = resource;
76 if ( ontResource != null ) {
77 this.label = ontResource.getLabel( "EN" );
78 if ( this.label == null ) this.label = ontResource.getLabel( null );
79 this.localName = ontResource.getLocalName();
80 this.propagateParentsProperties = PROPAGATE_PARENT_URIS.stream()
81 .map( uri -> resource.getModel().getProperty( uri ) )
82 .filter( Objects::nonNull )
83 .collect( Collectors.toSet() );
84 } else {
85 this.propagateParentsProperties = Collections.emptySet();
86 }
87 }
88
89 @Override
90 public boolean equals( Object obj ) {
91 if ( this == obj ) return true;
92
93 if ( !super.equals( obj ) ) return false;
94 if ( getClass() != obj.getClass() ) return false;
95
96 final OntologyTermImpl../ubic/basecode/ontology/model/OntologyTermImpl.html#OntologyTermImpl">OntologyTermImpl that = ( OntologyTermImpl ) obj;
97 if ( this.getUri() != null ) {
98 return Objects.equals( this.getUri(), that.getUri() );
99 }
100 return Objects.equals( this.getTerm(), that.getTerm() );
101 }
102
103 @Override
104 public Collection<String> getAlternativeIds() {
105 Collection<String> results = new HashSet<>();
106
107 Property alternate = ResourceFactory.createProperty( HAS_ALTERNATE_ID );
108 StmtIterator it = this.ontResource.listProperties( alternate );
109 while ( it.hasNext() ) {
110 Statement statement = it.next();
111 results.add( statement.asTriple().getMatchObject().getLiteralLexicalForm() );
112 }
113
114 return results;
115
116 }
117
118 @Override
119 public Collection<AnnotationProperty> getAnnotations() {
120 Collection<AnnotationProperty> annots = new HashSet<>();
121 StmtIterator iterator = ontResource.listProperties();
122
123 while ( iterator.hasNext() ) {
124 Statement state = iterator.next();
125 OntResource res = state.getPredicate().as( OntResource.class );
126 if ( res.isAnnotationProperty() ) {
127 com.hp.hpl.jena.ontology.AnnotationProperty p = res.asAnnotationProperty();
128 RDFNode n = state.getObject();
129 annots.add( new AnnotationPropertyImpl( p, n ) );
130 }
131 }
132 return annots;
133 }
134
135 @Override
136 public Collection<OntologyTerm> getChildren( boolean direct ) {
137 return getChildren( direct, true );
138 }
139
140 @Override
141 public Collection<OntologyTerm> getChildren( boolean direct, boolean includePartOf ) {
142 Collection<OntClass> result = new HashSet<>();
143 ExtendedIterator<OntClass> iterator = ontResource.listSubClasses( direct )
144 .filterDrop( new EqualityByUriFilter( NOTHING ) );
145 OntModel model = ontResource.getOntModel();
146
147 while ( iterator.hasNext() ) {
148 OntClass c = iterator.next();
149
150
151 if ( c.getURI() == null )
152 continue;
153
154 result.add( c );
155 }
156
157 if ( includePartOf ) {
158 Property subClassOf = model.getProfile().SUB_CLASS_OF();
159 ExtendedIterator<Restriction> restrictionsIterator = model.listRestrictions()
160 .filterKeep( new RestrictionWithPropertyAndValueFilter( propagateParentsProperties, ontResource ) );
161 while ( restrictionsIterator.hasNext() ) {
162 Restriction r = restrictionsIterator.next();
163 ResIterator ss = model.listResourcesWithProperty( subClassOf, r );
164 while ( ss.hasNext() ) {
165 Resource s = ss.next();
166 if ( s.getURI() != null ) {
167 OntClass o = model.getOntClass( s.getURI() );
168 if ( o != null ) {
169 result.add( o );
170 }
171 }
172 }
173 }
174 }
175
176 return result.stream().map( OntologyTermImpl::new ).collect( Collectors.toSet() );
177 }
178
179
180
181
182 private static class EqualityByUriFilter extends Filter<OntClass> {
183 private final String uri;
184
185 private EqualityByUriFilter( String uri ) {
186 this.uri = uri;
187 }
188
189 @Override
190 public boolean accept( OntClass o ) {
191 return uri.equals( o.getURI() );
192 }
193 }
194
195
196
197
198 private static class RestrictionWithPropertyAndValueFilter extends Filter<Restriction> {
199 private final Set<Property> properties;
200 private final Resource resource;
201
202 private RestrictionWithPropertyAndValueFilter( Set<Property> properties, OntClass resource ) {
203 this.properties = properties;
204 this.resource = resource;
205 }
206
207 @Override
208 public boolean accept( Restriction o ) {
209 return hasRestrictionValue( o, resource ) && properties.stream().anyMatch( o::onProperty );
210 }
211 }
212
213
214
215
216
217
218 @Override
219 public String getComment() {
220 String comment = this.ontResource.getComment( null );
221 return comment == null ? "" : comment;
222 }
223
224
225
226
227
228
229 @Override
230 public Collection<OntologyIndividual> getIndividuals() {
231 return getIndividuals( true );
232 }
233
234 @Override
235 public Collection<OntologyIndividual> getIndividuals( boolean direct ) {
236 Collection<OntologyIndividual> inds = new HashSet<>();
237 ExtendedIterator<? extends OntResource> iterator = this.ontResource.listInstances( direct );
238 while ( iterator.hasNext() ) {
239 OntResource r = iterator.next();
240 if ( r.isIndividual() ) {
241 inds.add( new OntologyIndividualImpl( r.asIndividual() ) );
242 }
243 }
244 return inds;
245 }
246
247 @Override
248 public String getLabel() {
249 return label;
250 }
251
252 @Override
253 public String getLocalName() {
254 return this.localName;
255 }
256
257 @Override
258 public Object getModel() {
259 return ontResource.getModel();
260 }
261
262 @Override
263 public Collection<OntologyTerm> getParents( boolean direct ) {
264 return getParents( direct, true );
265 }
266
267 @Override
268 public Collection<OntologyTerm> getParents( boolean direct, boolean includePartOf ) {
269 Collection<OntClass> result = new HashSet<>();
270 ExtendedIterator<OntClass> iterator;
271 Set<String> excludeProperties;
272 iterator = ontResource.listSuperClasses( direct );
273 excludeProperties = REJECT_PARENT_URIS;
274
275 while ( iterator.hasNext() ) {
276 OntClass c = iterator.next();
277
278
279 if ( includePartOf && c.isRestriction() ) {
280 Restriction r = c.asRestriction();
281 if ( propagateParentsProperties.contains( r.getOnProperty() ) ) {
282 Resource value = getRestrictionValue( c.asRestriction() );
283 if ( value instanceof OntClass ) {
284 c = ( OntClass ) value;
285 } else {
286 continue;
287 }
288 }
289 }
290
291
292 if ( c.getURI() == null )
293 continue;
294
295
296 if ( excludeProperties.contains( c.getURI() ) )
297 continue;
298
299
300 if ( result.contains( c ) )
301 continue;
302
303 result.add( c );
304 }
305
306 return result.stream().map( OntologyTermImpl::new ).collect( Collectors.toSet() );
307 }
308
309
310
311
312 @Override
313 public Collection<OntologyRestriction> getRestrictions() {
314
315
316
317 Collection<OntologyRestriction> result = new HashSet<>();
318 ExtendedIterator<OntClass> iterator = ontResource.listSuperClasses( false );
319 while ( iterator.hasNext() ) {
320 OntClass c = iterator.next();
321 if ( c.isRestriction() ) {
322 result.add( RestrictionFactory.asRestriction( c.asRestriction() ) );
323 }
324 }
325
326
327 iterator = ontResource.listSuperClasses( false );
328 while ( iterator.hasNext() ) {
329 OntClass c = iterator.next();
330
331 try {
332 c.asRestriction();
333 } catch ( Exception e ) {
334
335 ExtendedIterator<OntClass> supClassesIt = c.listSuperClasses( false );
336 loop:
337 while ( supClassesIt.hasNext() ) {
338 OntClass sc = supClassesIt.next();
339 Restriction sr;
340 try {
341 sr = sc.asRestriction();
342
343
344 OntologyRestriction candidateRestriction = RestrictionFactory.asRestriction( sr );
345 for ( OntologyRestriction restr : result ) {
346 if ( restr.getRestrictionOn().equals( candidateRestriction.getRestrictionOn() ) )
347 continue loop;
348 }
349 result.add( candidateRestriction );
350
351 } catch ( Exception ex ) {
352
353 }
354 }
355 }
356
357 }
358
359 return result;
360 }
361
362
363
364
365
366
367 @Override
368 public String getTerm() {
369 String res;
370 if ( this.label != null ) {
371 res = this.label;
372 } else if ( this.localName != null ) {
373 res = localName;
374 } else if ( this.getUri() != null ) {
375 res = this.getUri();
376 } else {
377 res = ontResource.toString();
378 }
379 return res;
380 }
381
382 @Override
383 public String getUri() {
384 return this.ontResource.getURI();
385 }
386
387 @Override
388 public int hashCode() {
389 if ( ontResource == null ) {
390 log.warn( "ontResource is null in hashCode()" );
391 return 0;
392 }
393
394 if ( this.getUri() != null ) {
395 return this.getUri().hashCode();
396 }
397 return this.getTerm().hashCode();
398 }
399
400
401
402
403
404
405 @Override
406 public boolean isRoot() {
407 return !this.ontResource.listSuperClasses( true ).hasNext();
408 }
409
410
411
412
413
414
415 @Override
416 public boolean isTermObsolete() {
417
418 Collection<OntologyTerm> parentsOntologyTerm = getParents( false );
419
420
421
422
423 for ( OntologyTerm parentOntologyTerm : parentsOntologyTerm ) {
424
425 if ( parentOntologyTerm.getLocalName() != null
426 && parentOntologyTerm.getLocalName().equalsIgnoreCase( "ObsoleteClass" ) ) {
427 return true;
428 }
429
430
431 if ( parentOntologyTerm.getUri() == null ) {
432
433 continue;
434 }
435
436 if ( parentOntologyTerm.getUri() != null
437 && parentOntologyTerm.getUri().equalsIgnoreCase(
438 "http://bioontology.org/projects/ontologies/birnlex#_birnlex_retired_class" )
439 || parentOntologyTerm
440 .getUri()
441 .equalsIgnoreCase(
442 "http://ontology.neuinfo.org/NIF/Backend/BIRNLex_annotation_properties.owl#_birnlex_retired_class" ) ) {
443 return true;
444 }
445 }
446
447
448 StmtIterator iterator = ontResource.listProperties();
449
450 while ( iterator.hasNext() ) {
451 Statement state = iterator.next();
452 if ( state.getPredicate() == null ) continue;
453 OntResource res = state.getPredicate().as( OntResource.class );
454 if ( res.isAnnotationProperty() ) {
455 com.hp.hpl.jena.ontology.AnnotationProperty p = res.asAnnotationProperty();
456 RDFNode n = state.getObject();
457
458 if ( p.getLocalName().equalsIgnoreCase( "deprecated" ) ) {
459 if ( n.toString().contains( "true" ) ) {
460 return true;
461 }
462 break;
463 }
464 }
465 }
466 return false;
467 }
468
469 @Override
470 public String toString() {
471 String res = null;
472 if ( this.getTerm() != null ) {
473 res = this.getTerm();
474 if ( this.localName != null && !this.getTerm().equals( this.localName ) ) {
475 res = res + " [" + this.localName + "]";
476 }
477 } else if ( this.localName != null ) {
478 res = localName;
479 } else if ( this.getUri() != null ) {
480 res = this.getUri();
481 } else {
482 res = ontResource.toString();
483 }
484 return res;
485 }
486
487 private static Resource getRestrictionValue( Restriction r ) {
488 if ( r.isSomeValuesFromRestriction() ) {
489 return r.asSomeValuesFromRestriction().getSomeValuesFrom();
490 } else if ( r.isAllValuesFromRestriction() ) {
491 return r.asAllValuesFromRestriction().getAllValuesFrom();
492 } else {
493 return null;
494 }
495 }
496
497 private static boolean hasRestrictionValue( Restriction r, Resource value ) {
498 if ( r.isSomeValuesFromRestriction() ) {
499 return r.asSomeValuesFromRestriction().hasSomeValuesFrom( value );
500 } else if ( r.isAllValuesFromRestriction() ) {
501 return r.asAllValuesFromRestriction().hasAllValuesFrom( value );
502 } else {
503 return false;
504 }
505 }
506 }