git-svn-id: https://stereo.googlecode.com/svn/trunk@440 c67ee986-0855-0410-825f-15918...
[stereo.git] / DACPlib / src / daap / DAAPClient.java
blob24968eafb76482f558d788b5100af0046008be23
1 package daap;
3 import interfaces.collection.AbstractSetSource;
4 import interfaces.collection.Collection;
5 import interfaces.collection.ConcreteCollection;
6 import interfaces.collection.Source;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Set;
16 public class DAAPClient extends AbstractSetSource<DAAPTrack>
17 implements Source<DAAPTrack> {
19 public static List<DAAPClient> create(String hostname, int port, int id) throws IOException {
21 DAAPUtilities helper = new DAAPUtilities(hostname, port);
23 final String name = helper.connect();
24 System.out.println("connected to " + name + " (" + hostname + ")");
26 final int revision = helper.update(0);
28 List<DAAPEntry> dbs = helper.databases(revision);
30 List<DAAPClient> collections = new ArrayList<DAAPClient>(dbs.size());
32 for (DAAPEntry e: dbs) {
33 String dbname = null;
34 int dbid = 0;
36 for (DAAPEntry a: e.children()) {
37 switch (a.code()) {
38 case dmap_itemid: dbid = (Integer)a.value(); break;
39 case dmap_itemname: dbname = (String)a.value(); break;
43 System.out.println(dbname);
45 int na = dbname.hashCode();
46 int hs = hostname.hashCode();
48 byte[] persistant = new byte[8];
49 persistant[0] = (byte)(na>>24 & 0xFF);
50 persistant[1] = (byte)(na>>16 & 0xFF);
51 persistant[2] = (byte)(na>>8 & 0xFF);
52 persistant[3] = (byte)(na & 0xFF);
53 persistant[4] = (byte)(hs>>24 & 0xFF);
54 persistant[5] = (byte)(hs>>16 & 0xFF);
55 persistant[6] = (byte)(hs>>8 & 0xFF);
56 persistant[7] = (byte)(hs & 0xFF);
58 long per = new BigInteger(persistant).longValue();
60 if (dbname == null) throw new IOException("Database name not found (" + hostname + ")");
62 collections.add(new DAAPClient(id++, per, revision, dbid, dbname, helper));
65 return collections;
68 private final DAAPUtilities connection;
69 private final int dbid;
70 private final Collection<DAAPTrack> collection;
72 private int revision;
74 public DAAPClient(int id, long per, int rev, int dbid, String name, DAAPUtilities connection) {
76 this.revision = rev;
77 this.dbid = dbid;
78 this.connection = connection;
80 collection = new ConcreteCollection<DAAPTrack>(id, per, name, Collection.GENERATED, false, null, 0, this) {
81 public int size() {
82 return _size();
86 updateTracks();
89 private int _size() {
90 return size();
93 public Collection<DAAPTrack> collection() {
94 return collection;
97 public void update() throws IOException {
99 int rev = connection.update(revision);
101 if (rev > revision) {
102 updateTracks();
106 public void close() {
108 List<DAAPTrack> tracks = this.store.tracks();
109 Set<DAAPTrack> trackSet = new HashSet<DAAPTrack>(tracks);
111 for (Source.Listener l: this.listeners()) {
112 l.removed(trackSet);
116 private void updateTracks() {
118 List<DAAPEntry> tracks;
120 try {
121 tracks = connection.tracks(dbid, revision);
123 catch (IOException ex) {
124 System.err.println("Unable to get track list");
125 ex.printStackTrace();
126 return;
129 List<DAAPTrack> added = new ArrayList<DAAPTrack>();
130 Set<DAAPTrack> update = new HashSet<DAAPTrack>();
131 for (DAAPEntry e : tracks) {
132 DAAPTrack track = DAAPTrack.create(e, this);
133 if (track != null) {
134 update.add(track);
135 if (!this.store.contains(track)) {
136 added.add(track);
141 Set<DAAPTrack> removed = new HashSet<DAAPTrack>();
142 for (DAAPTrack t: this.store.tracks()) {
143 if (!update.contains(t)) {
144 removed.add(t);
148 for (DAAPTrack t: removed) {
149 this.store.remove(t);
152 for (DAAPTrack t: added) {
153 this.store.add(t);
156 for (Source.Listener l: this.listeners()) {
157 l.added(added);
158 l.removed(removed);
163 public InputStream getStream(DAAPTrack track) throws IOException {
164 int song = track.id();
165 return connection.song(dbid, song);