001    package de.deepamehta.plugins.webservice;
002    
003    import de.deepamehta.core.Association;
004    import de.deepamehta.core.AssociationType;
005    import de.deepamehta.core.DeepaMehtaObject;
006    import de.deepamehta.core.RelatedAssociation;
007    import de.deepamehta.core.RelatedTopic;
008    import de.deepamehta.core.Topic;
009    import de.deepamehta.core.TopicType;
010    import de.deepamehta.core.model.AssociationModel;
011    import de.deepamehta.core.model.AssociationTypeModel;
012    import de.deepamehta.core.model.SimpleValue;
013    import de.deepamehta.core.model.TopicModel;
014    import de.deepamehta.core.model.TopicTypeModel;
015    import de.deepamehta.core.osgi.PluginActivator;
016    import de.deepamehta.core.service.Directives;
017    import de.deepamehta.core.service.PluginInfo;
018    import de.deepamehta.core.service.ResultList;
019    import de.deepamehta.core.service.Transactional;
020    
021    import javax.ws.rs.GET;
022    import javax.ws.rs.POST;
023    import javax.ws.rs.PUT;
024    import javax.ws.rs.DELETE;
025    import javax.ws.rs.Consumes;
026    import javax.ws.rs.DefaultValue;
027    import javax.ws.rs.HeaderParam;
028    import javax.ws.rs.Path;
029    import javax.ws.rs.PathParam;
030    import javax.ws.rs.Produces;
031    import javax.ws.rs.QueryParam;
032    
033    import java.util.List;
034    import java.util.logging.Logger;
035    
036    
037    
038    @Path("/core")
039    @Consumes("application/json")
040    @Produces("application/json")
041    public class WebservicePlugin extends PluginActivator {
042    
043        // ---------------------------------------------------------------------------------------------- Instance Variables
044    
045        private Logger logger = Logger.getLogger(getClass().getName());
046    
047        // -------------------------------------------------------------------------------------------------- Public Methods
048    
049    
050    
051        // === Topics ===
052    
053        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
054        @GET
055        @Path("/topic/{id}")
056        public Topic getTopic(@PathParam("id") long topicId) {
057            return dms.getTopic(topicId);
058        }
059    
060        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
061        @GET
062        @Path("/topic/by_value/{key}/{value}")
063        public Topic getTopic(@PathParam("key") String key, @PathParam("value") SimpleValue value) {
064            return dms.getTopic(key, value);
065        }
066    
067        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
068        @GET
069        @Path("/topic/multi/by_value/{key}/{value}")
070        public List<Topic> getTopics(@PathParam("key") String key, @PathParam("value") SimpleValue value) {
071            return dms.getTopics(key, value);
072        }
073    
074        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
075        @GET
076        @Path("/topic/by_type/{type_uri}")
077        public ResultList<RelatedTopic> getTopics(@PathParam("type_uri") String typeUri,
078                                                  @QueryParam("max_result_size") int maxResultSize) {
079            return dms.getTopics(typeUri, maxResultSize);
080        }
081    
082        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
083        @GET
084        @Path("/topic")
085        public List<Topic> searchTopics(@QueryParam("search") String searchTerm, @QueryParam("field")  String fieldUri) {
086            return dms.searchTopics(searchTerm, fieldUri);
087        }
088    
089        @POST
090        @Path("/topic")
091        @Transactional
092        public Topic createTopic(TopicModel model) {
093            return dms.createTopic(model);
094        }
095    
096        @PUT
097        @Path("/topic/{id}")
098        @Transactional
099        public Directives updateTopic(@PathParam("id") long topicId, TopicModel model) {
100            if (model.getId() != -1 && topicId != model.getId()) {
101                throw new RuntimeException("ID mismatch in update request");
102            }
103            model.setId(topicId);
104            dms.updateTopic(model);
105            return Directives.get();
106        }
107    
108        @DELETE
109        @Path("/topic/{id}")
110        @Transactional
111        public Directives deleteTopic(@PathParam("id") long topicId) {
112            dms.deleteTopic(topicId);
113            return Directives.get();
114        }
115    
116    
117    
118        // === Associations ===
119    
120        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
121        @GET
122        @Path("/association/{id}")
123        public Association getAssociation(@PathParam("id") long assocId) {
124            return dms.getAssociation(assocId);
125        }
126    
127        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
128        @GET
129        @Path("/association/{assoc_type_uri}/{topic1_id}/{topic2_id}/{role_type1_uri}/{role_type2_uri}")
130        public Association getAssociation(@PathParam("assoc_type_uri") String assocTypeUri,
131                       @PathParam("topic1_id") long topic1Id, @PathParam("topic2_id") long topic2Id,
132                       @PathParam("role_type1_uri") String roleTypeUri1, @PathParam("role_type2_uri") String roleTypeUri2) {
133            return dms.getAssociation(assocTypeUri, topic1Id, topic2Id, roleTypeUri1, roleTypeUri2);
134        }
135    
136        // ---
137    
138        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
139        @GET
140        @Path("/association/multiple/{topic1_id}/{topic2_id}")
141        public List<Association> getAssociations(@PathParam("topic1_id") long topic1Id,
142                                                 @PathParam("topic2_id") long topic2Id) {
143            return dms.getAssociations(topic1Id, topic2Id);
144        }
145    
146        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
147        @GET
148        @Path("/association/multiple/{topic1_id}/{topic2_id}/{assoc_type_uri}")
149        public List<Association> getAssociations(@PathParam("topic1_id") long topic1Id,
150                                                 @PathParam("topic2_id") long topic2Id,
151                                                 @PathParam("assoc_type_uri") String assocTypeUri) {
152            return dms.getAssociations(topic1Id, topic2Id, assocTypeUri);
153        }
154    
155        // ---
156    
157        @POST
158        @Path("/association")
159        @Transactional
160        public Association createAssociation(AssociationModel model) {
161            return dms.createAssociation(model);
162        }
163    
164        @PUT
165        @Path("/association/{id}")
166        @Transactional
167        public Directives updateAssociation(@PathParam("id") long assocId, AssociationModel model) {
168            if (model.getId() != -1 && assocId != model.getId()) {
169                throw new RuntimeException("ID mismatch in update request");
170            }
171            model.setId(assocId);
172            dms.updateAssociation(model);
173            return Directives.get();
174        }
175    
176        @DELETE
177        @Path("/association/{id}")
178        @Transactional
179        public Directives deleteAssociation(@PathParam("id") long assocId) {
180            dms.deleteAssociation(assocId);
181            return Directives.get();
182        }
183    
184    
185    
186        // === Topic Types ===
187    
188        @GET
189        @Path("/topictype")
190        public List<String> getTopicTypeUris() {
191            return dms.getTopicTypeUris();
192        }
193    
194        @GET
195        @Path("/topictype/{uri}")
196        public TopicType getTopicType(@PathParam("uri") String uri) {
197            return dms.getTopicType(uri);
198        }
199    
200        @GET
201        @Path("/topictype/all")
202        public List<TopicType> getAllTopicTypes() {
203            return dms.getAllTopicTypes();
204        }
205    
206        @POST
207        @Path("/topictype")
208        @Transactional
209        public TopicType createTopicType(TopicTypeModel model) {
210            return dms.createTopicType(model);
211        }
212    
213        @PUT
214        @Path("/topictype")
215        @Transactional
216        public Directives updateTopicType(TopicTypeModel model) {
217            dms.updateTopicType(model);
218            return Directives.get();
219        }
220    
221        @DELETE
222        @Path("/topictype/{uri}")
223        @Transactional
224        public Directives deleteTopicType(@PathParam("uri") String uri) {
225            dms.deleteTopicType(uri);
226            return Directives.get();
227        }
228    
229    
230    
231        // === Association Types ===
232    
233        @GET
234        @Path("/assoctype")
235        public List<String> getAssociationTypeUris() {
236            return dms.getAssociationTypeUris();
237        }
238    
239        @GET
240        @Path("/assoctype/{uri}")
241        public AssociationType getAssociationType(@PathParam("uri") String uri) {
242            return dms.getAssociationType(uri);
243        }
244    
245        @GET
246        @Path("/assoctype/all")
247        public List<AssociationType> getAssociationAllTypes() {
248            return dms.getAllAssociationTypes();
249        }
250    
251        @POST
252        @Path("/assoctype")
253        @Transactional
254        public AssociationType createAssociationType(AssociationTypeModel model) {
255            return dms.createAssociationType(model);
256        }
257    
258        @PUT
259        @Path("/assoctype")
260        @Transactional
261        public Directives updateAssociationType(AssociationTypeModel model) {
262            dms.updateAssociationType(model);
263            return Directives.get();
264        }
265    
266        @DELETE
267        @Path("/assoctype/{uri}")
268        @Transactional
269        public Directives deleteAssociationType(@PathParam("uri") String uri) {
270            dms.deleteAssociationType(uri);
271            return Directives.get();
272        }
273    
274    
275    
276        // === Role Types ===
277    
278        @POST
279        @Path("/roletype")
280        @Transactional
281        public Topic createRoleType(TopicModel model) {
282            return dms.createRoleType(model);
283        }
284    
285    
286    
287        // === Plugins ===
288    
289        @GET
290        @Path("/plugin")
291        public List<PluginInfo> getPluginInfo() {
292            return dms.getPluginInfo();
293        }
294    
295    
296    
297        // **********************
298        // *** Topic REST API ***
299        // **********************
300    
301    
302    
303        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
304        @GET
305        @Path("/topic/{id}/related_topics")
306        public ResultList<RelatedTopic> getTopicRelatedTopics(@PathParam("id")                    long topicId,
307                                                             @QueryParam("assoc_type_uri")        String assocTypeUri,
308                                                             @QueryParam("my_role_type_uri")      String myRoleTypeUri,
309                                                             @QueryParam("others_role_type_uri")  String othersRoleTypeUri,
310                                                             @QueryParam("others_topic_type_uri") String othersTopicTypeUri,
311                                                             @QueryParam("max_result_size")       int maxResultSize) {
312            Topic topic = dms.getTopic(topicId);
313            return getRelatedTopics(topic, "topic", assocTypeUri, myRoleTypeUri, othersRoleTypeUri,
314                othersTopicTypeUri, maxResultSize);
315        }
316    
317        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
318        @GET
319        @Path("/topic/{id}/related_assocs")
320        public ResultList<RelatedAssociation> getTopicRelatedAssociations(@PathParam("id")      long topicId,
321                                                           @QueryParam("assoc_type_uri")        String assocTypeUri,
322                                                           @QueryParam("my_role_type_uri")      String myRoleTypeUri,
323                                                           @QueryParam("others_role_type_uri")  String othersRoleTypeUri,
324                                                           @QueryParam("others_assoc_type_uri") String othersAssocTypeUri) {
325            Topic topic = dms.getTopic(topicId);
326            return getRelatedAssociations(topic, "topic", assocTypeUri, myRoleTypeUri, othersRoleTypeUri,
327                othersAssocTypeUri);
328        }
329    
330    
331    
332        // ****************************
333        // *** Association REST API ***
334        // ****************************
335    
336    
337    
338        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
339        @GET
340        @Path("/association/{id}/related_topics")
341        public ResultList<RelatedTopic> getAssociationRelatedTopics(@PathParam("id")              long assocId,
342                                                             @QueryParam("assoc_type_uri")        String assocTypeUri,
343                                                             @QueryParam("my_role_type_uri")      String myRoleTypeUri,
344                                                             @QueryParam("others_role_type_uri")  String othersRoleTypeUri,
345                                                             @QueryParam("others_topic_type_uri") String othersTopicTypeUri,
346                                                             @QueryParam("max_result_size")       int maxResultSize) {
347            Association assoc = dms.getAssociation(assocId);
348            return getRelatedTopics(assoc, "association", assocTypeUri, myRoleTypeUri, othersRoleTypeUri,
349                othersTopicTypeUri, maxResultSize);
350        }
351    
352        // Note: the "include_childs" query paramter is handled by the core's JerseyResponseFilter
353        @GET
354        @Path("/association/{id}/related_assocs")
355        public ResultList<RelatedAssociation> getAssociationRelatedAssociations(@PathParam("id") long assocId,
356                                                           @QueryParam("assoc_type_uri")        String assocTypeUri,
357                                                           @QueryParam("my_role_type_uri")      String myRoleTypeUri,
358                                                           @QueryParam("others_role_type_uri")  String othersRoleTypeUri,
359                                                           @QueryParam("others_assoc_type_uri") String othersAssocTypeUri) {
360            Association assoc = dms.getAssociation(assocId);
361            return getRelatedAssociations(assoc, "association", assocTypeUri, myRoleTypeUri, othersRoleTypeUri,
362                othersAssocTypeUri);
363        }
364    
365    
366    
367        // ------------------------------------------------------------------------------------------------- Private Methods
368    
369        private ResultList<RelatedTopic> getRelatedTopics(DeepaMehtaObject object, String objectInfo, String assocTypeUri,
370                                                          String myRoleTypeUri, String othersRoleTypeUri,
371                                                          String othersTopicTypeUri, int maxResultSize) {
372            String operation = "Fetching related topics of " + objectInfo + " " + object.getId();
373            String paramInfo = "(assocTypeUri=\"" + assocTypeUri + "\", myRoleTypeUri=\"" + myRoleTypeUri +
374                "\", othersRoleTypeUri=\"" + othersRoleTypeUri + "\", othersTopicTypeUri=\"" + othersTopicTypeUri +
375                "\", maxResultSize=" + maxResultSize + ")";
376            try {
377                logger.info(operation + " " + paramInfo);
378                return object.getRelatedTopics(assocTypeUri, myRoleTypeUri, othersRoleTypeUri, othersTopicTypeUri,
379                    maxResultSize);
380            } catch (Exception e) {
381                throw new RuntimeException(operation + " failed " + paramInfo, e);
382            }
383        }
384    
385        private ResultList<RelatedAssociation> getRelatedAssociations(DeepaMehtaObject object, String objectInfo,
386                                                                      String assocTypeUri, String myRoleTypeUri,
387                                                                      String othersRoleTypeUri, String othersAssocTypeUri) {
388            String operation = "Fetching related associations of " + objectInfo + " " + object.getId();
389            String paramInfo = "(assocTypeUri=\"" + assocTypeUri + "\", myRoleTypeUri=\"" + myRoleTypeUri +
390                "\", othersRoleTypeUri=\"" + othersRoleTypeUri + "\", othersAssocTypeUri=\"" + othersAssocTypeUri + "\")";
391            try {
392                logger.info(operation + " " + paramInfo);
393                return object.getRelatedAssociations(assocTypeUri, myRoleTypeUri, othersRoleTypeUri, othersAssocTypeUri);
394            } catch (Exception e) {
395                throw new RuntimeException(operation + " failed " + paramInfo, e);
396            }
397        }
398    }