1 package org.rpi.mpdplayer;
2
3 import java.io.BufferedReader;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.net.InetSocketAddress;
8 import java.net.Socket;
9 import java.net.SocketAddress;
10 import java.net.SocketTimeoutException;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Observable;
14 import java.util.Observer;
15
16 import org.apache.log4j.Logger;
17 import org.rpi.config.Config;
18 import org.rpi.player.IPlayer;
19 import org.rpi.player.events.EventBase;
20
21 public class TCPConnector extends Observable implements Observer {
22
23 private static Logger log = Logger.getLogger(TCPConnector.class);
24
25 final String MPD_OK = "OK";
26 final String list_begin = "command_list_begin";
27 final String list_end = "command_list_end";
28
29 private String host = "";
30 private int port = 6600;
31 private int timeout = 3000;
32 private StatusMonitor sm = null;
33 private Thread th = null;
34
35 private Socket socket = null;
36 private IPlayer iPlayer = null;
37
38 public TCPConnector(IPlayer iPlayer) {
39 this.iPlayer = iPlayer;
40 this.host = Config.mpd_host;
41 this.port = Config.mpd_port;
42 sm = new StatusMonitor(this);
43 sm.addObserver(this);
44 th = new Thread(sm);
45 th.start();
46 try {
47 connect();
48 } catch (Exception e) {
49 log.error("Cannot connect to MPD", e);
50 }
51 }
52
53
54 protected synchronized String connect() throws IOException {
55 this.socket = new Socket();
56 String version = "";
57 SocketAddress sockaddr = new InetSocketAddress(host, port);
58 try {
59 this.socket.connect(sockaddr, timeout);
60 } catch (SocketTimeoutException ste) {
61 log.error(ste);
62 }
63 BufferedReader in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
64 String line = in.readLine();
65 if (isOK(line)) {
66 version = removeText(line, MPD_OK);
67 log.info("MPD Version: " + version);
68 }
69 return line;
70 }
71
72 public synchronized HashMap<String, String> sendCommand(String command) {
73
74 HashMap<String, String> res = new HashMap<String, String>();
75 if (!this.socket.isConnected()) {
76 try {
77 connect();
78 } catch (IOException e) {
79 log.error(e);
80 try {
81 connect();
82 } catch (Exception ex) {
83
84 }
85 return res;
86 }
87 }
88 DataOutputStream dOut = null;
89 try {
90 dOut = new DataOutputStream(socket.getOutputStream());
91 byte[] bytesToSend = command.getBytes("UTF-8");
92 dOut.write(bytesToSend);
93 BufferedReader dIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
94 String line = null;
95 while ((line = dIn.readLine()) != null) {
96 if (isOK(line))
97 break;
98 if (line.startsWith("ACK")) {
99 log.error("Error: " + line);
100
101 break;
102 }
103 String[] splits = line.split(":");
104 if (splits.length > 1) {
105 String key = splits[0].trim();
106 String value = line.substring(key.length() + 1, line.length());
107 res.put(key, value.trim());
108 }
109 }
110 return res;
111 } catch (Exception e) {
112 log.error(e);
113 try {
114 socket.close();
115 connect();
116 } catch (Exception ex) {
117 log.error(ex);
118 }
119 } finally {
120 if (dOut != null) {
121 try {
122 dOut.flush();
123 } catch (IOException e) {
124 log.error(e);
125 }
126 }
127 }
128 return res;
129 }
130
131
132
133
134
135
136
137 public String createCommand(String command) {
138 return createCommand(command, null);
139 }
140
141
142
143
144
145
146
147
148 public String createCommand(String command, List<String> params) {
149 StringBuffer sb = new StringBuffer();
150 sb.append(command);
151 if (params != null) {
152 for (String p : params) {
153 if (p.contains(" ")) {
154 p = "\"" + p + "\"";
155 }
156 sb.append(" " + p);
157 }
158 }
159
160 sb.append("\n");
161 return sb.toString();
162 }
163
164
165
166
167
168
169
170 public String createCommandList(List<String> commands) {
171 StringBuffer sb = new StringBuffer();
172 if (commands == null) {
173 return null;
174 }
175 if (commands.size() == 1) {
176 return commands.get(0);
177 }
178 sb.append(list_begin);
179 sb.append("\n");
180 for (String s : commands) {
181 sb.append(s);
182 }
183 sb.append(list_end);
184 sb.append("\n");
185 return sb.toString();
186 }
187
188
189
190
191
192
193
194
195
196 private String removeText(String line, String remove) {
197 String res = "";
198 try {
199 res = line.substring(remove.length(), line.length()).trim();
200 } catch (Exception e) {
201
202 }
203 return res;
204 }
205
206
207
208
209
210
211
212 private boolean isOK(String line) {
213 if (line.startsWith(MPD_OK)) {
214 return true;
215 }
216 return false;
217 }
218
219 public IPlayer getiPlayer() {
220 return iPlayer;
221 }
222
223
224 public void destroy() {
225 th = null;
226 if (socket.isConnected()) {
227 try {
228 socket.close();
229 } catch (Exception e) {
230
231 }
232 }
233
234 }
235
236 @Override
237 public void update(Observable arg0, Object ev) {
238 EventBase e = (EventBase) ev;
239 fireEvent(e);
240 }
241
242 private void fireEvent(EventBase ev) {
243 setChanged();
244 notifyObservers(ev);
245 }
246
247 }