package jp.co.areaweb.tools.command;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;

public class XmlJob
{
    public static final boolean debug = false;

    /**
     * Jobファイルに記述されたコマンドを順次実行する。
     * @param jobFile Jobコマンドが記述されたファイル
     * @throws IOException JOBファイルの読み込み障害
     */
    public static void execJob(File jobFile) throws Exception {
        execJob(jobFile, null);
    }

    /**
     * Jobファイルに記述されたコマンドを順次実行する。
     * @param jobFile Jobコマンドが記述されたファイル
     * @param workDir コマンドを実行するさいのカレントディレクトリ
     * @throws IOException JOBファイルの読み込み障害
     */
    public static void execJob(File jobFile, File workDir) throws Exception {
        if (jobFile == null) {
            throw new IOException("実行するジョブファイルが指定されていません。");
        }
        
        if (debug) {
            System.out.println("[s JobFile] " + jobFile.getName());
        }
        
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Node rootNode = builder.parse(new FileInputStream(jobFile));
        NodeList nl = rootNode.getChildNodes();
        for (int i=0; i < nl.getLength(); i++) {
            Node jobgroupTag = nl.item(i);
            if (jobgroupTag.getNodeType() == Node.ELEMENT_NODE) {
                if ((jobgroupTag.getNodeName()).equals("jobgroup")) {
                    execJobElement(jobFile, workDir, jobgroupTag.getChildNodes());
                }
                else if ((jobgroupTag.getNodeName()).equals("xalan")) {
                    Xalan.execJobElement(jobgroupTag.getChildNodes(), workDir);
                }
            }
        }

        if (debug) {
            System.out.println("[e JobFile] " + jobFile.getName());
        }
    }

    /**
     * Jobファイルに記述されたコマンドを順次実行する。
     * @param jobFile Jobコマンドが記述されたファイル
     * @param workDir コマンドを実行するさいのカレントディレクトリ
     * @throws IOException JOBファイルの読み込み障害
     */
    protected static void execJobElement(File jobFile, File workDir, NodeList jobgroupNodes)
            throws Exception {
        if (debug) {
            System.out.println("XmlJob.execJobElement()");
        }
        
        String stdout = null;
        String errout = null;
        Vector<Command> commands = new Vector<Command>();

        for (int i=0; i < jobgroupNodes.getLength(); i++) {
            Node node = jobgroupNodes.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                String tagName = node.getNodeName();
                if (tagName.equals("job")) {
                    NodeList jobNodes = node.getChildNodes();
                    Command command = new Command();
                    for (int j=0; j < jobNodes.getLength(); j++) {
                        Node jobNode = jobNodes.item(j);
                        if (jobNode.getNodeType() == Node.ELEMENT_NODE) {
                            String tagName2 = jobNode.getNodeName();
                            if (tagName2.equals("cmd")) {
                                command.setCmd(jobNode.getFirstChild().getNodeValue());
                            }
                            else if (tagName2.equals("workDir")) {
                                command.setWorkDir(new File(jobNode.getFirstChild().getNodeValue()));
                            }
                        }
                    }
                    commands.addElement(command);                          
                }
                else if (tagName.equals("stdout")) {
                    NamedNodeMap attrs = node.getAttributes();
                    stdout = attrs.getNamedItem("file").getNodeValue();
                }
                else if (tagName.equals("errout")) {
                    NamedNodeMap attrs = node.getAttributes();
                    errout = attrs.getNamedItem("file").getNodeValue();
                }
            }
        }

        // コマンドの実行
        execJobs(stdout, errout, commands);
    }

    /**
     * Vector commandsに格納されたコマンドを順次実行する。
     * @throws IOException JOBファイルの読み込み障害
     */
    protected static void execJobs(String stdout, String errout, Vector<Command> commands) throws IOException {
        // コマンドの実行
        PrintWriter stdoutPW;
        if (stdout == null) {
            stdoutPW = new PrintWriter(System.out);
        }
        else {
            stdoutPW = new PrintWriter(new OutputStreamWriter(new FileOutputStream(new File(stdout))));
        }

        try {
            for (int i=0; i < commands.size(); i++) {
                Command command = commands.get(i);
                command.execCommand();
                stdoutPW.println(command.getOutput());
            }
        }
        finally {
            stdoutPW.close();
        }
    }
    
    /** 
    *	サンプル
    */
    static public void main(String[] args) throws Exception {
        if (args.length < 1) {
            System.out.println("exp: java tool.job.XmlJob [jobFileName]");
            return;
        }

        XmlJob.execJob(new File(args[0]));
    }
}
