Package sos.scheduler.managed

Source Code of sos.scheduler.managed.JobSchedulerManagedStarter_3

/********************************************************* begin of preamble
**
** Copyright (C) 2003-2010 Software- und Organisations-Service GmbH.
** All rights reserved.
**
** This file may be used under the terms of either the
**
**   GNU General Public License version 2.0 (GPL)
**
**   as published by the Free Software Foundation
**   http://www.gnu.org/licenses/gpl-2.0.txt and appearing in the file
**   LICENSE.GPL included in the packaging of this file.
**
** or the
** 
**   Agreement for Purchase and Licensing
**
**   as offered by Software- und Organisations-Service GmbH
**   in the respective terms of supply that ship with this file.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
********************************************************** end of preamble*/
package sos.scheduler.managed;

import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import sos.connection.SOSOracleConnection;
import sos.scheduler.command.RemoteScheduler;
import sos.scheduler.job.JobSchedulerJob;
import sos.scheduler.live.JobSchedulerLiveXml;
import sos.scheduler.live.JobSchedulerMetadataElement;
import sos.spooler.Order;
import sos.spooler.Variable_set;
import sos.util.SOSCrypt;
import sos.util.SOSFile;
import sos.util.SOSFileOperations;
import sos.util.SOSLogger;
import sos.util.SOSSchedulerLogger;
import sos.xml.SOSXMLXPath;

/**
* This class submits Managed (v3) Job Scheduler configurations from
* the database to the Job Scheduler using hot folders.<br/>
* @version 3.0
* @author Andreas Liebert
* @since 2007-04-13
*/

public class JobSchedulerManagedStarter_3 extends JobSchedulerJob {

  public static final int  ACTION_SUBMIT      = 1;
  public static final int  ACTION_SUBMIT_AND_START  = 2;
  public static final int  ACTION_TRY_OUT      = 3;
  public static final int  ACTION_REMOVE      = 4;
  public static final int  ACTION_REMOVE_ORDERS  = 5;
  public static final int  ACTION_REMOVE_DIR    = 6;
  public static final int  ACTION_MOVE        = 7;
  public static final int  ACTION_MOVE_DIR      = 8;

  public static final int getAction(String action) throws Exception {

    if (action.equalsIgnoreCase("submit"))
      return ACTION_SUBMIT;
    if (action.equalsIgnoreCase("submit_and_start"))
      return ACTION_SUBMIT_AND_START;
    if (action.equalsIgnoreCase("remove"))
      return ACTION_REMOVE;
    if (action.equalsIgnoreCase("remove_orders"))
      return ACTION_REMOVE_ORDERS;
    if (action.equalsIgnoreCase("remove_dir"))
      return ACTION_REMOVE_DIR;
    if (action.equalsIgnoreCase("try_out"))
      return ACTION_TRY_OUT;
    if (action.equalsIgnoreCase("move"))
      return ACTION_MOVE;
    if (action.equalsIgnoreCase("move_dir"))
      return ACTION_MOVE_DIR;

    throw new Exception("unknown action: \"" + action + "\"");
  }

  /** is this job running as a startscript? */
  private boolean          startscript            = true;

  /**
   * Regular Expression
   * (?:(.*),)?(.*)\.(.*)\.xml$<br>
   * groups:<br>
   * <ol>
   *   <li>empty or the name of the Job Chain (for order files)</li>
   *   <li>the name of the object</li>
   *   <li>the type (job, order...) of the object</li>
   * </ol>
   */
  private final static String    hotFolderRegEx          = "(?:(.*),)?(.*)\\.(.*)\\.xml$";

  protected Pattern        hotFolderRegExPattern;

  private final static String    noSchedulerFileRegEx      = "^.*(?<!\\.(job|order|lock|job_chain|process_class|params|schedule)\\.xml)$";

  protected Pattern        noSchedulerFileRegExPattern;

  /** ID of this Job Scheduler */
  // private String schedulerID = "";

  Variable_set          orderParams            = null;

  // private boolean once = false;
  // private boolean remove = false;

  // private static Pattern xmlEncodingPattern = Pattern.compile("\\<\\?xml.*encoding=\"(.*)\".*\\?\\>");

  // private boolean useLiveFolder = true;

  private File          liveFolder;
  private File          remoteFolder;

  // private Transformer managed2liveTransformer;
  // private final static String indicatorRegex = "(.*\\.xml)\\s([a-f0-9]+)\\s(\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}(\\.\\d)?)$";
  // private Pattern indicatorRegexPattern;

  // database interface support
  private boolean          isDatabaseInterfaceSupported  = false;
  private LinkedHashSet      listOfElements          = null;

  private DocumentBuilderFactory  docFactory;
  private DocumentBuilder      docBuilder;

  private final String getWhat(String type) {

    String what = "unknown type: " + type;
    if (type.equalsIgnoreCase("o"))
      what = "order";
    if (type.equalsIgnoreCase("j"))
      what = "orderjob";
    if (type.equalsIgnoreCase("i"))
      what = "job";
    if (type.equalsIgnoreCase("f"))
      what = "job.global";
    if (type.equalsIgnoreCase("l"))
      what = "lock";
    if (type.equalsIgnoreCase("c"))
      what = "job_chain";
    if (type.equalsIgnoreCase("p"))
      what = "process_class";
    if (type.equalsIgnoreCase("k"))
      what = "documentation";
    if (type.equalsIgnoreCase("s"))
      what = "schedule";
    if (type.equalsIgnoreCase("t"))
      what = "schedule.substitute";
    if (type.equalsIgnoreCase("v"))
      what = "params";
    if (type.equalsIgnoreCase("m"))
      what = "misc";
    return what;
  }

  private HashMap  dbCache;

  private final String getType(String what) {

    String type = "unknown type: " + what;

    if (what.equalsIgnoreCase("order"))
      type = "o";
    if (what.equalsIgnoreCase("orderjob"))
      type = "j";
    if (what.equalsIgnoreCase("job"))
      type = "i";
    if (what.equalsIgnoreCase("job.global"))
      type = "f";
    if (what.equalsIgnoreCase("lock"))
      type = "l";
    if (what.equalsIgnoreCase("job_chain"))
      type = "c";
    if (what.equalsIgnoreCase("process_class"))
      type = "p";
    if (what.equalsIgnoreCase("documentation"))
      type = "k";
    if (what.equalsIgnoreCase("schedule"))
      type = "s";
    if (what.equalsIgnoreCase("schedule.substitute"))
      type = "t";
    if (what.equalsIgnoreCase("params"))
      type = "v";
    if (what.equalsIgnoreCase("misc"))
      type = "m";

    return type;
  }

  /**
   * spooler_init() is called for startscripts on Job Scheduler start-up
   */
  public boolean spooler_init() {

    boolean rc = super.spooler_init();

    hotFolderRegExPattern = Pattern.compile(hotFolderRegEx);
    noSchedulerFileRegExPattern = Pattern.compile(noSchedulerFileRegEx);

    /*       
    try {
      String answer = spooler.execute_xml("<show_state what=\"remote_schedulers\"/>");
      SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(answer));
      String number = xpath.selectSingleNodeValue("/spooler/answer/state/remote_schedulers/@count");
      if (number==null || number.length()==0 || number.equalsIgnoreCase("0")) {
        spooler_log.debug1("No remote Job Schedulers found. Running in single Scheduler mode.");
        isSupervisor = false;
      } else isSupervisor = true;
    } catch(Exception e) {
      spooler_log.error("Error checking remote Job Schedulers: "+e);
      return false;
    }
    */

    try { // to check if the database interface is available
      String available = this.getConnection().getSingleValue("SELECT COUNT(*) FROM " + JobSchedulerManagedObject.getTableLiveObjects() + " WHERE 1=0");
      if (available != null && available.equals("0"))
        isDatabaseInterfaceSupported = true;
    }
    catch (Exception e) {
    } // ignore this error
    finally {
      try {
        getConnection().rollback();
      }
      catch (Exception e) {
        try {
          getLog().error("Error rolling back after checking live objects: " + e);
        }
        catch (Exception ex) {
        }
        return false;
      }
    }

    liveFolder = new File(spooler.configuration_directory());
    remoteFolder = new File(liveFolder.getParentFile(), "remote");

    startscript = spooler_job == null;
    // schedulerID = spooler.id().toLowerCase();
    if (!rc)
      return false || startscript;

    if (startscript)
      try {
        setLogger(new SOSSchedulerLogger(spooler.log()));
        getLog().info("JobSchedulerManagedStarter is running as startscript");
        spooler.set_var("scheduler_managed_jobs_version", "3");
      }
      catch (Exception e2) {
      }
    else
      try {
        setLogger(new SOSSchedulerLogger(spooler_log));
        getLog().info("JobSchedulerManagedStarter is running as job");
      }
      catch (Exception e3) {
      }

    try {
      docFactory = DocumentBuilderFactory.newInstance();
      docBuilder = docFactory.newDocumentBuilder();
    }
    catch (Exception e) {
      spooler_log.error("Failed to initialize DocumentBuilderFactory: " + e);
      return false;
    }

    if (startscript) {
      try {
        processLive();
        processSubmits();
        processDirs();
        processDatabase();

        return true;
      }
      catch (Exception e) {
        try {
          getLog().error("error occurred in initialization: " + e.getMessage());
        }
        catch (Exception e1) {
        }

        return false || startscript;
      }
      finally {
        if (this.getConnection() != null) {
          try {
            this.getConnection().rollback();
          }
          catch (Exception ex) {
          } // no error handling
          try {
            this.getConnection().disconnect();
          }
          catch (Exception ex) {
          } // no error handling
        }
      }
    }
    return true;
  }

