public void run() {
   try {
     IOUtils.copy(in, out);
   } catch (IOException e) {
     ErrorDialog.showDetails(e, ThrowableUtils.getStackTrace(e), "Error.socket_error");
   }
 }
  protected File promptForFile() {
    // prompt the user to pick a file
    final FileChooser fc =
        FileChooser.createFileChooser(
            window, (DirectoryConfigurer) Prefs.getGlobalPrefs().getOption(Prefs.MODULES_DIR_KEY));

    addFileFilters(fc);

    // loop until cancellation or we get an existing file
    if (fc.showOpenDialog() == FileChooser.APPROVE_OPTION) {
      lr.module = fc.getSelectedFile();
      if (lr.module != null) {
        if (lr.module.exists()) {
          final AbstractMetaData metadata = MetaDataFactory.buildMetaData(lr.module);
          if (metadata == null || !(metadata instanceof ModuleMetaData)) {
            ErrorDialog.show("Error.invalid_vassal_module", lr.module.getAbsolutePath());
            Logger.log(
                "-- Load of " + lr.module.getAbsolutePath() + " failed: Not a Vassal module");
            lr.module = null;
          }
        } else {
          lr.module = null;
        }
        // FIXME: do something to warn about nonexistant file
        //        FileNotFoundDialog.warning(window, lr.module);
      }
    }

    return lr.module;
  }
 @Override
 protected void done() {
   try {
     get();
   } catch (CancellationException e) {
     // FIXME: bug until we enable cancellation of loading
     ErrorDialog.bug(e);
   } catch (InterruptedException e) {
     ErrorDialog.bug(e);
   } catch (ExecutionException e) {
     // determine what kind of exception occurred
     final Throwable c = e.getCause();
     if (c instanceof IOException) {
       ErrorDialog.showDetails(e, ThrowableUtils.getStackTrace(e), "Error.socket_error");
     } else {
       ErrorDialog.bug(e);
     }
   } finally {
     IOUtils.closeQuietly(clientSocket);
     IOUtils.closeQuietly(serverSocket);
     children.remove(cmdC);
   }
 }
    public Object execute() {
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              theLaunchAction.setWaitCursor(false);
            }
          });

      ErrorDialog.showDetails(
          thrown,
          ThrowableUtils.getStackTrace(thrown),
          "Error.module_load_failed",
          thrown.getMessage());

      return "OK";
    }
  /**
   * Ask child processes to close.
   *
   * @return <code>true</code> iff all child processes will terminate
   */
  public static boolean shutDown() {
    ModuleManagerWindow.getInstance().toBack();

    // must synchronize when iterating over a Collections.synchronizedList()
    synchronized (children) {
      for (CommandClient child : children) {
        try {
          if ("NOK".equals(child.request(new Launcher.CloseRequest()))) {
            return false;
          }
        } catch (EOFException ignore) {
          // Normal. Child closed.
        } catch (SocketException ignore) {
          // Normal. Child closed.
        } catch (IOException e) {
          ErrorDialog.showDetails(e, ThrowableUtils.getStackTrace(e), "Error.socket_error");
        }
      }
    }

    return true;
  }
