/[svn]/jsampler/trunk/src/org/jsampler/DefaultLSConsoleModel.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/DefaultLSConsoleModel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2288 - (show annotations) (download)
Wed Nov 23 21:19:44 2011 UTC (12 years, 4 months ago) by iliev
File size: 14811 byte(s)
* Added option to select a sampler engine in Add/Edit Instrument dialog
* Moved all Swing dependent code outside the JSampler core

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler;
24
25 import java.io.InputStream;
26 import java.io.IOException;
27 import java.io.OutputStream;
28 import java.io.UnsupportedEncodingException;
29
30 import java.net.Socket;
31
32 import java.util.LinkedList;
33 import java.util.Vector;
34
35 import java.util.logging.Level;
36
37 import net.sf.juife.PDUtils;
38 import net.sf.juife.event.GenericEvent;
39 import net.sf.juife.event.GenericListener;
40 import net.sf.juife.event.TaskEvent;
41 import net.sf.juife.event.TaskListener;
42
43 import org.jsampler.event.LSConsoleEvent;
44 import org.jsampler.event.LSConsoleListener;
45
46 import org.jsampler.task.LSConsoleConnect;
47
48 import static org.jsampler.JSI18n.i18n;
49
50
51 /**
52 * This class provides default implementation of the <code>LSConsoleModel</code> interface.
53 * @author Grigor Iliev
54 */
55 public class DefaultLSConsoleModel implements LSConsoleModel {
56 private Socket socket;
57 private LscpOutputStream out;
58
59 private final String[] cmdList = LscpUtils.getCommandList();
60
61 private String cmdLine = "";
62
63 /**
64 * Contains the global command history, excluding blank lines and comments.
65 */
66 private final LinkedList<String> cmdHistory = new LinkedList<String>();
67
68 private int cmdHistoryIdx = -1;
69
70 private int commandHistorySize = 1000;
71
72 private final LSConsoleThread lsConsoleThread = new LSConsoleThread();
73
74 /**
75 * Contains the command history of the current
76 * session, including blank lines and comments.
77 */
78 private final Vector<String> sessionHistory = new Vector<String>();
79
80 /** Used to hold the current command when browsing through command history, etc. */
81 private String currentCmd = "";
82
83 private final Vector<LSConsoleListener> listeners = new Vector<LSConsoleListener>();
84
85
86 /** Creates a new instance of <code>DefaultLSConsoleModel</code>. */
87 public
88 DefaultLSConsoleModel() {
89 CC.addReconnectListener(new GenericListener() {
90 public void
91 jobDone(GenericEvent e) { reconnect(); }
92 });
93
94 lsConsoleThread.start();
95 }
96
97 private Socket
98 getSocket() { return socket; }
99
100 private void
101 setSocket(Socket socket) { this.socket = socket; }
102
103 private void
104 reconnect() {
105 final LSConsoleConnect cnt = new LSConsoleConnect(getSocket());
106
107 cnt.addTaskListener(new TaskListener() {
108 public void
109 taskPerformed(TaskEvent e) { changeSocket(cnt.getResult()); }
110 });
111
112 CC.getTaskQueue().add(cnt);
113 }
114
115 public void
116 disconnect() {
117 try { if(getSocket() != null) getSocket().close(); }
118 catch(Exception x) { CC.getLogger().info(HF.getErrorMessage(x)); }
119 }
120
121 private void
122 changeSocket(Socket sock) {
123 setSocket(sock);
124
125 try {
126 LscpInputStream in;
127 in = sock == null ? null : new LscpInputStream(sock.getInputStream());
128 out = sock == null ? null : new LscpOutputStream(sock.getOutputStream());
129
130 lsConsoleThread.setInputStream(in);
131 } catch(Exception x) { CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x); }
132 }
133
134 /**
135 * Registers the specified listener for receiving event messages.
136 * @param l The <code>LSConsoleListener</code> to register.
137 */
138 @Override
139 public void
140 addLSConsoleListener(LSConsoleListener l) { listeners.add(l); }
141
142 /**
143 * Removes the specified listener.
144 * @param l The <code>LSConsoleListener</code> to remove.
145 */
146 @Override
147 public void
148 removeLSConsoleListener(LSConsoleListener l) { listeners.remove(l); }
149
150 /** Executes the command specified in the command line. */
151 @Override
152 public void
153 execCommand() {
154 String cmd = getCommandLineText();
155 sessionHistory.add(cmd);
156 if(cmd.trim().length() > 0 && !cmd.startsWith("#")) addToCommandHistory(cmd);
157 while(cmdHistory.size() > getCommandHistorySize()) cmdHistory.removeFirst();
158
159 setCommandLineText("");
160 currentCmd = "";
161 cmdHistoryIdx = -1;
162
163 if( getSocket() == null || getSocket().isClosed() || !getSocket().isConnected()
164 || getSocket().isOutputShutdown() || out == null ) {
165
166 fireResponseReceived(i18n.getMessage("DefaultLSConsoleModel.notConnected"));
167 } else {
168 CC.getTaskQueue().add(new LSConsoleExecCommand(cmd));
169 }
170
171 fireCommandExecuted();
172 }
173
174 /**
175 * Gets the last executed command.
176 * @return The last command executed in the LS Console.
177 */
178 @Override
179 public String
180 getLastExecutedCommand() {
181 int size = sessionHistory.size();
182 return size == 0 ? "" : sessionHistory.get(size - 1);
183 }
184
185 /**
186 * Sets the text in the command line.
187 * @param cmdLine The new command line text.
188 */
189 @Override
190 public void
191 setCommandLineText(String cmdLine) {
192 if(this.cmdLine.equals(cmdLine)) return;
193
194 String oldCmdLine = this.cmdLine;
195 this.cmdLine = cmdLine;
196 fireCommandLineTextChanged(oldCmdLine);
197 }
198
199 /**
200 * Gets the text in the command line.
201 * @return The command line's text.
202 */
203 @Override
204 public String
205 getCommandLineText() { return cmdLine; }
206
207 /**
208 * Gets the command history of the current session, including blank lines and comments.
209 * @return The command history of the current session, including blank lines and comments.
210 */
211 @Override
212 public String[]
213 getSessionHistory() {
214 return sessionHistory.toArray(new String[sessionHistory.size()]);
215 }
216
217 /**
218 * Clears the session history.
219 * @see #getSessionHistory
220 */
221 @Override
222 public void
223 clearSessionHistory() { sessionHistory.removeAllElements(); }
224
225 /**
226 * Adds the specified <code>command</code> to command history.
227 * @param command The command to be added to command history.
228 */
229 @Override
230 public void
231 addToCommandHistory(String command) { cmdHistory.add(command); }
232
233 /**
234 * Gets the complete command history, excluding blank lines and comments.
235 * @return The complete command history, excluding blank lines and comments.
236 */
237 @Override
238 public String[]
239 getCommandHistory() {
240 return cmdHistory.toArray(new String[cmdHistory.size()]);
241 }
242
243 /**
244 * Clears the complete/multisession command history.
245 * @see #getCommandHistory
246 */
247 @Override
248 public void
249 clearCommandHistory() {
250 cmdHistory.clear();
251 cmdHistoryIdx = -1;
252 }
253
254 /**
255 * Determines the maximum number of lines to be kept in the command history.
256 * @return The maximum number of lines to be kept in the command history.
257 */
258 @Override
259 public int
260 getCommandHistorySize() { return commandHistorySize; }
261
262 /**
263 * Sets the maximum number of lines to be kept in the command history.
264 * @param size Determines the maximum number of lines to be kept in the command history.
265 */
266 @Override
267 public void
268 setCommandHistorySize(int size) { commandHistorySize = size; }
269
270 /**
271 * Gets a list of all LSCP commands.
272 * @return A list of all LSCP commands.
273 */
274 @Override
275 public String[]
276 getCommandList() { return cmdList; }
277
278 /** Browses the command history one line up. */
279 @Override
280 public void
281 browseCommandHistoryUp() {
282 if(cmdHistory.size() == 0) return;
283
284 if(cmdHistoryIdx == -1) {
285 currentCmd = getCommandLineText();
286 cmdHistoryIdx = cmdHistory.size() - 1;
287 setCommandLineText(cmdHistory.get(cmdHistoryIdx));
288 return;
289 }
290
291 if(cmdHistoryIdx == 0) return;
292
293 setCommandLineText(cmdHistory.get(--cmdHistoryIdx));
294 }
295
296 /** Browses the command history one line down. */
297 @Override
298 public void
299 browseCommandHistoryDown() {
300 if(cmdHistory.size() == 0 || cmdHistoryIdx == -1) return;
301 if(cmdHistoryIdx == cmdHistory.size() - 1) {
302 cmdHistoryIdx = -1;
303 setCommandLineText(currentCmd);
304 currentCmd = "";
305 return;
306 }
307
308 setCommandLineText(cmdHistory.get(++cmdHistoryIdx));
309 }
310
311 /** Browses to the first line of the command history. */
312 @Override
313 public void
314 browseCommandHistoryFirst() {
315 if(cmdHistory.size() == 0) return;
316 cmdHistoryIdx = 0;
317 setCommandLineText(cmdHistory.get(cmdHistoryIdx));
318 }
319
320 /** Browses to the last line of the command history. */
321 @Override
322 public void
323 browseCommandHistoryLast() {
324 if(cmdHistory.size() == 0) return;
325 cmdHistoryIdx = cmdHistory.size() - 1;
326 setCommandLineText(cmdHistory.get(cmdHistoryIdx));
327 }
328
329 private Vector<String> tmpVector = new Vector<String>();
330
331 /**
332 * Searches the command history for commands
333 * containing the string returned by {@link #getCommandLineText}.
334 * @return All commands that contains the string returned by {@link #getCommandLineText}.
335 * @see #getCommandHistory
336 */
337 @Override
338 public String[]
339 searchCommandHistory() { return searchCommandHistory(getCommandLineText()); }
340
341 /**
342 * Searches the command history for commands containing <code>substring</code>.
343 * @param substring The substring to be used to perform the search.
344 * @return All commands that contains <code>substring</code>.
345 * @see #getCommandList
346 */
347 @Override
348 public String[]
349 searchCommandHistory(String substring) {
350 tmpVector.removeAllElements();
351 for(String s : cmdHistory) if(s.indexOf(substring) != -1) tmpVector.add(s);
352
353 return tmpVector.toArray(new String[tmpVector.size()]);
354 }
355
356 /**
357 * Searches the LSCP command list for commands
358 * containing the string returned by {@link #getCommandLineText}.
359 * @return All commands that contains the string returned by {@link #getCommandLineText}.
360 * @see #getCommandList
361 */
362 @Override
363 public String[]
364 searchCommandList() { return searchCommandList(getCommandLineText()); }
365
366 /**
367 * Searches the LSCP command list for commands containing <code>substring</code>.
368 * @param substring The substring to be used to perform the search.
369 * @return All commands that contains <code>substring</code>.
370 * @see #getCommandList
371 */
372 @Override
373 public String[]
374 searchCommandList(String substring) {
375 tmpVector.removeAllElements();
376 for(String s : cmdList) if(s.indexOf(substring) != -1) tmpVector.add(s);
377
378 return tmpVector.toArray(new String[tmpVector.size()]);
379 }
380
381 public void
382 quit() { disconnect(); }
383
384 /** Notifies listeners that the text in the command line has changed. */
385 private void
386 fireCommandLineTextChanged(String oldCmdLine) {
387 LSConsoleEvent e = new LSConsoleEvent(this, null, oldCmdLine);
388 for(LSConsoleListener l : listeners) l.commandLineTextChanged(e);
389 }
390
391 /** Notifies listeners that the command in the command line has been executed. */
392 private void
393 fireCommandExecuted() {
394 LSConsoleEvent e = new LSConsoleEvent(this);
395 for(LSConsoleListener l : listeners) l.commandExecuted(e);
396 }
397
398 /**
399 * Notifies listeners that response is received from LinuxSampler.
400 * @param response The response received from LinuxSampler.
401 */
402 private void
403 fireResponseReceived(final String response) {
404 PDUtils.runOnUiThread(new Runnable() {
405 public void
406 run() {
407 LSConsoleEvent e = new LSConsoleEvent(this, response);
408 for(LSConsoleListener l : listeners) l.responseReceived(e);
409 }
410 });
411 }
412
413 /** Executes LS Console command. */
414 private class LSConsoleExecCommand extends org.jsampler.task.EnhancedTask {
415 private String cmd;
416
417 /** Creates a new instance of <code>LSConsoleExecCommand</code>. */
418 public
419 LSConsoleExecCommand(String cmd) {
420 setTitle("LSConsoleExecCommand_task");
421 setDescription(i18n.getMessage("LSConsoleExecCommand.description"));
422 this.cmd = cmd;
423 }
424
425 /** The entry point of the task. */
426 public void
427 exec() throws Exception { out.writeLine(cmd); }
428 }
429
430 class LSConsoleThread extends Thread {
431 LscpInputStream in;
432 private boolean terminate = false;
433
434 LSConsoleThread() {super("LS-Console-Thread"); }
435
436 @Override
437 public void
438 run() {
439 while(!mustTerminate()) {
440 try { processInput(); }
441 catch(Exception x) {
442 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
443 }
444
445 try { synchronized(this) { wait(100); } }
446 catch(Exception x) {
447 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
448 }
449 }
450 }
451
452 private synchronized boolean
453 mustTerminate() { return terminate; }
454
455 public synchronized void
456 terminate() {
457 terminate = true;
458 this.notifyAll();
459 }
460
461 /** Processes the input sent by LinuxSampler */
462 private synchronized void
463 processInput() throws IOException {
464 while(in != null && in.available() > 0) {
465 String response = in.readLine();
466 fireResponseReceived(response);
467 }
468 }
469
470 public synchronized void
471 setInputStream(LscpInputStream in) { this.in = in; }
472 }
473
474 class LscpInputStream {
475 private InputStream in;
476 private StringBuffer buf = new StringBuffer();
477
478 /**
479 * Creates a new instance of LscpInputStream.
480 *
481 */
482 public
483 LscpInputStream(InputStream in) {
484 this.in = in;
485 }
486
487 /**
488 * Reads a line.
489 * This method is thread safe.
490 *
491 * @return A string containing the next line readed from the stream or
492 * <code>null</code> if the end of the stream has been reached.
493 * @throws IOException If an I/O error occurs.
494 */
495 public synchronized String
496 readLine() throws IOException {
497 int i;
498 buf.setLength(0);
499
500 while((i = in.read()) != -1) {
501 if(i == '\r') {
502 checkLF();
503 break;
504 }
505 buf.append((char)i);
506 }
507
508 if(i == -1) {
509 if(buf.length() > 0)
510 throw new IOException("Unexpected end of line!");
511 return null;
512 }
513 return buf.toString();
514 }
515
516 /**
517 * Returns the number of bytes that can
518 * be read from this input stream without blocking.
519 *
520 * @return The number of bytes that can
521 * be read from this input stream without blocking.
522 * @throws IOException If an I/O error occurs.
523 */
524 public synchronized int
525 available() throws IOException { return in.available(); }
526
527 private void
528 checkLF() throws IOException {
529 int i = in.read();
530 if(i == -1) throw new IOException("Unexpected end of file!");
531 if(i != '\n') throw new IOException("Unexpected end of line!");
532 }
533 }
534
535 class LscpOutputStream {
536 private OutputStream out;
537
538 /** Creates a new instance of LscpOutputStream */
539 public
540 LscpOutputStream(OutputStream out) { this.out = out; }
541
542 /*
543 * Writes a line.
544 * @param line a string to be written.
545 */
546 public void
547 writeLine(String line) throws IOException {
548 try {
549 out.write(line.getBytes("US-ASCII"));
550 out.write('\r');
551 out.write('\n');
552 out.flush();
553 } catch(UnsupportedEncodingException x) {
554 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
555 }
556 }
557 }
558 }

  ViewVC Help
Powered by ViewVC