View Javadoc

1   /* This file is part of COPAL (COntext Provisioning for All).
2    *
3    * COPAL is a part of SM4All (Smart hoMes for All) project.
4    *
5    * COPAL is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU Lesser General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * COPAL is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with COPAL. If not, see <http://www.gnu.org/licenses/>.
17   */
18  package at.ac.tuwien.infosys.sm4all.copal.rest.internal;
19  
20  import java.util.concurrent.atomic.AtomicReference;
21  import javax.ws.rs.core.Response;
22  import javax.ws.rs.core.Response.Status;
23  import javax.ws.rs.core.UriBuilder;
24  import javax.ws.rs.core.UriInfo;
25  import at.ac.tuwien.infosys.sm4all.copal.api.ContextException;
26  import at.ac.tuwien.infosys.sm4all.copal.api.event.ContextEventType;
27  import at.ac.tuwien.infosys.sm4all.copal.api.event.MalformedDocumentException;
28  import at.ac.tuwien.infosys.sm4all.copal.api.event.XMLContextEventType;
29  import at.ac.tuwien.infosys.sm4all.copal.api.listener.ContextListener;
30  import at.ac.tuwien.infosys.sm4all.copal.api.processor.ContextProcessor;
31  import at.ac.tuwien.infosys.sm4all.copal.api.publisher.ContextPublisher;
32  import at.ac.tuwien.infosys.sm4all.copal.api.query.ContextQuery;
33  import at.ac.tuwien.infosys.sm4all.copal.api.query.ProcessedEventQuery;
34  import at.ac.tuwien.infosys.sm4all.copal.api.query.QueryDestroyedException;
35  import at.ac.tuwien.infosys.sm4all.copal.api.service.ContextEventTypeRegistry;
36  import at.ac.tuwien.infosys.sm4all.copal.api.service.ContextProcessorRegistry;
37  import at.ac.tuwien.infosys.sm4all.copal.api.service.ContextPublisherRegistry;
38  import at.ac.tuwien.infosys.sm4all.copal.api.service.ContextQueryFactory;
39  import at.ac.tuwien.infosys.sm4all.copal.api.util.AlreadyRegisteredException;
40  import at.ac.tuwien.infosys.sm4all.copal.api.util.NotRegisteredException;
41  import at.ac.tuwien.infosys.sm4all.copal.rest.Service;
42  import at.ac.tuwien.infosys.sm4all.copal.rest.model.ContextListeners;
43  import at.ac.tuwien.infosys.sm4all.copal.rest.model.ContextProcessors;
44  import at.ac.tuwien.infosys.sm4all.copal.rest.model.ContextPublishers;
45  import at.ac.tuwien.infosys.sm4all.copal.rest.model.Event;
46  import at.ac.tuwien.infosys.sm4all.copal.rest.model.ProcessedEventQueries;
47  import at.ac.tuwien.infosys.sm4all.copal.rest.model.RESTfulListener;
48  import at.ac.tuwien.infosys.sm4all.copal.rest.model.RESTfulPublisher;
49  import at.ac.tuwien.infosys.sm4all.copal.rest.model.XMLContextEventTypes;
50  
51  /**
52   * Implementation of the {@link Service} interface.
53   * 
54   * @author sanjin
55   */
56  public class ServiceImpl implements Service {
57  
58      private final AtomicReference<ContextEventTypeRegistry> eventTypeRegistry = new AtomicReference<ContextEventTypeRegistry>();
59      private final AtomicReference<ContextPublisherRegistry> publisherRegistry = new AtomicReference<ContextPublisherRegistry>();
60      private final AtomicReference<ContextProcessorRegistry> processorRegistry = new AtomicReference<ContextProcessorRegistry>();
61      private final AtomicReference<ContextQueryFactory> queryFactory = new AtomicReference<ContextQueryFactory>();
62  
63      /**
64       * Returns the {@link ContextEventTypeRegistry} this service is using.
65       * 
66       * @return the {@link ContextEventTypeRegistry} this service is using.
67       */
68      public ContextEventTypeRegistry getEventTypeRegistry() {
69          return this.eventTypeRegistry.get();
70      }
71  
72      /**
73       * Sets the {@link ContextEventTypeRegistry} this service should use.
74       * 
75       * @param eventTypeRegistry the {@link ContextEventTypeRegistry}.
76       */
77      public void setEventTypeRegistry(
78              final ContextEventTypeRegistry eventTypeRegistry) {
79          this.eventTypeRegistry.set(eventTypeRegistry);
80      }
81  
82      /**
83       * Returns the {@link ContextPublisherRegistry} this service is using.
84       * 
85       * @return the {@link ContextPublisherRegistry} this service is using.
86       */
87      public ContextPublisherRegistry getPublisherRegistry() {
88          return this.publisherRegistry.get();
89      }
90  
91      /**
92       * Sets the {@link ContextPublisherRegistry} this service should use.
93       * 
94       * @param publisherRegistry the {@link ContextPublisherRegistry}.
95       */
96      public void setPublisherRegistry(
97              final ContextPublisherRegistry publisherRegistry) {
98          this.publisherRegistry.set(publisherRegistry);
99      }
100 
101     /**
102      * Returns the {@link ContextProcessorRegistry} this service is using.
103      * 
104      * @return the {@link ContextProcessorRegistry} this service is using.
105      */
106     public ContextProcessorRegistry getProcessorRegistry() {
107         return this.processorRegistry.get();
108     }
109 
110     /**
111      * Sets the {@link ContextProcessorRegistry} this service should use.
112      * 
113      * @param processorRegistry the {@link ContextProcessorRegistry}.
114      */
115     public void setProcessorRegistry(
116             final ContextProcessorRegistry processorRegistry) {
117         this.processorRegistry.set(processorRegistry);
118     }
119 
120     /**
121      * Returns the {@link ContextQueryFactory} this service is using.
122      * 
123      * @return the {@link ContextQueryFactory} this service is using.
124      */
125     public ContextQueryFactory getQueryFactory() {
126         return this.queryFactory.get();
127     }
128 
129     /**
130      * Sets the {@link ContextQueryFactory} this service should use.
131      * 
132      * @param queryFactory the {@link ContextQueryFactory}.
133      */
134     public void setQueryFactory(final ContextQueryFactory queryFactory) {
135         this.queryFactory.set(queryFactory);
136     }
137 
138     @Override
139     public Response getEventTypes() {
140         final Response result;
141 
142         final ContextEventTypeRegistry registry = this.eventTypeRegistry.get();
143         if (null == registry) {
144             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
145         } else {
146             result = Response.ok(new XMLContextEventTypes(registry.getAll())).build();
147         }
148 
149         return result;
150     }
151 
152     @Override
153     public Response register(final UriInfo uriInfo,
154             final XMLContextEventType eventType) {
155         final Response result;
156 
157         final ContextEventTypeRegistry registry = this.eventTypeRegistry.get();
158         if (null == registry) {
159             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
160         } else {
161             Response response = null;
162             try {
163                 registry.register(eventType);
164                 final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder().path(
165                         Service.class, "getEventType");
166                 response = Response.created(
167                         uriBuilder.build(eventType.getName())).build();
168             } catch (final AlreadyRegisteredException ignored) {
169                 response = Response.status(Status.CONFLICT).build();
170             }
171             result = response;
172         }
173 
174         return result;
175     }
176 
177     @Override
178     public Response getEventType(final String name) {
179         final Response result;
180 
181         final ContextEventTypeRegistry registry = this.eventTypeRegistry.get();
182         if (null == registry) {
183             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
184         } else {
185             final ContextEventType eventType = registry.get(name);
186             if (null == eventType) {
187                 result = Response.status(Status.NOT_FOUND).build();
188             } else if (eventType instanceof XMLContextEventType) {
189                 result = Response.ok(
190                         new XMLContextEventTypes(
191                                 (XMLContextEventType) eventType)).build();
192             } else {
193                 result = Response.status(Status.FORBIDDEN).build();
194             }
195         }
196 
197         return result;
198     }
199 
200     @Override
201     public Response unregisterEventType(final String name) {
202         final Response result;
203 
204         final ContextEventTypeRegistry registry = this.eventTypeRegistry.get();
205         if (null == registry) {
206             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
207         } else {
208             final ContextEventType eventType = registry.get(name);
209             if (null == eventType) {
210                 result = Response.status(Status.NOT_FOUND).build();
211             } else if (eventType instanceof XMLContextEventType) {
212                 Response response = null;
213                 try {
214                     registry.unregister(name);
215                     response = Response.ok(
216                             new XMLContextEventTypes(
217                                     (XMLContextEventType) eventType)).build();
218                 } catch (final NotRegisteredException ignored) {
219                     response = Response.status(Status.NOT_FOUND).build();
220                 }
221                 result = response;
222             } else {
223                 result = Response.status(Status.FORBIDDEN).build();
224             }
225         }
226 
227         return result;
228     }
229 
230     @Override
231     public Response getProcessors(final String eventName) {
232         final Response result;
233 
234         final ContextProcessorRegistry registry = this.processorRegistry.get();
235         if (null == registry) {
236             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
237         } else {
238             result = Response.ok(
239                     new ContextProcessors(registry.getAll(eventName))).build();
240         }
241 
242         return result;
243     }
244 
245     @Override
246     public Response getQueries(final String eventName) {
247         final Response result;
248 
249         final ContextQueryFactory factory = this.queryFactory.get();
250         if (null == factory) {
251             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
252         } else {
253             result = Response.ok(
254                     new ProcessedEventQueries(factory.getQueries(eventName))).build();
255         }
256 
257         return result;
258     }
259 
260     @Override
261     public Response getPublishers(final String eventName) {
262         final Response result;
263 
264         final ContextPublisherRegistry registry = this.publisherRegistry.get();
265         if (null == registry) {
266             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
267         } else {
268             result = Response.ok(
269                     new ContextPublishers(registry.getAll(eventName))).build();
270         }
271 
272         return result;
273     }
274 
275     @Override
276     public Response getPublishers() {
277         final Response result;
278 
279         final ContextPublisherRegistry registry = this.publisherRegistry.get();
280         if (null == registry) {
281             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
282         } else {
283             result = Response.ok(new ContextPublishers(registry.getAll())).build();
284         }
285 
286         return result;
287     }
288 
289     @Override
290     public Response register(final UriInfo uriInfo,
291             final RESTfulPublisher publisher) {
292         final Response result;
293 
294         final ContextPublisherRegistry registry = this.publisherRegistry.get();
295         if (null == registry) {
296             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
297         } else {
298             Response response = null;
299             try {
300                 registry.register(publisher);
301                 final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder().path(
302                         Service.class, "getPublisher");
303                 response = Response.created(
304                         uriBuilder.build(publisher.getSourceID())).build();
305             } catch (final AlreadyRegisteredException ignored) {
306                 response = Response.status(Status.CONFLICT).build();
307             }
308             result = response;
309         }
310 
311         return result;
312     }
313 
314     @Override
315     public Response getPublisher(final String sourceID) {
316         final Response result;
317 
318         final ContextPublisherRegistry registry = this.publisherRegistry.get();
319         if (null == registry) {
320             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
321         } else {
322             final ContextPublisher publisher = registry.get(sourceID);
323             if (null == publisher) {
324                 result = Response.status(Status.NOT_FOUND).build();
325             } else {
326                 result = Response.ok(new ContextPublishers(publisher)).build();
327             }
328         }
329 
330         return result;
331     }
332 
333     @Override
334     public Response publish(final String sourceID, final Event event) {
335         final Response result;
336 
337         final ContextPublisherRegistry registry = this.publisherRegistry.get();
338         if (null == registry) {
339             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
340         } else {
341             final ContextPublisher publisher = registry.get(sourceID);
342             if (null == publisher) {
343                 result = Response.status(Status.NOT_FOUND).build();
344             } else if (publisher instanceof RESTfulPublisher) {
345                 Response response = null;
346                 try {
347                     ((RESTfulPublisher) publisher).publish(event);
348                     response = Response.ok().build();
349                 } catch (final MalformedDocumentException ignored) {
350                     response = Response.status(Status.BAD_REQUEST).build();
351                 } catch (final ContextException ignored) {
352                     response = Response.status(Status.INTERNAL_SERVER_ERROR).build();
353                 }
354                 result = response;
355             } else {
356                 result = Response.status(Status.FORBIDDEN).build();
357             }
358         }
359 
360         return result;
361     }
362 
363     @Override
364     public Response unregisterPublisher(final String sourceID) {
365         final Response result;
366 
367         final ContextPublisherRegistry registry = this.publisherRegistry.get();
368         if (null == registry) {
369             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
370         } else {
371             final ContextPublisher publisher = registry.get(sourceID);
372             if (null == publisher) {
373                 result = Response.status(Status.NOT_FOUND).build();
374             } else if (publisher instanceof RESTfulPublisher) {
375                 Response response = null;
376                 try {
377                     registry.unregister(sourceID);
378                     response = Response.ok().build();
379                 } catch (final NotRegisteredException ignored) {
380                     response = Response.status(Status.NOT_FOUND).build();
381                 }
382                 result = response;
383             } else {
384                 result = Response.status(Status.FORBIDDEN).build();
385             }
386         }
387 
388         return result;
389     }
390 
391     @Override
392     public Response getProcessors() {
393         final Response result;
394 
395         final ContextProcessorRegistry registry = this.processorRegistry.get();
396         if (null == registry) {
397             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
398         } else {
399             result = Response.ok(new ContextProcessors(registry.getAll())).build();
400         }
401 
402         return result;
403     }
404 
405     @Override
406     public Response getProcessor(final String name) {
407         final Response result;
408 
409         final ContextProcessorRegistry registry = this.processorRegistry.get();
410         if (null == registry) {
411             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
412         } else {
413             final ContextProcessor processor = registry.get(name);
414             if (null == processor) {
415                 result = Response.status(Status.NOT_FOUND).build();
416             } else {
417                 result = Response.ok(new ContextProcessors(processor)).build();
418             }
419         }
420 
421         return result;
422     }
423 
424     @Override
425     public Response getQueries() {
426         final Response result;
427 
428         final ContextQueryFactory factory = this.queryFactory.get();
429         if (null == factory) {
430             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
431         } else {
432             result = Response.ok(
433                     new ProcessedEventQueries(factory.getQueries())).build();
434         }
435 
436         return result;
437     }
438 
439     @Override
440     public Response create(final UriInfo uriInfo,
441             final ProcessedEventQuery query) {
442         final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder().path(
443                 Service.class, "getQuery");
444         return Response.created(uriBuilder.build(query.getName())).build();
445     }
446 
447     @Override
448     public Response getQuery(final String name) {
449         final Response result;
450 
451         final ContextQueryFactory factory = this.queryFactory.get();
452         if (null == factory) {
453             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
454         } else {
455             final ContextQuery query = factory.getQuery(name);
456             if (null == query) {
457                 result = Response.status(Status.NOT_FOUND).build();
458             } else if (query instanceof ProcessedEventQuery) {
459                 result = Response.ok(new ProcessedEventQueries(query)).build();
460             } else {
461                 result = Response.status(Status.FORBIDDEN).build();
462             }
463         }
464 
465         return result;
466     }
467 
468     @Override
469     public Response destroy(final String name) {
470         final Response result;
471 
472         final ContextQueryFactory factory = this.queryFactory.get();
473         if (null == factory) {
474             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
475         } else {
476             final ContextQuery query = factory.getQuery(name);
477             if (null == query) {
478                 result = Response.status(Status.NOT_FOUND).build();
479             } else if (query instanceof ProcessedEventQuery) {
480                 Response response;
481                 try {
482                     query.destroy();
483                     response = Response.ok(new ProcessedEventQueries(query)).build();
484                 } catch (final QueryDestroyedException ignored) {
485                     response = Response.status(Status.NOT_FOUND).build();
486                 }
487                 result = response;
488             } else {
489                 result = Response.status(Status.FORBIDDEN).build();
490             }
491         }
492 
493         return result;
494     }
495 
496     @Override
497     public Response getListeners(final String queryName) {
498         final Response result;
499 
500         final ContextQueryFactory factory = this.queryFactory.get();
501         if (null == factory) {
502             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
503         } else {
504             final ContextQuery query = factory.getQuery(queryName);
505             if (null == query) {
506                 result = Response.status(Status.NOT_FOUND).build();
507             } else if (query instanceof ProcessedEventQuery) {
508                 result = Response.ok(
509                         new ContextListeners(
510                                 ((ProcessedEventQuery) query).getAll())).build();
511             } else {
512                 result = Response.status(Status.FORBIDDEN).build();
513             }
514         }
515 
516         return result;
517     }
518 
519     @Override
520     public Response register(final UriInfo uriInfo, final String queryName,
521             final RESTfulListener listener) {
522         final Response result;
523 
524         final ContextQueryFactory factory = this.queryFactory.get();
525         if (null == factory) {
526             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
527         } else {
528             final ContextQuery query = factory.getQuery(queryName);
529             if (null == query) {
530                 result = Response.status(Status.NOT_FOUND).build();
531             } else if (query instanceof ProcessedEventQuery) {
532                 Response response = null;
533                 try {
534                     ((ProcessedEventQuery) query).register(listener);
535                     final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder().path(
536                             Service.class, "getListener");
537                     response = Response.created(
538                             uriBuilder.build(queryName, listener.getName())).build();
539                 } catch (final AlreadyRegisteredException ignored) {
540                     response = Response.status(Status.CONFLICT).build();
541                 } catch (final QueryDestroyedException ignored) {
542                     Response.status(Status.NOT_FOUND).build();
543                 }
544                 result = response;
545             } else {
546                 result = Response.status(Status.FORBIDDEN).build();
547             }
548         }
549 
550         return result;
551     }
552 
553     @Override
554     public Response getListener(final String queryName, final String name) {
555         final Response result;
556 
557         final ContextQueryFactory factory = this.queryFactory.get();
558         if (null == factory) {
559             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
560         } else {
561             final ContextQuery query = factory.getQuery(queryName);
562             if (null == query) {
563                 result = Response.status(Status.NOT_FOUND).build();
564             } else if (query instanceof ProcessedEventQuery) {
565                 final ContextListener listener = ((ProcessedEventQuery) query).get(name);
566                 if (null == listener) {
567                     result = Response.status(Status.NOT_FOUND).build();
568                 } else {
569                     result = Response.ok(new ContextListeners(listener)).build();
570                 }
571             } else {
572                 result = Response.status(Status.FORBIDDEN).build();
573             }
574         }
575 
576         return result;
577     }
578 
579     @Override
580     public Response unregisterListener(final String queryName, final String name) {
581         final Response result;
582 
583         final ContextQueryFactory factory = this.queryFactory.get();
584         if (null == factory) {
585             result = Response.status(Status.SERVICE_UNAVAILABLE).build();
586         } else {
587             final ContextQuery query = factory.getQuery(queryName);
588             if (null == query) {
589                 result = Response.status(Status.NOT_FOUND).build();
590             } else if (query instanceof ProcessedEventQuery) {
591                 ContextListener resultListener = null;
592                 for (final ContextListener listener : ((ProcessedEventQuery) query).getAll()) {
593                     if (name.equals(listener.getName())) {
594                         resultListener = listener;
595                         break;
596                     }
597                 }
598                 if (null == resultListener) {
599                     result = Response.status(Status.NOT_FOUND).build();
600                 } else if (resultListener instanceof RESTfulListener) {
601                     Response response = null;
602                     try {
603                         ((ProcessedEventQuery) query).unregister(name);
604                         response = Response.ok(
605                                 new ContextListeners(resultListener)).build();
606                     } catch (final NotRegisteredException ignored) {
607                         response = Response.status(Status.NOT_FOUND).build();
608                     }
609                     result = response;
610                 } else {
611                     result = Response.status(Status.FORBIDDEN).build();
612                 }
613             } else {
614                 result = Response.status(Status.FORBIDDEN).build();
615             }
616         }
617 
618         return result;
619     }
620 }