  private void processLive() throws Exception {

    if (!isDatabaseInterfaceSupported)
      return;

    try {
      Iterator resultset = null;
      HashMap rec;

      spooler_log.debug3("Exporting configurations from database interface");
      String selStr = "SELECT oh.\"PK_ID\", oh.\"OBJECT_ID\", " + " oh.\"NAME\" AS \"NEW_NAME\", oh.\"PATH\" AS \"NEW_PATH\", "
          + " oh.\"OPERATION\", o.\"NAME\", o.\"PATH\", o.\"TYPE\"" + " FROM " + JobSchedulerManagedObject.getTableLiveObjectHistory()
          + " oh LEFT OUTER JOIN " + JobSchedulerManagedObject.getTableLiveObjects() + " o" + " ON oh.\"OBJECT_ID\"=o.\"PK_ID\""
          + " WHERE oh.\"IN_SYNC\"=0";

      if (!startscript && orderParams.value("history_id") != null && orderParams.value("history_id").length() > 0) {
        selStr += " AND oh.\"PK_ID\"=" + orderParams.value("history_id");
      }

      spooler_log.debug3("processLive: " + selStr);

      ArrayList arrayList = new ArrayList();
      arrayList = this.getConnection().getArray(selStr);
      resultset = arrayList.iterator();

      while (resultset.hasNext()) {
        rec = (HashMap) resultset.next();
        if (rec.get("name") != null && rec.get("name").toString().length() > 0) { // should the record in live_objects have been
                                              // removed
          if (getLiveValue(rec, "operation").equalsIgnoreCase("delete") || getLiveValue(rec, "operation").equalsIgnoreCase("rename")) {
            File currentFile = null;
            File newFile = null;
            String jobChainName = "";

            if (getLiveValue(rec, "type").equalsIgnoreCase("order")) {
              jobChainName = this.getConnection().getSingleValue(
                  "SELECT \"JOB_CHAIN\" FROM " + JobSchedulerManagedObject.getTableLiveOrders() + " WHERE \"OBJECT_ID\"="
                      + getLiveValue(rec, "object_id"));
              if (jobChainName != null && jobChainName.length() > 0) {
                currentFile = new File(liveFolder + "/" + getLiveValue(rec, "path"), jobChainName + "," + getLiveValue(rec, "name")
                    + ".order.xml");
              }
              else {
                currentFile = new File(liveFolder + "/" + getLiveValue(rec, "path"), getLiveValue(rec, "name") + "."
                    + getLiveValue(rec, "type") + ".xml");
              }
            }
            else {
              currentFile = new File(liveFolder + "/" + getLiveValue(rec, "path"), getLiveValue(rec, "name") + "." + getLiveValue(rec, "type")
                  + ".xml");
            }
            getLogger().debug7("current file: " + currentFile.getAbsolutePath());

            if (currentFile.exists()) {
              boolean rc = false;
              if (getLiveValue(rec, "operation").equalsIgnoreCase("delete")) {
                getLogger().debug("deleting file " + currentFile.getAbsolutePath());
                rc = currentFile.delete();
                if (!rc)
                  getLogger().warn("failed to delete file " + currentFile.getAbsolutePath());
              }
              else
                if (getLiveValue(rec, "operation").equalsIgnoreCase("rename")) {
                  if (getLiveValue(rec, "type").equalsIgnoreCase("order")) {
                    if (jobChainName != null && jobChainName.length() > 0) {
                      newFile = new File(liveFolder + "/" + getLiveValue(rec, "new_path"), jobChainName + ","
                          + getLiveValue(rec, "new_name") + ".order.xml");
                    }
                    else {
                      newFile = new File(liveFolder + "/" + getLiveValue(rec, "new_path"), getLiveValue(rec, "new_name") + "."
                          + getLiveValue(rec, "type") + ".xml");
                    }
                  }
                  else {
                    newFile = new File(liveFolder + "/" + getLiveValue(rec, "new_path"), getLiveValue(rec, "new_name") + "."
                        + getLiveValue(rec, "type") + ".xml");
                  }
                  getLogger().debug("renaming file " + currentFile.getAbsolutePath() + " to " + newFile.getAbsolutePath());
                  rc = currentFile.renameTo(newFile);
                  if (!rc)
                    getLogger().warn("failed to rename file " + currentFile.getAbsolutePath() + " to " + newFile.getAbsolutePath());
                }

              if (rc && !isWindows() && !startscript) {
                // notify Job Scheduler
                spooler.execute_xml("<check_folders/>");
              }
            }
          }
          else {
            liveExport(rec);
          }
        }

        String updString = "UPDATE " + JobSchedulerManagedObject.getTableLiveObjectHistory()
            + " SET \"SYNCHRONIZED\"=%now, \"IN_SYNC\"=1 WHERE \"PK_ID\"=" + getLiveValue(rec, "pk_id");
        this.getConnection().executeUpdate(updString);
        if (getLiveValue(rec, "operation").equalsIgnoreCase("delete")) {
          updString = "DELETE FROM " + JobSchedulerManagedObject.getTableLiveObjects() + " WHERE \"PK_ID\"=" + getLiveValue(rec, "object_id");
          this.getConnection().executeUpdate(updString);
        }
        this.getConnection().commit();
      }

    }
    catch (Exception e) {
      throw new Exception("Error processing configuration from database interface: " + e, e);
    }
  }

  private void processSubmits() throws Exception {

    try {
      String query = "SELECT \"ID\", \"OBJECT_ID\", \"PATH\", \"OLD_PATH\", \"HOST\", \"PORT\", \"ACTION\", \"HASH\" FROM "
          + JobSchedulerManagedObject.tableManagedSubmits + " WHERE \"STATE\"='ordered' AND \"SPOOLER_ID\"='" + spooler.id()
          + "' ORDER BY \"ID\" ASC";
      ArrayList submits = getConnection().getArray(query);
      getLogger().debug1("Found " + submits.size() + " submits.");
      Iterator submitIterator = submits.iterator();
      while (submitIterator.hasNext()) {
        HashMap submit = (HashMap) submitIterator.next();
        String submitID = submit.get("id").toString();
        String xml = getConnection().getClob("SELECT \"XML\" FROM " + JobSchedulerManagedObject.tableManagedSubmits + " WHERE \"ID\"=" + submitID);
        submit.put("xml", xml);
        try {
          processSubmit(submit);
        }
        catch (Exception e) {
          getLogger().warn("Error processing submit: " + e);
        }
      }
    }
    catch (Exception e) {
      throw new Exception("Error processing previously submitted commands: " + e, e);
    }
  }

  private final static String getPathWithoutSupervisor(String path) {

    int index = path.indexOf('/', 1);
    if (index == -1)
      return "/";
    String pathWithoutSup = path.substring(index);
    return pathWithoutSup;
  }

  private void processSubmit(HashMap submit) throws Exception {

    String state = "stored";

    try {
      logSubmit(submit);

      if (submit.get("path").toString().length() > 0) {
        submit.put("path", getPathWithoutSupervisor(submit.get("path").toString()));
      }

      if (submit.get("old_path").toString().length() > 0) {
        submit.put("old_path", getPathWithoutSupervisor(submit.get("old_path").toString()));
      }

      String host = submit.get("host").toString();
      String port = submit.get("port").toString();

      File currentRoot = liveFolder.getParentFile();
      getLogger().debug7("current root folder: " + currentRoot.getAbsolutePath());
      File currentFile = new File(currentRoot, submit.get("path").toString());
      getLogger().debug7("current file: " + currentFile.getAbsolutePath());
      File oldFile = currentFile;
      if (submit.get("old_path").toString().length() > 0) {
        oldFile = new File(currentRoot, submit.get("old_path").toString());
      }

      String action = submit.get("action").toString();
      if (action == null || action.length() == 0)
        throw new Exception("submit has no action!");

      switch (getAction(action)) {
        case ACTION_SUBMIT:
          processActionSubmit(currentFile, submit);
          break;
        case ACTION_SUBMIT_AND_START:
          processActionSubmit(currentFile, submit);
          processActionAndStart(submit, host, port);
          break;
        case ACTION_TRY_OUT:
          processActionTryOut(submit, host, port);
          break;
        case ACTION_REMOVE:
          processActionRemove(currentFile, submit);
          break;
        case ACTION_REMOVE_ORDERS:
          processActionRemoveOrders(currentFile, submit);
          break;
        case ACTION_REMOVE_DIR:
          processActionRemoveDir(currentFile.getAbsolutePath());
          break;
        case ACTION_MOVE:
          // processActionMove(new File(oldFile.getParent(), currentFile.getName()), currentFile, submit);
          processActionMove(oldFile, currentFile, submit);
          break;
        case ACTION_MOVE_DIR:
          processActionMoveDir(oldFile, currentFile, submit);
      }
    }
    catch (Exception e) {
      state = "error";
      throw new Exception("Error executing MANAGED_SUBMIT[" + submit.get("id").toString() + "]: " + e, e);
    }
    finally {
      try {
        String sql = "UPDATE " + JobSchedulerManagedObject.tableManagedSubmits + " SET \"STATE\"='" + state + "', "
            + "\"MODIFIED\"=%now, \"MODIFIED_BY\"='JobSchedulerManagedStarter' WHERE \"ID\"=" + submit.get("id").toString();
        getConnection().executeUpdate(sql);
        getConnection().commit();
      }
      catch (Exception e) {
        throw new Exception("Error updating MANAGED_SUBMISSION[" + submit.get("id").toString() + "]: " + e, e);
      }
    }
  }

