/[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 913 - (hide annotations) (download)
Mon Aug 7 18:45:48 2006 UTC (17 years, 8 months ago) by iliev
File size: 14521 byte(s)
updating to JSampler 0.3a

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

  ViewVC Help
Powered by ViewVC