Switched SPI code to use Java 5-style SPI service loading. Makes stereo Java 5 compat...
[stereo.git] / MemphisDJ / src / music / Library.java
blob5ed81612fe0c2bbe23043b35310c5d17b62a5c9e
2 package music;
4 import interfaces.Album;
5 import interfaces.Track;
6 import interfaces.collection.AbstractCollection;
7 import interfaces.collection.AbstractSetSource;
8 import interfaces.collection.Collection;
9 import interfaces.collection.Source;
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.Iterator;
14 import java.util.List;
15 import java.util.Set;
17 import javax.imageio.spi.ServiceRegistry;
19 import spi.SourceProvider;
21 import notification.AbstractEventGenerator;
22 import notification.LibraryListener;
24 public class Library extends AbstractSetSource<LibraryTrack>
25 implements Source.Listener, interfaces.Library<LibraryTrack> {
27 private final Set<Source<? extends Track>> sources = new HashSet<Source<? extends Track>>();
28 private final Set<Collection<? extends Track>> collections = new HashSet<Collection<? extends Track>>();
29 private final Set<SourceProvider> providers = new HashSet<SourceProvider>();
31 private volatile int nextCollection = Collection.FIRST_AVAILABLE_ID;
33 public Library(String name) {
34 super();
35 this.name = name;
36 this.lib = this;
38 addCollection(this.collection()); //library is a collection in the library
39 monitor.nextVersion();
41 for (Iterator<SourceProvider> it = ServiceRegistry.lookupProviders(SourceProvider.class); it.hasNext();) {
42 SourceProvider provider = it.next();
43 System.out.println("using source provider: " + provider.getClass().getName());
44 provider.create(this);
45 providers.add(provider);
49 private final String name;
50 private final Library lib;
51 private final Collection<LibraryTrack> collection = new AbstractCollection<LibraryTrack>(Collection.LIBRARY_ID, Collection.LIBRARY_PERSISTENT_ID) {
53 public int editStatus() {
54 return Collection.NOT_EDITABLE;
57 public boolean isRoot() {
58 return true;
61 public String name() {
62 return name;
65 public Collection<? extends LibraryTrack> parent() {
66 return null;
69 public int size() {
70 return lib.size();
73 public Source<LibraryTrack> source() {
74 return lib;
78 public Collection<LibraryTrack> collection() {
79 return collection;
82 public boolean addSource(Source<? extends Track> source) {
83 if (sources.add(source)) {
84 added(source.tracks());
85 source.registerListener(this);
86 return true;
88 return false;
91 public boolean removeSource(Source<? extends Track> source) {
92 if (sources.remove(source)) {
93 source.removeListener(this);
94 Set<Track> trackSet = new HashSet<Track>();
95 for (Track t: source.tracks()) {
96 trackSet.add(t);
98 removed(trackSet);
99 return true;
101 return false;
104 public void added(Iterable<? extends Track> tracks) {
106 List<LibraryTrack> added = new ArrayList<LibraryTrack>();
108 for (Track t: tracks) {
109 LibraryTrack l = LibraryTrack.factory().create(t);
110 l.addBackingTrack(t);
111 added.add(l);
114 add(added);
115 monitor.nextVersion();
118 public void removed(Set<? extends Track> tracks) {
120 Set<LibraryTrack> removed = new HashSet<LibraryTrack>();
122 for (Track t: tracks) {
123 LibraryTrack l = LibraryTrack.factory().create(t);
124 if (store.contains(l)) {
125 l.removeBackingTrack(t);
126 if (l.numBackingTracks() == 0) {
127 removed.add(l);
132 remove(removed);
133 monitor.nextVersion();
136 public synchronized int nextCollectionId() {
137 return nextCollection++;
140 public boolean addCollection(Collection<? extends Track> collection) {
141 boolean added = collections.add(collection);
142 if (added) {
143 monitor.nextVersion();
145 return added;
148 public Iterable<Collection<? extends Track>> collections() {
149 return collections;
152 public int numCollections() {
153 return collections.size();
156 public boolean removeCollection(Collection<? extends Track> collection) {
157 boolean removed = collections.remove(collection);
158 if (removed) {
159 monitor.nextVersion();
161 return removed;
164 public Iterable<? extends Album> albums() {
166 Set<Album> albums = new HashSet<Album>();
167 for (Track t: tracks()) {
168 albums.add(t.getAlbum());
170 return albums;
173 public int numAlbums() {
174 Set<Album> albums = new HashSet<Album>();
175 for (Track t: tracks()) {
176 albums.add(t.getAlbum());
178 return albums.size();
181 public void registerLibraryListener(LibraryListener listener) {
182 monitor.registerListener(listener);
185 public void removeLibraryListener(LibraryListener listener) {
186 monitor.removeListener(listener);
189 public int version() {
190 return monitor.version();
193 public void connect(String path) {
195 for (SourceProvider provider: providers) {
196 provider.connect(path);
201 private LibraryMonitor monitor = new LibraryMonitor();
202 private class LibraryMonitor extends AbstractEventGenerator<LibraryListener> {
203 private int version;
204 public synchronized int version() {
205 return version;
207 public synchronized void nextVersion() {
208 version++;
209 for (LibraryListener l: listeners()) {
210 l.libraryVersionChanged(version);