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

Quick Search    Search Deep

Source code: org/esau/ptarmigan/impl/filter/PLSFilter.java


1   /* $Header: /cvsroot/ptarmigan/ptarmigan/src/java/org/esau/ptarmigan/impl/filter/PLSFilter.java,v 1.3 2002/09/19 03:48:00 reedesau Exp $ */
2   
3   package org.esau.ptarmigan.impl.filter;
4   
5   import java.io.BufferedReader;
6   import java.io.IOException;
7   import java.text.ParseException;
8   
9   import org.xml.sax.SAXException;
10  
11  import org.apache.commons.logging.Log;
12  import org.apache.commons.logging.LogFactory;
13  
14  import org.esau.ptarmigan.util.HelperMisc;
15  
16  /**
17   * PLSFilter -- transforms PLS playlist to ptarmigan playlist
18   * <p>
19   * TODO: recursively scan all playlists found.
20   *
21   * @author Reed Esau
22   * @version $Revision: 1.3 $ $Date: 2002/09/19 03:48:00 $
23   */
24  public final class PLSFilter extends SimplePlaylistFilter {
25  
26      public PLSFilter() throws SAXException {
27      }
28  
29      static final String PLS_MARKER = "[playlist]";
30  
31      /** does the specified stream contain a marker for the tag? */
32      public boolean isMatch(String str) throws IOException {
33          log.debug("sniffing for " + PLS_MARKER);
34          return str.startsWith(PLS_MARKER);
35      }
36  
37      /**
38       * Parse a document from a buffered source.
39       */
40      public void doParsePlaylist(BufferedReader reader)
41      throws SAXException, IOException, ParseException {
42  
43          m_media_properties.setMimeType("audio/x-scpls");
44  
45          log.debug("doParsePlaylist");
46  
47          // first parse all the entries to an internal list
48  
49          //TODO: do something with duration_total
50  
51          int entry_count = 0;
52  
53          startPlaylist();
54  
55          if (readHeader( reader )) {
56              while (readEntry( reader )) {
57                  entry_count++;
58              }
59          }
60  
61          endPlaylist();
62      }
63  
64      /** consume the header */
65      boolean readHeader(BufferedReader reader) throws IOException, SAXException {
66  
67          final String PLAYLIST_NAME = "PlaylistName";
68  
69          reader.mark(READ_AHEAD_LIMIT);
70  
71          // consume all lines that start with [playlist] or PlaylistName
72          String line;
73          while ((line = reader.readLine()) != null) {
74              if (line.startsWith(PLS_MARKER)) {
75                  reader.mark(READ_AHEAD_LIMIT);
76                  continue;
77              }
78              if (line.startsWith(PLAYLIST_NAME)) {
79                  this.setTitle ( line.substring(PLAYLIST_NAME.length() + 1) );
80                  reader.mark(READ_AHEAD_LIMIT);
81                  continue;
82              }
83              reader.reset();     // we're probably at the first entry; start reading them
84              break;
85          }
86  
87          writeProperties();
88  
89          return line != null;
90      }
91  
92      /**
93       * Obtain the next Tune (or playlist?) object from the playlist.
94       *
95       * @return Next available Entry if one is available; otherwise returns null
96       * @exception IOException
97       */
98      boolean readEntry(BufferedReader reader) throws IOException, SAXException {
99  
100         int index = 0;
101         boolean ready_to_commit = false;
102 
103         // preserve the initial file position in case we encounter a
104         // subsequent .pls record (requiring a reset of the file position)
105         reader.mark(READ_AHEAD_LIMIT);
106 
107         // Keep reading lines until we've read a complete entry (or end-
108         // of-file has been reached)
109 
110         String line;
111         while ((line=reader.readLine()) != null ) {
112 
113             if (log.isDebugEnabled())
114                 log.debug("readEntry: line=" + line);
115 
116             String trimmed = line.trim();
117 
118             if (trimmed.length() == 0)         // ignore all blank lines
119                 continue;
120 
121             // This is what a .pls entry looks like:
122             //File1=\download\02. Raindrops Keep Falling on My Head.mp3
123             //Title1=Burt Bacharach - Raindrops Keep Falling on My Head (from Butch Cassidy and the Sundance Kid)
124             //Length1=151
125             //
126             //or possibly with a url instead of a file:
127             //File1=http://192.168.100.105/02.%20Raindrops%20Keep%20Falling%20on%20My%20Head.mp3
128 
129             for (int i = 0; i < PLS_KEYS.length; i++) {
130                 String key = PLS_KEYS[i];   //File, Title or Length
131                 if (line.startsWith(key) == false)
132                     continue;
133 
134                 // extract N and value found in the keyN=value line
135                 int rec_no_pos = key.length();
136                 int equal_pos = line.indexOf(EQUALS, rec_no_pos);
137                 String s_rec_no = line.substring(rec_no_pos, equal_pos);
138                 int rec_no = HelperMisc.parseInt(s_rec_no, -1);
139                 if (rec_no < 1)
140                     continue;
141                 String val = line.substring(equal_pos + 1);
142 
143                 if (index == 0) {
144                     // if this is the first line of the record we're encountering...
145                     index = rec_no;
146                 }
147                 else if (index != rec_no) {
148                     // we're done with this entry if we've inadvertently
149                     // swerved into a subsequent record
150                     reader.reset();        // undo the recent read
151                     ready_to_commit = true;
152                     break;
153                 }
154 
155                 switch (i) {
156                 case PLS_TUNE_FILE:
157                     setEntryPath(val);
158                     break;
159                 case PLS_TUNE_TITLE:
160                     setEntryTitle(val);
161                     break;
162                 case PLS_TUNE_DURATION:
163                     setEntryDuration(HelperMisc.parseInt(val, 0) * 1000);   // millisecs
164                     break;
165                 }
166 
167                 break;      // ready for the next line
168             }
169 
170             if (ready_to_commit)
171                 break;
172 
173             // preserve the current file position in case we encounter a
174             // subsequent .pls record (requiring a reset of the file position)
175             reader.mark(READ_AHEAD_LIMIT);
176         }
177 
178         writeEntry();
179 
180         return line != null;
181     }
182 
183     static final int READ_AHEAD_LIMIT = 1024;
184 
185     static final String PLS_KEYS[] = { "File", "Title", "Length"};
186     static final int PLS_TUNE_FILE     = 0;
187     static final int PLS_TUNE_TITLE    = 1;
188     static final int PLS_TUNE_DURATION = 2;
189 
190     static final int COMMA_CH = ',';
191     static final String EQUALS = "=";
192 
193     /**
194      * logging object
195      */
196     static Log log = LogFactory.getLog(PLSFilter.class);
197 }
198 
199 /*
200 PTARMIGAN MODIFIED BSD LICENSE
201 
202 Copyright (c) 2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
203 
204 Redistribution and use in source and binary forms, with or without
205 modification, are permitted provided that the following conditions are
206 met:
207 
208 Redistributions of source code must retain the above copyright notice,
209 this list of conditions and the following disclaimer.
210 
211 Redistributions in binary form must reproduce the above copyright notice,
212 this list of conditions and the following disclaimer in the documentation
213 and/or other materials provided with the distribution.
214 
215 Neither the name of the Ptarmigan Project
216 (http://ptarmigan.sourceforge.net) nor the names of its contributors may
217 be used to endorse or promote products derived from this software without
218 specific prior written permission.
219 
220 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
221 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
222 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
223 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
224 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
225 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
226 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
227 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
228 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
229 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
230 POSSIBILITY OF SUCH DAMAGE.
231 */