view src/main/java/org/icedrobot/ika/runtime/IkaRuntime.java @ 29:3b0d6002605a

Add patch to output commands names. Contributed by Giulio Franco.
author Mario Torre <neugens.limasoftware@gmail.com>
date Fri, 15 Apr 2011 17:13:03 +0200
parents 1366f29ac6fa
children
line wrap: on
line source

/*
 * IKA - IcedRobot Kiosk Application
 * Copyright (C) 2011  IcedRobot team
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.icedrobot.ika.runtime;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.icedrobot.ika.output.DefaultWorkerStatus;
import org.icedrobot.ika.output.StatusKeeper;
import org.icedrobot.ika.output.StatusListener;
import org.icedrobot.ika.output.UnformattedConsoleWriter;
import org.icedrobot.ika.output.WorkerStatus;
import org.icedrobot.ika.plugins.IkaPluginException;

public class IkaRuntime {

    private static StatusListener viewer = null;


    /**
     * Executes the given command on the passed path.
     */
    public static void exec(File path, RuntimeCommand command) {
        Process p = startProcess(path, command.getCommandLine());
        trackProcess(command, p);
    }

    /**
     * Executes the given command on the passed path.
     */
    public static void exec(File path, String... commandLine) {
        String commandName = "";

        switch (commandLine.length) {
            default:
                //Falls through
            case 2:
                commandName = commandLine[1] + commandName;
                //Falls through
            case 1:
                commandName = commandLine[0] + commandName;
                break;
            case 0:
                break;
        }
        
        RuntimeCommand command = new RuntimeCommand(commandName, commandLine);
        exec(path, command);
    }

    private static Process startProcess(File path, String... commandLine) {
        try {
            Logger.getLogger(IkaRuntime.class.getName()).log(
                    Level.FINE,
                    "Execution of command {0} in path: {1}",
                    new Object[] { Arrays.toString(commandLine), path } );

            ProcessBuilder pb = new ProcessBuilder(commandLine);
            pb.redirectErrorStream(true);
            pb.directory(path);
            return pb.start();

        } catch (IOException ex) {
            String error = "cannot execute: " + Arrays.toString(commandLine);

            Logger.getLogger(IkaRuntime.class.getName()).
                                                   log(Level.SEVERE, error, ex);
            throw new IkaPluginException(error, ex);
        }        
    }

    private static void trackProcess(RuntimeCommand command, Process proc) {
        BufferedReader input = new BufferedReader(
                                    new InputStreamReader(
                                        proc.getInputStream() ));

        String line;

        registerViewerIfNeeded();

        try {
            while ((line = input.readLine()) != null) {
                command.process(line);
            }

            WorkerStatus lastStatus;
            int exitStatus;

            try {
                exitStatus = proc.waitFor();
                if (exitStatus != 0) {
                    String status = "Terminated with status "
                                                + Integer.toString(exitStatus);
                    
                    lastStatus = new DefaultWorkerStatus( command.getName(),
                                                          1f,
                                                          status);
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(IkaRuntime.class.getName()).log(Level.INFO,
                        "Interrupted while waiting for command termination: "
                        + command.getName(),
                        ex);
            }

            StatusKeeper.getInstance().deregisterWorker(command.getName());
            
        } catch (IOException ex) {
            Logger.getLogger(IkaRuntime.class.getName()).log(
                   Level.SEVERE, command + ": error on the input stream", ex);
            
            throw new IkaPluginException("error on the input stream: "
                                                                + command, ex);
        }

        deregisterViewerIfIdle(StatusKeeper.getInstance());
    }

    private static synchronized void registerViewerIfNeeded () {
        if (StatusKeeper.getInstance().getStatusListenersCount() == 0) {
            viewer = new UnformattedConsoleWriter(System.out);
            StatusKeeper.getInstance().addStatusListener(viewer);
        }
    }

    private static synchronized void deregisterViewerIfIdle (StatusKeeper sk) {
        if (viewer != null && sk.getActiveTasksCount() == 0) {
            sk.removeStatusListener(viewer);
            viewer = null;
        }
    }
}