Example #1
0
  /**
   * Construct a {@link SubProcessHeavy SubProcessHeavy} instance which when executed will fulfill
   * the given action agenda.
   *
   * <p>
   *
   * @param agenda The agenda to be accomplished by the action.
   * @param outFile The file to which all STDOUT output is redirected.
   * @param errFile The file to which all STDERR output is redirected.
   * @return The SubProcess which will fulfill the agenda.
   * @throws PipelineException If unable to prepare a SubProcess due to illegal, missing or
   *     imcompatable information in the action agenda or a general failure of the prep method code.
   */
  public SubProcessHeavy prep(ActionAgenda agenda, File outFile, File errFile)
      throws PipelineException {
    NodeID nodeID = agenda.getNodeID();

    /* sanity checks */
    File targetScene = null;
    ArrayList<File> sourceScenes = new ArrayList<File>();
    ArrayList<String> mergePatterns = new ArrayList<String>();
    File preBuild = null;
    File postBuild = null;
    File preScene = null;
    File postScene = null;
    {
      DoubleMap<Integer, String, TreeSet<FileSeq>> sources =
          new DoubleMap<Integer, String, TreeSet<FileSeq>>();

      for (String sname : agenda.getSourceNames()) {
        if (hasSourceParams(sname)) {
          FileSeq fseq = agenda.getPrimarySource(sname);
          Integer order = (Integer) getSourceParamValue(sname, "Order");
          addSourceSeq(order, sname, fseq, sources);
        }

        for (FileSeq fseq : agenda.getSecondarySources(sname)) {
          FilePattern fpat = fseq.getFilePattern();
          if (hasSecondarySourceParams(sname, fpat)) {
            Integer order = (Integer) getSecondarySourceParamValue(sname, fpat, "Order");
            addSourceSeq(order, sname, fseq, sources);
          }
        }
      }

      for (Integer order : sources.keySet()) {
        for (String sname : sources.get(order).keySet()) {
          for (FileSeq fseq : sources.get(order).get(sname)) {
            String pattern = null;
            if (fseq.equals(agenda.getPrimarySource(sname)))
              pattern = (String) getSourceParamValue(sname, "MergePattern");
            else {
              FilePattern fpat = fseq.getFilePattern();
              pattern = (String) getSecondarySourceParamValue(sname, fpat, "MergePattern");
            }

            if ((pattern == null) || (pattern.length() == 0))
              throw new PipelineException(
                  "The Merge Pattern for file sequence ("
                      + fseq
                      + ") of source node "
                      + "("
                      + sname
                      + ") was not specified!");

            NodeID snodeID = new NodeID(nodeID, sname);
            File sfile =
                new File(PackageInfo.sProdDir, snodeID.getWorkingParent() + "/" + fseq.getFile(0));

            sourceScenes.add(sfile);
            mergePatterns.add(pattern);
          }
        }
      }

      /* generate the name of the Houdini scene to save */
      {
        FileSeq fseq = agenda.getPrimaryTarget();
        String suffix = fseq.getFilePattern().getSuffix();
        if (!fseq.isSingle() || (suffix == null) || !suffix.equals("hip"))
          throw new PipelineException(
              "The HfsBuild Action requires that the primary target file sequence must "
                  + "be a single Houdini scene file!");

        targetScene =
            new File(PackageInfo.sProdDir, nodeID.getWorkingParent() + "/" + fseq.getFile(0));
      }

      /* command script files */
      {
        String sname = (String) getSingleParamValue("PreBuildScript");
        if (sname != null) {
          FileSeq fseq = agenda.getPrimarySource(sname);
          if (fseq == null)
            throw new PipelineException(
                "Somehow the Pre Build Script node ("
                    + sname
                    + ") was not one of the "
                    + "source nodes!");

          String suffix = fseq.getFilePattern().getSuffix();
          if (!fseq.isSingle() || (suffix == null) || !(suffix.equals("cmd")))
            throw new PipelineException(
                "The HfsBuild Action requires that the source node specified by the Pre "
                    + "Build Script parameter ("
                    + sname
                    + ") must have a single command "
                    + "script (.cmd) as its primary file sequence!");

          NodeID snodeID = new NodeID(nodeID, sname);
          preBuild =
              new File(PackageInfo.sProdDir, snodeID.getWorkingParent() + "/" + fseq.getFile(0));
        }
      }

      {
        String sname = (String) getSingleParamValue("PostBuildScript");
        if (sname != null) {
          FileSeq fseq = agenda.getPrimarySource(sname);
          if (fseq == null)
            throw new PipelineException(
                "Somehow the Post Build Script node ("
                    + sname
                    + ") was not one of the "
                    + "source nodes!");

          String suffix = fseq.getFilePattern().getSuffix();
          if (!fseq.isSingle() || (suffix == null) || !(suffix.equals("cmd")))
            throw new PipelineException(
                "The HfsBuild Action requires that the source node specified by the Post "
                    + "Build Script parameter ("
                    + sname
                    + ") must have a single command "
                    + "script (.cmd) as its primary file sequence!");

          NodeID snodeID = new NodeID(nodeID, sname);
          postBuild =
              new File(PackageInfo.sProdDir, snodeID.getWorkingParent() + "/" + fseq.getFile(0));
        }
      }

      {
        String sname = (String) getSingleParamValue("PreSceneScript");
        if (sname != null) {
          FileSeq fseq = agenda.getPrimarySource(sname);
          if (fseq == null)
            throw new PipelineException(
                "Somehow the Pre Scene Script node ("
                    + sname
                    + ") was not one of the "
                    + "source nodes!");

          String suffix = fseq.getFilePattern().getSuffix();
          if (!fseq.isSingle() || (suffix == null) || !(suffix.equals("cmd")))
            throw new PipelineException(
                "The HfsBuild Action requires that the source node specified by the Pre "
                    + "Scene Script parameter ("
                    + sname
                    + ") must have a single command script "
                    + "(.cmd) as its primary file sequence!");

          NodeID snodeID = new NodeID(nodeID, sname);
          preScene =
              new File(PackageInfo.sProdDir, snodeID.getWorkingParent() + "/" + fseq.getFile(0));
        }
      }

      {
        String sname = (String) getSingleParamValue("PostSceneScript");
        if (sname != null) {
          FileSeq fseq = agenda.getPrimarySource(sname);
          if (fseq == null)
            throw new PipelineException(
                "Somehow the Post Scene Script node ("
                    + sname
                    + ") was not one of the "
                    + "source nodes!");

          String suffix = fseq.getFilePattern().getSuffix();
          if (!fseq.isSingle() || (suffix == null) || !(suffix.equals("cmd")))
            throw new PipelineException(
                "The HfsBuild Action requires that the source node specified by the Post "
                    + "Scene Script parameter ("
                    + sname
                    + ") must have a single command script "
                    + "(.cmd) as its primary file sequence!");

          NodeID snodeID = new NodeID(nodeID, sname);
          postScene =
              new File(PackageInfo.sProdDir, snodeID.getWorkingParent() + "/" + fseq.getFile(0));
        }
      }
    }

    /* create the temporary Houdini command script */
    File hscript = createTemp(agenda, 0644, "cmd");
    try {
      FileWriter out = new FileWriter(hscript);

      if (preBuild != null) out.write("source " + preBuild + "\n");

      /* load the source scenes */
      int wk;
      for (wk = 0; wk < sourceScenes.size(); wk++) {
        File sourceScene = sourceScenes.get(wk);
        String pattern = mergePatterns.get(wk);

        if (preScene != null) out.write("source " + preScene + "\n");

        out.write("mread");
        if (wk > 0) out.write(" -o -m " + pattern);
        out.write(" " + sourceScene + "\n");

        if (postScene != null) out.write("source " + postScene + "\n");
      }

      if (postBuild != null) out.write("source " + postBuild + "\n");

      /* save the file */
      out.write("mwrite " + targetScene + "\n");

      out.close();
    } catch (IOException ex) {
      throw new PipelineException(
          "Unable to write temporary command file ("
              + hscript
              + ") for Job "
              + "("
              + agenda.getJobID()
              + ")!\n"
              + ex.getMessage());
    }

    /* create the wrapper shell script */
    File script = createTemp(agenda, 0755, "bash");
    try {
      FileWriter out = new FileWriter(script);
      out.write("#!/bin/bash\n\n" + "cat " + hscript + " | hscript");
      out.close();
    } catch (IOException ex) {
      throw new PipelineException(
          "Unable to write temporary script file ("
              + script
              + ") for Job "
              + "("
              + agenda.getJobID()
              + ")!\n"
              + ex.getMessage());
    }

    try {
      return new SubProcessHeavy(
          agenda.getNodeID().getAuthor(),
          getName() + "-" + agenda.getJobID(),
          script.getPath(),
          new ArrayList<String>(),
          agenda.getEnvironment(),
          agenda.getWorkingDir(),
          outFile,
          errFile);
    } catch (Exception ex) {
      throw new PipelineException(
          "Unable to generate the SubProcess to perform this Action!\n" + ex.getMessage());
    }
  }