Commits

Anonymous committed a942d18

Made main launch tab functional.

  • Participants
  • Parent commits 89202c3

Comments (0)

Files changed (6)

File src/org/lispdev/swank/AvailablePortFinder.java

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+// package org.apache.mina.util;
+
+package org.lispdev.swank;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Finds currently available server ports.
+ *
+ * @author The Apache MINA Project (dev@mina.apache.org)
+ * @version $Rev: 576217 $
+ * @see <a href="http://www.iana.org/assignments/port-numbers">IANA.org</a>
+ */
+public class AvailablePortFinder
+{
+  /**
+   * The minimum number of server port number.
+   */
+  public static final int MIN_PORT_NUMBER = 1;
+
+  /**
+   * The maximum number of server port number.
+   */
+  public static final int MAX_PORT_NUMBER = 49151;
+
+  /**
+   * Creates a new instance.
+   */
+  private AvailablePortFinder()
+  {}
+
+  /**
+   * Returns the {@link Set} of currently available port numbers (
+   * {@link Integer}). This method is identical to
+   * <code>getAvailablePorts(MIN_PORT_NUMBER, MAX_PORT_NUMBER)</code>.
+   *
+   * WARNING: this can take a very long time.
+   */
+  public static Set<Integer> getAvailablePorts()
+  {
+    return getAvailablePorts(MIN_PORT_NUMBER, MAX_PORT_NUMBER);
+  }
+
+  /**
+   * Gets the next available port starting at the lowest port number.
+   *
+   * @throws NoSuchElementException
+   *           if there are no ports available
+   */
+  public static int getNextAvailable()
+  {
+    return getNextAvailable(MIN_PORT_NUMBER);
+  }
+
+  /**
+   * Gets the next available port starting at a port.
+   *
+   * @param fromPort
+   *          the port to scan for availability
+   * @throws NoSuchElementException
+   *           if there are no ports available
+   */
+  public static int getNextAvailable(int fromPort)
+  {
+    if( fromPort < MIN_PORT_NUMBER || fromPort > MAX_PORT_NUMBER )
+    {
+      throw new IllegalArgumentException("Invalid start port: " + fromPort);
+    }
+
+    for(int i = fromPort; i <= MAX_PORT_NUMBER; i++)
+    {
+      if( available(i) )
+      {
+        return i;
+      }
+    }
+
+    throw new NoSuchElementException("Could not find an available port "
+        + "above " + fromPort);
+  }
+
+  /**
+   * Checks to see if a specific port is available.
+   *
+   * @param port
+   *          the port to check for availability
+   */
+  public static boolean available(int port)
+  {
+    if( port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER )
+    {
+      throw new IllegalArgumentException("Invalid start port: " + port);
+    }
+
+    ServerSocket ss = null;
+    DatagramSocket ds = null;
+    try
+    {
+      ss = new ServerSocket(port);
+      ss.setReuseAddress(true);
+      ds = new DatagramSocket(port);
+      ds.setReuseAddress(true);
+      return true;
+    }
+    catch(IOException e)
+    {}
+    finally
+    {
+      if( ds != null )
+      {
+        ds.close();
+      }
+
+      if( ss != null )
+      {
+        try
+        {
+          ss.close();
+        }
+        catch(IOException e)
+        {
+          /* should not be thrown */
+        }
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Returns the {@link Set} of currently avaliable port numbers (
+   * {@link Integer}) between the specified port range.
+   *
+   * @throws IllegalArgumentException
+   *           if port range is not between {@link #MIN_PORT_NUMBER} and
+   *           {@link #MAX_PORT_NUMBER} or <code>fromPort</code> if greater than
+   *           <code>toPort</code>.
+   */
+  public static Set<Integer> getAvailablePorts(int fromPort, int toPort)
+  {
+    if( fromPort < MIN_PORT_NUMBER || toPort > MAX_PORT_NUMBER
+        || fromPort > toPort )
+    {
+      throw new IllegalArgumentException("Invalid port range: " + fromPort
+          + " ~ " + toPort);
+    }
+
+    Set<Integer> result = new TreeSet<Integer>();
+
+    for(int i = fromPort; i <= toPort; i++)
+    {
+      ServerSocket s = null;
+
+      try
+      {
+        s = new ServerSocket(i);
+        result.add(new Integer(i));
+      }
+      catch(IOException e)
+      {}
+      finally
+      {
+        if( s != null )
+        {
+          try
+          {
+            s.close();
+          }
+          catch(IOException e)
+          {
+            /* should not be thrown */
+          }
+        }
+      }
+    }
+
+    return result;
+  }
+}

File src/org/lispdev/swank/BaseLocalLispLaunchDelegate.java

   public final static String ID =
     "org.lispdev.swank.baseLocalLaunchConfigurationType";
   public final static String ATTR_EXE = "path-to-executable-string";
+  public final static String ATTR_SWANK = "path-to-swank-loader.lisp";
   public final static String ATTR_CMD_PARAMS = "command-line-params-list";
-  public final static String ATTR_ENV = "environment-variables-map";
+  public final static String ATTR_ENV = ILaunchManager.ATTR_ENVIRONMENT_VARIABLES;
   public final static String ATTR_PORT = "port-int";
   public final static String ATTR_EXT = "lisp-extensions-path-string";
   //for now to folder containing lisp-extensions folder: see basicStartup
     {
       Log.abort("File " + exe + " is not executable", null);
     }
+    final String swankDir = config.getAttribute(ATTR_SWANK, "");
+    File swankf = new File(swankDir,"swank-loader.lisp");
+    if( !swankf.exists() )
+    {
+      Log.abort("Swank was not found in folder "+swankDir, null);
+    }
+    final int port = config.getAttribute(ATTR_PORT, -1);
+    if( port < AvailablePortFinder.MIN_PORT_NUMBER
+        || port > AvailablePortFinder.MAX_PORT_NUMBER )
+    {
+      Log.abort("Port is outside of available range", null);
+    }
     final LocalLispImplementation implem =
-      new LocalLispImplementation(exe,
+      new LocalLispImplementation(exe, swankDir,
           config.getAttribute(ATTR_CMD_PARAMS, new ArrayList()),
           config.getAttribute(ATTR_ENV, new HashMap()),
-          config.getAttribute(ATTR_PORT, 4005));
+          port);
     final String ext = config.getAttribute(ATTR_EXT, "");
     final File extf = new File(ext);
     if( !extf.isDirectory() )
     {
       Log.abort("Extensions directory "+ext+" does not exist", null);
     }
-    final SwankInterface s = new SwankInterface(ext,4005,implem,r);
+    final SwankInterface s = new SwankInterface(ext,implem,r);
 
     LispProcess p = new LispProcess(launch, "swank", null, s);
     launch.addProcess(p);
     return p;
   }
 
-
   @Override
   public void launch(ILaunchConfiguration configuration, String mode,
       ILaunch launch, IProgressMonitor monitor) throws CoreException

File src/org/lispdev/swank/LispImplementation.java

   // Probably lisp implementation specific - tested with SBCL
   protected String fatalError = "fatal error";
 
+  protected final int port;
+
+  public LispImplementation(int port)
+  {
+    this.port = port;
+  }
+
+  public int getPort()
+  {
+    return port;
+  }
+
   /**
    * @return string (case is ignored) which signals to lispdev that
    * lisp process has died, so need to cleanup and close connection

File src/org/lispdev/swank/LocalLispImplementation.java

   private final String[] commandLine;
   @SuppressWarnings("unchecked")
   private final Map env;
-  private final int port;
 
   @SuppressWarnings("unchecked")
-  public LocalLispImplementation(String exePath, List cmdParams,
+  public LocalLispImplementation(String exePath, String swankDir, List cmdParams,
       Map env, int port)
   {
-    commandLine = new String[1+cmdParams.size()];
+    super(port);
+    commandLine = new String[3+cmdParams.size()];
     commandLine[0] = exePath;
+    commandLine[1] = "--load";
+    commandLine[2] = (swankDir + File.separator + "swank-loader.lisp")
+        .replace(File.separator+File.separator, File.separator);
     for( int i = 0; i < cmdParams.size(); ++i )
     {
-      commandLine[i+1] = String.valueOf(cmdParams.get(i));
+      commandLine[i+3] = String.valueOf(cmdParams.get(i));
     }
     this.env = (env == null ? new HashMap<String,String>() : env);
-    this.port = port;
   }
 
   @Override
         commandLine[0]+" does not exist");
     Assert.isLegal(cmd.canExecute(), "File " + commandLine[0] +
         " is not executable");
+    File sw = new File(commandLine[2]);
+    Assert.isLegal(sw.exists(), "Swank loader "
+        + commandLine[2] + " does not exist");
     final ProcessBuilder pb = new ProcessBuilder(commandLine);
     for( Object k : env.keySet() )
     {

File src/org/lispdev/swank/SwankInterface.java

  */
 public class SwankInterface implements ISwank
 {
-  public SwankInterface(String extDir, int port, LispImplementation implem,
+  public SwankInterface(String extDir, LispImplementation implem,
       IRunnableDriver r)
   {
     this.extDir = extDir;
-    swank = new SwankInterfaceCore(r, implem, port);
+    swank = new SwankInterfaceCore(r, implem,
+        (implem == null?-1:implem.getPort()));
   }
 
   protected final SwankInterfaceCore swank;

File src/org/lispdev/swank/SwankInterfaceTest.java

 
   public SwankInterfaceTest()
   {
-    super(null,0,null,null);
+    super(null,null,null);
   }
 
   private static SwankInterface startSwank()
       ILaunchConfigurationWorkingCopy wc = cfg.getWorkingCopy();
       wc.setAttribute(BaseLocalLispLaunchDelegate.ATTR_EXE,
           "D:\\projects\\lispdev\\ws\\org.lispdev.swank\\sbcl\\sbcl.exe");
-      wc.setAttribute(BaseLocalLispLaunchDelegate.ATTR_CMD_PARAMS,
-          Arrays.asList("--load",
-              "D:\\projects\\lispdev\\ws\\org.lispdev.swank\\slime\\swank-loader.lisp"));
+      wc.setAttribute(BaseLocalLispLaunchDelegate.ATTR_SWANK,
+          "D:\\projects\\lispdev\\ws\\org.lispdev.swank\\slime\\");
       wc.setAttribute(BaseLocalLispLaunchDelegate.ATTR_ENV,
           new HashMap<String,String>()
           {private static final long serialVersionUID = 1L;