public String getDefaultCompileCommands(File source) {
   /* TODO Split into String[] */
   return GUI.getExternalToolsSetting("PATH_MAKE")
       + " "
       + getExpectedFirmwareFile(source).getName()
       + " TARGET="
       + target;
 }
Exemplo n.º 2
0
  /**
   * Builds executable JAR from current simulation
   *
   * @param gui GUI. Must contain simulation
   * @param outputFile Output file
   */
  public static boolean buildExecutableJAR(GUI gui, File outputFile) {
    String executeDir = null;
    executeDir = outputFile.getName();
    if (!executeDir.endsWith(".jar")) {
      throw new RuntimeException("Not a proper JAR archive: " + executeDir);
    }
    executeDir = executeDir.substring(0, executeDir.length() - ".jar".length());

    Simulation simulation = gui.getSimulation();
    if (simulation == null) {
      throw new RuntimeException("No simulation active");
    }

    /* Check dependencies: mote type */
    for (MoteType t : simulation.getMoteTypes()) {
      if (!t.getClass().getName().contains("SkyMoteType")) {
        throw new RuntimeException(
            "You simulation contains the mote type: "
                + GUI.getDescriptionOf(t.getClass())
                + "\n"
                + "Only the Sky Mote Type is currently supported.\n");
      }
      logger.info("Checking mote types: '" + GUI.getDescriptionOf(t.getClass()) + "'");
    }

    /* Check dependencies: Contiki Test Editor */
    boolean hasTestEditor = false;
    for (Plugin startedPlugin : gui.getStartedPlugins()) {
      if (startedPlugin instanceof ScriptRunner) {
        hasTestEditor = true;
        break;
      }
    }
    logger.info("Checking that Contiki Test Editor exists: " + hasTestEditor);
    if (!hasTestEditor) {
      throw new RuntimeException(
          "The simulation needs at least one active Contiki Test Editor plugin.\n"
              + "The plugin is needed to control the non-visualized simulation.");
    }

    /* Create temporary directory */
    File workingDir;
    try {
      workingDir = File.createTempFile("cooja", ".tmp");
      workingDir.delete();
      workingDir.mkdir();
      logger.info("Creating temporary directory: " + workingDir.getAbsolutePath());
    } catch (IOException e1) {
      throw (RuntimeException)
          new RuntimeException("Error when creating temporary directory: " + e1.getMessage())
              .initCause(e1);
    }

    /* Unpacking project JARs */
    ProjectConfig config = gui.getProjectConfig();
    String[] projectJARs = config.getStringArrayValue(GUI.class.getName() + ".JARFILES");
    for (String jar : projectJARs) {
      /* Locate project */
      File project = config.getUserProjectDefining(GUI.class, "JARFILES", jar);
      File jarFile = new File(project, jar);
      if (!jarFile.exists()) {
        jarFile = new File(project, "lib/" + jar);
      }
      if (!jarFile.exists()) {
        throw new RuntimeException("Project JAR could not be found: " + jarFile.getAbsolutePath());
      }

      logger.info("Unpacking project JAR " + jar + " (" + project + ")");
      try {
        Process unjarProcess =
            Runtime.getRuntime()
                .exec(new String[] {"jar", "xf", jarFile.getAbsolutePath()}, null, workingDir);
        unjarProcess.waitFor();
      } catch (Exception e1) {
        throw (RuntimeException)
            new RuntimeException("Error unpacking JAR file: " + e1.getMessage()).initCause(e1);
      }
    }

    /* Unpacking COOJA core JARs */
    String[] coreJARs =
        new String[] {
          "tools/cooja/lib/jdom.jar", "tools/cooja/lib/log4j.jar", "tools/cooja/dist/cooja.jar"
        };
    for (String jar : coreJARs) {
      File jarFile = new File(GUI.getExternalToolsSetting("PATH_CONTIKI"), jar);
      if (!jarFile.exists()) {
        throw new RuntimeException("Project JAR could not be found: " + jarFile.getAbsolutePath());
      }
      logger.info("Unpacking core JAR " + jar);
      try {
        Process unjarProcess =
            Runtime.getRuntime()
                .exec(new String[] {"jar", "xf", jarFile.getAbsolutePath()}, null, workingDir);
        unjarProcess.waitFor();
      } catch (Exception e1) {
        throw (RuntimeException)
            new RuntimeException("Error unpacking JAR file: " + e1.getMessage()).initCause(e1);
      }
    }

    /* Prepare simulation config */
    Element rootElement = gui.extractSimulationConfig();
    logger.info("Extracting simulation configuration");
    handleExportAttributesToJAR(rootElement, gui, workingDir);

    /* Save simulation config */
    File configFile = new File(workingDir, SIMCONFIG_FILENAME);
    try {
      Document doc = new Document(rootElement);
      FileOutputStream out = new FileOutputStream(configFile);
      XMLOutputter outputter = new XMLOutputter();
      outputter.setFormat(Format.getPrettyFormat());
      outputter.output(doc, out);
      out.close();
    } catch (Exception e1) {
      throw (RuntimeException)
          new RuntimeException("Error when writing simulation configuration: " + configFile)
              .initCause(e1);
    }
    logger.info("Wrote simulation configuration: " + configFile.getName());

    /* Export external tools config (without projects) */
    try {
      File externalToolsConfig = new File(workingDir, EXTERNALTOOLS_FILENAME);
      FileOutputStream out = new FileOutputStream(externalToolsConfig);
      Properties differingSettings = new Properties();
      Enumeration<Object> keyEnum = GUI.currentExternalToolsSettings.keys();
      while (keyEnum.hasMoreElements()) {
        String key = (String) keyEnum.nextElement();
        String defaultSetting = GUI.getExternalToolsDefaultSetting(key, "");
        String currentSetting = GUI.currentExternalToolsSettings.getProperty(key, "");

        if (key.equals("DEFAULT_PROJECTDIRS")) {
          differingSettings.setProperty(key, "");
        } else if (!defaultSetting.equals(currentSetting)) {
          differingSettings.setProperty(key, currentSetting);
        }
      }

      differingSettings.store(out, "Cooja External Tools (User specific)");
      out.close();
      logger.info("Wrote external tools config: " + externalToolsConfig.getName());
    } catch (Exception e2) {
      throw (RuntimeException)
          new RuntimeException(
                  "Error when writing external tools configuration: " + e2.getMessage())
              .initCause(e2);
    }

    /* Export current project configuration */
    try {
      ProjectConfig pConfig = gui.getProjectConfig().clone();
      Enumeration<String> pValues = pConfig.getPropertyNames();
      File newConfigFile = new File(workingDir, PROJECT_DEFAULT_CONFIG_FILENAME);
      Properties newConfig = new Properties();
      while (pValues.hasMoreElements()) {
        String name = pValues.nextElement();
        newConfig.setProperty(name, pConfig.getStringValue(name));
      }
      FileOutputStream out = new FileOutputStream(newConfigFile);
      newConfig.store(out, "Cooja Project Config");
      logger.info("Wrote project config: " + newConfigFile.getName());
    } catch (Exception e1) {
      e1.printStackTrace();
      throw (RuntimeException)
          new RuntimeException("Error when writing project config: " + e1.getMessage())
              .initCause(e1);
    }

    /* Delete existing META-INF dir */
    File metaInfDir = new File(workingDir, "META-INF");
    if (metaInfDir.exists() && metaInfDir.isDirectory()) {
      if (!deleteDirectory(metaInfDir)) {
        if (!deleteDirectory(metaInfDir)) {
          deleteDirectory(metaInfDir);
        }
      }
    }

    /* Prepare JAR manifest */
    File manifestFile = new File(workingDir, "manifest.tmp");
    if (manifestFile.exists()) {
      manifestFile.delete();
    }
    StringBuilder sb = new StringBuilder();
    sb.append("Manifest-Version: 1.0\r\n");
    sb.append("Main-Class: " + ExecuteJAR.class.getName() + "\r\n");
    sb.append("Class-path: .\r\n");
    StringUtils.saveToFile(manifestFile, sb.toString());
    logger.info("Wrote manifest file: " + manifestFile.getName());

    /* Build executable JAR */
    if (outputFile.exists()) {
      outputFile.delete();
    }

    logger.info("Building executable JAR: " + outputFile);
    MessageList errors = new MessageList();
    try {
      CompileContiki.compile(
          "jar cfm " + outputFile.getAbsolutePath() + " manifest.tmp .",
          null,
          outputFile,
          workingDir,
          null,
          null,
          errors,
          true);
    } catch (Exception e) {
      logger.warn("Building executable JAR error: " + e.getMessage());
      MessageContainer[] err = errors.getMessages();
      for (int i = 0; i < err.length; i++) {
        logger.fatal(">> " + err[i]);
      }

      /* Forward exception */
      throw (RuntimeException)
          new RuntimeException("Error when building executable JAR: " + e.getMessage())
              .initCause(e);
    }

    /* Delete temporary working directory */
    logger.info("Deleting temporary files in: " + workingDir.getAbsolutePath());
    if (!deleteDirectory(workingDir)) {
      if (!deleteDirectory(workingDir)) {
        deleteDirectory(workingDir);
      }
    }

    /* We are done! */
    logger.info("Done! To run simulation: > java -jar " + outputFile.getName());
    return true;
  }