/[svn]/jlscp/trunk/src/org/linuxsampler/lscp/Client.java
ViewVC logotype

Diff of /jlscp/trunk/src/org/linuxsampler/lscp/Client.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1139 by iliev, Mon Apr 2 20:43:58 2007 UTC revision 1539 by iliev, Mon Dec 3 22:59:39 2007 UTC
# Line 34  import java.util.Vector; Line 34  import java.util.Vector;
34  import java.util.logging.Level;  import java.util.logging.Level;
35  import java.util.logging.Logger;  import java.util.logging.Logger;
36    
 import static org.linuxsampler.lscp.Parser.*;  
37  import org.linuxsampler.lscp.event.*;  import org.linuxsampler.lscp.event.*;
38    
39    import static org.linuxsampler.lscp.Parser.*;
40    
41    
42  /**  /**
43   * This class is the abstraction representing a client endpoint for communication with LinuxSampler   * This class is the abstraction representing a client endpoint for communication with LinuxSampler
# Line 69  public class Client { Line 70  public class Client {
70          private String address;          private String address;
71          private int port;          private int port;
72          private Socket sock = null;          private Socket sock = null;
73          private int soTimeout = 10000;          private int soTimeout = 20000;
74                    
75          private LscpInputStream in = null;          private LscpInputStream in = null;
76          private LscpOutputStream out = null;          private LscpOutputStream out = null;
# Line 79  public class Client { Line 80  public class Client {
80          private boolean printOnlyMode = false;          private boolean printOnlyMode = false;
81                    
82          class EventThread extends Thread {          class EventThread extends Thread {
83                    private Vector<String> queue = new Vector<String>();
84                  private boolean terminate = false;                  private boolean terminate = false;
85                                    
86                  EventThread() { super("LSCP-Event-Thread"); }                  EventThread() { super("LSCP-Event-Thread"); }
# Line 86  public class Client { Line 88  public class Client {
88                  public void                  public void
89                  run() {                  run() {
90                          while(!mustTerminate()) {                          while(!mustTerminate()) {
91                                  try { processNotifications(); }                                  try {
92                                  catch(Exception x) {                                          processQueue();
93                                            processNotifications();
94                                    } catch(Exception x) {
95                                          getLogger().log(Level.FINE, x.getMessage(), x);                                          getLogger().log(Level.FINE, x.getMessage(), x);
96                                  }                                  }
97                                  try { synchronized(this) { wait(100); } }                                  try { synchronized(this) { wait(100); } }
# Line 105  public class Client { Line 109  public class Client {
109                          terminate = true;                          terminate = true;
110                          this.notifyAll();                          this.notifyAll();
111                  }                  }
112                    
113                    public synchronized void
114                    scheduleNotification(String s) { queue.add(s); }
115                    
116                    private void
117                    processQueue() {
118                            String[] notifications = popAllNotifications();
119                            for(String n : notifications) fireEvent(n);
120                    }
121                    
122                    private synchronized String[]
123                    popAllNotifications() {
124                            String[] notifications = queue.toArray(new String[queue.size()]);
125                            queue.removeAllElements();
126                            return notifications;
127                    }
128          }          }
129                    
130          /**          /**
# Line 329  public class Client { Line 349  public class Client {
349                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
350                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
351                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
352                    if(!llID.isEmpty()) {
353                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
354                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
355                            subscribe("DB_INSTRUMENT_COUNT");
356                            subscribe("DB_INSTRUMENT_INFO");
357                    }
358                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
359          }          }
360                    
# Line 376  public class Client { Line 402  public class Client {
402                  String s;                  String s;
403                  for(;;) {                  for(;;) {
404                          s = in.readLine();                          s = in.readLine();
405                          if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));                          if(s.startsWith("NOTIFY:")) {
406                                    eventThread.scheduleNotification(s.substring("NOTIFY:".length()));
407                            }
408                          else break;                          else break;
409                  }                  }
410                  return s;                  return s;
# Line 469  public class Client { Line 497  public class Client {
497          /** MIDI instrument info listeners */          /** MIDI instrument info listeners */
498          private final Vector<MidiInstrumentInfoListener> llMII =          private final Vector<MidiInstrumentInfoListener> llMII =
499                  new Vector<MidiInstrumentInfoListener>();                  new Vector<MidiInstrumentInfoListener>();
500            private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
501          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
502                    
503                    
# Line 498  public class Client { Line 527  public class Client {
527                          !llMIMI.isEmpty() ||                          !llMIMI.isEmpty() ||
528                          !llMIC.isEmpty()  ||                          !llMIC.isEmpty()  ||
529                          !llMII.isEmpty()  ||                          !llMII.isEmpty()  ||
530                            !llID.isEmpty()   ||
531                          !llGI.isEmpty();                          !llGI.isEmpty();
532          }          }
533                    
534          private void          private synchronized void
535          fireEvent(String s) {          fireEvent(String s) {
536                  if(s.startsWith("CHANNEL_COUNT:")) {                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
537                            s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
538                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
539                            for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
540                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_INFO:")) {
541                            InstrumentsDbEvent e;
542                            s = s.substring("DB_INSTRUMENT_DIRECTORY_INFO:".length());
543                            if(s.startsWith("NAME ")) {
544                                    String[] list;
545                                    try {
546                                            s = s.substring("NAME ".length());
547                                            list = parseEscapedStringList(s, ' ');
548                                            if(list.length != 2) throw new LscpException();
549                                            list[1] = toNonEscapedString(list[1]);
550                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
551                                            for(InstrumentsDbListener l : llID) {
552                                                    l.directoryNameChanged(e);
553                                            }
554                                    } catch(LscpException x) {
555                                            getLogger().log (
556                                                    Level.WARNING,
557                                                    LscpI18n.getLogMsg("CommandFailed!"),
558                                                    x
559                                            );
560                                    }
561                            } else {
562                                    e = new InstrumentsDbEvent(this, s);
563                                    for(InstrumentsDbListener l : llID) l.directoryInfoChanged(e);
564                            }
565                    } else if(s.startsWith("DB_INSTRUMENT_COUNT:")) {
566                            s = s.substring("DB_INSTRUMENT_COUNT:".length());
567                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
568                            for(InstrumentsDbListener l : llID) l.instrumentCountChanged(e);
569                    } else if(s.startsWith("DB_INSTRUMENT_INFO:")) {
570                            InstrumentsDbEvent e;
571                            s = s.substring("DB_INSTRUMENT_INFO:".length());
572                            if(s.startsWith("NAME ")) {
573                                    String[] list;
574                                    try {
575                                            s = s.substring("NAME ".length());
576                                            list = parseEscapedStringList(s, ' ');
577                                            if(list.length != 2) throw new LscpException();
578                                            list[1] = toNonEscapedString(list[1]);
579                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
580                                            for(InstrumentsDbListener l : llID) {
581                                                    l.instrumentNameChanged(e);
582                                            }
583                                    } catch(LscpException x) {
584                                            getLogger().log (
585                                                    Level.WARNING,
586                                                    LscpI18n.getLogMsg("CommandFailed!"),
587                                                    x
588                                            );
589                                    }
590                            } else {
591                                    e = new InstrumentsDbEvent(this, s);
592                                    for(InstrumentsDbListener l : llID) l.instrumentInfoChanged(e);
593                            }
594                    } else if(s.startsWith("DB_INSTRUMENTS_JOB_INFO:")) {
595                            s = s.substring("DB_INSTRUMENTS_JOB_INFO:".length());
596                            try {
597                                    int i = Integer.parseInt(s);
598                                    InstrumentsDbEvent e = new InstrumentsDbEvent(this, i);
599                                    for(InstrumentsDbListener l : llID) l.jobStatusChanged(e);
600                            } catch(NumberFormatException x) {
601                                    s = "Unknown DB_INSTRUMENTS_JOB_INFO format";
602                                    getLogger().log(Level.WARNING, s, x);
603                            }
604                            
605                    } else if(s.startsWith("CHANNEL_COUNT:")) {
606                          try {                          try {
607                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));
608                                  ChannelCountEvent e = new ChannelCountEvent(this, i);                                  ChannelCountEvent e = new ChannelCountEvent(this, i);
# Line 1145  public class Client { Line 1244  public class Client {
1244          /**          /**
1245           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1246           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1247             * @param l The <code>InstrumentsDbListener</code> to register.
1248             */
1249            public synchronized void
1250            addInstrumentsDbListener(InstrumentsDbListener l) {
1251                    if(llID.isEmpty()) {
1252                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1253                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1254                            subscribe("DB_INSTRUMENT_COUNT");
1255                            subscribe("DB_INSTRUMENT_INFO");
1256                            subscribe("DB_INSTRUMENTS_JOB_INFO");
1257                    }
1258                    llID.add(l);
1259            }
1260            
1261            /**
1262             * Removes the specified listener.
1263             * Listeners can be removed regardless of the connection state.
1264             * @param l The <code>InstrumentsDbListener</code> to remove.
1265             */
1266            public synchronized void
1267            removeInstrumentsDbListener(InstrumentsDbListener l) {
1268                    boolean b = llID.remove(l);
1269                    if(b && llID.isEmpty()) {
1270                            unsubscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1271                            unsubscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1272                            unsubscribe("DB_INSTRUMENT_COUNT");
1273                            unsubscribe("DB_INSTRUMENT_INFO");
1274                            unsubscribe("DB_INSTRUMENTS_JOB_INFO");
1275                    }
1276            }
1277            
1278            /**
1279             * Registers the specified listener for receiving event messages.
1280             * Listeners can be registered regardless of the connection state.
1281           * @param l The <code>GlobalInfoListener</code> to register.           * @param l The <code>GlobalInfoListener</code> to register.
1282           */           */
1283          public synchronized void          public synchronized void
# Line 1227  public class Client { Line 1360  public class Client {
1360          /**          /**
1361           * Gets detailed information about a specific audio output driver.           * Gets detailed information about a specific audio output driver.
1362           * @param driverName The name of the audio output driver.           * @param driverName The name of the audio output driver.
1363           *           * @param depList An optional list of dependences parameters.
1364           * @return An <code>AudioOutputDriver</code> object containing           * @return An <code>AudioOutputDriver</code> object containing
1365           * information about the specified audio output driver.           * information about the specified audio output driver.
1366           *           *
# Line 1237  public class Client { Line 1370  public class Client {
1370           *           *
1371           * @see #getAudioOutputDriverNames           * @see #getAudioOutputDriverNames
1372           */           */
1373          private synchronized AudioOutputDriver          public synchronized AudioOutputDriver
1374          getAudioOutputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getAudioOutputDriverInfo(String driverName, Parameter... depList)
1375                                            throws IOException, LscpException, LSException {
1376                    
1377                  verifyConnection();                  verifyConnection();
1378                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);
1379                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 1248  public class Client { Line 1383  public class Client {
1383                  aod.setName(driverName);                  aod.setName(driverName);
1384                                    
1385                  for(String s : aod.getParameterNames())                  for(String s : aod.getParameterNames())
1386                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s));                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s, depList));
1387                                    
1388                  return aod;                  return aod;
1389          }          }
# Line 1282  public class Client { Line 1417  public class Client {
1417                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
1418                  args.append(' ').append(param);                  args.append(' ').append(param);
1419                                    
1420                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
1421                            if(p.getValue() == null) continue;
1422                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1423                    }
1424                                    
1425                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());
1426                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 1344  public class Client { Line 1481  public class Client {
1481                  verifyConnection();                  verifyConnection();
1482                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1483                                    
1484                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
1485                            if(p.getValue() == null) continue;
1486                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1487                    }
1488                                    
1489                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
1490                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
# Line 1806  public class Client { Line 1945  public class Client {
1945          /**          /**
1946           * Gets detailed information about a specific MIDI input driver.           * Gets detailed information about a specific MIDI input driver.
1947           * @param driverName The name of the MIDI input driver.           * @param driverName The name of the MIDI input driver.
1948           *           * @param depList An optional list of dependences parameters.
1949           * @return A <code>MidiInputDriver</code> object containing           * @return A <code>MidiInputDriver</code> object containing
1950           * information about the specified MIDI input driver.           * information about the specified MIDI input driver.
1951           *           *
# Line 1816  public class Client { Line 1955  public class Client {
1955           *           *
1956           * @see #getMidiInputDriverNames           * @see #getMidiInputDriverNames
1957           */           */
1958          private synchronized MidiInputDriver          public synchronized MidiInputDriver
1959          getMidiInputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getMidiInputDriverInfo(String driverName, Parameter... depList)
1960                                            throws IOException, LscpException, LSException {
1961                    
1962                  verifyConnection();                  verifyConnection();
1963                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);
1964                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 1828  public class Client { Line 1969  public class Client {
1969                  mid.setName(driverName);                  mid.setName(driverName);
1970                                    
1971                  for(String s : mid.getParameterNames())                  for(String s : mid.getParameterNames())
1972                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s));                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s, depList));
1973                                    
1974                  return mid;                  return mid;
1975          }          }
# Line 1862  public class Client { Line 2003  public class Client {
2003                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
2004                  args.append(' ').append(param);                  args.append(' ').append(param);
2005                                    
2006                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
2007                            if(p.getValue() == null) continue;
2008                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2009                    }
2010                                    
2011                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());
2012                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 1925  public class Client { Line 2068  public class Client {
2068                  verifyConnection();                  verifyConnection();
2069                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2070                                    
2071                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
2072                            if(p.getValue() == null) continue;
2073                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2074                    }
2075                                    
2076                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());
2077                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
# Line 2071  public class Client { Line 2216  public class Client {
2216                                  mid.setActive(Boolean.parseBoolean(s));                                  mid.setActive(Boolean.parseBoolean(s));
2217                          } else if(s.startsWith("PORTS: ")) {                          } else if(s.startsWith("PORTS: ")) {
2218                                  s = s.substring("PORTS: ".length());                                  s = s.substring("PORTS: ".length());
2219                                  int ports = Parser.parseInt(s);                                  
2220                                  MidiPort[] midiPorts = new MidiPort[ports > 0 ? ports : 0];                                  Parameter<Integer> ports = (Parameter<Integer>)
2221                                            getMidiInputDriverParameterInfo(drv, "PORTS");
2222                                    
2223                                    ports.parseValue(s);
2224                                    mid.setPortsParameter(ports);
2225                                    
2226                                    int j = ports.getValue();
2227                                    MidiPort[] midiPorts = new MidiPort[j > 0 ? j : 0];
2228                                                                    
2229                                  for(int i = 0; i < midiPorts.length; i++)                                  for(int i = 0; i < midiPorts.length; i++)
2230                                          midiPorts[i] = getMidiInputPortInfo(deviceId, i);                                          midiPorts[i] = getMidiInputPortInfo(deviceId, i);
# Line 2315  public class Client { Line 2467  public class Client {
2467          public synchronized int          public synchronized int
2468          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2469                  verifyConnection();                  verifyConnection();
2470                  out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + name + "'");                  out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + toEscapedString(name) + "'");
2471                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
2472                                    
2473                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 2418  public class Client { Line 2570  public class Client {
2570                                    
2571                  for(String s : lnS) {                  for(String s : lnS) {
2572                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
2573                                  name = s.substring("NAME: ".length());                                  name = toNonEscapedString(s.substring("NAME: ".length()));
2574                          } else if(s.startsWith("DEFAULT: ")) {                          } else if(s.startsWith("DEFAULT: ")) {
2575                                  b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));                                  b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));
2576                          } else {                          } else {
# Line 2466  public class Client { Line 2618  public class Client {
2618                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
2619                                    
2620                  verifyConnection();                  verifyConnection();
2621                    name = toEscapedString(name);
2622                  out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");                  out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");
2623                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
2624                                    
2625                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2626          }          }
2627                    
2628            
2629            
2630          /**          /**
2631           * Creates or replaces a MIDI instrument map entry.           * Creates or replaces a MIDI instrument map entry.
2632           * @param mapId The ID of the map, where this instrument should be mapped.           * @param mapId The ID of the map, where this instrument should be mapped.
# Line 2486  public class Client { Line 2641  public class Client {
2641          public synchronized void          public synchronized void
2642          mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info)          mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info)
2643                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
2644                    mapMidiInstrument(mapId, entry, info, false);
2645            }
2646            
2647            /**
2648             * Creates or replaces a MIDI instrument map entry.
2649             * @param mapId The ID of the map, where this instrument should be mapped.
2650             * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2651             * @param info Provides the needed information of the
2652             * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2653             * @param nonModal If <code>true</code> the function returns immediately
2654             * and the mapping is established in the background.
2655             * @throws IOException If some I/O error occurs.
2656             * @throws LSException If the mapping failed.
2657             * @throws LscpException If LSCP protocol corruption occurs.
2658             * @see #unmapMidiInstrument
2659             */
2660            public synchronized void
2661            mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info, boolean nonModal)
2662                                            throws IOException, LSException, LscpException {
2663                                    
2664                  verifyConnection();                  verifyConnection();
2665                  StringBuffer cmd = new StringBuffer("MAP MIDI_INSTRUMENT ");                  StringBuffer cmd = new StringBuffer("MAP MIDI_INSTRUMENT ");
2666                    if(nonModal) cmd.append("NON_MODAL ");
2667                  cmd.append(mapId).append(' ');                  cmd.append(mapId).append(' ');
2668                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
2669                  cmd.append(entry.getMidiProgram()).append(' ');                  cmd.append(entry.getMidiProgram()).append(' ');
2670                  cmd.append(info.getEngine()).append(" '");                  cmd.append(info.getEngine()).append(" '");
2671                  cmd.append(info.getFileName()).append("' ");                  cmd.append(info.getFilePath()).append("' ");
2672                  cmd.append(info.getInstrumentIndex()).append(' ');                  cmd.append(info.getInstrumentIndex()).append(' ');
2673                  cmd.append(info.getVolume());                  cmd.append(info.getVolume());
2674                  if(!info.getLoadMode().name().equals("DEFAULT")) {                  if(!info.getLoadMode().name().equals("DEFAULT")) {
2675                          cmd.append(' ').append(info.getLoadMode().name());                          cmd.append(' ').append(info.getLoadMode().name());
2676                  }                  }
2677                  if(info.getName() != null) cmd.append(" '").append(info.getName()).append("'");                  
2678                    if(info.getName() != null) {
2679                            String s = toEscapedString(info.getName());
2680                            cmd.append(" '").append(s).append("'");
2681                    }
2682                                    
2683                  out.writeLine(cmd.toString());                  out.writeLine(cmd.toString());
2684                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
# Line 3348  public class Client { Line 3527  public class Client {
3527                                    
3528                  verifyConnection();                  verifyConnection();
3529                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3530                  if(name != null) s += " '" + name + "'";                  if(name != null) s += " '" + toEscapedString(name) + "'";
3531                  out.writeLine("CREATE FX_SEND " + s);                  out.writeLine("CREATE FX_SEND " + s);
3532                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
3533                                    
# Line 3479  public class Client { Line 3658  public class Client {
3658                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3659                                    
3660                  verifyConnection();                  verifyConnection();
3661                  String args = " " + channel + " " + fxSend + " '" + name + "'";                  String args = " " + channel + " " + fxSend + " '" + toEscapedString(name) + "'";
3662                  out.writeLine("SET FX_SEND NAME" + args);                  out.writeLine("SET FX_SEND NAME" + args);
3663                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
3664                                    
# Line 3568  public class Client { Line 3747  public class Client {
3747          }          }
3748                    
3749          /**          /**
3750             * Starts an instrument editor for editing the loaded instrument
3751             * on the specified sampler channel.
3752             * @param samplerChn The sampler channel number.
3753             * @throws IOException If some I/O error occurs.
3754             * @throws LscpException If LSCP protocol corruption occurs.
3755             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3756             * there is no instrument loaded on the specified sampler channel.
3757             * @see #getSamplerChannels
3758             */
3759            public synchronized void
3760            editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException {
3761                    verifyConnection();
3762                    out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn);
3763                    if(getPrintOnlyMode()) return;
3764                    
3765                    ResultSet rs = getEmptyResultSet();
3766            }
3767            
3768            
3769            
3770            /**
3771             * Adds the specified directory to the instruments database.
3772             * @param dir The absolute (escaped) path name of the directory to add.
3773             * @throws IOException If some I/O error occurs.
3774             * @throws LSException If the creation of the directory failed.
3775             * @throws LscpException If LSCP protocol corruption occurs.
3776             */
3777            public synchronized void
3778            addDbDirectory(String dir) throws IOException, LSException, LscpException {
3779                    verifyConnection();
3780                    out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");
3781                    if(getPrintOnlyMode()) return;
3782                    
3783                    ResultSet rs = getEmptyResultSet();
3784            }
3785            
3786            /**
3787             * Removes the specified directory from the instruments database.
3788             * @param dir The absolute (escaped) path name of the directory to remove.
3789             * @throws IOException If some I/O error occurs.
3790             * @throws LscpException If LSCP protocol corruption occurs.
3791             * @throws LSException If the specified directory is not
3792             * empty or if the removal of the directory failed.
3793             */
3794            public synchronized void
3795            removeDbDirectory(String dir) throws IOException, LscpException, LSException {
3796                    removeDbDirectory(dir, false);
3797            }
3798            
3799            /**
3800             * Removes the specified directory from the instruments database.
3801             * @param dir The absolute path name of the directory to remove.
3802             * @param force If <code>true</code> forces the removal of non-empty
3803             * directory and all its content.
3804             * @throws IOException If some I/O error occurs.
3805             * @throws LscpException If LSCP protocol corruption occurs.
3806             * @throws LSException If the removing of the directory failed.
3807             */
3808            public synchronized void
3809            removeDbDirectory(String dir, boolean force)
3810                                    throws IOException, LscpException, LSException {
3811                    
3812                    verifyConnection();
3813                    String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3814                    if(force) s += "FORCE ";
3815                    out.writeLine(s + "'" + dir + "'");
3816                    if(getPrintOnlyMode()) return;
3817                    
3818                    ResultSet rs = getEmptyResultSet();
3819            }
3820            
3821            /**
3822             * Removes the specified directories from the instruments database.
3823             * @param dirs The absolute (escaped) path names of the directories to remove.
3824             * @param force If <code>true</code> forces the removal of non-empty
3825             * directories.
3826             * @throws IOException If some I/O error occurs.
3827             * @throws LscpException If LSCP protocol corruption occurs.
3828             * @throws LSException If the removing of the directores failed.
3829             */
3830            public synchronized void
3831            removeDbDirectories(String[] dirs, boolean force)
3832                                    throws IOException, LscpException, LSException {
3833                    
3834                    verifyConnection();
3835                    String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3836                    if(force) cmd += "FORCE ";
3837                    
3838                    for(String s : dirs) out.writeLine(cmd + "'" + s + "'");
3839                    
3840                    if(getPrintOnlyMode()) return;
3841                    
3842                    getEmptyResultSets(dirs.length, "Client.dirDeletionFailed!");
3843            }
3844            
3845            /**
3846             * Gets the number of directories in the specified directory.
3847             * @return The current number of directories in the specified directory.
3848             * @param dir The absolute path name of the directory.
3849             * @throws IOException If some I/O error occurs.
3850             * @throws LscpException If LSCP protocol corruption occurs.
3851             * @throws LSException If some other error occurs.
3852             */
3853            public synchronized int
3854            getDbDirectoryCount(String dir) throws IOException, LscpException, LSException {
3855                    return getDbDirectoryCount(dir, false);
3856            }
3857            
3858            /**
3859             * Gets the number of directories in the specified directory.
3860             * @return The current number of directories in the specified directory.
3861             * @param dir The absolute path name of the directory.
3862             * @param recursive If <code>true</code>, the number of all directories
3863             * in the specified subtree will be returned.
3864             * @throws IOException If some I/O error occurs.
3865             * @throws LscpException If LSCP protocol corruption occurs.
3866             * @throws LSException If some other error occurs.
3867             */
3868            public synchronized int
3869            getDbDirectoryCount(String dir, boolean recursive)
3870                                    throws IOException, LscpException, LSException {
3871                    
3872                    verifyConnection();
3873                    String s;
3874                    if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
3875                    else s = "GET DB_INSTRUMENT_DIRECTORIES '";
3876                    out.writeLine(s + dir + "'");
3877                    if(getPrintOnlyMode()) return -1;
3878                    
3879                    s = getSingleLineResultSet().getResult();
3880                    return parseInt(s);
3881            }
3882            
3883            /**
3884             * Gets the list of directories in the specified directory.
3885             * @param dir The absolute path name of the directory.
3886             * @return A <code>String</code> array providing the names of
3887             * all directories in the specified directory.
3888             * @throws IOException If some I/O error occurs.
3889             * @throws LscpException If LSCP protocol corruption occurs.
3890             * @throws LSException If the specified path name is invalid.
3891             */
3892            public synchronized String[]
3893            getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
3894                    verifyConnection();
3895                    out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");
3896                    if(getPrintOnlyMode()) return null;
3897                    
3898                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
3899                    for(int i = 0; i < names.length; i++) {
3900                            names[i] = toNonEscapedString(names[i]);
3901                    }
3902                    return names;
3903            }
3904            
3905            /**
3906             * Gets information about the specified directory.
3907             * @param dir The absolute path name of the directory.
3908             * @return A <code>DbDirectoryInfo</code> instance providing information
3909             * about the specified directory.
3910             * @throws IOException If some I/O error occurs.
3911             * @throws LscpException If LSCP protocol corruption occurs.
3912             * @throws LSException If the specified directory is not found.
3913             */
3914            public synchronized DbDirectoryInfo
3915            getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
3916                    verifyConnection();
3917                    out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");
3918                    if(getPrintOnlyMode()) return null;
3919                    
3920                    ResultSet rs = getMultiLineResultSet();
3921                    DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());
3922                    if(dir.equals("/")) {
3923                            info.setName("/");
3924                    } else {
3925                            dir = removeEndingFileSeparator(dir);
3926                    }
3927                    String s = getFileName(dir);
3928                    if(s != null) info.setName(toNonEscapedFileName(s));
3929                    s = getParentDirectory(dir);
3930                    if(s != null) info.setParentDirectoryPath(s);
3931                    
3932                    return info;
3933            }
3934            
3935            /**
3936             * Gets the list of directories in the specified directory.
3937             * @param dir The absolute path name of the directory.
3938             * @return A <code>DbDirectoryInfo</code> array providing
3939             * information about all directories in the specified directory.
3940             * @throws IOException If some I/O error occurs.
3941             * @throws LscpException If LSCP protocol corruption occurs.
3942             * @throws LSException If the specified path name is invalid.
3943             */
3944            public synchronized DbDirectoryInfo[]
3945            getDbDirectories(String dir) throws IOException, LscpException, LSException {
3946                    String[] dirS = getDbDirectoryNames(dir);
3947                    if(!hasEndingFileSeparator(dir)) dir += "/";
3948                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
3949                    for(int i = 0; i < dirS.length; i++) {
3950                            infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i]));
3951                    }
3952                    return infoS;
3953            }
3954            
3955            /**
3956             * Gets the list of directories in the specified directory.
3957             * @param dir The absolute path name of the directory.
3958             * @return A <code>DbDirectoryInfo</code> array providing
3959             * information about all directories in the specified directory.
3960             * @throws IOException If some I/O error occurs.
3961             * @throws LscpException If LSCP protocol corruption occurs.
3962             * @throws LSException If the specified path name is invalid.
3963             *
3964            public synchronized DbDirectoryInfo[]
3965            getDbDirectories(String dir) throws IOException, LscpException, LSException {
3966                    String[] dirS = getDbDirectoryNames(dir);
3967                    if(dirS.length == 0) return new DbDirectoryInfo[0];
3968                    
3969                    if(dir.charAt(dir.length() - 1) != '/') dir += "/";
3970                    
3971                    for(int i = 0; i < dirS.length; i++) {
3972                            out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");
3973                    }
3974                    
3975                    if(getPrintOnlyMode()) return null;
3976                    
3977                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
3978                    StringBuffer sb = new StringBuffer();
3979                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
3980                    for(int i = 0; i < dirS.length; i++) {
3981                            try {
3982                                    ResultSet rs = getMultiLineResultSet();
3983                                    infoS[i] = new DbDirectoryInfo(rs.getMultiLineResult());
3984                                    infoS[i].setName(dirS[i]);
3985                                    infoS[i].setParentDirectoryPath(dir);
3986                            } catch (SocketTimeoutException e) {
3987                                    getLogger().log(Level.FINE, e.getMessage(), e);
3988                                    sb.append(e.getMessage()).append("\n");
3989                                    break;
3990                            } catch (Exception e) {
3991                                    getLogger().log(Level.FINE, e.getMessage(), e);
3992                                    sb.append(e.getMessage()).append("\n");
3993                            }
3994                    }
3995                    
3996                    String details = sb.toString();
3997                    if(details.length() > 0) {
3998                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
3999                            throw new LSException(0, err, details);
4000                    }
4001                    
4002                    return infoS;
4003            }*/
4004            
4005            /**
4006             * Renames the specified directory.
4007             * @param dir The absolute path name of the directory to rename.
4008             * @param name The new name for the directory.
4009             * @throws IOException If some I/O error occurs.
4010             * @throws LSException If the renaming of the directory failed.
4011             * @throws LscpException If LSCP protocol corruption occurs.
4012             */
4013            public synchronized void
4014            renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4015                    verifyConnection();
4016                    name = toEscapedString(name);
4017                    out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + dir + "' '" + name + "'");
4018                    if(getPrintOnlyMode()) return;
4019                    
4020                    ResultSet rs = getEmptyResultSet();
4021            }
4022            
4023            /**
4024             * Moves the specified directory into the specified location.
4025             * @param dir The absolute path name of the directory to move.
4026             * @param dst The location where the directory will be moved to.
4027             * @throws IOException If some I/O error occurs.
4028             * @throws LSException If the operation failed.
4029             * @throws LscpException If LSCP protocol corruption occurs.
4030             */
4031            public synchronized void
4032            moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4033                    verifyConnection();
4034                    out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4035                    if(getPrintOnlyMode()) return;
4036                    
4037                    ResultSet rs = getEmptyResultSet();
4038            }
4039            
4040            /**
4041             * Moves the specified directories into the specified location.
4042             * @param dirs The absolute path names of the directories to move.
4043             * @param dst The location where the directories will be moved to.
4044             * @throws IOException If some I/O error occurs.
4045             * @throws LSException If the operation failed.
4046             * @throws LscpException If LSCP protocol corruption occurs.
4047             */
4048            public synchronized void
4049            moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4050                    verifyConnection();
4051                    for(String s : dirs) {
4052                            out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4053                    }
4054                    if(getPrintOnlyMode()) return;
4055                    
4056                    getEmptyResultSets(dirs.length, "Client.dirMovingFailed!");
4057            }
4058            
4059            /**
4060             * Copies the specified directory into the specified location.
4061             * @param dir The absolute path name of the directory to copy.
4062             * @param dst The location where the directory will be copied to.
4063             * @throws IOException If some I/O error occurs.
4064             * @throws LSException If the operation failed.
4065             * @throws LscpException If LSCP protocol corruption occurs.
4066             */
4067            public synchronized void
4068            copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4069                    verifyConnection();
4070                    out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4071                    if(getPrintOnlyMode()) return;
4072                    
4073                    ResultSet rs = getEmptyResultSet();
4074            }
4075            
4076            /**
4077             * Copies the specified directories into the specified location.
4078             * @param dirs The absolute path names of the directories to copy.
4079             * @param dst The location where the directories will be copied to.
4080             * @throws IOException If some I/O error occurs.
4081             * @throws LSException If the operation failed.
4082             * @throws LscpException If LSCP protocol corruption occurs.
4083             */
4084            public synchronized void
4085            copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4086                    verifyConnection();
4087                    for(String s : dirs) {
4088                            out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4089                    }
4090                    if(getPrintOnlyMode()) return;
4091                    
4092                    getEmptyResultSets(dirs.length, "Client.dirCopyingFailed!");
4093            }
4094            
4095            /**
4096             * Changes the description of the specified directory.
4097             * @param dir The absolute path name of the directory.
4098             * @param desc The new description for the directory.
4099             * @throws IOException If some I/O error occurs.
4100             * @throws LSException If failed to change the description.
4101             * @throws LscpException If LSCP protocol corruption occurs.
4102             */
4103            public synchronized void
4104            setDbDirectoryDescription(String dir, String desc)
4105                                    throws IOException, LSException, LscpException {
4106                    
4107                    verifyConnection();
4108                    String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4109                    out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'");
4110                    if(getPrintOnlyMode()) return;
4111                    
4112                    ResultSet rs = getEmptyResultSet();
4113            }
4114            
4115            public static enum ScanMode {
4116                    RECURSIVE, NON_RECURSIVE, FLAT
4117            }
4118            
4119            /**
4120             * Adds the specified instrument to the specified instruments database directory.
4121             * @param dbDir The absolute path name of the database directory in which the
4122             * specified instrument will be added.
4123             * @param filePath The absolute path name of the instrument file.
4124             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4125             * @throws IOException If some I/O error occurs.
4126             * @throws LSException If the operation failed.
4127             * @throws LscpException If LSCP protocol corruption occurs.
4128             */
4129            public synchronized void
4130            addDbInstrument(String dbDir, String filePath, int instrIndex)
4131                                            throws IOException, LSException, LscpException {
4132                    
4133                    addDbInstrument(dbDir, filePath, instrIndex, false);
4134            }
4135            
4136            /**
4137             * Adds the specified instrument to the specified instruments database directory.
4138             * @param dbDir The absolute path name of the database directory in which the
4139             * specified instrument will be added.
4140             * @param filePath The absolute path name of the instrument file.
4141             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4142             * @param background If <code>true</code>, the scan will be done
4143             * in background and this method may return before the job is finished.
4144             * @return If <code>background</code> is <code>true</code>, the ID
4145             * of the scan job.
4146             * @throws IOException If some I/O error occurs.
4147             * @throws LSException If the operation failed.
4148             * @throws LscpException If LSCP protocol corruption occurs.
4149             * @see #addInstrumentsDbListener
4150             */
4151            public synchronized int
4152            addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4153                                            throws IOException, LSException, LscpException {
4154                    
4155                    verifyConnection();
4156                    String s = "ADD DB_INSTRUMENTS";
4157                    if(background) s += " NON_MODAL";
4158                    s += " '" + dbDir + "' '" + filePath + "' ";
4159                    out.writeLine(s + String.valueOf(instrIndex));
4160                    if(getPrintOnlyMode()) return -1;
4161                    
4162                    ResultSet rs = getEmptyResultSet();
4163                    return rs.getIndex();
4164            }
4165            
4166            /**
4167             * Adds the instruments in the specified file to the specified
4168             * instruments database directory.
4169             * @param dbDir The absolute path name of the database directory
4170             * in which the the supported instruments will be added.
4171             * @param filePath The absolute path name of the file to scan for instruments.
4172             * @throws IOException If some I/O error occurs.
4173             * @throws LSException If the operation failed.
4174             * @throws LscpException If LSCP protocol corruption occurs.
4175             */
4176            public synchronized void
4177            addDbInstruments(String dbDir, String filePath)
4178                                            throws IOException, LSException, LscpException {
4179                    
4180                    addDbInstruments(dbDir, filePath, false);
4181            }
4182            
4183            /**
4184             * Adds the instruments in the specified file to the specified
4185             * instruments database directory.
4186             * @param dbDir The absolute path name of the database directory
4187             * in which the the supported instruments will be added.
4188             * @param filePath The absolute path name of the file to scan for instruments.
4189             * @param background If <code>true</code>, the scan will be done
4190             * in background and this method may return before the job is finished.
4191             * @return If <code>background</code> is <code>true</code>, the ID
4192             * of the scan job.
4193             * @throws IOException If some I/O error occurs.
4194             * @throws LSException If the operation failed.
4195             * @throws LscpException If LSCP protocol corruption occurs.
4196             * @see #addInstrumentsDbListener
4197             */
4198            public synchronized int
4199            addDbInstruments(String dbDir, String filePath, boolean background)
4200                                            throws IOException, LSException, LscpException {
4201                    
4202                    verifyConnection();
4203                    String s = "ADD DB_INSTRUMENTS";
4204                    if(background) s += " NON_MODAL";
4205                    out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");
4206                    if(getPrintOnlyMode()) return -1;
4207                    
4208                    ResultSet rs = getEmptyResultSet();
4209                    return rs.getIndex();
4210            }
4211            
4212            /**
4213             * Adds the instruments in the specified file system directory
4214             * to the specified instruments database directory.
4215             * @param mode Determines the scanning mode. If RECURSIVE is
4216             * specified, all supported instruments in the specified file system
4217             * direcotry will be added to the specified instruments database
4218             * directory, including the instruments in subdirectories
4219             * of the supplied directory. If NON_RECURSIVE is specified,
4220             * the instruments in the subdirectories will not be processed.
4221             * If FLAT is specified, all supported instruments in the specified
4222             * file system direcotry will be added, including the instruments in
4223             * subdirectories of the supplied directory, but the respective
4224             * subdirectory structure will not be recreated in the instruments
4225             * database and all instruments will be added directly in the
4226             * specified database directory.
4227             * @param dbDir The absolute path name of the database directory
4228             * in which the supported instruments will be added.
4229             * @param fsDir The absolute path name of the file system directory.
4230             * @throws IOException If some I/O error occurs.
4231             * @throws LSException If the operation failed.
4232             * @throws LscpException If LSCP protocol corruption occurs.
4233             */
4234            public synchronized void
4235            addDbInstruments(ScanMode mode, String dbDir, String fsDir)
4236                                            throws IOException, LSException, LscpException {
4237                    
4238                    addDbInstruments(mode, dbDir, fsDir, false);
4239            }
4240            
4241            /**
4242             * Adds the instruments in the specified file system directory
4243             * to the specified instruments database directory.
4244             * @param mode Determines the scanning mode. If RECURSIVE is
4245             * specified, all supported instruments in the specified file system
4246             * direcotry will be added to the specified instruments database
4247             * directory, including the instruments in subdirectories
4248             * of the supplied directory. If NON_RECURSIVE is specified,
4249             * the instruments in the subdirectories will not be processed.
4250             * If FLAT is specified, all supported instruments in the specified
4251             * file system direcotry will be added, including the instruments in
4252             * subdirectories of the supplied directory, but the respective
4253             * subdirectory structure will not be recreated in the instruments
4254             * database and all instruments will be added directly in the
4255             * specified database directory.
4256             * @param dbDir The absolute path name of the database directory
4257             * in which the supported instruments will be added.
4258             * @param fsDir The absolute path name of the file system directory.
4259             * @param background If <code>true</code>, the scan will be done
4260             * in background and this method may return before the job is finished.
4261             * @return If <code>background</code> is <code>true</code>, the ID
4262             * of the scan job.
4263             * @throws IOException If some I/O error occurs.
4264             * @throws LSException If the operation failed.
4265             * @throws LscpException If LSCP protocol corruption occurs.
4266             * @see #addInstrumentsDbListener
4267             */
4268            public synchronized int
4269            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
4270                                            throws IOException, LSException, LscpException {
4271                    
4272                    verifyConnection();
4273                    StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
4274                    if(background) sb.append(" NON_MODAL");
4275                    
4276                    switch(mode) {
4277                            case RECURSIVE:
4278                                    sb.append(" RECURSIVE");
4279                                    break;
4280                            case NON_RECURSIVE:
4281                                    sb.append(" NON_RECURSIVE");
4282                                    break;
4283                            case FLAT:
4284                                    sb.append(" FLAT");
4285                                    break;
4286                    }
4287                    
4288                    sb.append(" '").append(dbDir).append("' '");
4289                    sb.append(fsDir).append("'");
4290                    out.writeLine(sb.toString());
4291                    if(getPrintOnlyMode()) return -1;
4292                    
4293                    ResultSet rs = getEmptyResultSet();
4294                    return rs.getIndex();
4295            }
4296            
4297            /**
4298             * Removes the specified instrument from the instruments database.
4299             * @param instr The absolute path name of the instrument to remove.
4300             * @throws IOException If some I/O error occurs.
4301             * @throws LscpException If LSCP protocol corruption occurs.
4302             * @throws LSException If the removing of the instrument failed.
4303             */
4304            public synchronized void
4305            removeDbInstrument(String instr) throws IOException, LscpException, LSException {
4306                    
4307                    verifyConnection();
4308                    out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");
4309                    if(getPrintOnlyMode()) return;
4310                    
4311                    ResultSet rs = getEmptyResultSet();
4312            }
4313            
4314            /**
4315             * Removes the specified instruments from the instruments database.
4316             * @param instrs The absolute path names of the instruments to remove.
4317             * @throws IOException If some I/O error occurs.
4318             * @throws LscpException If LSCP protocol corruption occurs.
4319             * @throws LSException If the removing of the instruments failed.
4320             */
4321            public synchronized void
4322            removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
4323                    verifyConnection();
4324                    for(String s : instrs) {
4325                            out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");
4326                    }
4327                    if(getPrintOnlyMode()) return;
4328                    
4329                    getEmptyResultSets(instrs.length, "Client.instrDeletionFailed!");
4330            }
4331            
4332            /**
4333             * Gets the number of instruments in the specified directory.
4334             * @return The current number of instruments in the specified directory.
4335             * @param dir The absolute path name of the directory.
4336             * @throws IOException If some I/O error occurs.
4337             * @throws LscpException If LSCP protocol corruption occurs.
4338             * @throws LSException If some other error occurs.
4339             */
4340            public synchronized int
4341            getDbInstrumentCount(String dir) throws IOException, LscpException, LSException {
4342                    return getDbInstrumentCount(dir, false);
4343            }
4344            
4345            /**
4346             * Gets the number of instruments in the specified directory.
4347             * @return The current number of instruments in the specified directory.
4348             * @param dir The absolute path name of the directory.
4349             * @param recursive If <code>true</code>, the number of all instruments
4350             * in the specified subtree will be returned.
4351             * @throws IOException If some I/O error occurs.
4352             * @throws LscpException If LSCP protocol corruption occurs.
4353             * @throws LSException If some other error occurs.
4354             */
4355            public synchronized int
4356            getDbInstrumentCount(String dir, boolean recursive)
4357                                    throws IOException, LscpException, LSException {
4358                    
4359                    verifyConnection();
4360                    String s;
4361                    if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
4362                    else s = "GET DB_INSTRUMENTS '";
4363                    out.writeLine(s + dir + "'");
4364                    if(getPrintOnlyMode()) return -1;
4365                    
4366                    s = getSingleLineResultSet().getResult();
4367                    return parseInt(s);
4368            }
4369            
4370            /**
4371             * Gets the list of instruments in the specified directory.
4372             * @param dir The absolute path name of the directory.
4373             * @return A <code>String</code> array providing the names of
4374             * all instruments in the specified directory.
4375             * @throws IOException If some I/O error occurs.
4376             * @throws LscpException If LSCP protocol corruption occurs.
4377             * @throws LSException If the specified path name is invalid.
4378             */
4379            public synchronized String[]
4380            getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
4381                    verifyConnection();
4382                    out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");
4383                    if(getPrintOnlyMode()) return null;
4384                    
4385                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
4386                    for(int i = 0; i < names.length; i++) {
4387                            names[i] = toNonEscapedString(names[i]);
4388                    }
4389                    return names;
4390            }
4391            
4392            /**
4393             * Gets information about the specified instrument.
4394             * @param instr The absolute path name of the instrument.
4395             * @return A <code>DbInstrumentInfo</code> instance providing information
4396             * about the specified instrument.
4397             * @throws IOException If some I/O error occurs.
4398             * @throws LscpException If LSCP protocol corruption occurs.
4399             * @throws LSException If the specified instrument is not found.
4400             */
4401            public synchronized DbInstrumentInfo
4402            getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
4403                    verifyConnection();
4404                    out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");
4405                    if(getPrintOnlyMode()) return null;
4406                    
4407                    ResultSet rs = getMultiLineResultSet();
4408                    DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());
4409                    String s = getParentDirectory(instr);
4410                    if(s != null) info.setDirectoryPath(s);
4411                    s = getFileName(instr);
4412                    if(s != null) info.setName(toNonEscapedFileName(s));
4413                    
4414                    return info;
4415            }
4416            
4417            /**
4418             * Gets the list of instruments in the specified directory.
4419             * @param dir The absolute path name of the directory.
4420             * @return A <code>DbInstrumentInfo</code> array providing
4421             * information about all instruments in the specified directory.
4422             * @throws IOException If some I/O error occurs.
4423             * @throws LscpException If LSCP protocol corruption occurs.
4424             * @throws LSException If the specified path name is invalid.
4425             */
4426            public synchronized DbInstrumentInfo[]
4427            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4428                    String[] instrS = getDbInstrumentNames(dir);
4429                    if(!hasEndingFileSeparator(dir)) dir += "/";
4430                    
4431                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4432                    for(int i = 0; i < instrS.length; i++) {
4433                            infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i]));
4434                    }
4435                    return infoS;
4436            }
4437            
4438            /**
4439             * Gets the list of instruments in the specified directory.
4440             * @param dir The absolute path name of the directory.
4441             * @return A <code>DbInstrumentInfo</code> array providing
4442             * information about all instruments in the specified directory.
4443             * @throws IOException If some I/O error occurs.
4444             * @throws LscpException If LSCP protocol corruption occurs.
4445             * @throws LSException If the specified path name is invalid.
4446             *
4447            public synchronized DbInstrumentInfo[]
4448            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4449                    String[] instrS = getDbInstrumentNames(dir);
4450                    if(instrS.length == 0) return new DbInstrumentInfo[0];
4451                    
4452                    if(dir.charAt(dir.length() - 1) != '/') dir += "/";
4453                    
4454                    for(int i = 0; i < instrS.length; i++) {
4455                            out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");
4456                    }
4457                    
4458                    if(getPrintOnlyMode()) return null;
4459                    
4460                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
4461                    StringBuffer sb = new StringBuffer();
4462                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4463                    for(int i = 0; i < instrS.length; i++) {
4464                            try {
4465                                    ResultSet rs = getMultiLineResultSet();
4466                                    infoS[i] = new DbInstrumentInfo(rs.getMultiLineResult());
4467                                    infoS[i].setName(instrS[i]);
4468                                    infoS[i].setDirectoryPath(dir);
4469                            } catch (SocketTimeoutException e) {
4470                                    getLogger().log(Level.FINE, e.getMessage(), e);
4471                                    sb.append(e.getMessage()).append("\n");
4472                                    break;
4473                            } catch (Exception e) {
4474                                    getLogger().log(Level.FINE, e.getMessage(), e);
4475                                    sb.append(e.getMessage()).append("\n");
4476                            }
4477                    }
4478                    
4479                    String details = sb.toString();
4480                    if(details.length() > 0) {
4481                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
4482                            throw new LSException(0, err, details);
4483                    }
4484                    
4485                    return infoS;
4486            }*/
4487            
4488            /**
4489             * Renames the specified instrument.
4490             * @param instr The absolute path name of the instrument to rename.
4491             * @param name The new name for the instrument.
4492             * @throws IOException If some I/O error occurs.
4493             * @throws LSException If the renaming of the instrument failed.
4494             * @throws LscpException If LSCP protocol corruption occurs.
4495             */
4496            public synchronized void
4497            renameDbInstrument(String instr, String name)
4498                                    throws IOException, LSException, LscpException {
4499                    
4500                    verifyConnection();
4501                    name = toEscapedString(name);
4502                    out.writeLine("SET DB_INSTRUMENT NAME '" + instr + "' '" + name + "'");
4503                    if(getPrintOnlyMode()) return;
4504                    
4505                    ResultSet rs = getEmptyResultSet();
4506            }
4507            
4508            /**
4509             * Moves the specified instrument into the specified location.
4510             * @param instr The absolute path name of the instrument to move.
4511             * @param dst The directory where the specified instrument will be moved to.
4512             * @throws IOException If some I/O error occurs.
4513             * @throws LSException If the operation failed.
4514             * @throws LscpException If LSCP protocol corruption occurs.
4515             */
4516            public synchronized void
4517            moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4518                    verifyConnection();
4519                    out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4520                    if(getPrintOnlyMode()) return;
4521                    
4522                    ResultSet rs = getEmptyResultSet();
4523            }
4524            
4525            /**
4526             * Moves the specified instruments into the specified location.
4527             * @param instrs The absolute path names of the instruments to move.
4528             * @param dst The directory where the specified instruments will be moved to.
4529             * @throws IOException If some I/O error occurs.
4530             * @throws LSException If the operation failed.
4531             * @throws LscpException If LSCP protocol corruption occurs.
4532             */
4533            public synchronized void
4534            moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4535                    verifyConnection();
4536                    for(String s : instrs) {
4537                            out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");
4538                    }
4539                    if(getPrintOnlyMode()) return;
4540                    
4541                    getEmptyResultSets(instrs.length, "Client.instrMovingFailed!");
4542            }
4543            
4544            /**
4545             * Copies the specified instrument into the specified location.
4546             * @param instr The absolute path name of the instrument to copy.
4547             * @param dst The directory where the specified instrument will be copied to.
4548             * @throws IOException If some I/O error occurs.
4549             * @throws LSException If the operation failed.
4550             * @throws LscpException If LSCP protocol corruption occurs.
4551             */
4552            public synchronized void
4553            copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4554                    verifyConnection();
4555                    out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4556                    if(getPrintOnlyMode()) return;
4557                    
4558                    ResultSet rs = getEmptyResultSet();
4559            }
4560            
4561            /**
4562             * Copies the specified instruments into the specified location.
4563             * @param instrs The absolute path name of the instruments to copy.
4564             * @param dst The directory where the specified instruments will be copied to.
4565             * @throws IOException If some I/O error occurs.
4566             * @throws LSException If the operation failed.
4567             * @throws LscpException If LSCP protocol corruption occurs.
4568             */
4569            public synchronized void
4570            copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4571                    verifyConnection();
4572                    for(String s : instrs) {
4573                            out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");
4574                    }
4575                    if(getPrintOnlyMode()) return;
4576                    
4577                    getEmptyResultSets(instrs.length, "Client.instrCopyingFailed!");
4578            }
4579            
4580            /**
4581             * Changes the description of the specified instrument.
4582             * @param instr The absolute path name of the instrument.
4583             * @param desc The new description for the instrument.
4584             * @throws IOException If some I/O error occurs.
4585             * @throws LSException If failed to change the description.
4586             * @throws LscpException If LSCP protocol corruption occurs.
4587             */
4588            public synchronized void
4589            setDbInstrumentDescription(String instr, String desc)
4590                                    throws IOException, LSException, LscpException {
4591                    
4592                    verifyConnection();
4593                    desc = toEscapedString(desc);
4594                    out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + instr + "' '" + desc + "'");
4595                    if(getPrintOnlyMode()) return;
4596                    
4597                    ResultSet rs = getEmptyResultSet();
4598            }
4599            
4600            /**
4601             * Finds all directories in the specified directory
4602             * that corresponds to the specified search criterias.
4603             * @param dir The absolute path name of the directory to search.
4604             * @param query Provides the search criterias.
4605             * @return A <code>DbDirectoryInfo</code> array providing
4606             * information about all directories that are found in the specified directory.
4607             * @throws IOException If some I/O error occurs.
4608             * @throws LscpException If LSCP protocol corruption occurs.
4609             * @throws LSException If the specified path name is invalid.
4610             */
4611            public synchronized DbDirectoryInfo[]
4612            findDbDirectories(String dir, DbSearchQuery query)
4613                                    throws IOException, LscpException, LSException {
4614                    
4615                    return findDbDirectories(dir, query, false);
4616            }
4617            
4618            /**
4619             * Finds all directories in the specified directory
4620             * that corresponds to the specified search criterias.
4621             * @param dir The absolute path name of the directory to search.
4622             * @param query Provides the search criterias.
4623             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4624             * @return A <code>DbDirectoryInfo</code> array providing
4625             * information about all directories that are found in the specified directory.
4626             * @throws IOException If some I/O error occurs.
4627             * @throws LscpException If LSCP protocol corruption occurs.
4628             * @throws LSException If the specified path name is invalid.
4629             */
4630            public synchronized DbDirectoryInfo[]
4631            findDbDirectories(String dir, DbSearchQuery query, boolean nonRecursive)
4632                                    throws IOException, LscpException, LSException {
4633                    
4634                    verifyConnection();
4635                    StringBuffer sb = new StringBuffer();
4636                    sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
4637                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4638                    sb.append(" '").append(dir).append("'");
4639                    
4640                    if(query.name != null && query.name.length() > 0) {
4641                            sb.append(" NAME='").append(toEscapedString(query.name)).append("'");
4642                    }
4643                    
4644                    String s = query.getCreatedAfter();
4645                    String s2 = query.getCreatedBefore();
4646                    if(s != null || s2 != null) {
4647                            sb.append(" CREATED='");
4648                            if(s != null) sb.append(s);
4649                            sb.append("..");
4650                            if(s2 != null) sb.append(s2);
4651                            sb.append("'");
4652                    }
4653                    
4654                    s = query.getModifiedAfter();
4655                    s2 = query.getModifiedBefore();
4656                    if(s != null || s2 != null) {
4657                            sb.append(" MODIFIED='");
4658                            if(s != null) sb.append(s);
4659                            sb.append("..");
4660                            if(s2 != null) sb.append(s2);
4661                            sb.append("'");
4662                    }
4663                    
4664                    if(query.description != null && query.description.length() > 0) {
4665                            sb.append(" DESCRIPTION='");
4666                            sb.append(toEscapedString(query.description)).append("'");
4667                    }
4668                    
4669                    out.writeLine(sb.toString());
4670                    if(getPrintOnlyMode()) return null;
4671                    
4672                    String[] dirS = parseEscapedStringList(getSingleLineResultSet().getResult());
4673                    
4674                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4675                    for(int i = 0; i < dirS.length; i++) {
4676                            infoS[i] = getDbDirectoryInfo(dirS[i]);
4677                    }
4678                    return infoS;
4679            }
4680            
4681            /**
4682             * Finds all instruments in the specified directory
4683             * that corresponds to the specified search criterias.
4684             * @param dir The absolute path name of the directory to search.
4685             * @param query Provides the search criterias.
4686             * @return A <code>DbInstrumentInfo</code> array providing
4687             * information about all instruments that are found in the specified directory.
4688             * @throws IOException If some I/O error occurs.
4689             * @throws LscpException If LSCP protocol corruption occurs.
4690             * @throws LSException If the specified path name is invalid.
4691             */
4692            public synchronized DbInstrumentInfo[]
4693            findDbInstruments(String dir, DbSearchQuery query)
4694                                    throws IOException, LscpException, LSException {
4695                    
4696                    return findDbInstruments(dir, query, false);
4697            }
4698            
4699            /**
4700             * Finds all instruments in the specified directory
4701             * that corresponds to the specified search criterias.
4702             * @param dir The absolute path name of the directory to search.
4703             * @param query Provides the search criterias.
4704             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4705             * @return A <code>DbInstrumentInfo</code> array providing
4706             * information about all instruments that are found in the specified directory.
4707             * @throws IOException If some I/O error occurs.
4708             * @throws LscpException If LSCP protocol corruption occurs.
4709             * @throws LSException If the specified path name is invalid.
4710             */
4711            public synchronized DbInstrumentInfo[]
4712            findDbInstruments(String dir, DbSearchQuery query, boolean nonRecursive)
4713                                    throws IOException, LscpException, LSException {
4714                    
4715                    verifyConnection();
4716                    StringBuffer sb = new StringBuffer();
4717                    sb.append("FIND DB_INSTRUMENTS");
4718                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4719                    sb.append(" '").append(dir).append("'");
4720                    
4721                    if(query.name != null && query.name.length() > 0) {
4722                            sb.append(" NAME='").append(toEscapedString(query.name)).append("'");
4723                    }
4724                    
4725                    if(query.formatFamilies.size() > 0) {
4726                            sb.append(" FORMAT_FAMILIES='").append(query.formatFamilies.get(0));
4727                            for(int i = 1; i < query.formatFamilies.size(); i++) {
4728                                    sb.append(',').append(query.formatFamilies.get(i));
4729                            }
4730                            sb.append("'");
4731                    }
4732                    
4733                    if(query.minSize != -1 || query.maxSize != -1) {
4734                            sb.append(" SIZE='");
4735                            if(query.minSize != -1) sb.append(query.minSize);
4736                            sb.append("..");
4737                            if(query.maxSize != -1) sb.append(query.maxSize);
4738                            sb.append("'");
4739                    }
4740                    
4741                    String s = query.getCreatedAfter();
4742                    String s2 = query.getCreatedBefore();
4743                    if(s != null || s2 != null) {
4744                            sb.append(" CREATED='");
4745                            if(s != null) sb.append(s);
4746                            sb.append("..");
4747                            if(s2 != null) sb.append(s2);
4748                            sb.append("'");
4749                    }
4750                    
4751                    s = query.getModifiedAfter();
4752                    s2 = query.getModifiedBefore();
4753                    if(s != null || s2 != null) {
4754                            sb.append(" MODIFIED='");
4755                            if(s != null) sb.append(s);
4756                            sb.append("..");
4757                            if(s2 != null) sb.append(s2);
4758                            sb.append("'");
4759                    }
4760                    
4761                    if(query.description != null && query.description.length() > 0) {
4762                            sb.append(" DESCRIPTION='");
4763                            sb.append(toEscapedString(query.description)).append("'");
4764                    }
4765                    
4766                    if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
4767                            sb.append(" IS_DRUM=");
4768                            if(query.instrumentType == DbSearchQuery.InstrumentType.DRUM) {
4769                                    sb.append("'true'");
4770                            } else {
4771                                    sb.append("'false'");
4772                            }
4773                    }
4774                    
4775                    if(query.product != null && query.product.length() > 0) {
4776                            sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'");
4777                    }
4778                    
4779                    if(query.artists != null && query.artists.length() > 0) {
4780                            sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'");
4781                    }
4782                    
4783                    if(query.keywords != null && query.keywords.length() > 0) {
4784                            sb.append(" KEYWORDS='");
4785                            sb.append(toEscapedString(query.keywords)).append("'");
4786                    }
4787                    
4788                    out.writeLine(sb.toString());
4789                    if(getPrintOnlyMode()) return null;
4790                    
4791                    String[] instrS = parseEscapedStringList(getSingleLineResultSet().getResult());
4792                    
4793                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4794                    for(int i = 0; i < instrS.length; i++) {
4795                            infoS[i] = getDbInstrumentInfo(instrS[i]);
4796                    }
4797                    return infoS;
4798            }
4799            
4800            /**
4801             * Gets status information about the specified job.
4802             * @param jobId The ID of the job.
4803             * @return A <code>ScanJobInfo</code> instance providing information
4804             * about the specified job.
4805             * @throws IOException If some I/O error occurs.
4806             * @throws LscpException If LSCP protocol corruption occurs.
4807             * @throws LSException If the specified job is not found.
4808             */
4809            public synchronized ScanJobInfo
4810            getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
4811                    verifyConnection();
4812                    out.writeLine("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId));
4813                    if(getPrintOnlyMode()) return null;
4814                    
4815                    ResultSet rs = getMultiLineResultSet();
4816                    ScanJobInfo info = new ScanJobInfo(rs.getMultiLineResult());
4817                    
4818                    return info;
4819            }
4820            
4821            /**
4822             * Removes all instruments and directories and re-creates
4823             * the instruments database structure.
4824             * @throws IOException If some I/O error occurs.
4825             * @throws LscpException If LSCP protocol corruption occurs.
4826             * @throws LSException If the formatting of the instruments database failed.
4827             */
4828            public synchronized void
4829            formatInstrumentsDb() throws IOException, LscpException, LSException {
4830                    verifyConnection();
4831                    out.writeLine("FORMAT INSTRUMENTS_DB");
4832                    if(getPrintOnlyMode()) return;
4833                    
4834                    ResultSet rs = getEmptyResultSet();
4835            }
4836            
4837            /**
4838           * Resets the specified sampler channel.           * Resets the specified sampler channel.
4839           *           *
4840           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
# Line 3693  public class Client { Line 4960  public class Client {
4960          }          }
4961                    
4962          /**          /**
4963             * Gets the number of instruments in the specified instrument file.
4964             * @param filename The absolute path name of the instrument file.
4965             * @return The number of instruments in the specified instrument file.
4966             * @throws IOException If some I/O error occurs.
4967             * @throws LscpException If LSCP protocol corruption occurs.
4968             * @throws LSException If the file is not found, or other error occur.
4969             */
4970            public synchronized int
4971            getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {
4972                    verifyConnection();
4973                    out.writeLine("GET FILE INSTRUMENTS '" + filename +"'");
4974                    if(getPrintOnlyMode()) return -1;
4975                    
4976                    String s = getSingleLineResultSet().getResult();
4977                    return parseInt(s);
4978            }
4979            
4980            /**
4981             * Gets information about the instrument with index
4982             * <code>instrIdx</code> in the specified instrument file.
4983             * @param filename The absolute path name of the instrument file.
4984             * @param instrIdx The index of the instrument in the specified instrument file.
4985             * @throws IOException If some I/O error occurs.
4986             * @throws LscpException If LSCP protocol corruption occurs.
4987             * @throws LSException If failed to retrieve information.
4988             */
4989            public synchronized Instrument
4990            getFileInstrumentInfo(String filename, int instrIdx)
4991                                    throws IOException, LscpException, LSException {
4992                    
4993                    verifyConnection();
4994                    out.writeLine("GET FILE INSTRUMENT INFO '" + filename + "' " + String.valueOf(instrIdx));
4995                    if(getPrintOnlyMode()) return null;
4996                    
4997                    ResultSet rs = getMultiLineResultSet();
4998                    Instrument instr = new FileInstrument(rs.getMultiLineResult()) { };
4999                    
5000                    return instr;
5001            }
5002            
5003            /**
5004             * Gets the list of instruments in the specified instrument file.
5005             * @param filename The absolute path name of the instrument file.
5006             * @return An <code>Instrument</code> array providing
5007             * information about all instruments in the specified instrument file.
5008             * @throws IOException If some I/O error occurs.
5009             * @throws LscpException If LSCP protocol corruption occurs.
5010             * @throws LSException If the specified file name is invalid.
5011             */
5012            public synchronized Instrument[]
5013            getFileInstruments(String filename) throws IOException, LscpException, LSException {
5014                    int l = getFileInstrumentCount(filename);
5015                    if(l < 0) return null;
5016                    Instrument[] instrS = new FileInstrument[l];
5017                    
5018                    for(int i = 0; i < instrS.length; i++) {
5019                            instrS[i] = getFileInstrumentInfo(filename, i);
5020                    }
5021                    return instrS;
5022            }
5023            
5024            private static class FileInstrument extends AbstractInstrument {
5025                    FileInstrument(String[] resultSet) throws LscpException {
5026                            super(resultSet);
5027                    }
5028                    
5029                    public String
5030                    getEngine() {
5031                            // TODO: engine lookup?
5032                            return getFormatFamily();
5033                    }
5034                    
5035                    public boolean
5036                    parse(String s) throws LscpException {
5037                            if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;
5038                            return super.parse(s);
5039                    }
5040            }
5041            
5042            private void
5043            getEmptyResultSets(int count, String err) throws LSException {
5044                    StringBuffer sb = new StringBuffer();
5045                    for(int i = 0; i < count; i++) {
5046                            try { getEmptyResultSet(); }
5047                            catch (SocketTimeoutException e) {
5048                                    getLogger().log(Level.FINE, e.getMessage(), e);
5049                                    sb.append(e.getMessage()).append("\n");
5050                                    break;
5051                            } catch (Exception e) {
5052                                    getLogger().log(Level.FINE, e.getMessage(), e);
5053                                    sb.append(e.getMessage()).append("\n");
5054                            }
5055                    }
5056                    
5057                    String details = sb.toString();
5058                    if(details.length() > 0) {
5059                            String s = LscpI18n.getLogMsg(err);
5060                            throw new LSException(0, s, details);
5061                    }
5062            }
5063            
5064            /**
5065           * Returns the logger for this library.           * Returns the logger for this library.
5066           * @return The logger for this library.           * @return The logger for this library.
5067           */           */

Legend:
Removed from v.1139  
changed lines
  Added in v.1539

  ViewVC Help
Powered by ViewVC