Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jreceiver/client/rio/RioLauncher.java


1   /* $Header: /cvsroot/jreceiver/jreceiver/src/jreceiver/client/rio/RioLauncher.java,v 1.11 2002/12/29 00:44:09 reedesau Exp $ */
2   
3   package jreceiver.client.rio;
4   
5   import java.io.IOException;
6   import java.io.Writer;
7   import java.net.InetAddress;
8   import java.net.URL;
9   import java.net.UnknownHostException;
10  import java.util.Vector;
11  import javax.servlet.*;
12  import javax.servlet.http.*;
13  
14  import org.apache.commons.lang.Strings;
15  
16  import jreceiver.client.common.ClientLauncher;
17  import jreceiver.client.rio.hack.*;
18  import jreceiver.client.rio.status.*;
19  import jreceiver.common.LauncherException;
20  import jreceiver.common.rec.driver.*;
21  import jreceiver.common.rpc.Drivers;
22  import jreceiver.common.rpc.RpcException;
23  import jreceiver.common.rpc.RpcFactory;
24  
25  /**
26   * launches background daemons to interact with the Rio Receiver
27   * <p>
28   *   RioSSDP - listens for queries from Rio for server address and port
29   * <p>
30   *   RioStatus - queries all known Rio Receivers for status every couple of
31   *               seconds on their 18678 ports
32   * <p>
33   * All settings are loaded from database using the following
34   * keys and defaults:
35   * <p>
36   *     hardware/rio/ssdp_port   = 21075
37   *     hardware/rio/mserve_port = 8080
38   *     hardware/rio/mserve_host = ""  blank to get host from Java
39   *     hardware/rio/status_port = 18678
40   *
41   * @author Reed Esau
42   * @version $Revision: 1.11 $ $Date: 2002/12/29 00:44:09 $
43   */
44  public class RioLauncher extends ClientLauncher {
45  
46      public static final String CALLBACK_URL_PARAM = "rio-rpc";
47  
48      protected static Driver driver = null;
49  
50      public static int getDriverId() {
51          return driver!=null ? driver.getId() : 0;
52      }
53  
54      public static Driver getDriver() {
55          return driver;
56      }
57  
58      /**
59       * Called by the servlet container to indicate to a servlet that the
60       * servlet is being placed into service.
61       *
62       * @param user - the user whose credentials were used to register the client
63       */
64      public void serverDetectedInit() throws LauncherException {
65  
66          log.debug("RioLauncher: serverDetectedInit");
67  
68          int ssdp_port;
69          int mserve_port;
70          int status_port;
71          boolean ds_hack;
72  
73          // this initializes the settings cache for the creds used to register this driver
74          RioSettingCache settings = RioSettingCache.getInstance(getDefaultUser());
75  
76          // register with the server (so that we can receive events
77          // and provide services through the XML-RPC interface)
78          try {
79              // initialize security to authenticate callbacks from server
80              String callback_user_id =  "riocallback";
81              String callback_password = Strings.randomAlphanumeric(10);
82              RioSecurityBean security_bean = RioSecurityBean.getInstance();
83              security_bean.setCredentials(callback_user_id, callback_password);
84  
85              RpcFactory.setDefaultCredentials(getDefaultUser());
86  
87              log.info("RioLauncher: registering driver with server");
88              URL callback_url = getPropertyURL(CALLBACK_URL_PARAM);
89              Drivers drv_rpc = RpcFactory.newDrivers();
90  
91              // build a list of natively supported mime-types
92              Vector mime_types = new Vector();
93              mime_types.add( "audio/x-mp3"   );
94              if (settings.getNativeWMA())
95                  mime_types.add( "audio/x-ms-wma" );
96              if (settings.getNativeOGG())
97                  mime_types.add( "audio/x-ogg" );
98              if (settings.getNativeFLAC())
99                  mime_types.add( "audio/x-flac" );
100 
101             Vector slave_types = new Vector();
102             slave_types.add( "IR" );
103             driver = drv_rpc.register(callback_url,
104                                       callback_user_id,
105                                       callback_password,
106                                       mime_types,
107                                       null,         //no master medium types
108                                       slave_types,
109                                       false);           // settings restricted to driver registrar
110 
111             int cmd_type = settings.getDsHack()
112                            ? Command.TYPE_DIRECT
113                            : Command.TYPE_IR;
114 
115             Vector cmds = new Vector();
116             cmds.add( new CommandRec(0, Command.STD_PWRTGL   , cmd_type) );
117             cmds.add( new CommandRec(0, Command.STD_PREV     , cmd_type) );
118             cmds.add( new CommandRec(0, Command.STD_PLAYPAUSE, cmd_type) );
119             cmds.add( new CommandRec(0, Command.STD_STOP     , cmd_type) );
120             cmds.add( new CommandRec(0, Command.STD_NEXT     , cmd_type) );
121 
122             drv_rpc.registerCommandSet(getDriverId(), cmds);
123 
124             ssdp_port   = settings.getSsdpPort();
125             mserve_port = settings.getMservePort();
126             status_port = settings.getStatusPort();
127             ds_hack     = settings.getDsHack();
128         }
129         catch (RpcException e) {
130             throw new LauncherException("RioLauncher: rpc-problem registering the driver", e);
131         }
132 
133         // initialize and launch the daemons
134         String host_ip = getHostIP();
135 
136         log.debug("RioLauncher: creating and initializing the daemons");
137         ssdp_daemon = RioSSDP.getInstance(ssdp_port, host_ip, mserve_port);
138 
139         // create the singleton and add it as a listener to the SSDP daemon
140         status_daemon = RioStatusDaemon.getInstance( new Integer(status_port) );
141         if (status_daemon != null) {
142             ssdp_daemon.addListener( status_daemon );
143 
144             log.info("RioLauncher: starting status_daemon");
145             status_daemon.start();     // start listening
146         }
147         else {
148             log.warn("RioLauncher: unable to start the status daemon");
149         }
150 
151         log.info("RioLauncher: starting ssdp_daemon");
152         ssdp_daemon.start();     // start listening
153 
154         if (ds_hack) {
155             hack_daemon = RioHackDaemon.getInstance();
156             if (hack_daemon != null) {
157                 log.info("RioLauncher: starting hack_daemon");
158                 hack_daemon.start();     // start listening
159             }
160             else {
161                 log.warn("RioLauncher: unable to start the hack daemon");
162             }
163         }
164     }
165 
166     /**
167      * support method for serverDetectedInit to obtain a valid host ip address
168      */
169     private String getHostIP() throws LauncherException {
170 
171         String host_ip = null;
172         String hostname;
173 
174         try {
175             RioSettingCache settings = RioSettingCache.getInstance();
176 
177             hostname = settings.getMserveHost();
178         }
179         catch (RpcException e) {
180             throw new LauncherException("unable to obtain the mserve host", e);
181         }
182 
183         if (hostname != null && hostname.length() > 0) {
184             log.info("RioLauncher: getting music server IP for hostname " + hostname);
185         }
186         else {
187             log.debug("RioLauncher: attempting to determine music server hostname");
188             try {
189                 hostname = InetAddress.getLocalHost().getHostName();
190             }
191             catch (UnknownHostException e) {
192                 throw new LauncherException("unable to determine local hostname", e);
193             }
194         }
195 
196         hostname = hostname.trim();
197 
198         if (Character.isDigit(hostname.charAt(0))) {   //TODO: need more sophistication
199             host_ip = hostname;
200         }
201         else {    // attempt to resolve name into an IP
202             try {
203                 InetAddress addr = InetAddress.getByName(hostname);
204                 if (addr != null) {
205                     host_ip = addr.getHostAddress();
206                 }
207                 else
208                     throw new LauncherException("unable to resolve hostname");
209             }
210             catch (UnknownHostException e) {
211                 throw new LauncherException("unable to resolve hostname", e);
212             }
213         }
214 
215         return host_ip;
216     }
217 
218     /**
219      * Called by the servlet container to indicate to a servlet that the
220      * servlet is being taken out of service.  See {@link Servlet#destroy}.
221      */
222     public void destroy() {
223         if (ssdp_daemon != null)
224             ssdp_daemon.stop();      // stop listening
225         if (status_daemon != null)
226             status_daemon.stop();      // stop listening
227     }
228 
229     /**
230      * test method
231      */
232     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
233     throws ServletException,IOException {
234         Writer writer = resp.getWriter();
235         writer.write("I'm the Rio Launcher Servlet.");
236     }
237 
238 //
239 // internal data members
240 //
241 
242     /**
243      * The RioSSDP daemon listens for Rio Receivers in search
244      * of a server, responds to them offering the services
245      * of the server that typically hosts the daemon.
246      * <p>
247      * IMPORTANT: keep this reference to the singleton,
248      * otherwise it might be garbage collected.
249      */
250     protected RioSSDP ssdp_daemon = null;
251 
252     /**
253      * the RioStatus daemon queries all known Rios for status
254      * and produces events for (local) listeners
255      * <p>
256      * IMPORTANT: keep this reference to the singleton,
257      * otherwise it might be garbage collected.
258      */
259     protected RioStatusDaemon status_daemon = null;
260 
261     protected RioHackDaemon hack_daemon = null;
262 }
263 
264 
265 /*
266 JRECEIVER MODIFIED BSD LICENSE
267 
268 Copyright (c) 2001-2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
269 
270 Redistribution and use in source and binary forms, with or without
271 modification, are permitted provided that the following conditions are
272 met:
273 
274 Redistributions of source code must retain the above copyright notice,
275 this list of conditions and the following disclaimer.
276 
277 Redistributions in binary form must reproduce the above copyright notice,
278 this list of conditions and the following disclaimer in the documentation
279 and/or other materials provided with the distribution.
280 
281 Neither the name of the JReceiver Project
282 (http://jreceiver.sourceforge.net) nor the names of its contributors may
283 be used to endorse or promote products derived from this software without
284 specific prior written permission.
285 
286 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
287 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
288 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
289 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
290 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
291 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
292 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
293 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
294 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
295 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
296 POSSIBILITY OF SUCH DAMAGE.
297 */
298