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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2288 - (hide annotations) (download)
Wed Nov 23 21:19:44 2011 UTC (12 years, 5 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 iliev 913 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1786 * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 913 *
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 iliev 2288 import net.sf.juife.PDUtils;
38     import net.sf.juife.event.GenericEvent;
39     import net.sf.juife.event.GenericListener;
40 iliev 913 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 iliev 2288 CC.addReconnectListener(new GenericListener() {
90 iliev 913 public void
91 iliev 2288 jobDone(GenericEvent e) { reconnect(); }
92 iliev 913 });
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 iliev 1786 public void
116     disconnect() {
117     try { if(getSocket() != null) getSocket().close(); }
118     catch(Exception x) { CC.getLogger().info(HF.getErrorMessage(x)); }
119     }
120    
121 iliev 913 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 iliev 1786 @Override
139 iliev 913 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 iliev 1786 @Override
147 iliev 913 public void
148     removeLSConsoleListener(LSConsoleListener l) { listeners.remove(l); }
149    
150     /** Executes the command specified in the command line. */
151 iliev 1786 @Override
152 iliev 913 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 iliev 1786 @Override
179 iliev 913 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 iliev 1786 @Override
190 iliev 913 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 iliev 1786 @Override
204 iliev 913 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 iliev 1786 @Override
212 iliev 913 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 iliev 1786 @Override
222 iliev 913 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 iliev 1786 @Override
230 iliev 913 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 iliev 1786 @Override
238 iliev 913 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 iliev 1786 @Override
248 iliev 913 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 iliev 1786 @Override
259 iliev 913 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 iliev 1786 @Override
267 iliev 913 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 iliev 1786 @Override
275 iliev 913 public String[]
276     getCommandList() { return cmdList; }
277    
278     /** Browses the command history one line up. */
279 iliev 1786 @Override
280 iliev 913 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 iliev 1786 @Override
298 iliev 913 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 iliev 1786 @Override
313 iliev 913 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 iliev 1786 @Override
322 iliev 913 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 iliev 1786 @Override
338 iliev 913 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 iliev 1786 @Override
348 iliev 913 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 iliev 1786 @Override
363 iliev 913 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 iliev 1786 @Override
373 iliev 913 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 iliev 1883 public void
382     quit() { disconnect(); }
383    
384 iliev 913 /** 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 iliev 2288 PDUtils.runOnUiThread(new Runnable() {
405 iliev 913 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 iliev 1867 exec() throws Exception { out.writeLine(cmd); }
428 iliev 913 }
429    
430     class LSConsoleThread extends Thread {
431     LscpInputStream in;
432     private boolean terminate = false;
433    
434     LSConsoleThread() {super("LS-Console-Thread"); }
435    
436 iliev 1786 @Override
437 iliev 913 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