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;
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.Entities;
28  import eu.ehri.project.definitions.Ontology;
29  import eu.ehri.project.models.annotations.EntityType;
30  import eu.ehri.project.models.annotations.Fetch;
31  import eu.ehri.project.models.annotations.Meta;
32  import eu.ehri.project.models.base.Accessor;
33  import eu.ehri.project.models.base.Actioner;
34  import eu.ehri.project.models.base.Annotatable;
35  import eu.ehri.project.models.base.Versioned;
36  import eu.ehri.project.models.base.Watchable;
37  
38  import static eu.ehri.project.definitions.Ontology.ACCESSOR_BELONGS_TO_GROUP;
39  import static eu.ehri.project.definitions.Ontology.USER_FOLLOWS_USER;
40  import static eu.ehri.project.definitions.Ontology.USER_WATCHING_ITEM;
41  import static eu.ehri.project.models.utils.JavaHandlerUtils.*;
42  
43  /**
44   * A frame class representing a user within the database.
45   */
46  @EntityType(EntityClass.USER_PROFILE)
47  public interface UserProfile extends Accessor, Actioner, Versioned, Annotatable {
48  
49      String FOLLOWER_COUNT = "followers";
50      String FOLLOWING_COUNT = "following";
51      String WATCHING_COUNT = "watching";
52  
53      @Meta(FOLLOWER_COUNT)
54      @JavaHandler
55      int getFollowerCount();
56  
57      @Meta(FOLLOWING_COUNT)
58      @JavaHandler
59      int getFollowingCount();
60  
61      @Meta(WATCHING_COUNT)
62      @JavaHandler
63      int getWatchingCount();
64  
65      /**
66       * Get the groups to which this user belongs.
67       *
68       * @return an iterable of group frames
69       */
70      @Fetch(Ontology.ACCESSOR_BELONGS_TO_GROUP)
71      @Adjacency(label = ACCESSOR_BELONGS_TO_GROUP)
72      Iterable<Group> getGroups();
73  
74      /**
75       * Get users who follow this user.
76       *
77       * @return an iterable of user frames
78       */
79      @Adjacency(label = USER_FOLLOWS_USER, direction = Direction.IN)
80      Iterable<UserProfile> getFollowers();
81  
82      /**
83       * Get users who this user follows.
84       *
85       * @return an iterable of user frames
86       */
87      @Adjacency(label = USER_FOLLOWS_USER, direction = Direction.OUT)
88      Iterable<UserProfile> getFollowing();
89  
90      /**
91       * Add a user the those this user follows.
92       *
93       * @param user a user frame
94       */
95      @JavaHandler
96      void addFollowing(UserProfile user);
97  
98      /**
99       * Remove a user from those this user follows.
100      *
101      * @param user a user frame
102      */
103     @JavaHandler
104     void removeFollowing(UserProfile user);
105 
106     /**
107      * Ascertain whether this user is following another user.
108      *
109      * @param otherUser a user frame
110      * @return whether this user is following the other
111      */
112     @JavaHandler
113     boolean isFollowing(UserProfile otherUser);
114 
115     /**
116      * Ascertain whether the other user is following this user.
117      *
118      * @param otherUser a user frame
119      * @return whether the other user is following this user
120      */
121     @JavaHandler
122     boolean isFollower(UserProfile otherUser);
123 
124     /**
125      * Fetch items this user is watching.
126      *
127      * @return an iterable of generic item frames
128      */
129     @Adjacency(label = USER_WATCHING_ITEM, direction = Direction.OUT)
130     Iterable<Watchable> getWatching();
131 
132     /**
133      * Fetch links belonging to this user.
134      *
135      * @return an iterable of link frames
136      */
137     @Adjacency(label = Ontology.LINK_HAS_LINKER, direction = Direction.IN)
138     Iterable<Link> getLinks();
139 
140     /**
141      * Fetch annotations belonging to this user.
142      *
143      * @return an iterable of annotation frames
144      */
145     @Adjacency(label = Ontology.ANNOTATOR_HAS_ANNOTATION)
146     Iterable<Annotation> getAnnotations();
147 
148     /**
149      * Fetch virtual units created by this user.
150      *
151      * @return an iterable of virtual unit frames
152      */
153     @Adjacency(label = Ontology.VC_HAS_AUTHOR, direction = Direction.IN)
154     Iterable<VirtualUnit> getVirtualUnits();
155 
156     /**
157      * Add an item to this user's watch list.
158      *
159      * @param item a generic item frame
160      */
161     @JavaHandler
162     void addWatching(Watchable item);
163 
164     /**
165      * Remove an item from this user's watch list.
166      *
167      * @param item a generic item frame
168      */
169     @JavaHandler
170     void removeWatching(Watchable item);
171 
172     /**
173      * Add a user to this user's block list.
174      *
175      * @param user a user frame
176      */
177     @JavaHandler
178     void addBlocked(UserProfile user);
179 
180     /**
181      * Remove a user from this user's block list.
182      *
183      * @param user a user frame
184      */
185     @JavaHandler
186     void removeBlocked(UserProfile user);
187 
188     /**
189      * Fetch users on this user's block list.
190      *
191      * @return an iterable of user frames
192      */
193     @Adjacency(label = Ontology.USER_BLOCKS_USER)
194     Iterable<UserProfile> getBlocked();
195 
196     /**
197      * Ascertain whether this user is blocking another user.
198      *
199      * @param user a user frame
200      * @return whther the other user is on this user's block list
201      */
202     @JavaHandler
203     boolean isBlocking(UserProfile user);
204 
205     /**
206      * Fetch users who share groups with this user.
207      *
208      * @return an iterable of user frames
209      */
210     @JavaHandler
211     Iterable<UserProfile> coGroupMembers();
212 
213     /**
214      * Ascertain whether this user is watching an item.
215      *
216      * @param item a generic item frame
217      * @return whether the item is in this user's watch list
218      */
219     @JavaHandler
220     boolean isWatching(Watchable item);
221 
222 
223     abstract class Impl implements JavaHandlerContext<Vertex>, UserProfile {
224 
225         @Override
226         public int getFollowerCount() {
227             return Math.toIntExact(gremlin().inE(USER_FOLLOWS_USER).count());
228         }
229 
230         @Override
231         public int getFollowingCount() {
232             return Math.toIntExact(gremlin().outE(USER_FOLLOWS_USER).count());
233         }
234 
235         @Override
236         public int getWatchingCount() {
237             return Math.toIntExact(gremlin().outE(USER_WATCHING_ITEM).count());
238         }
239 
240         @Override
241         public void addFollowing(UserProfile user) {
242             addUniqueRelationship(it(), user.asVertex(), USER_FOLLOWS_USER);
243         }
244 
245         @Override
246         public void removeFollowing(UserProfile user) {
247             removeAllRelationships(it(), user.asVertex(), USER_FOLLOWS_USER);
248         }
249 
250         @Override
251         public boolean isFollowing(UserProfile otherUser) {
252             return hasRelationship(it(), otherUser.asVertex(), USER_FOLLOWS_USER);
253         }
254 
255         @Override
256         public boolean isFollower(UserProfile otherUser) {
257             return hasRelationship(otherUser.asVertex(), it(), USER_FOLLOWS_USER);
258         }
259 
260         @Override
261         public void addWatching(Watchable item) {
262             addUniqueRelationship(it(), item.asVertex(), USER_WATCHING_ITEM);
263         }
264 
265         @Override
266         public void removeWatching(Watchable item) {
267             removeAllRelationships(it(), item.asVertex(), USER_WATCHING_ITEM);
268         }
269 
270         @Override
271         public boolean isWatching(Watchable item) {
272             return hasRelationship(it(), item.asVertex(), USER_WATCHING_ITEM);
273         }
274 
275         @Override
276         public Iterable<UserProfile> coGroupMembers() {
277             return frameVertices(gremlin().as("n")
278                     .out(Ontology.ACCESSOR_BELONGS_TO_GROUP)
279                     .loop("n", defaultMaxLoops, noopLoopFunc)
280                     .in(Ontology.ACCESSOR_BELONGS_TO_GROUP).filter(vertex -> {
281                         // Exclude the current user...
282                         if (it().equals(vertex)) {
283                             return false;
284                         }
285                         // Exclude other groups...
286                         String type = vertex.getProperty(EntityType.TYPE_KEY);
287                         return Entities.USER_PROFILE.equals(type);
288                     }));
289         }
290 
291         @Override
292         public void addBlocked(UserProfile user) {
293             addUniqueRelationship(it(), user.asVertex(),
294                     Ontology.USER_BLOCKS_USER);
295         }
296 
297         @Override
298         public void removeBlocked(UserProfile user) {
299             removeAllRelationships(it(), user.asVertex(),
300                     Ontology.USER_BLOCKS_USER);
301         }
302 
303         @Override
304         public boolean isBlocking(UserProfile user) {
305             return hasRelationship(it(), user.asVertex(),
306                     Ontology.USER_BLOCKS_USER);
307         }
308     }
309 }