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

Quick Search    Search Deep

Source code: com/virtuosotechnologies/asaph/standardmodel/StdSongIDResultSet.java


1   /*
2   ================================================================================
3   
4     FILE:  StdSongIDResultSet.java
5     
6     PROJECT:
7     
8       Asaph
9     
10    CONTENTS:
11    
12      Standard implementation of SongIDResultSet
13    
14    PROGRAMMERS:
15    
16      Daniel Azuma (DA)  <dazuma@kagi.com>
17    
18    COPYRIGHT:
19    
20      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
21      
22      This program is free software; you can redistribute it and/or
23      modify it under the terms of the GNU General Public License as
24      published by the Free Software Foundation; either version 2
25      of the License, or (at your option) any later version.
26      
27      This program is distributed in the hope that it will be useful,
28      but WITHOUT ANY WARRANTY; without even the implied warranty of
29      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30      GNU General Public License for more details.
31      
32      You should have received a copy of the GNU General Public
33      License along with this program; if not, write to
34        Free Software Foundation, Inc.
35        59 Temple Place, Suite 330
36        Boston, MA 02111-1307 USA
37  
38  ================================================================================
39  */
40  
41  
42  package com.virtuosotechnologies.asaph.standardmodel;
43  
44  
45  import java.util.Set;
46  import java.util.Collection;
47  import java.util.Map;
48  import java.util.LinkedHashMap;
49  import java.util.Iterator;
50  
51  import com.virtuosotechnologies.asaph.model.SongIDResultSet;
52  import com.virtuosotechnologies.asaph.model.SongDatabase;
53  import com.virtuosotechnologies.asaph.model.SongID;
54  import com.virtuosotechnologies.asaph.model.Song;
55  import com.virtuosotechnologies.asaph.model.SongDatabaseFailedException;
56  
57  
58  /**
59   * Standard implementation of SongIDResultSet
60   */
61  /*package*/ class StdSongIDResultSet
62  implements SongIDResultSet
63  {
64    private SongDatabase database_;
65    private Map dataMap_;
66    private StdSongIDResultSet setLink_;
67    
68    
69    /*package*/ StdSongIDResultSet(
70      SongDatabase database)
71    {
72      database_ = database;
73      dataMap_ = new LinkedHashMap();
74      setLink_ = null;
75    }
76    
77    
78    /*package*/ StdSongIDResultSet(
79      StdSongIDResultSet link)
80    {
81      setLink_ = link;
82      dataMap_ = new LinkedHashMap();
83      database_ = setLink_.getDatabase();
84      synchronized(setLink_)
85      {
86        for (Iterator iter = setLink_.getEntryCollection().iterator(); iter.hasNext(); )
87        {
88          EntryImpl entry = (EntryImpl)iter.next();
89          dataMap_.put(entry.getSongID(), new EntryImpl(entry));
90        }
91      }
92    }
93    
94    
95    /*package*/ class EntryImpl
96    implements Entry
97    {
98      private SongID songID_;
99      private Song cachedSong_;
100     private boolean isCached_;
101     private Object data_;
102     private EntryImpl entryLink_;
103     
104     /*package*/ EntryImpl(
105       SongID songID)
106     {
107       songID_ = songID;
108       entryLink_ = null;
109       cachedSong_ = null;
110       isCached_ = false;
111       data_ = null;
112     }
113     
114     /*package*/ EntryImpl(
115       EntryImpl link)
116     {
117       entryLink_ = link;
118       songID_ = entryLink_.songID_;
119       synchronized(entryLink_)
120       {
121         cachedSong_ = entryLink_.cachedSong_;
122         isCached_ = entryLink_.isCached_;
123         data_ = entryLink_.data_;
124       }
125     }
126     
127     /*package*/ synchronized void setCachedSong(
128       Song cachedSong)
129     {
130       cachedSong_ = cachedSong;
131     }
132     
133     /*package*/ synchronized void clearCachedSong()
134     {
135       cachedSong_ = null;
136       isCached_ = false;
137     }
138     
139     public SongID getSongID()
140     {
141       return songID_;
142     }
143     
144     public synchronized Object getData()
145     {
146       return data_;
147     }
148     
149     public synchronized void setData(
150       Object data)
151     {
152       data_ = data;
153     }
154     
155     public synchronized Song getSong()
156     {
157       if (!isCached_)
158       {
159         if (setLink_ != null)
160         {
161           if (entryLink_ == null)
162           {
163             entryLink_ = (EntryImpl)setLink_.getEntryFor(songID_);
164           }
165           if (entryLink_ != null)
166           {
167             cachedSong_ = entryLink_.getSong();
168           }
169         }
170         if (cachedSong_ == null)
171         {
172           try
173           {
174             cachedSong_ = database_.checkOutSong(songID_);
175             if (entryLink_ != null)
176             {
177               entryLink_.setCachedSong(cachedSong_);
178             }
179           }
180           catch (SongDatabaseFailedException ex)
181           {
182           }
183         }
184         isCached_ = true;
185       }
186       return cachedSong_;
187     }
188   }
189   
190   
191   //-------------------------------------------------------------------------
192   // Methods of Set
193   //-------------------------------------------------------------------------
194   
195   public synchronized int size()
196   {
197     return dataMap_.size();
198   }
199   
200   
201   public synchronized boolean isEmpty()
202   {
203     return dataMap_.isEmpty();
204   }
205   
206   
207   public synchronized boolean contains(
208     Object o)
209   {
210     return dataMap_.containsKey(o);
211   }
212   
213   
214   public synchronized Iterator iterator()
215   {
216     return dataMap_.keySet().iterator();
217   }
218   
219   
220   public synchronized Object[] toArray()
221   {
222     return dataMap_.keySet().toArray();
223   }
224   
225   
226   public synchronized Object[] toArray(
227     Object a[])
228   {
229     return dataMap_.keySet().toArray(a);
230   }
231   
232   
233   public synchronized boolean add(
234     Object o)
235   {
236     SongID songID = (SongID)o;
237     if (songID.getDatabase() != database_)
238     {
239       throw new IllegalArgumentException("Added SongID part of the wrong database");
240     }
241     if (dataMap_.get(songID) == null)
242     {
243       EntryImpl entry = null;
244       if (setLink_ != null)
245       {
246         entry = (EntryImpl)setLink_.getEntryFor(songID);
247       }
248       if (entry != null)
249       {
250         entry = new EntryImpl(entry);
251       }
252       else
253       {
254         entry = new EntryImpl(songID);
255       }
256       dataMap_.put(songID, entry);
257       return true;
258     }
259     else
260     {
261       return false;
262     }
263   }
264   
265   
266   public synchronized boolean remove(
267     Object o)
268   {
269     Object val = dataMap_.remove(o);
270     return val != null;
271   }
272   
273   
274   public synchronized boolean containsAll(
275     Collection c)
276   {
277     for (Iterator iter = c.iterator(); iter.hasNext(); )
278     {
279       if (!dataMap_.containsKey(iter.next()))
280       {
281         return false;
282       }
283     }
284     return true;
285   }
286   
287   
288   public synchronized boolean addAll(
289     Collection c)
290   {
291     boolean modified = false;
292     for (Iterator iter = c.iterator(); iter.hasNext(); )
293     {
294       modified |= add(iter.next());
295     }
296     return modified;
297   }
298   
299   
300   public synchronized boolean retainAll(
301     Collection c)
302   {
303     boolean modified = false;
304     for (Iterator iter = dataMap_.keySet().iterator(); iter.hasNext(); )
305     {
306       Object obj = iter.next();
307       if (!c.contains(obj))
308       {
309         iter.remove();
310         modified = true;
311       }
312     }
313     return modified;
314   }
315   
316   
317   public synchronized boolean removeAll(
318     Collection c)
319   {
320     boolean modified = false;
321     for (Iterator iter = c.iterator(); iter.hasNext(); )
322     {
323       modified |= remove(iter.next());
324     }
325     return modified;
326   }
327   
328   
329   public synchronized void clear()
330   {
331     dataMap_.clear();
332   }
333   
334   
335   //-------------------------------------------------------------------------
336   // Methods of SongIDResultSet
337   //-------------------------------------------------------------------------
338   
339   /**
340    * Create a copy of this result set that is linked to this one.
341    * A linked copy shares the song cache of the original. In addition, its initial
342    * data values are the same as the data for the original; however, the data can later
343    * be changed independent of the original.
344    *
345    * @return copy of this result set
346    */
347   public synchronized SongIDResultSet createLinkedCopy()
348   {
349     return new StdSongIDResultSet(this);
350   }
351   
352   
353   /**
354    * Get the SongDatabase that created this result set.
355    *
356    * @return SongDatabase
357    */
358   public SongDatabase getDatabase()
359   {
360     return database_;
361   }
362   
363   
364   /**
365    * Get the data associated with the given SongID.
366    *
367    * @param songID SongID to query
368    * @return the entry for this songID, or null if there isn't one.
369    */
370   public synchronized Entry getEntryFor(
371     SongID songID)
372   {
373     return (Entry)dataMap_.get(songID);
374   }
375   
376   
377   /**
378    * Get a collection view of the entries in the set, backed by the set.
379    * Each item in the collection is an Entry object.
380    * The collection can be modified by removing elements, but not by adding.
381    *
382    * @return Collection of Entry objects
383    */
384   public synchronized Collection getEntryCollection()
385   {
386     return dataMap_.values();
387   }
388   
389   
390   /**
391    * Clear the song caches for all entries in the set
392    */
393   public synchronized void clearSongCache()
394   {
395     for (Iterator iter = dataMap_.values().iterator(); iter.hasNext(); )
396     {
397       EntryImpl entry = (EntryImpl)iter.next();
398       entry.clearCachedSong();
399     }
400   }
401 }