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

Quick Search    Search Deep

Source code: jreceiver/client/rio/servlet/RioHostTags.java


1   /* $Header: /cvsroot/jreceiver/jreceiver/src/jreceiver/client/rio/servlet/RioHostTags.java,v 1.7 2002/12/29 00:44:07 reedesau Exp $ */
2   
3   package jreceiver.client.rio.servlet;
4   
5   import java.io.*;
6   import javax.servlet.*;
7   import javax.servlet.http.*;
8   
9   import org.apache.commons.logging.*;
10  
11  import jreceiver.client.common.servlet.*;
12  import jreceiver.client.rio.RioLauncher;
13  import jreceiver.common.rec.source.Source;
14  import jreceiver.common.rpc.RpcException;
15  import jreceiver.common.rpc.RpcFactory;
16  import jreceiver.common.rpc.TagEncoder;
17  import jreceiver.util.HexDump;
18  
19  /**
20   * Servlet answering 'tags' requests from Rio Server.
21   * <p>
22   * Called by the server (via the <code>service</code> method) to
23   * allow a servlet to handle a GET request.
24   * <p>
25   * Some sample URLs:
26   * <p>
27   *    http://.../tags
28   * <p>
29   * It is asking for a simple list of available tags:
30   * <p>
31   *       fid
32   *       title
33   *       artist
34   *       source
35   *       year
36   *       comment
37   *       length
38   *       type
39   *       path
40   *       genre
41   *       bitrate
42   *       playlist
43   *       codec
44   *       offset
45   *       duration
46   *       tracknr
47   * <p>
48   * If it asks for the special 0x100 file id...
49   * <p>
50   *    http://.../tags/100
51   * <p>
52   * where '100' is a hex number representing the fileid for
53   * the default playlist, which consists of all tracks.  Send
54   * back a description of that "All Tracks" playlist.
55   * <p>
56   * Otherwise it will ask for tag info for a specific tune or playlist
57   * <p>
58   *    http://.../tags/2b0
59   * <p>
60   * where '2b0' is a hex number representing the src id for
61   * that tune or playlist.
62   *
63   * @author Reed Esau
64   * @version $Revision: 1.7 $ $Date: 2002/12/29 00:44:07 $
65   */
66  public class RioHostTags extends RioHostBase {
67  
68      // The following key_ids are used as field identifiers
69      // by the Rio when decoding binary tags.
70      //
71      // Note that they do NOT correspond to the MessageFormatB
72      // field arguments.
73      public static final int KEY_SRC_ID         = 0x00;
74      public static final int KEY_TITLE          = 0x01;
75      public static final int KEY_ARTIST         = 0x02;
76      public static final int KEY_ALBUM          = 0x03;
77      public static final int KEY_YEAR           = 0x04;
78      public static final int KEY_COMMENT        = 0x05;
79      public static final int KEY_FILESIZE       = 0x06;
80      public static final int KEY_SRCTYPE        = 0x07;
81      public static final int KEY_FILEPATH       = 0x08;
82      public static final int KEY_GENRE          = 0x09;
83      public static final int KEY_BITRATE        = 0x0A;
84      public static final int KEY_PLAYLIST       = 0x0B;
85      public static final int KEY_CODEC          = 0x0C;
86      public static final int KEY_DATA_OFFSET    = 0x0D;
87      public static final int KEY_DURATION       = 0x0E;
88      public static final int KEY_TRACKNO        = 0x0F;
89  
90      /**
91      * the server which hosts the data
92      */
93      protected TagEncoder tag_rpc;
94  
95      /**
96       * Create the pattern for the calls to MessageFormatB to encode tune
97       * tags for the Rio.
98       */
99      protected static byte[] tune_pattern = null;
100     static {
101         try {
102             ByteArrayOutputStream buf = new ByteArrayOutputStream();
103             buf.write(KEY_ARTIST);
104             buf.write( ("{"+TagEncoder.TAG_ARTIST+",string,pp}").getBytes() );
105             buf.write(KEY_BITRATE);
106             buf.write( ("{"+TagEncoder.TAG_BITRATE+",string,pp,p=fs}").getBytes() );  // prefix by fs
107             buf.write(KEY_CODEC);
108             buf.write( ("{"+TagEncoder.TAG_CODEC+",string,pp}").getBytes() );
109             buf.write(KEY_DURATION);
110             buf.write( ("{"+TagEncoder.TAG_DURATION+",string,pp}").getBytes() );
111             buf.write(KEY_SRC_ID);
112             buf.write( ("{"+TagEncoder.TAG_SRC_ID+",string,pp}").getBytes() );
113             buf.write(KEY_GENRE);
114             buf.write( ("{"+TagEncoder.TAG_GENRE+",string,pp}").getBytes() );
115             buf.write(KEY_FILESIZE);
116             buf.write( ("{"+TagEncoder.TAG_FILESIZE+",string,pp}").getBytes() );
117             buf.write(KEY_FILEPATH);
118             buf.write( ("{"+TagEncoder.TAG_FILEPATH+",string,pp}").getBytes() );
119             buf.write(KEY_TITLE);
120             buf.write( ("{"+TagEncoder.TAG_TITLE+",string,pp}").getBytes() );
121             buf.write(KEY_ALBUM);
122             buf.write( ("{"+TagEncoder.TAG_ALBUM+",string,pp}").getBytes() );
123             buf.write(KEY_TRACKNO);
124             buf.write( ("{"+TagEncoder.TAG_TRACKNO+",string,pp}").getBytes() );
125             buf.write(KEY_SRCTYPE);
126             buf.write(4);                       // length of 'tune'
127             buf.write( "tune".getBytes() );
128             buf.write(0xFF);
129             tune_pattern = buf.toByteArray();
130         }
131         catch (IOException ignored) {
132         }
133     }
134 
135     /**
136      * Create the pattern for the calls to MessageFormatB to encode
137      * playlist tags for the Rio.
138      */
139     protected static byte[] playlist_pattern = null;
140     static {
141         final byte[] pl = "playlist".getBytes();
142         try {
143             ByteArrayOutputStream buf = new ByteArrayOutputStream();
144             buf.write(KEY_SRC_ID);
145             buf.write( ("{"+TagEncoder.TAG_SRC_ID+",string,pp}").getBytes() );
146             buf.write(KEY_TITLE);
147             buf.write( ("{"+TagEncoder.TAG_TITLE+",string,pp}").getBytes() );
148             buf.write(KEY_SRCTYPE);
149             buf.write( pl.length );
150             buf.write( pl );
151             buf.write(KEY_FILESIZE);
152             buf.write( ("{"+TagEncoder.TAG_COUNT_X_4+",string,pp}").getBytes() );
153             buf.write(0xFF);
154             playlist_pattern = buf.toByteArray();
155         }
156         catch (IOException ignored) {
157         }
158     }
159 
160     /**
161      */
162     public void init() throws ServletException {
163         super.init();
164 
165         try {
166             tag_rpc = RpcFactory.newTagEncoder();
167         }
168         catch (RpcException e) {
169             throw new ServletException("problem contacting remote server", e);
170         }
171     }
172 
173 
174     /**
175      * subclasses must define this
176      */
177     protected void handleRequest(HttpServletRequest req,
178                                  HttpServletResponse resp,
179                                  int src_id)
180     throws ServletException, IOException, RpcException {
181 
182         BaseResponseWriter writer = null;
183         try {
184             if ( src_id == 0x100 || src_id >= Source.MIN_SRC_ID ) {
185                 if (log.isDebugEnabled())
186                     log.debug("handleRequest: src_id=" + src_id);
187 
188                 int driver_id = RioLauncher.getDriverId();
189 
190                 // encode binary tag info for tune or playlist
191                 writer = new ResponseStreamWriter();
192                 byte[] ar = tag_rpc.encodeTag(src_id, driver_id, tune_pattern, playlist_pattern);
193 
194                 if (log.isDebugEnabled ())
195                     log.debug(HexDump.dumpHexData("handleRequest", ar));
196 
197                 writer.write(ar);
198             }
199             else {    // no src_id provided
200                 // encode file descriptors as plain text
201                 writer = new ResponseWriter();
202                 writer.write("fid\n");
203                 writer.write("title\n");
204                 writer.write("artist\n");
205                 writer.write("source\n");
206                 writer.write("year\n");
207                 writer.write("comment\n");
208                 writer.write("length\n");
209                 writer.write("type\n");
210                 writer.write("path\n");
211                 writer.write("genre\n");
212                 writer.write("bitrate\n");
213                 writer.write("playlist\n");
214                 writer.write("codec\n");
215                 writer.write("offset\n");
216                 writer.write("duration\n");
217                 writer.write("tracknr\n");
218             }
219 
220             writer.respond(resp);
221         }
222         finally {
223             if (writer != null)
224                 writer.close();
225         }
226     }
227 
228     /**
229      * DON'T implicitly fail if no src_id is provided in the * query
230      */
231     protected boolean requireMfileId() {
232         return false;
233     }
234 
235 //
236 // internal constants
237 //
238 
239     /**
240     * logging sink
241     */
242     protected static Log log = LogFactory.getLog(RioHostTags.class);
243 }
244 
245 
246 /*
247 JRECEIVER MODIFIED BSD LICENSE
248 
249 Copyright (c) 2001-2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
250 
251 Redistribution and use in source and binary forms, with or without
252 modification, are permitted provided that the following conditions are
253 met:
254 
255 Redistributions of source code must retain the above copyright notice,
256 this list of conditions and the following disclaimer.
257 
258 Redistributions in binary form must reproduce the above copyright notice,
259 this list of conditions and the following disclaimer in the documentation
260 and/or other materials provided with the distribution.
261 
262 Neither the name of the JReceiver Project
263 (http://jreceiver.sourceforge.net) nor the names of its contributors may
264 be used to endorse or promote products derived from this software without
265 specific prior written permission.
266 
267 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
268 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
269 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
270 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
271 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
272 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
273 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
274 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
275 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
276 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
277 POSSIBILITY OF SUCH DAMAGE.
278 */
279