View Javadoc

1   /*
2    * Copyright 2015 Data Archiving and Networked Services (an institute of
3    * Koninklijke Nederlandse Akademie van Wetenschappen), King's College London,
4    * Georg-August-Universitaet Goettingen Stiftung Oeffentlichen Rechts
5    *
6    * Licensed under the EUPL, Version 1.1 or – as soon they will be approved by
7    * the European Commission - subsequent versions of the EUPL (the "Licence");
8    * You may not use this work except in compliance with the Licence.
9    * You may obtain a copy of the Licence at:
10   *
11   * https://joinup.ec.europa.eu/software/page/eupl
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the Licence is distributed on an "AS IS" basis,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the Licence for the specific language governing
17   * permissions and limitations under the Licence.
18   */
19  
20  package eu.ehri.project.models.cvoc;
21  
22  import com.tinkerpop.blueprints.Direction;
23  import com.tinkerpop.blueprints.Vertex;
24  import com.tinkerpop.frames.Adjacency;
25  import com.tinkerpop.frames.modules.javahandler.JavaHandler;
26  import com.tinkerpop.frames.modules.javahandler.JavaHandlerContext;
27  import eu.ehri.project.definitions.Ontology;
28  import eu.ehri.project.models.EntityClass;
29  import eu.ehri.project.models.annotations.EntityType;
30  import eu.ehri.project.models.annotations.Fetch;
31  import eu.ehri.project.models.annotations.InverseOf;
32  import eu.ehri.project.models.annotations.Mandatory;
33  import eu.ehri.project.models.annotations.Meta;
34  import eu.ehri.project.models.base.Described;
35  import eu.ehri.project.models.base.ItemHolder;
36  import eu.ehri.project.models.utils.JavaHandlerUtils;
37  
38  /**
39   * This models the thesaurus terms or keywords in a way that is better managing multi-linguality. 
40   * The terms are then labels of concepts in a specific language and concepts can have many labels.  
41   * This is following the SKOS-Core concept, but not fully so we don't use 'SKOS' in the class name. 
42   * For SKOS core see: http://www.w3.org/2009/08/skos-reference/skos.html
43   * 
44   * Also note that the labels and textual information of a single language 
45   * are all placed in a ConceptDescription, following the pattern 
46   * that the textual details of an entity are described by a Description entity.  
47   * 
48   * A nice glossary of terms used with controlled vocabularies can be found here: 
49   * http://www.willpowerinfo.co.uk/glossary.htm
50   */
51  @EntityType(EntityClass.CVOC_CONCEPT)
52  public interface Concept extends Described, AuthoritativeItem, ItemHolder {
53  
54      // NB: As an AuthoritativeItem the set will be @Fetched automatically
55      @Mandatory
56      @Adjacency(label = Ontology.ITEM_IN_AUTHORITATIVE_SET)
57      Vocabulary getVocabulary();
58  
59      @Adjacency(label = Ontology.ITEM_IN_AUTHORITATIVE_SET)
60      void setVocabulary(Vocabulary vocabulary);
61  
62      @Meta(CHILD_COUNT)
63      @JavaHandler
64      int getChildCount();
65  
66      // relations to other concepts
67      
68      // Note that multiple broader concepts are possible
69      @Fetch(Ontology.CONCEPT_HAS_BROADER)
70      @Adjacency(label = Ontology.CONCEPT_HAS_NARROWER, direction=Direction.IN)
71      Iterable<Concept> getBroaderConcepts();
72  
73      // NOTE: don't put a Fetch on it, because it can be a large tree of concepts
74      @Adjacency(label = Ontology.CONCEPT_HAS_NARROWER, direction = Direction.OUT)
75      @InverseOf(Ontology.CONCEPT_HAS_BROADER)
76      Iterable<Concept> getNarrowerConcepts();
77  
78      @JavaHandler
79      void addNarrowerConcept(Concept concept);
80  
81      @JavaHandler
82      void addBroaderConcept(Concept concept);
83  
84      @JavaHandler
85      void removeNarrowerConcept(Concept concept);
86  
87      @JavaHandler
88      void removeBroaderConcept(Concept concept);
89  
90      // Related concepts, should be like a symmetric associative link...
91      @Adjacency(label = Ontology.CONCEPT_HAS_RELATED)
92      Iterable<Concept> getRelatedConcepts();
93  
94      @JavaHandler
95      void addRelatedConcept(Concept concept);
96  
97      @Adjacency(label = Ontology.CONCEPT_HAS_RELATED)
98      void removeRelatedConcept(Concept concept);
99      
100     // Hmm, does not 'feel' symmetric
101     @Adjacency(label = Ontology.CONCEPT_HAS_RELATED, direction=Direction.IN)
102     Iterable<Concept> getRelatedByConcepts();
103 
104     /**
105      * Implementation of complex methods.
106      */
107     abstract class Impl  implements JavaHandlerContext<Vertex>, Concept {
108 
109         @Override
110         public int getChildCount() {
111             return Math.toIntExact(gremlin().outE(Ontology.CONCEPT_HAS_NARROWER).count());
112         }
113 
114         @Override
115         public void addRelatedConcept(Concept related) {
116             JavaHandlerUtils.addUniqueRelationship(it(),
117                     related.asVertex(), Ontology.CONCEPT_HAS_RELATED);
118         }
119 
120         @Override
121         public void addNarrowerConcept(Concept concept) {
122             if (!concept.asVertex().equals(it())) {
123                 JavaHandlerUtils.addUniqueRelationship(it(),
124                         concept.asVertex(), Ontology.CONCEPT_HAS_NARROWER);
125             }
126         }
127 
128         @Override
129         public void addBroaderConcept(Concept concept) {
130             if (!concept.asVertex().equals(it())) {
131                 JavaHandlerUtils.addUniqueRelationship(concept.asVertex(),
132                         it(), Ontology.CONCEPT_HAS_NARROWER);
133             }
134         }
135 
136         @Override
137         public void removeNarrowerConcept(Concept concept) {
138             JavaHandlerUtils.removeAllRelationships(it(), concept.asVertex(),
139                     Ontology.CONCEPT_HAS_NARROWER);
140         }
141 
142         @Override
143         public void removeBroaderConcept(Concept concept) {
144             JavaHandlerUtils.removeAllRelationships(concept.asVertex(), it(),
145                     Ontology.CONCEPT_HAS_NARROWER);
146         }
147     }
148 }