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

Quick Search    Search Deep

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


1   /* $Header: /cvsroot/jreceiver/jreceiver/src/jreceiver/client/rio/servlet/RioHostResults.java,v 1.12 2003/05/14 06:24:28 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.client.rio.RioSettingCache;
14  import jreceiver.common.rpc.*;
15  import jreceiver.util.*;
16  import jreceiver.common.rec.util.TuneQuery;
17  import jreceiver.common.rec.util.TuneQueryRec;
18  
19  /**
20   * Servlet answering 'result' requests from Rio Server.
21   * <p>
22   * Called by the Rio Receiver to retrieve tune fileids and
23   * titles (if text)
24   * <p>
25   * TEXT RESPONSE
26   * <p>
27   * A request for text will be made with the "_extended=1" option.
28   * All other responses will be in binary -- see below.
29   * <p>
30   * A text request like
31   * <p>
32   *   http://...:12078/results?artist=&_extended=1
33   * <p>
34   * will return results for all known artists with song titles as
35   * <p>
36   *     160=TAll Of A Sudden (It's Too Late)
37   *     1c0=TBall And Chain
38   *     180=TEnglish Roundabout
39   *     1f0=TFly On The Wall
40   *     120=TIt's Nearly Africa
41   *     1d0=TSenses Working Overtime
42   * <p>
43   * The same goes if you replace 'artist' with 'title',
44   * 'source'(album) or 'genre'.
45   * <p>
46   * Add the exact artist name
47   * <p>
48   *   http://...:12078/results?artist=Billie%20Holiday&_extended=1
49   * <p>
50   * BINARY RESPONSE
51   * <p>
52   * Two possibilities:
53   * <p>
54   * 1. Two DWORDs - this is used when the query contains
55   *     "_extended=0" or if no "_extended" attribute is
56   *     provided:
57   * <p>
58   *     c001000 e5655000
59   * <p>
60   *    where the first dword contains the src_id and
61   *    the second contains the filesize
62   * <p>
63   * 2. Three DWORDs - this is used when the query contains
64   *    "_extended=2"
65   * <p>
66   *     c001000 e5655000 b5010000
67   * <p>
68   *    where the first dword contains the src_id, the
69   *    second contains the filesize, and the third
70   *    contains what the mpeg data offset in the file.
71   * And you get results for only that artist.  Note that the artist
72   * name has been encoded for use in the URI.
73   *
74   * @author Reed Esau
75   * @version $Revision: 1.12 $ $Date: 2003/05/14 06:24:28 $
76   */
77  public class RioHostResults extends RioHostBase {
78  
79      /**
80      * the server which hosts the data
81      */
82      protected Tunes tune_rpc;
83  
84      /**
85       */
86      public void init() throws ServletException {
87          super.init();
88  
89          try {
90              tune_rpc = RpcFactory.newTunes();
91          }
92          catch (RpcException e) {
93              throw new ServletException("problem contacting remote server", e);
94          }
95      }
96  
97  
98      /**
99       * subclasses must define this
100      */
101     protected void handleRequest(HttpServletRequest req,
102                                  HttpServletResponse resp,
103                                  int src_id)
104     throws ServletException, IOException, RpcException {
105 
106         RioSettingCache settings = RioSettingCache.getInstance();
107 
108         int extended = HelperServlet.getIntParam(req, "_extended");
109 
110         // set the range
111         int rec_offset = HelperServlet.getIntParam(req, "_begin", 0);
112         int rec_end = HelperServlet.getIntParam(req, "_end", -1);
113         if (rec_offset < 0)
114             rec_offset = 0;
115         int limit = rec_offset + settings.getResultEncodingLimit() - 1;    //TODO: cache this value
116         if (rec_end < 0 || limit < rec_end)
117             rec_end = limit;
118         int rec_count = rec_end - rec_offset + 1;
119 
120         String query = null;
121         int target;
122         for (target = 0; target < targets.length; target++) {
123             if ((query = req.getParameter(targets[target])) != null)
124                 break;
125         }
126         if (target == targets.length)
127             throw new ServletException(invalid_target);
128 
129         // new functionality: strip the " (18)" count off the end of the query, if present
130         // Note that it assumes that the paren, if present, is not required.
131         String regexp = null;
132         if (query != null) {
133             int pos = query.lastIndexOf(" (");
134             if (pos >= 0)
135                 query = query.substring(0, pos);
136 
137             // refine the regular expression query for use with REGEXP or similar
138             //String regexp = "^" + query + ".*";
139             if (query.length() > 0) {
140                 regexp = "^" + query + "$";         // fix for [ 644489 ]
141             }
142         }
143 
144         // respond based upon value of extended
145         if (extended == 1) {
146             //format: 0=src_id, 1=title of tune
147             //example: '1d0=TSenses Working Overtime\r\n'
148             final String pattern = "{0,hex}=T{1}\r\n";
149 
150             textResponse(resp, pattern, target, regexp, rec_offset, rec_count);
151         }
152         else {
153             byte[] pattern;
154             if (extended == 2)
155                 //         [-src_id--][filesize-][data_offset]
156                 pattern = "{0,word,le}{1,word,le}{2,word,le}".getBytes();
157             else   // extended==0 or not specified
158                 pattern = "{0,word,le}{1,word,le}".getBytes();
159 
160             binaryResponse(resp, pattern, target, regexp, rec_offset, rec_count);
161         }
162     }
163 
164 
165     /**
166      * encode a response suitable retaining minimal playlist data in memory
167      */
168     protected void binaryResponse(HttpServletResponse resp,
169                                   byte[] pattern,
170                                   int target,
171                                   String query,
172                                   int rec_offset, int rec_count)
173     throws ServletException, IOException, RpcException {
174 
175         TuneQuery tq = new TuneQueryRec();
176 
177         switch (target) {
178         case TARGET_ARTIST:
179             tq.setArtistName(query, TuneQuery.IS_REG_EXP);
180             break;
181         case TARGET_ALBUM:
182             tq.setAlbumName(query, TuneQuery.IS_REG_EXP);
183             break;
184         case TARGET_GENRE:
185             tq.setGenreName(query, TuneQuery.IS_REG_EXP);
186             break;
187         case TARGET_TITLE:
188             tq.setTitle(query, TuneQuery.IS_REG_EXP);
189             break;
190         default:
191             throw new ServletException(invalid_target);
192         }
193 
194         int driver_id = RioLauncher.getDriverId();
195         byte[] data = data = tune_rpc.encodeBinary(tq,
196                                                    driver_id,
197                                                    pattern,
198                                                    rec_offset, rec_count);
199 
200         ResponseStreamWriter writer = null;
201         try {
202             writer = new ResponseStreamWriter();
203             writer.write( data );
204             writer.respond(resp);
205         }
206         finally {
207             if (writer != null)
208                 writer.close();
209         }
210     }
211 
212 
213     /**
214      * encode a response suitable for menu display
215      */
216     protected void textResponse(HttpServletResponse resp,
217                                 String pattern,
218                                 int target,
219                                 String query,
220                                 int rec_offset, int rec_count)
221     throws ServletException, IOException, RpcException {
222 
223         TuneQuery tq = new TuneQueryRec();
224 
225         switch (target) {
226         case TARGET_ARTIST:
227             tq.setArtistName(query, TuneQuery.IS_REG_EXP);
228             break;
229         case TARGET_ALBUM:
230             tq.setAlbumName(query, TuneQuery.IS_REG_EXP);
231             break;
232         case TARGET_GENRE:
233             tq.setGenreName(query, TuneQuery.IS_REG_EXP);
234             break;
235         case TARGET_TITLE:
236             tq.setTitle(query, TuneQuery.IS_REG_EXP);
237             break;
238         default:
239             throw new ServletException(invalid_target);
240         }
241 
242         int driver_id = RioLauncher.getDriverId();
243         String data = tune_rpc.encodeText(tq,
244                                           driver_id,
245                                           pattern,
246                                           rec_offset, rec_count);
247 
248         ResponseWriter writer = null;
249         try {
250             writer = new ResponseWriter();
251             writer.write( data );
252             writer.respond(resp);
253         }
254         finally {
255             if (writer != null)
256                 writer.close();
257         }
258     }
259 
260 
261     /**
262      * DON'T implicitly fail if no src_id is provided in the * query
263      */
264     protected boolean requireMfileId() {
265         return false;
266     }
267 
268 //
269 // internal data members and constants
270 //
271 
272     protected static final String[] targets = {"artist","source","genre","title"};
273     protected static final int TARGET_ARTIST = 0;
274     protected static final int TARGET_ALBUM  = 1;
275     protected static final int TARGET_GENRE  = 2;
276     protected static final int TARGET_TITLE  = 3;
277 
278     protected static final String invalid_target = "invalid target";
279 
280     /**
281      * logging object
282      */
283     protected static Log log = LogFactory.getLog(RioHostResults.class);
284 }
285 /*
286 JRECEIVER MODIFIED BSD LICENSE
287 
288 Copyright (c) 2001-2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
289 
290 Redistribution and use in source and binary forms, with or without
291 modification, are permitted provided that the following conditions are
292 met:
293 
294 Redistributions of source code must retain the above copyright notice,
295 this list of conditions and the following disclaimer.
296 
297 Redistributions in binary form must reproduce the above copyright notice,
298 this list of conditions and the following disclaimer in the documentation
299 and/or other materials provided with the distribution.
300 
301 Neither the name of the JReceiver Project
302 (http://jreceiver.sourceforge.net) nor the names of its contributors may
303 be used to endorse or promote products derived from this software without
304 specific prior written permission.
305 
306 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
307 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
308 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
309 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
310 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
311 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
312 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
313 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
314 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
315 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
316 POSSIBILITY OF SUCH DAMAGE.
317 */
318