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

Quick Search    Search Deep

Source code: jreceiver/server/stream/capture/MusicInputStreamFactory.java


1   /* $Header: /cvsroot/jreceiver/jreceiver/src/jreceiver/server/stream/capture/MusicInputStreamFactory.java,v 1.8 2002/12/29 00:44:07 reedesau Exp $ */
2   
3   /*
4   JRECEIVER MODIFIED BSD LICENSE
5   
6   Copyright (c) 2001, Reed Esau (reed.esau@pobox.com) All rights reserved.
7   
8   Redistribution and use in source and binary forms, with or without
9   modification, are permitted provided that the following conditions are
10  met:
11  
12  Redistributions of source code must retain the above copyright notice,
13  this list of conditions and the following disclaimer.
14  
15  Redistributions in binary form must reproduce the above copyright notice,
16  this list of conditions and the following disclaimer in the documentation
17  and/or other materials provided with the distribution.
18  
19  Neither the name of the JReceiver Project
20  (http://jreceiver.sourceforge.net) nor the names of its contributors may
21  be used to endorse or promote products derived from this software without
22  specific prior written permission.
23  
24  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
28  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  POSSIBILITY OF SUCH DAMAGE.
35  */
36  
37  package jreceiver.server.stream.capture;
38  
39  import java.io.*;
40  import java.net.URL;
41  import java.util.Hashtable;
42  import java.util.LinkedList;
43  import java.util.List;
44  import java.util.ListIterator;
45  
46  import org.apache.commons.logging.*;
47  
48  /**
49   * This provides support for getting MusicInputStream objects. It stores them
50   * and then returns the correct object at a later date. It can store multiple
51   * MusicInputStream objects for a single URL -- think multiple players playing
52   * the same stream. It serves up the object that has a correct offset. This is
53   * not quite the optimal strategy -- it probably ought to preferentially return the stream
54   * where the requested offset is at the 'end'.
55   *
56   * @author Philip Gladstone
57   * @version $Revision: 1.8 $ $Date: 2002/12/29 00:44:07 $
58   */
59  public final class MusicInputStreamFactory {
60  
61      /**
62       * A table of current MusicInputStream objects -- indexed by URL
63       */
64      private static Hashtable table = new Hashtable();
65  
66      /**
67       * Obtains a MusicInputStream object for the requested URL
68       * at the requested position. This allows us to disabiguate
69       * two people asking for the same stream.
70       *
71       * @param url the requested URL
72       * @param pos the requested byte offset.
73       * @param mimeType the required mime type (or null for native)
74       * @returns the requested MusicInputStream object or null if not possible
75       * @exception IOException if the MusicInputStream object cannot be created.
76       */
77  
78      public static synchronized MusicInputStream getStream(URL url, int pos, String mimeType)
79      throws IOException
80      {
81         return getStream(url, pos, mimeType, null);
82      }
83  
84      /**
85       * Obtains a MusicInputStream object for the requested URL
86       * at the requested position. This allows us to disabiguate
87       * two people asking for the same stream.
88       *
89       * @param url the requested URL
90       * @param pos the requested byte offset.
91       * @param mimeType the required mime type (or null for native)
92       * @param srcMimeType the type of the source (in case we cannot figure it out)
93       * @returns the requested MusicInputStream object or null if not possible
94       * @exception IOException if the MusicInputStream object cannot be created.
95       */
96  
97      public static synchronized MusicInputStream getStream(URL url, int pos, String mimeType, String srcMimeType)
98      throws IOException
99      {
100        MusicInputStream s = null;
101 
102        List l;
103 
104        l = (List) table.get(url);
105 
106        if (l != null) {
107            /* See if we can find our stream */
108            ListIterator li;
109 
110            for (li = l.listIterator(0); li.hasNext(); ) {
111                s = (MusicInputStream) li.next();
112 
113                if (s.posInRange(pos)) {
114                    s.seek(pos);
115                    break;
116                }
117                s = null;
118            }
119        }
120        if (s == null) {
121            if (log.isDebugEnabled())
122                log.debug("Creating new MusicInputStream object for " + url.toString() + "@" + pos);
123            s = new MusicInputStream(url, pos, mimeType, srcMimeType);
124            if (s != null) {
125                if (l == null) {
126                    l = new LinkedList();       
127                    table.put(url, l);
128                }
129                l.add(0, s); // Put new object at front
130            }
131        }
132        if (s == null) {
133            if (log.isDebugEnabled())
134                log.debug("Failed to find MusicInputStream object for " + url.toString() + " with offset " + pos);
135        } else {
136            s.lock();
137        }
138 
139        return s;
140     }
141 
142     public static synchronized void removeStream(URL url, int pos)
143     {
144        List l;
145 
146        l = (List) table.get(url);
147 
148        if (l != null) {
149            /* See if we can find our stream */
150            ListIterator li;
151 
152            for (li = l.listIterator(0); li.hasNext(); ) {
153                MusicInputStream s = (MusicInputStream) li.next();
154 
155                if (s.posInRange(pos)) {
156                    li.remove();
157                    s.shutdown();
158                    break;
159                }
160            }
161            if (l.isEmpty()) {
162                table.remove(url);
163            }
164        }
165     }
166 
167     /**
168      * Removes a music stream from the table. This is only called by the
169      * MusicInputStream object itself on a timeout.
170      *
171      * @param url the URL of the stream
172      * @param stream the MusicInputStream object itself
173      */
174     public static synchronized void removeMusicInputStream(URL url, MusicInputStream stream)
175     {
176        List l;
177 
178        l = (List) table.get(url);
179 
180        if (l != null) {
181            /* See if we can find our stream */
182            ListIterator li;
183 
184            for (li = l.listIterator(0); li.hasNext(); ) {
185                MusicInputStream s = (MusicInputStream) li.next();
186 
187                if (s == stream) {
188                    if (log.isDebugEnabled())
189                        log.debug(stream.toString() + ": Removing MusicInputStream object");
190                    li.remove();
191                    stream = null;
192                    break;
193                }
194            }
195            if (l.isEmpty()) {
196                table.remove(url);
197            }
198        }
199        if (stream != null) {
200            if (log.isDebugEnabled())
201                log.debug(stream.toString() + ": Failed to remove MusicInputStream object");
202        }
203     }
204 
205     /**
206      * logging object
207      */
208 
209     protected static Log log = LogFactory.getLog(MusicInputStreamFactory.class);
210 }