Exemple #6
0
  protected void importPiece(String className) {
    if (className == null) return;

    Object o = null;
    try {
      o =
          GameModule.getGameModule()
              .getDataArchive()
              .loadClass(className)
              .getConstructor()
              .newInstance();
    } catch (Throwable t) {
      ReflectionUtils.handleImportClassFailure(t, className);
    }

    if (o == null) return;

    if (o instanceof GamePiece) {
      availableModel.addElement((GamePiece) o);
    } else {
      ErrorDialog.show("Error.not_a_gamepiece", className);
    }
  }
    @Override
    public Void doInBackground() throws InterruptedException, IOException {
      // FIXME: this should be in an abstract method and farmed out to subclasses
      // send some basic information to the log
      if (lr.module != null) {
        Logger.log("-- Loading module file " + lr.module.getAbsolutePath());
      }

      if (lr.game != null) {
        Logger.log("-- Loading game file " + lr.game.getAbsolutePath());
      }

      if (lr.importFile != null) {
        Logger.log("-- Importing module file " + lr.importFile.getAbsolutePath());
      }
      // end FIXME

      // set default heap sizes
      int initialHeap = DEFAULT_INITIAL_HEAP;
      int maximumHeap = DEFAULT_MAXIMUM_HEAP;

      String moduleName = null;

      // FIXME: this should be in an abstract method and farmed out to subclasses,
      // rather than a case structure for each kind of thing which may be loaded.
      // find module-specific heap settings, if any
      if (lr.module != null) {
        final AbstractMetaData data = MetaDataFactory.buildMetaData(lr.module);

        if (data == null) {
          ErrorDialog.show("Error.invalid_vassal_file", lr.module.getAbsolutePath());
          setWaitCursor(false);
          return null;
        }

        if (data instanceof ModuleMetaData) {
          moduleName = ((ModuleMetaData) data).getName();

          // log the module name
          Logger.log("-- Loading module " + moduleName);

          // read module prefs
          final ReadOnlyPrefs p = new ReadOnlyPrefs(moduleName);

          // read initial heap size
          initialHeap = getHeapSize(p, GlobalOptions.INITIAL_HEAP, DEFAULT_INITIAL_HEAP);

          // read maximum heap size
          maximumHeap = getHeapSize(p, GlobalOptions.MAXIMUM_HEAP, DEFAULT_MAXIMUM_HEAP);
        }
      } else if (lr.importFile != null) {
        final Prefs p = Prefs.getGlobalPrefs();

        // read initial heap size
        initialHeap = getHeapSize(p, GlobalOptions.INITIAL_HEAP, DEFAULT_INITIAL_HEAP);

        // read maximum heap size
        maximumHeap = getHeapSize(p, GlobalOptions.MAXIMUM_HEAP, DEFAULT_MAXIMUM_HEAP);
      }
      // end FIXME

      //
      // Heap size sanity checks: fall back to failsafe heap sizes in
      // case the given initial or maximum heap is not usable.
      //

      // FIXME: The heap size messages are too nonspecific. They should
      // differientiate between loading a module and importing a module,
      // since the heap sizes are set in different places for those two
      // actions.
      // maximum heap must fit in physical RAM
      if (maximumHeap > PHYS_MEMORY && PHYS_MEMORY > 0) {
        initialHeap = FAILSAFE_INITIAL_HEAP;
        maximumHeap = FAILSAFE_MAXIMUM_HEAP;

        FutureUtils.wait(
            WarningDialog.show("Warning.maximum_heap_too_large", FAILSAFE_MAXIMUM_HEAP));
      }
      // maximum heap must be at least the failsafe size
      else if (maximumHeap < FAILSAFE_MAXIMUM_HEAP) {
        initialHeap = FAILSAFE_INITIAL_HEAP;
        maximumHeap = FAILSAFE_MAXIMUM_HEAP;

        FutureUtils.wait(
            WarningDialog.show("Warning.maximum_heap_too_small", FAILSAFE_MAXIMUM_HEAP));
      }
      // initial heap must be at least the failsafe size
      else if (initialHeap < FAILSAFE_INITIAL_HEAP) {
        initialHeap = FAILSAFE_INITIAL_HEAP;
        maximumHeap = FAILSAFE_MAXIMUM_HEAP;

        FutureUtils.wait(
            WarningDialog.show("Warning.initial_heap_too_small", FAILSAFE_INITIAL_HEAP));
      }
      // initial heap must be less than or equal to maximum heap
      else if (initialHeap > maximumHeap) {
        initialHeap = FAILSAFE_INITIAL_HEAP;
        maximumHeap = FAILSAFE_MAXIMUM_HEAP;

        FutureUtils.wait(
            WarningDialog.show("Warning.initial_heap_too_large", FAILSAFE_INITIAL_HEAP));
      }

      // create a socket for communicating which the child process
      serverSocket = new ServerSocket(0, 0, InetAddress.getByName(null));
      cmdS = new LaunchCommandServer(serverSocket);
      new Thread(cmdS, "command server " + id).start();

      // build the argument list
      final ArrayList<String> al = new ArrayList<String>();
      al.add(Info.javaBinPath);
      al.add(""); // reserved for initial heap
      al.add(""); // reserved for maximum heap
      al.add("-DVASSAL.id=" + id); // instance id

      // pass on the user's home, if it's set
      final String userHome = System.getProperty("user.home");
      if (userHome != null) al.add("-Duser.home=" + userHome);

      // set the classpath
      al.add("-cp");
      al.add(System.getProperty("java.class.path"));

      if (Info.isMacOSX()) {
        // set the MacOS X dock parameters

        // use the module name for the dock if we found a module name
        // FIXME: should "Unnamed module" be localized?
        final String d_name =
            moduleName != null && moduleName.length() > 0 ? moduleName : "Unnamed module";

        // get the path to the app icon
        final String d_icon =
            new File(Info.getBaseDir(), "Contents/Resources/VASSAL.icns").getAbsolutePath();

        al.add("-Xdock:name=" + d_name);
        al.add("-Xdock:icon=" + d_icon);

        // Quartz can cause font rendering problems; turn it off?
        final Boolean disableQuartz =
            (Boolean) Prefs.getGlobalPrefs().getValue(Prefs.DISABLE_QUARTZ);

        al.add(
            "-Dapple.awt.graphics.UseQuartz="
                + (Boolean.TRUE.equals(disableQuartz) ? "false" : "true"));
      } else if (Info.isWindows()) {
        // Disable the 2D to Direct3D pipeline?
        final Boolean disableD3d = (Boolean) Prefs.getGlobalPrefs().getValue(Prefs.DISABLE_D3D);
        if (Boolean.TRUE.equals(disableD3d)) {
          al.add("-Dsun.java2d.d3d=false");
        }
      }

      al.add(entryPoint);

      final String[] args = al.toArray(new String[al.size()]);

      // try to start a child process with the given heap sizes
      args[1] = "-Xms" + initialHeap + "M";
      args[2] = "-Xmx" + maximumHeap + "M";
      Process p = launch(args);

      // launch failed, use conservative heap sizes
      if (p == null) {
        args[1] = "-Xms" + FAILSAFE_INITIAL_HEAP + "M";
        args[2] = "-Xmx" + FAILSAFE_MAXIMUM_HEAP + "M";
        p = launch(args);

        if (p == null) {
          throw new IOException("failed to start child process");
        } else {
          FutureUtils.wait(
              WarningDialog.show("Warning.maximum_heap_too_large", FAILSAFE_MAXIMUM_HEAP));
        }
      }

      // read the port for the child's socket from its stdout
      final DataInputStream din = new DataInputStream(p.getInputStream());
      final int childPort = din.readInt();

      // pump child's stderr to our own stderr
      new Thread(new StreamPump(p.getErrorStream(), System.err), "err pump " + id).start();

      // pump child's stdout to our own stdout
      new Thread(new StreamPump(p.getInputStream(), System.out), "out pump " + id).start();

      // Check that the child's port is sane. Reading stdout from a
      // failed launch tends to give impossible port numbers.
      if (childPort < 0 || childPort > 65535) {
        throw new IOException("port out of range: " + childPort);
      }

      // create the client for the child's socket
      clientSocket = new Socket((String) null, childPort);
      cmdC = new CommandClient(clientSocket);
      children.add(cmdC);

      // block until the process ends
      p.waitFor();
      return null;
    }