View Javadoc
1   /*
2    * Copyright (C) 2013 4th Line GmbH, Switzerland
3    *
4    * The contents of this file are subject to the terms of either the GNU
5    * Lesser General Public License Version 2 or later ("LGPL") or the
6    * Common Development and Distribution License Version 1 or later
7    * ("CDDL") (collectively, the "License"). You may not use this file
8    * except in compliance with the License. See LICENSE.txt for more
9    * information.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14   */
15  
16  package org.fourthline.cling;
17  
18  import org.fourthline.cling.controlpoint.ControlPoint;
19  import org.fourthline.cling.model.meta.LocalDevice;
20  import org.fourthline.cling.model.meta.RemoteDevice;
21  import org.fourthline.cling.protocol.ProtocolFactory;
22  import org.fourthline.cling.registry.Registry;
23  import org.fourthline.cling.registry.RegistryListener;
24  import org.fourthline.cling.registry.event.After;
25  import org.fourthline.cling.registry.event.Before;
26  import org.fourthline.cling.registry.event.FailedRemoteDeviceDiscovery;
27  import org.fourthline.cling.registry.event.LocalDeviceDiscovery;
28  import org.fourthline.cling.registry.event.Phase;
29  import org.fourthline.cling.registry.event.RegistryShutdown;
30  import org.fourthline.cling.registry.event.RemoteDeviceDiscovery;
31  import org.fourthline.cling.transport.DisableRouter;
32  import org.fourthline.cling.transport.EnableRouter;
33  import org.fourthline.cling.transport.Router;
34  
35  import javax.enterprise.context.ApplicationScoped;
36  import javax.enterprise.event.Event;
37  import javax.enterprise.event.Observes;
38  import javax.enterprise.inject.Any;
39  import javax.enterprise.inject.Instance;
40  import javax.enterprise.util.AnnotationLiteral;
41  import javax.inject.Inject;
42  import java.util.logging.Logger;
43  
44  /**
45   * Adapter for CDI environments.
46   * <p>
47   * The CDI container provides injectable instances of Cling UPnP interfaces, e.g.
48   * you can <code>@Inject Registry</code> or <code>@Inject ControlPoint</code>.
49   * </p>
50   * <p>
51   * Furthermore, this adapter also binds Cling into the CDI eventing system. You
52   * can <code>@Observe RemoteDeviceDiscoveryStart</code> etc. events of the
53   * registry.
54   * </p>
55   * <p>
56   * Even better, in the future you might be able to listen to GENA UPnP events with
57   * the same API - although this will require some magic for subscription...
58   * </p>
59   * <p>
60   * TODO: This is a work in progress.
61   * </p>
62   *
63   * @author Christian Bauer
64   */
65  @ApplicationScoped
66  public class ManagedUpnpService implements UpnpService {
67  
68      final private static Logger log = Logger.getLogger(ManagedUpnpService.class.getName());
69  
70      @Inject
71      RegistryListenerAdapter registryListenerAdapter;
72  
73      @Inject
74      Instance<UpnpServiceConfiguration> configuration;
75  
76      @Inject
77      Instance<Registry> registryInstance;
78  
79      @Inject
80      Instance<Router> routerInstance;
81  
82      @Inject
83      Instance<ProtocolFactory> protocolFactoryInstance;
84  
85      @Inject
86      Instance<ControlPoint> controlPointInstance;
87  
88      @Inject
89      Event<EnableRouter> enableRouterEvent;
90  
91      @Inject
92      Event<DisableRouter> disableRouterEvent;
93  
94      @Override
95      public UpnpServiceConfiguration getConfiguration() {
96          return configuration.get();
97      }
98  
99      @Override
100     public ControlPoint getControlPoint() {
101         return controlPointInstance.get();
102     }
103 
104     @Override
105     public ProtocolFactory getProtocolFactory() {
106         return protocolFactoryInstance.get();
107     }
108 
109     @Override
110     public Registry getRegistry() {
111         return registryInstance.get();
112     }
113 
114     @Override
115     public Router getRouter() {
116         return routerInstance.get();
117     }
118 
119     public void start(@Observes Start start) {
120         log.info(">>> Starting managed UPnP service...");
121 
122         // First start the registry before we can receive messages through the transport
123 
124         getRegistry().addListener(registryListenerAdapter);
125 
126         enableRouterEvent.fire(new EnableRouter());
127 
128         log.info("<<< Managed UPnP service started successfully");
129     }
130 
131     @Override
132     public void shutdown() {
133         shutdown(null);
134     }
135 
136     public void shutdown(@Observes Shutdown shutdown) {
137 
138         // Well, since java.util.logging has its own shutdown hook, this
139         // might actually make it into the log or not...
140         log.info(">>> Shutting down managed UPnP service...");
141 
142         // First stop the registry and announce BYEBYE on the transport
143         getRegistry().shutdown();
144 
145         disableRouterEvent.fire(new DisableRouter());
146 
147         getConfiguration().shutdown();
148 
149         log.info("<<< Managed UPnP service shutdown completed");
150     }
151 
152     @ApplicationScoped
153     static class RegistryListenerAdapter implements RegistryListener {
154 
155         @Inject
156         @Any
157         Event<RemoteDeviceDiscovery> remoteDeviceDiscoveryEvent;
158 
159         @Inject
160         @Any
161         Event<FailedRemoteDeviceDiscovery> failedRemoteDeviceDiscoveryEvent;
162 
163         @Inject
164         @Any
165         Event<LocalDeviceDiscovery> localDeviceDiscoveryEvent;
166 
167         @Inject
168         @Any
169         Event<RegistryShutdown> registryShutdownEvent;
170 
171         @Override
172         public void remoteDeviceDiscoveryStarted(Registry registry, RemoteDevice device) {
173             remoteDeviceDiscoveryEvent.select(Phase.ALIVE).fire(
174                     new RemoteDeviceDiscovery(device)
175             );
176         }
177 
178         @Override
179         public void remoteDeviceDiscoveryFailed(Registry registry, RemoteDevice device, Exception ex) {
180             failedRemoteDeviceDiscoveryEvent.fire(
181                     new FailedRemoteDeviceDiscovery(device, ex)
182             );
183         }
184 
185         @Override
186         public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
187             remoteDeviceDiscoveryEvent.select(Phase.COMPLETE).fire(
188                     new RemoteDeviceDiscovery(device)
189             );
190         }
191 
192         @Override
193         public void remoteDeviceUpdated(Registry registry, RemoteDevice device) {
194             remoteDeviceDiscoveryEvent.select(Phase.UPDATED).fire(
195                     new RemoteDeviceDiscovery(device)
196             );
197         }
198 
199         @Override
200         public void remoteDeviceRemoved(Registry registry, RemoteDevice device) {
201             remoteDeviceDiscoveryEvent.select(Phase.BYEBYE).fire(
202                     new RemoteDeviceDiscovery(device)
203             );
204         }
205 
206         @Override
207         public void localDeviceAdded(Registry registry, LocalDevice device) {
208             localDeviceDiscoveryEvent.select(Phase.COMPLETE).fire(
209                     new LocalDeviceDiscovery(device)
210             );
211         }
212 
213         @Override
214         public void localDeviceRemoved(Registry registry, LocalDevice device) {
215             localDeviceDiscoveryEvent.select(Phase.BYEBYE).fire(
216                     new LocalDeviceDiscovery(device)
217             );
218         }
219 
220         @Override
221         public void beforeShutdown(Registry registry) {
222             registryShutdownEvent.select(new AnnotationLiteral<Before>() {
223             }).fire(
224                     new RegistryShutdown()
225             );
226         }
227 
228         @Override
229         public void afterShutdown() {
230             registryShutdownEvent.select(new AnnotationLiteral<After>() {
231             }).fire(
232                     new RegistryShutdown()
233             );
234         }
235     }
236 
237 }