  private void processActionSubmit(File file, HashMap submit) throws Exception {

    try {
      getLogger().debug9("processActionSubmit()");
      String hash = submit.get("hash").toString();

      String fileHash = "";
      if (file.exists()) {
        fileHash = SOSCrypt.MD5encrypt(file);
      }
      else
        if (!file.getParentFile().exists()) {
          getLogger().debug1("Creating directory " + file.getParent());
          if (!file.getParentFile().mkdirs()) {
            throw new Exception("Failed to create directory " + file.getParent());
          }
        }

      if (hash.length() > 0) {
        if (!hash.equals(fileHash)) {
          getLogger().debug1("File has changed, possible conflict. Database wins.");
        }
      }

      String xml = submit.get("xml").toString();
      String path = submit.get("path").toString();

      updateLiveFile(xml, path, file, submit.get("object_id").toString());
    }
    catch (Exception e) {
      throw new Exception("Error in submit action: " + e);
    }
  }

  private void updateLiveFile(String xml, String currentPath, File resultFile, String objectID) throws Exception {

    try {
      getLogger().debug6("updating live file " + resultFile.getAbsolutePath());
      Matcher mat = noSchedulerFileRegExPattern.matcher(resultFile.getName());
      if (mat.matches()) {
        getLogger().debug5(resultFile.getAbsolutePath() + " is no scheduler configuration file.");
        FileWriter fstream = new FileWriter(resultFile);
        BufferedWriter out = new BufferedWriter(fstream);
        out.write(xml);
        out.close();
      }
      else {
        ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes("UTF-8"));
        Document xmlDoc = docBuilder.parse(bis);

        writeXMLFile(xmlDoc, resultFile);
      }

      if (objectID != null && objectID.length() > 0) {
        String fileHash = SOSCrypt.MD5encrypt(resultFile);
        String sql = "UPDATE " + JobSchedulerManagedObject.tableManagedObjects + " SET \"HASH\"='" + fileHash + "', \"STATE\"=10 " + " WHERE \"ID\"="
            + objectID;
        getConnection().executeUpdate(sql);
        getConnection().commit();
      }
    }
    catch (Exception e) {
      throw new Exception("Error updating live file: " + e, e);
    }
  }

  private void processActionRemove(File file, HashMap submit) throws Exception {

    try {
      String hash = submit.get("hash").toString();
      String fileHash = "";
      if (file.exists())
        fileHash = SOSCrypt.MD5encrypt(file);

      if (hash.length() > 0) {
        if (!hash.equals(fileHash)) {
          getLogger().debug1("File has changed, possible conflict. Database wins.");
        }
      }
      if (file.exists()) {
        getLogger().debug("deleting file " + file.getAbsolutePath());
        boolean rc = file.delete();
        // check if parent directory is empty
        if (!file.getParentFile().equals(liveFolder) && !file.getParentFile().getParentFile().equals(remoteFolder)
            && file.getParentFile().list().length == 0) {
          getLogger().debug("Parent directory is now empty, deleting parent directory...");
          deleteDirectory(file.getParentFile());
        }
        if (!rc)
          getLogger().warn("failed to delete file " + file.getAbsolutePath());
        else
          if (!isWindows() && !startscript) {
            // notify Job Scheduler
            spooler.execute_xml("<check_folders/>");
          }
      }
    }
    catch (Exception e) {
      throw new Exception("Error in remove action: " + e);
    }
  }

  private void processActionRemoveOrders(File file, HashMap submit) throws Exception {

    try {
      String orderRegEx = file.getName().replaceAll("\\.job_chain\\.xml", ",.*\\.order\\.xml");
      Vector orderFiles = SOSFile.getFilelist(file.getParent(), orderRegEx, 0);
      Iterator iter = orderFiles.iterator();
      boolean dirChanged = false;
      while (iter.hasNext()) {
        File orderFile = (File) iter.next();
        if (orderFile.exists()) {
          getLogger().debug("deleting file " + orderFile.getAbsolutePath());
          boolean rc = orderFile.delete();
          if (!rc)
            getLogger().warn("failed to delete file " + orderFile.getAbsolutePath());
          else
            dirChanged = true;
        }
      }

      if (!isWindows() && !startscript && dirChanged) {
        // notify Job Scheduler
        spooler.execute_xml("<check_folders/>");
      }
    }
    catch (Exception e) {
      throw new Exception("Error in remove orders action: " + e);
    }
  }

  private void processActionRemoveDir(String dir) throws Exception {

    try {
      getLogger().debug6("remove directory: " + dir);

      File d = new File(dir);
      /*
      boolean dirChanged = SOSFileOperations.removeFile(d, SOSFileOperations.REMOVE_DIR
                                                         | SOSFileOperations.RECURSIVE
                                                         | SOSFileOperations.GRACIOUS, getLogger());
      dirChanged |= SOSFileOperations.removeFile(d.getParentFile(),"^"+d.getName()+"$",
                                                              SOSFileOperations.REMOVE_DIR
                                                         | SOSFileOperations.GRACIOUS, getLogger());
       */
      boolean dirChanged = deleteDirectory(d);
      if (!isWindows() && !startscript && dirChanged) {
        // notify Job Scheduler
        spooler.execute_xml("<check_folders/>");
      }
      if (!dirChanged) {
        throw new Exception("Directory " + d.getAbsolutePath() + " could not be removed.");
      }
    }
    catch (Exception e) {
      throw new Exception("Error in remove directory action: " + e);
    }
  }

  private void processActionMove(File oldFile, File newFile, HashMap submit) throws Exception {

    try {
      boolean dirChanged = false;
      getLogger().debug1("Moving " + oldFile.getAbsolutePath() + " to " + newFile.getAbsolutePath());

      SOSFileOperations.renameFile(oldFile, newFile, getLogger());

      // Wenn das parent-Verzeichnis leer ist, kann es gel�scht werden
      // File grandParentDir = oldFile.getParentFile().getParentFile();
      // File parentDir = oldFile.getParentFile();
      // SOSFileOperations.removeFile(grandParentDir, "^"+parentDir.getName()+"$", SOSFileOperations.REMOVE_DIR |
      // SOSFileOperations.GRACIOUS, getLogger());

      /*if (!rc){
        getLogger().warn("Failed to move "+oldFile.getAbsolutePath()+" to "+newFile.getAbsolutePath());
      }else{*/

      dirChanged = true;

      // update state in Managed Objects:
      String sql = "UPDATE " + JobSchedulerManagedObject.tableManagedObjects + " SET \"STATE\"=10 " + " WHERE \"ID\"="
          + submit.get("object_id").toString();
      getConnection().executeUpdate(sql);
      getConnection().commit();

      // reload objects which reference this object
      /*
      String objectID = submit.get("object_id").toString();
      String sql = "SELECT o.\"ID\", o.\"NAME\", o.\"TYPE\", o.\"SPOOLER_ID\", o.\"XML\", t.\"PATH\" "+
      "FROM "+JobSchedulerManagedObject.tableManagedObjects+" o, "+JobSchedulerManagedObject.tableManagedTree+" t, "+JobSchedulerManagedObject.tableManagedRefernces+" r"+
      " WHERE o.\"ID\"=r.\"REFERNCED_BY\" AND o.\"ID\" = t.\"ITEM_ID\" AND r.\"OBJECT_ID\"="+objectID+
      " AND o.\"SUSPENDED\"=0";
      ArrayList referencedObjects = getConnection().getArrayValue(sql);
      reloadObjects(referencedObjects);
      */
      // }

      if (!isWindows() && !startscript && dirChanged) {
        // notify Job Scheduler
        spooler.execute_xml("<check_folders/>");
      }
    }
    catch (Exception e) {
      throw new Exception("Error in move action: " + e);
    }
  }

  private void moveDir(File source, File target, SOSLogger log) throws Exception {

    try {
      SOSFileOperations.renameFile(source, target, SOSFileOperations.GRACIOUS | SOSFileOperations.CREATE_DIR | SOSFileOperations.RECURSIVE, log);

      /*
      SOSFileOperations.removeFile(source, SOSFileOperations.GRACIOUS
                                         | SOSFileOperations.REMOVE_DIR
                                         | SOSFileOperations.RECURSIVE, log);
     
      SOSFileOperations.removeFile(source.getParentFile(), "^"+source.getName()+"$",
                                           SOSFileOperations.GRACIOUS
                                         | SOSFileOperations.REMOVE_DIR, log);
      */
      deleteDirectory(source);
    }
    catch (Exception e) {
      throw new Exception("Failed to move " + source.getAbsolutePath() + " to " + target.getAbsolutePath() + ": " + e, e);
    }
  }

  private void processActionMoveDir(File oldFile, File newFile, HashMap submit) throws Exception {

    try {
      boolean dirChanged = false;
      getLogger().debug1("Moving " + oldFile.getAbsolutePath() + " to " + newFile.getAbsolutePath());
      moveDir(oldFile, newFile, getLogger());
      dirChanged = true;

      String relativePath = submit.get("path").toString();
      if (!relativePath.endsWith("/"))
        relativePath += "/";
      // find ids of all objects in this dir and subdirs
      String sql = "SELECT \"ITEM_ID\" FROM " + JobSchedulerManagedObject.tableManagedTree + " WHERE \"PATH\" LIKE " + "'/" + spooler.id() + relativePath
          + "%'";
      ArrayList objectIDs = getConnection().getArrayValue(sql);
      if (objectIDs.size() > 0) {
        Iterator iter = objectIDs.iterator();
        String comma = "";
        StringBuffer objectIDList = new StringBuffer();
        while (iter.hasNext()) {
          String objectID = (String) iter.next();
          objectIDList.append(comma);
          objectIDList.append(objectID);
          comma = ", ";
        }
        sql = "UPDATE " + JobSchedulerManagedObject.tableManagedObjects + " SET \"STATE\"=10 " + " WHERE \"ID\" IN (" + objectIDList.toString()
            + ") AND \"STATE\"=5";
        getConnection().executeUpdate(sql);
        getConnection().commit();

        // reload objects which reference objects in this dir
        /*
        sql = "SELECT o.\"ID\" o.\"NAME\", o.\"TYPE\", o.\"SPOOLER_ID\", o.\"XML\", t.\"PATH\" "+
                "FROM "+JobSchedulerManagedObject.tableManagedObjects+" o, "+JobSchedulerManagedObject.tableManagedTree+" t, "+JobSchedulerManagedObject.tableManagedRefernces+" r"+
                " WHERE o.\"ID\"=r.\"REFERNCED_BY\" AND o.\"ID\" = t.\"ITEM_ID\" AND r.\"OBJECT_ID\" IN ("+objectIDList.toString()+")"+
                " AND o.\"SUSPENDED\"=0";
        ArrayList referencedObjects = getConnection().getArrayValue(sql);
        reloadObjects(referencedObjects);
        */
      }

      if (!isWindows() && !startscript && dirChanged) {
        // notify Job Scheduler
        spooler.execute_xml("<check_folders/>");
      }
    }
    catch (Exception e) {
      throw new Exception("Error in move action: " + e);
    }
  }

  /*
  private void reloadObjects(ArrayList objects) throws Exception {
 
      try {
      Iterator iter = objects.iterator();
      while (iter.hasNext()) {
        HashMap object = (HashMap) iter.next();
        String xml = object.get("xml").toString();
        String what = getWhat(object.get("type").toString());
        String name = object.get("name").toString();
        String path = object.get("path").toString();
        String scheduler = object.get("spooler_id").toString();
        String objectID = object.get("id").toString();
        writeConfigFile(xml, what, name, path, scheduler, objectID);
      }
    } catch(Exception e) {
      throw new Exception("Error reloading objects: "+e, e);
    }
  }
  */

  public boolean deleteDirectory(File path) {

    if (path.exists()) {
      File[] files = path.listFiles();
      for (int i = 0; i < files.length; i++) {
        boolean rc = true;
        String what = "File ";
        if (files[i].isDirectory()) {
          rc = deleteDirectory(files[i]);
        }
        else {
          rc = files[i].delete();
          what = "Directory";
        }
        if (!rc)
          try {
            getLogger().warn(what + files[i].getAbsolutePath() + " could not be deleted");
          }
          catch (Exception e) {
          }
      }
    }
    return (path.delete());
  }

  private void processActionAndStart(HashMap submit, String host, String port) throws Exception {

    try {
      if (startscript) {
        getLogger().debug1("Start request is skipped, because this is a startscript.");
        return;
      }
      SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(submit.get("xml").toString()));

      String path = submit.get("path").toString();
      path = extractRelativePath(path);
      String endOfPath = new File(path).getName();
      String startPath = new File(path).getParent().replaceAll("\\\\", "/");
      if (startPath.equals("/"))
        startPath = "";

      Matcher mat = hotFolderRegExPattern.matcher(endOfPath);
      mat.matches();
      String type = mat.group(3);
      String name = mat.group(2);

      boolean start = true;
      String nodeQuery = "//add_order[@at]";
      Node runtime;

      if (type.equals("order")) {
        Node atNode = xpath.selectSingleNode(nodeQuery);
        nodeQuery = "//run_time";
        runtime = xpath.selectSingleNode(nodeQuery);

        if (atNode == null && runtime == null) {
          start = false;
          getLog().debug1(
              "processActionAndStart:" + name
                  + " once=yes. Order will not be modified because 'no at and no run_time' is specified by <add_order>");
        }
      }

      nodeQuery = "//run_time[@repeat]";
      runtime = xpath.selectSingleNode(nodeQuery);
      if (runtime != null) {
        start = false;
        getLog().debug1("processActionAndStart:" + name + " once=yes. " + type + " will not be modified because 'repeat' is specified by <run_time>");
      }

      nodeQuery = "//run_time/period[@repeat]";
      runtime = xpath.selectSingleNode(nodeQuery);
      if (runtime != null && start) {
        start = false;
        getLog().debug1("processActionAndStart:" + name + " once=yes. " + type + " will not be started because 'repeat' is specified by <run_time>");
      }

      if (start) {
        String command = "";
        if (type.equalsIgnoreCase("order")) {
          String jobChain = startPath + "/" + mat.group(1);
          command = "<modify_order at=\"now\" job_chain=\"" + jobChain + "\"  order=\"" + name + "\"/>";
        }
        else {
          command = "<start_job job=\"" + name + "\" at=\"now\"/>";
        }

        executeCommandOnOneOrAllSchedulers(host, port, command);
      }
    }
    catch (Exception e) {
      throw new Exception("Error processing start request: " + e, e);
    }
  }

  private void executeCommandOnOneOrAllSchedulers(String host, String port, String command) throws Exception {

    try {
      ArrayList remoteSchedulers = new ArrayList();
      if (port.equalsIgnoreCase("0") && host.equalsIgnoreCase("self")) {
        try {
          spooler.execute_xml(command);
        }
        catch (Exception e) {
          getLogger().warn("Failed to send command: " + e);
        }
      }
      else
        if (port.equalsIgnoreCase("0") && host.equalsIgnoreCase("all")) {
          String answer = spooler.execute_xml("<show_state what=\"remote_schedulers\"/>");
          SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(answer));
          NodeList remoteSchedulerList = xpath.selectNodeList("/spooler/answer/state/remote_schedulers/remote_scheduler[@connected='yes']");
          for (int i = 0; i < remoteSchedulerList.getLength(); i++) {
            Element rem = (Element) remoteSchedulerList.item(i);
            // TODO: besser ip verwenden?
            String currHost = rem.getAttribute("hostname");
            String currPort = rem.getAttribute("tcp_port");
            int iCurrPort = Integer.parseInt(currPort);
            RemoteScheduler sched = new RemoteScheduler(currHost, iCurrPort);
            remoteSchedulers.add(sched);
          }
        }
        else {
          int iPort = Integer.parseInt(port);
          RemoteScheduler sched = new RemoteScheduler(host, iPort);
          remoteSchedulers.add(sched);
        }

      Iterator iter = remoteSchedulers.iterator();
      while (iter.hasNext()) {
        RemoteScheduler scheduler = (RemoteScheduler) iter.next();
        try {
          scheduler.sendCommand(command);
        }
        catch (Exception e) {
          getLogger().warn("Failed to send command: " + e);
        }
      }
    }
    catch (Exception e) {
      throw new Exception("Error executing command: " + e, e);
    }
  }

  private void processActionTryOut(HashMap submit, String host, String port) throws Exception {

    try {
      if (startscript) {
        getLogger().debug1("TryOut request is skipped, because this is a startscript.");
        return;
      }
      String path = submit.get("path").toString();
      path = extractRelativePath(path);

      String endOfPath = new File(path).getName();
      String startPath = new File(path).getParent().replaceAll("\\\\", "/");
      if (startPath.equals("/"))
        startPath = "";

      Matcher mat = hotFolderRegExPattern.matcher(endOfPath);
      mat.matches();

      String jobChain = startPath + "/" + mat.group(1);

      ByteArrayInputStream bai = new ByteArrayInputStream(submit.get("xml").toString().getBytes());
      InputSource source = new InputSource(bai);

      Document orderDoc = docBuilder.parse(source);
      Element orderElement = orderDoc.getDocumentElement();
      orderElement.removeAttribute("at");
      orderElement.removeAttribute("id");
      orderElement.setAttribute("job_chain", jobChain);
      NodeList orderChildren = orderElement.getChildNodes();
      for (int i = 0; i < orderChildren.getLength(); i++) {
        Node child = orderChildren.item(i);
        if (child.getNodeName().equals("run_time")) {
          orderElement.removeChild(child);
        }
      }

      StringWriter out = new StringWriter();
      OutputFormat format = new OutputFormat(orderDoc);
      XMLSerializer serializer = new XMLSerializer(out, format);
      serializer.serialize(orderDoc);
      out.close();

      executeCommandOnOneOrAllSchedulers(host, port, out.toString());
    }
    catch (Exception e) {
      throw new Exception("Error processing tryout request: " + e, e);
    }
  }

  private void writeXMLFile(Document xml, File file) throws Exception {

    try {
      getLogger().debug("writing " + file.getAbsolutePath());
      OutputStream fout = new FileOutputStream(file, false);
      OutputStreamWriter out = new OutputStreamWriter(fout, "UTF-8");
      OutputFormat format = new OutputFormat(xml);
      format.setEncoding("UTF-8");
      format.setIndenting(true);
      format.setIndent(2);
      XMLSerializer serializer = new XMLSerializer(out, format);
      serializer.serialize(xml);
      out.close();
      if (!isWindows() && !startscript) {
        // notify Job Scheduler
        spooler.execute_xml("<check_folders/>");
      }
    }
    catch (Exception e) {
      throw new Exception("Error writing xml file: " + e, e);
    }
  }

  private static boolean isWindows() {

    String OS = System.getProperty("os.name").toLowerCase();
    boolean win = false;

    if ((OS.indexOf("windows") > -1)) {
      win = true;
    }
    return win;
  }

  private static final String extractRelativePath(String path) throws Exception {

    String relativePath = "";
    if (path.startsWith("/live/"))
      relativePath = path.substring(4);
    if (path.startsWith("/remote/")) {
      int index = path.indexOf('/', 8);
      relativePath = path.substring(index);
    }
    return relativePath;
  }

  private void logSubmit(HashMap submit) {

    try {
      String id = "";
      if (submit.get("id") != null) {
        id = submit.get("id").toString();
      }
      getLogger().debug7("Processing submit[" + id + "]:");
      Iterator iter = submit.keySet().iterator();
      while (iter.hasNext()) {
        String key = iter.next().toString();
        if (key.equals("xml")) {
          getLogger().debug9("  " + key + ": " + submit.get(key));
        }
        else
          if (!key.equals("id")) {
            getLogger().debug7("  " + key + ": " + submit.get(key));
          }
      }
    }
    catch (Exception e) {
    } // do nothing
  }

  @SuppressWarnings("unchecked")
  private void processDirs() throws Exception {

    dbCache = new HashMap();

    try {
      String sql = "SELECT o.\"ID\", o.\"SUSPENDED\", o.\"HASH\", t.\"PATH\", t.\"TYPE\", t.\"OWNER\", t.\"GROUP\", "
          + "t.\"ID\" AS \"TREE_ID\", t.\"PERMISSION\" ";
      if (!(getConnection() instanceof SOSOracleConnection)) {
        sql += " FROM " + JobSchedulerManagedObject.tableManagedTree + " t LEFT OUTER JOIN " + " " + JobSchedulerManagedObject.tableManagedObjects
            + " o ON o.\"ID\"=t.\"ITEM_ID\"" + " WHERE (t.\"LINK_ID\"=0 OR t.\"LINK_ID\" IS NULL) ";
      }
      else {
        sql += " FROM " + JobSchedulerManagedObject.tableManagedTree + " t," + " " + JobSchedulerManagedObject.tableManagedObjects + " o"
            + " WHERE o.\"ID\"(+)=t.\"ITEM_ID\" ";
      }
      sql += "AND (t.\"PATH\" LIKE '/" + spooler.id() + "/%' OR t.\"PATH\"='/" + spooler.id() + "')";
      ArrayList dbContent = getConnection().getArray(sql);

      if (dbContent.size() == 0)
        createDBSupervisorDir();

      Iterator dbIterator = dbContent.iterator();
      while (dbIterator.hasNext()) {
        HashMap node = (HashMap) dbIterator.next();
        String path = node.get("path").toString();
        String type = node.get("type").toString();
        char cType = type.charAt(0);
        switch (cType) {
          case 'd':
          case 'm':
            break;
          case 'o':
          case 'i':
          case 'l':
          case 'c':
          case 'p':
          case 's':
          case 'v':
            path = path + "." + getWhat(type) + ".xml";
            break;
          case 'j':
            path = path + ".job.xml";
            break;
          case 't':
            path = path + ".schedule.xml";
            break;
          default:
            continue;
        }

        dbCache.put(getPathWithoutSupervisor(path), node);
      }
    }
    catch (Exception e) {
      throw new Exception("Error creating local cache of managed objects in database: " + e, e);
    }

    try {
      // iterate over all remote folders
      /*
      Vector folderList = SOSFile.getFolderlist(remoteFolder.getAbsolutePath(), ".*", 0, false);
      Iterator folderIterator = folderList.iterator();
      while (folderIterator.hasNext()){
          File currentDir = (File) folderIterator.next();
          if (!currentDir.isDirectory()) continue;       
          processDir(currentDir,"/remote/"+currentDir.getName());
      }
      */
      processDir(remoteFolder, "/remote");
      processDir(liveFolder, "/live");

    }
    catch (Exception e) {
      throw new Exception("Error processing directories: " + e, e);
    }
  }

  private void processDir(File directory, String dbDir) {

    try {
      getLogger().debug7("Processing directoy " + dbDir);
      // check if current dir is in db
      Object obj = dbCache.get(dbDir);
      if (obj == null) {
        getLogger().info("Directory " + dbDir + " does not exist in database. Creating directory...");
        createDBDir(dbDir);
      }

      // iterate over files in this dir
      Vector fileList = SOSFile.getFilelist(directory.getAbsolutePath(), ".*", java.util.regex.Pattern.CASE_INSENSITIVE);
      Iterator fileIterator = fileList.iterator();
      while (fileIterator.hasNext()) {
        File confFile = (File) fileIterator.next();
        processFile(confFile, dbDir + "/" + confFile.getName());
      }

      // iterate over subfolders
      Vector folderList = SOSFile.getFolderlist(directory.getAbsolutePath(), ".*", 0, false);
      Iterator folderIterator = folderList.iterator();
      while (folderIterator.hasNext()) {
        File currentDir = (File) folderIterator.next();
        if (!currentDir.isDirectory())
          continue;
        processDir(currentDir, dbDir + "/" + currentDir.getName());
      }
    }
    catch (Exception e) {
      try {
        getLogger().warn("Failed to process directory " + directory.getAbsolutePath() + ": " + e);
      }
      catch (Exception f) {
      }
    }
  }

  private void processFile(File confFile, String dbPath) {

    try {
      getLogger().debug7("Processing file " + dbPath);
      Matcher mat = noSchedulerFileRegExPattern.matcher(confFile.getName());
      boolean schedulerFile = !mat.matches();
      if (schedulerFile || !isBinary(confFile)) {
        // check if current dir is in db
        Object obj = dbCache.get(dbPath);
        if (obj == null) {
          getLogger().info("Configuration file " + dbPath + " does not exist in database. Adding file...");
          createDBFile(confFile, dbPath, schedulerFile);
        }
        else {
          String fileHash = SOSCrypt.MD5encrypt(confFile);
          HashMap dbObject = (HashMap) obj;
          String dbHash = dbObject.get("hash").toString();
          if (dbHash.equalsIgnoreCase(fileHash)) {
            getLogger().debug9("File is unchanged: " + dbPath);
          }
          else {
            if (dbHash.length() == 0) {
              getLogger().debug1("File has been added to folder and database. Conflict->folder wins");
            }
            getLogger().info("Configuration file " + dbPath + " has changed. Updating database.");
            updateDBFile(confFile, dbPath, fileHash, dbObject, schedulerFile);
          }
        }
      }
    }
    catch (Exception e) {
      try {
        getLogger().warn("Failed to process file " + confFile.getAbsolutePath() + ": " + e);
      }
      catch (Exception f) {
      }
    }
  }

  private boolean isBinary(File file) throws Exception {
    try {
      boolean result = false;

      InputStream in = new FileInputStream(file);

      int curByte = in.read();
      while (curByte != -1 && result == false) {
        if (curByte == 0) {
          result = true;
          break;
        }
        curByte = in.read();
      }

      in.close();
      if (result)
        getLogger().debug5("File " + file.getAbsolutePath() + " is binary.");
      return result;
    }
    catch (Exception e) {
      throw new Exception("Failed to check if file " + file.getAbsolutePath() + " is binary: " + e, e);
    }
  }

  private void updateDBFile(File confFile, String path, String hash, HashMap dbObject, boolean isSchedulerFile) throws Exception {

    try {
      String type = "";
      if (isSchedulerFile)
        type = getType(confFile);
      else
        type = "m";

      String sql = "UPDATE " + JobSchedulerManagedObject.tableManagedObjects + " SET \"TYPE\"='" + type + "', \"HASH\"='" + hash
          + "', \"STATE\"=10 WHERE \"ID\"=" + dbObject.get("id").toString();
      getConnection().execute(sql);

      String fileContent = SOSFile.readFileUnicode(confFile);
      getConnection().updateClob(JobSchedulerManagedObject.tableManagedObjects, "XML", fileContent, "\"ID\"=" + dbObject.get("id").toString());

      if (isDatabaseInterfaceSupported) {
        /* begin: ap 2008-09-19 */

        spooler_log.debug1("live confFile: " + confFile.getAbsolutePath());
        spooler_log.debug1("live path: " + path);

        JobSchedulerLiveXml liveXml = new JobSchedulerLiveXml(this.getConnection(), this.getLogger(), confFile);
        // TODO remove live folder from path
        liveXml.store(path.substring(6));

        /* end: ap 2008-09-19 */
      }

      String treeID = (dbObject.get("tree_id") != null) ? dbObject.get("tree_id").toString() : "";
      if (treeID.equals("")) {
        String name = path.replaceAll("\\\\", "/");
        if (isSchedulerFile)
          name = name.replaceAll("\\..*\\.xml$", "");
        String dbPath = "/" + spooler.id() + name;
        treeID = this.getConnection().getSingleValue(
            "SELECT \"ID\" FROM " + JobSchedulerManagedObject.tableManagedTree + " WHERE \"PATH\"='" + dbPath + "'");
      }
      if (treeID.equals(""))
        throw new Exception("element not found in tree: " + path);

      sql = "UPDATE " + JobSchedulerManagedObject.tableManagedTree + " SET \"TYPE\"='" + type
          + "', \"MODIFIED\"=%now, \"MODIFIED_BY\"='Managed Starter 3' WHERE \"ID\"=" + treeID;
      getConnection().execute(sql);
      getConnection().commit();

      // log to submission table
      int nextSubmissionID = getConnectionSettings().getLockedSequence("scheduler", "counter", "scheduler_managed_submissions.id");
      sql = "INSERT INTO "
          + JobSchedulerManagedObject.tableManagedSubmits
          + " (\"ID\", \"OBJECT_ID\", \"TREE_ID\", \"PATH\", \"OLD_PATH\", \"SPOOLER_ID\", \"ACTION\", \"STATE\",  \"MODIFIED\", \"MODIFIED_BY\", \"HASH\") "
          + "VALUES(" + nextSubmissionID + ", " + dbObject.get("id").toString() + ", " + treeID + ", '" + path + "', '" + path + "', '"
          + spooler.id() + "', 'submit', 'stored', %now, 'Managed Starter 3', '" + hash + "')";
      getConnection().executeUpdate(sql);
      getConnection().commit();

      // update cache
      dbObject.put("hash", hash);
      dbObject.put("type", type);
    }
    catch (Exception e) {
      throw new Exception("Failed to update file in database: " + e, e);
    }
  }

  private String getType(File configFile) throws Exception {

    String type = "";

    try {
      Matcher mat = hotFolderRegExPattern.matcher(configFile.getName());
      mat.matches();

      String longType = mat.group(3);
      type = getType(longType);
      if (type.length() > 1)
        throw new Exception(type);

      if (longType.equals("job")) {
        if (isOrderJob(configFile))
          type = "j";
      }
      if (longType.equals("schedule")) {
        if (isSubstituteSchedule(configFile))
          type = "t";
      }
    }
    catch (Exception e) {
      throw new Exception("Failed to get type for file [" + configFile.getAbsolutePath() + "]: " + e);
    }
    return type;
  }

  private boolean isOrderJob(File configFile) throws Exception {

    SOSXMLXPath xp = new SOSXMLXPath(configFile.getAbsolutePath());
    String orderAtt = xp.selectSingleNodeValue("/job/@order");
    if (orderAtt != null && orderAtt.equalsIgnoreCase("yes")) {
      getLogger().debug8("File " + configFile + " is orderjob.");
      return true;
    }
    getLogger().debug8("File " + configFile + " is independent job.");
    return false;
  }

  private boolean isSubstituteSchedule(File configFile) throws Exception {

    SOSXMLXPath xp = new SOSXMLXPath(configFile.getAbsolutePath());
    String orderAtt = xp.selectSingleNodeValue("/schedule/@substitute");
    if (orderAtt != null && orderAtt.length() > 0) {
      getLogger().debug8("File " + configFile + " is substitute schedule.");
      return true;
    }
    getLogger().debug8("File " + configFile + " is ordinary schedule.");
    return false;
  }

  private void createDBFile(File confFile, String path, boolean isSchedulerFile) throws Exception {

    try {
      String parentID = "0";

      if (confFile == null)
        throw new Exception("why is confFile null?");

      String name = confFile.getName();
      if (isSchedulerFile)
        name = name.replaceAll("\\..*\\.xml$", "");
      String owner = "0";
      String group = "0";
      String permission = "774";
      String fileHash = SOSCrypt.MD5encrypt(confFile);

      File dirFile = new File(path);
      String parentPath = dirFile.getParent().replaceAll("\\\\", "/");
      String dbPath = "/" + spooler.id() + parentPath + "/" + name;
      HashMap parent = (HashMap) dbCache.get(parentPath);
      if (parent == null)
        throw new Exception("failed to find parent directory of " + path + " in database.");
      parentID = (parent.get("tree_id") != null) ? parent.get("tree_id").toString() : "";
      if (parentID.equals(""))
        parentID = this.getConnection().getSingleValue(
            "SELECT \"ID\" FROM " + JobSchedulerManagedObject.tableManagedTree + " WHERE \"PATH\"='" + "/" + spooler.id() + parentPath + "'");
      owner = (parent.get("owner") != null) ? parent.get("owner").toString() : "";
      group = (parent.get("group") != null) ? parent.get("group").toString() : "";
      permission = (parent.get("permission") != null) ? parent.get("permission").toString() : "";

      int nextID = 0;
      int nextObjectID = 0;
      String type = "";
      if (isSchedulerFile)
        type = getType(confFile);
      else
        type = "m";
      nextID = getConnectionSettings().getLockedSequence("scheduler", "counter", "scheduler_managed_tree.id");
      nextObjectID = getConnectionSettings().getLockedSequence("scheduler", "counter", "scheduler_managed_objects.id");
      String sql = "INSERT INTO " + JobSchedulerManagedObject.tableManagedObjects + " (\"ID\", \"NAME\", \"TYPE\", \"HASH\", \"STATE\", \"REFERENCE\") "
          + "VALUES(" + nextObjectID + ", '" + name + "', '" + type + "', '" + fileHash + "', 10, 0)";
      getConnection().execute(sql);
      String fileContent = SOSFile.readFileUnicode(confFile);
      getConnection().updateClob(JobSchedulerManagedObject.tableManagedObjects, "XML", fileContent, "\"ID\"=" + nextObjectID);

      if (isDatabaseInterfaceSupported) {
        /* begin: ap 2008-09-19 */

        spooler_log.debug1("live confFile: " + confFile.getAbsolutePath());
        spooler_log.debug1("live path: " + path);

        JobSchedulerLiveXml liveXml = new JobSchedulerLiveXml(this.getConnection(), this.getLogger(), confFile);
        // TODO remove live folder from path
        liveXml.store(path.substring(6));

        /* end: ap 2008-09-19 */
      }

      sql = "INSERT INTO "
          + JobSchedulerManagedObject.tableManagedTree
          + " (\"ID\", \"PARENT\", \"LEAF\", \"TYPE\", \"ITEM_ID\", \"NAME\", \"OWNER\", \"GROUP\", \"PERMISSION\", \"CREATED\", \"CREATED_BY\", \"MODIFIED\", \"MODIFIED_BY\", \"PATH\") "
          + "VALUES(" + nextID + ", " + parentID + ", 1, '" + type + "', " + nextObjectID + ", '" + name + "', " + owner + ", " + group + ", "
          + permission + ", %now, 'Managed Starter 3', %now, 'Managed Starter 3', '" + dbPath + "')";
      getConnection().execute(sql);
      getConnection().commit();

      // log to submission table
      int nextSubmissionID = getConnectionSettings().getLockedSequence("scheduler", "counter", "scheduler_managed_submissions.id");
      sql = "INSERT INTO "
          + JobSchedulerManagedObject.tableManagedSubmits
          + " (\"ID\", \"OBJECT_ID\", \"TREE_ID\", \"PATH\", \"OLD_PATH\", \"SPOOLER_ID\", \"ACTION\", \"STATE\",  \"MODIFIED\", \"MODIFIED_BY\", \"HASH\") "
          + "VALUES(" + nextSubmissionID + ", " + nextObjectID + ", " + nextID + ", '" + path + "', '" + path + "', '" + spooler.id()
          + "', 'submit', 'stored', %now, 'Managed Starter 3', '" + fileHash + "')";
      getConnection().executeUpdate(sql);
      getConnection().commit();

      // update cache
      HashMap newFile = new HashMap();
      newFile.put("id", "" + nextObjectID);
      newFile.put("suspended", "0");
      newFile.put("hash", fileHash);
      newFile.put("path", dbPath);
      newFile.put("type", type);
      newFile.put("owner", owner);
      newFile.put("group", group);
      newFile.put("tree_id", "" + nextID);
      newFile.put("permission", permission);
      dbCache.put(path, newFile);
    }
    catch (Exception e) {
      throw new Exception("Failed to create file in database: " + e, e);
    }
  }

  private void createDBSupervisorDir() throws Exception {

    try {
      getLogger().info("creating supervisor root dir...");
      String parentID = "1";
      String dir = "/" + spooler.id();
      String name = "";
      String owner = "0";
      String group = "0";
      String permission = "774";

      File dirFile = new File(dir);
      name = dirFile.getName();

      int nextID = 0;
      // id must be at least 50
      while (nextID < 50) {
        nextID = getConnectionSettings().getLockedSequence("scheduler", "counter", "scheduler_managed_tree.id");
      }
      String sql = "INSERT INTO "
          + JobSchedulerManagedObject.tableManagedTree
          + "(\"ID\", \"PARENT\", \"TYPE\", \"NAME\", \"OWNER\", \"GROUP\", \"PERMISSION\", \"CREATED\", \"CREATED_BY\", \"MODIFIED\", \"MODIFIED_BY\", \"PATH\") "
          + "VALUES (" + nextID + ", " + parentID + ", 'd', '" + name + "', " + owner + ", " + group + ", " + permission
          + ", %now, 'Managed Starter 3', %now, 'Managed Starter 3', '" + dir + "')";
      getConnection().execute(sql);
      getConnection().commit();

      // update cache
      HashMap newDir = new HashMap();
      newDir.put("id", "");
      newDir.put("suspended", "0");
      newDir.put("hash", "");
      newDir.put("path", dir);
      newDir.put("type", "d");
      newDir.put("owner", owner);
      newDir.put("group", group);
      newDir.put("tree_id", "" + nextID);
      newDir.put("permission", permission);
      dbCache.put("/", newDir);
    }
    catch (Exception e) {
      throw new Exception("Failed to create supervisor root directory: " + e, e);
    }
  }

  private void createDBDir(String dir) throws Exception {

    try {
      String parentID = "0";
      String name = dir;
      String owner = "0";
      String group = "0";
      String permission = "774";

      if (!dir.equals("/")) {
        File dirFile = new File(dir);
        String parentPath = dirFile.getParent().replaceAll("\\\\", "/");
        name = dirFile.getName();
        HashMap parent = (HashMap) dbCache.get(parentPath);
        if (parent == null)
          throw new Exception("failed to find parent directory of " + dir + " in database.");
        parentID = (parent.get("tree_id") != null) ? parent.get("tree_id").toString() : "";
        if (parentID.equals(""))
          parentID = this.getConnection().getSingleValue(
              "SELECT \"ID\" FROM " + JobSchedulerManagedObject.tableManagedTree + " WHERE \"PATH\"='" + "/" + spooler.id() + parentPath + "'");
        if (parentID.equals(""))
          parentID = "0";
        owner = (parent.get("owner") != null) ? parent.get("owner").toString() : "0";
        group = (parent.get("group") != null) ? parent.get("group").toString() : "0";
        permission = (parent.get("permission") != null) ? parent.get("permission").toString() : "774";
      }

      int nextID = 0;
      nextID = getConnectionSettings().getLockedSequence("scheduler", "counter", "scheduler_managed_tree.id");
      String sql = "INSERT INTO "
          + JobSchedulerManagedObject.tableManagedTree
          + "(\"ID\", \"PARENT\", \"TYPE\", \"NAME\", \"OWNER\", \"GROUP\", \"PERMISSION\", \"CREATED\", \"CREATED_BY\", \"MODIFIED\", \"MODIFIED_BY\", \"PATH\") "
          + "VALUES(" + nextID + ", " + parentID + ", 'd', '" + name + "', " + owner + ", " + group + ", " + permission
          + ", %now, 'Managed Starter 3', %now, 'Managed Starter 3', '/" + spooler.id() + dir + "')";
      getConnection().execute(sql);
      getConnection().commit();

      // update cache
      HashMap newDir = new HashMap();
      newDir.put("id", "");
      newDir.put("suspended", "0");
      newDir.put("hash", "");
      newDir.put("path", "/" + spooler.id() + dir);
      newDir.put("type", "d");
      newDir.put("owner", owner);
      newDir.put("group", group);
      newDir.put("tree_id", "" + nextID);
      newDir.put("permission", permission);
      dbCache.put(dir, newDir);
    }
    catch (Exception e) {
      throw new Exception("Failed to create directory: " + e, e);
    }
  }

  private void processDatabase() throws Exception {

    try {
      Iterator iter = dbCache.keySet().iterator();
      while (iter.hasNext()) {
        String submitPath = (String) iter.next();
        File realPath = new File(liveFolder.getParentFile(), submitPath);
        if (!realPath.exists()) {
          HashMap dbObject = (HashMap) dbCache.get(submitPath);
          if (dbObject.get("hash") != null && dbObject.get("hash").toString().length() > 0) {
            getLogger().debug1("File " + submitPath + " has been deleted in file system and will be deleted from database.");
            deleteDBFile(dbObject, submitPath);
            iter.remove();
          }
          else {
            getLogger().debug1("File " + submitPath + " is in database but has not yet been submitted.");
          }
        }
      }
    }
    catch (Exception e) {
      throw new Exception("Error processing objects in database: " + e, e);
    }
  }

  private void deleteDBFile(HashMap dbObject, String submitPath) {

    try {
      String treeID = (dbObject.get("tree_id") != null) ? dbObject.get("tree_id").toString() : "0";
      /*
      if (treeID.equals("0")) {
          File dirFile = new File(submitPath);
          String parentPath = dirFile.getParent().replaceAll("\\\\", "/"); 
          treeID = this.getConnection().getSingleValue("SELECT \"ID\" FROM " + JobSchedulerManagedObject.tableManagedTree + " WHERE \"PATH\"='" + "/" + spooler.id() + parentPath + "'");
      }
      */
      if (treeID.equals("0")) {
        spooler_log.debug1("no object found in database, ignoring delete request for file: " + submitPath);
        return;
      }

      String objectID = (dbObject.get("id") != null) ? dbObject.get("id").toString() : "";
      String action = "remove_dir";
      String sql = "DELETE FROM " + JobSchedulerManagedObject.tableManagedTree + " WHERE \"ID\"=" + treeID;
      getConnection().execute(sql);
      if (objectID.length() > 0) { // directories have no object
        action = "remove";
        sql = "DELETE FROM " + JobSchedulerManagedObject.tableManagedObjects + " WHERE \"ID\"=" + objectID;
        getConnection().execute(sql);
      }
      getConnection().commit();

      int nextSubmissionID = getConnectionSettings().getLockedSequence("scheduler", "counter", "scheduler_managed_submissions.id");
      sql = "INSERT INTO " + JobSchedulerManagedObject.tableManagedSubmits
          + " (\"ID\", \"OBJECT_ID\", \"TREE_ID\", \"PATH\", \"OLD_PATH\", \"SPOOLER_ID\", \"ACTION\", \"STATE\",  \"MODIFIED\", \"MODIFIED_BY\") "
          + " VALUES(" + nextSubmissionID + ", " + objectID + ", " + treeID + ", '" + submitPath + "', '" + submitPath + "', '" + spooler.id()
          + "', '" + action + "', 'stored', %now, 'Managed Starter 3')";
      getConnection().executeUpdate(sql);
      getConnection().commit();
    }
    catch (Exception e) {
      String path = "";
      if (dbObject != null && dbObject.get("path") != null)
        path = dbObject.get("path").toString();
      try {
        getLogger().warn("Failed to delete file [" + path + "] from database: " + e);
      }
      catch (Exception f) {
      }
    }
  }

  /*
  private void addParam(Document params, Element p, String name, String value) {
     
      Element param = params.createElement("param");
      param.setAttribute("name", name);
      param.setAttribute("value", value);
      p.appendChild(param);
  }
  */

  public SOSLogger getLog() {

    return getLogger();
  }

  public boolean spooler_process() throws Exception {

    boolean orderJob = true;
    boolean includeInterface = false;

    try {
      if (spooler_task.params().value("include_interface") != null
          && (spooler_task.params().value("include_interface").equalsIgnoreCase("yes")
              || spooler_task.params().value("include_interface").equalsIgnoreCase("true") || spooler_task.params()
              .value("include_interface")
              .equals("1"))) {
        includeInterface = true;
      }

      if (spooler_job.order_queue() != null) {
        Order order = spooler_task.order();
        orderParams = order.params();
        String action = orderParams.value("action");
        if (action == null)
          action = "";

        if (orderParams.value("include_interface") != null
            && (orderParams.value("include_interface").equalsIgnoreCase("yes") || orderParams.value("include_interface").equalsIgnoreCase("true") || orderParams.value(
                "include_interface")
                .equals("1"))) {
          includeInterface = true;
        }

        if (action.equalsIgnoreCase("read_submits")) {
          processSubmits();
        }
        else
          if (action.equalsIgnoreCase("read_interface")) {
            processLive();
          }
          else {
            if (includeInterface)
              processLive();
            processDirs();
            processDatabase();
          }
      }
      else {
        // works only for live folder
        orderJob = false;
        // Variable_set taskParams = spooler_task.params();
        // String eventAction = taskParams.value("scheduler_live_event");
        // String changedFile = taskParams.value("scheduler_live_filepath");
      }

      return orderJob;
    }
    catch (Exception e) {
      getLog().warn("Error occurred processing order: " + e.getMessage());
      spooler_task.order().setback();
      spooler_task.order().params().set_var("message", e.getMessage());
      spooler_task.end();
      return false;
    }
    finally {
      if (this.getConnection() != null) {
        try {
          this.getConnection().rollback();
        }
        catch (Exception ex) {
        } // no error handling
      }
    }
  }

  /*
  private void testOrder() {
 
    startscript=false;
      String name = "Testorder";
      String xml = "<add_order id=\"myOrder\"  job_chain=\"jobchain\"   title=\"Test fuer Managed Starter\"  state=\"100\">       <run_time let_run=\"no\"/></add_order>";
      try  {
          handleOrderInit(name, xml);
      } catch(Exception e) {
          e.printStackTrace();
      }
  }
  */

  /*
  private void testFactoryIni() throws Exception {
 
    startscript=false;
    SOSLogger log = new SOSStandardLogger(SOSLogger.DEBUG9);
    // setLogger(log);
      String name = "TestJob_new";
      String xml = "<email_settings to=\"oh@sos-berlin.com\"/>";
      try {
          updateFactoryIni(xml,name);
      } catch(Exception e) {
          e.printStackTrace();
      }
  }
  */

  /*
  private void testDocumentation() throws Exception {
 
    startscript=false;
      SOSLogger log = new SOSStandardLogger(SOSLogger.DEBUG9);
      SOSConnection conn = SOSConnection.createInstance("j:/e/java/al/sos.scheduler/config/sos_setup_settings.ini", log);
      // setLogger(log);
      try {
         conn.connect();
         String xml = conn.getClob("SELECT \"XML\" FROM SCHEDULER_MANAGED_OBJECTS WHERE \"ID\" = 347");
   
         try {
            updateSchedulerFile(xml, "New_job_documentation.xml", SOSDate.getCurrentTimeAsString(), "documentation");
         } catch(Exception e) {
            e.printStackTrace();
         }
      } catch(Exception e) {
        e.printStackTrace();
      } finally {
        if (conn!=null) conn.disconnect();
      }
  }
  */

  private void liveExport(HashMap rec) throws Exception {

    // Get all dependent elements
    String object_name = getLiveValue(rec, "name");
    String object_path = getLiveValue(rec, "path");
    String object_type = getLiveValue(rec, "type");
    File currentFile = null;

    listOfElements = new LinkedHashSet();
    String selStr = "SELECT r.\"PK_ID\", r.\"PARENT_ID\", m.\"ELEMENT_PATH\", m.\"TABLE_NAME\", m.\"ELEMENT_NAME\", m.\"NESTING\"" + " FROM "
        + JobSchedulerManagedObject.getTableLiveObjectMetadata() + " m LEFT JOIN " + JobSchedulerManagedObject.getTableLiveObjectReferences() + " r"
        + " ON m.\"ELEMENT_PATH\"=r.\"OBJECT_PATH\" " + " WHERE r.\"OBJECT_ID\"=" + getLiveValue(rec, "object_id") + " ORDER BY m.\"ORDERING\"";

    ArrayList arrayList = new ArrayList();
    arrayList = this.getConnection().getArray(selStr);
    Iterator xml_elements = arrayList.iterator();

    spooler_log.debug3(selStr);
    while (xml_elements.hasNext()) {
      rec = (HashMap) xml_elements.next();
      JobSchedulerMetadataElement element = new JobSchedulerMetadataElement(rec);
      element.attributes = new HashMap();
      listOfElements.add(element);
      if (element.attributes == null)
        spooler_log.debug3("Hashmap is null");
    }

    String xml = getLiveXml();
    spooler_log.debug3("liveExport: " + xml);

    SOSXMLXPath xpath = new SOSXMLXPath(new StringBuffer(xml));
    String jobChainName = xpath.selectSingleNodeValue("//order/@job_chain");
    File currentRoot = liveFolder.getParentFile();
    getLogger().debug7("current root folder: " + currentRoot.getAbsolutePath());

    if (jobChainName != null && jobChainName.length() > 0) {
      xml = xml.replaceFirst(" job_chain=\"" + jobChainName + "\"", "");
      currentFile = new File(liveFolder + "/" + object_path, jobChainName + "," + object_name + "." + object_type + ".xml");
    }
    else {
      currentFile = new File(liveFolder + "/" + object_path, object_name + "." + object_type + ".xml");
    }
    getLogger().debug7("current file: " + currentFile.getAbsolutePath());

    if (!currentFile.exists()) {
      if (!currentFile.getParentFile().exists()) {
        getLogger().debug1("Creating directory " + currentFile.getParent());
        if (!currentFile.getParentFile().mkdirs()) {
          throw new Exception("Failed to create directory " + currentFile.getParent());
        }
      }
    }

    updateLiveFile(xml, object_path, currentFile, "");
    getLog().info("Object synchronized from database interface: " + object_path + "/" + currentFile.getName());
  }

  private String getLiveXml() throws Exception {

    String erg = "";
    JobSchedulerMetadataElement element = null;
    JobSchedulerMetadataElement rootElement = null;

    Iterator it = listOfElements.iterator();
    while (it.hasNext()) {
      element = (JobSchedulerMetadataElement) it.next();
      if (rootElement == null) {
        rootElement = element;
      }
      element.attribute = getLiveAttributes(element);
    }

    String encoding = "ISO-8859-1";
    org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
    String xml = "<?xml version=\"1.0\" encoding=\"" + encoding + "\"?> ";
    xml += "<" + rootElement.element_name + " " + rootElement.attribute + "></" + rootElement.element_name + ">";
    spooler_log.debug3(xml);
    org.jdom.Document parentDoc = builder.build(new java.io.StringReader(xml));
    org.jdom.Element root = parentDoc.getRootElement();

    it = listOfElements.iterator();
    element = (JobSchedulerMetadataElement) it.next(); // ignore root element
    String s = "";
    org.jdom.Element aktEle = root;
    while (it.hasNext()) {
      element = (JobSchedulerMetadataElement) it.next();
      if (element.nesting != -1) {
        aktEle = liveAddMissingNodes(root, element);

        s = element.element_name;
        org.jdom.Element ele = new org.jdom.Element(s);
        setLiveXmlAttribute(element, ele);

        aktEle.addContent(ele);
        element.nesting = -1;
        liveAddDependendNodes(element, root, aktEle);
      }
    }

    org.jdom.output.XMLOutputter output = new org.jdom.output.XMLOutputter(org.jdom.output.Format.getPrettyFormat());
    erg = output.outputString(root);
    erg = erg.replaceAll("pk_id=\"[0-9]*\"", "");
    return erg;
  }

  private boolean livePathContains(JobSchedulerMetadataElement element, JobSchedulerMetadataElement el) {

    boolean erg = true;
    int eSize = element.elements.size();
    int pSize = el.elements.size();

    int minSize = pSize;
    if (eSize < pSize)
      minSize = eSize;

    for (int i = 0; i < minSize; i++) {
      if (!element.elements.get(i).toString().equals(el.elements.get(i).toString())) {
        spooler_log.debug3("--->" + element.elements.get(i) + "<>" + el.elements.get(i));
        erg = false;
      }
    }

    return erg;
  }

  private void liveAddDependendNodes(JobSchedulerMetadataElement parent, org.jdom.Element root, org.jdom.Element aktEle) {

    spooler_log.debug3("looking for depending nodes of:" + aktEle.getName());
    Iterator it = listOfElements.iterator();
    JobSchedulerMetadataElement element = (JobSchedulerMetadataElement) it.next(); // ignore root element
    String s = "";
    while (it.hasNext()) {
      element = (JobSchedulerMetadataElement) it.next();
      if (element.nesting != -1) {
        if (element.parent_id.equals(parent.pkid) && livePathContains(element, parent)) {
          aktEle = liveAddMissingNodes(root, element);
          s = element.element_name;
          spooler_log.debug3("adding depending node:" + s + "-->" + aktEle.getName());

          org.jdom.Element ele = new org.jdom.Element(s);
          setLiveXmlAttribute(element, ele);

          aktEle.addContent(ele);
          element.nesting = -1;
          liveAddDependendNodes(element, root, ele);
        }
      }
    }
  }

  private org.jdom.Element liveAddMissingNodes(org.jdom.Element root, JobSchedulerMetadataElement element) {

    org.jdom.Element aktEle = root;
    String s = "";
    for (int i = 1; i < element.nesting; i++) {
      s = element.elements.get(i).toString();
      spooler_log.debug3("checking " + s);
      if (aktEle.getChild(s) == null) {
        spooler_log.debug3("adding:" + s);
        org.jdom.Element ele = new org.jdom.Element(s);
        aktEle.addContent(ele);
        aktEle = ele;
      }
      else {
        List children = aktEle.getChildren(s);
        if (children.size() == 1) {
          aktEle = aktEle.getChild(s);
        }
        else {

          // Looking up the current child.
          Iterator itChildren = children.iterator();
          while (itChildren.hasNext()) {
            org.jdom.Element node = (org.jdom.Element) itChildren.next();
            List l = node.getAttributes();
            Iterator itAttr = l.iterator();
            while (itAttr.hasNext()) {
              org.jdom.Attribute attr = (org.jdom.Attribute) itAttr.next();
              if (attr.getName().equals("pk_id") && (attr.getValue().equals(element.parent_id))) {
                aktEle = node;
              }
            }
          }
        }
      }
    }
    return aktEle;
  }

  private void setLiveXmlAttribute(JobSchedulerMetadataElement element, org.jdom.Element ele) {

    Iterator attrs = element.attributes.keySet().iterator();
    while (attrs.hasNext()) {
      String k = attrs.next().toString();
      spooler_log.debug3(k + "=" + element.attributes.get(k).toString());
      ele.setAttribute(k, element.attributes.get(k).toString());
    }
  }

  private String getLiveAttributes(JobSchedulerMetadataElement element) throws Exception {

    // To get the table name of the element
    HashMap rec = null;
    String attr = "";
    if (element.table_name.equals("")) {
      return null;
    }
    else {
      String selStr = "SELECT * FROM " + element.table_name + " WHERE \"PK_ID\" = " + element.pkid;
      ArrayList arrayList = new ArrayList();
      arrayList = this.getConnection().getArray(selStr);
      Iterator resultset = arrayList.iterator();
      if (resultset.hasNext()) {
        rec = (HashMap) resultset.next();
        Iterator fieldnames = rec.keySet().iterator();
        while (fieldnames.hasNext()) {
          String f = fieldnames.next().toString();
          if (!f.equals("object_path") && !f.equals("cdata") && !f.equals("parent_id") && !f.equals("object_id") && rec.get(f) != null
              && !rec.get(f).equals("")) {
            attr += f;
            attr += "=\"" + rec.get(f) + "\"" + " ";
            element.attributes.put(f, rec.get(f).toString());
          }
        }
      }
    }
    return attr.trim();
  }

  private String getLiveValue(HashMap h, String k) {

    String erg = "";
    try {
      if (h.containsKey(k) && h.get(k) == null) {
        erg = "";
      }
      else {
        erg = h.get(k).toString();
      }
      return erg;
    }
    catch (Exception e) {
      return "";
    }
  }

  public static void main(String args[]) throws Exception {

    /*
    JobSchedulerManagedStarter_3 x = new JobSchedulerManagedStarter_3();

    String source = "C:/scheduler.managed/config/live/test/datei";
    File oldFile = new File(source);
    File grandParentDir = oldFile.getParentFile().getParentFile();
    File parentDir      = oldFile.getParentFile();
     */

    /*   
    File f = new File(source);
    System.out.println("f.getParentFile().getName(): "+f.getParentFile().getName());
    System.out.println("f.getParentFile(): "+f.getParentFile());
    System.out.println("f.getParentFile().getParentFile(): "+f.getParentFile().getParentFile());
    SOSFileOperations.removeFile(f.getParentFile().getParentFile(), "^"+f.getParentFile().getName()+"$", SOSFileOperations.REMOVE_DIR, new SOSStandardLogger(9));
     */

    // x.testDocumentation();
    // x.testOrder();
    // x.testFactoryIni();
  }

}
TOP

Related Classes of sos.scheduler.managed.JobSchedulerManagedStarter_3

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.