View Javadoc

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  		// log.debug( command);
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 					// Raise an Error
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 	 * Create a command
133 	 * 
134 	 * @param command
135 	 * @return
136 	 */
137 	public String createCommand(String command) {
138 		return createCommand(command, null);
139 	}
140 
141 	/***
142 	 * Create a command
143 	 * 
144 	 * @param command
145 	 * @param params
146 	 * @return
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 	 * Create a List of Commands.
166 	 * 
167 	 * @param commands
168 	 * @return
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 	 * Remove the String from the line of Text
191 	 * 
192 	 * @param line
193 	 * @param remove
194 	 * @return
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 	 * Did the Server Return OK
208 	 * 
209 	 * @param line
210 	 * @return
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 }