001package net.sf.hajdbc.util;
002
003import java.io.BufferedReader;
004import java.io.File;
005import java.io.FileReader;
006import java.io.InputStreamReader;
007import java.io.PrintWriter;
008import java.security.AccessController;
009import java.security.PrivilegedAction;
010import java.security.PrivilegedExceptionAction;
011import java.util.Map;
012
013import net.sf.hajdbc.logging.Level;
014import net.sf.hajdbc.logging.Logger;
015import net.sf.hajdbc.logging.LoggerFactory;
016
017public class Processes
018{
019        private static final Logger logger = LoggerFactory.getLogger(Processes.class);
020
021        public static Map<String, String> environment(final ProcessBuilder builder)
022        {
023                PrivilegedAction<Map<String, String>> action = new PrivilegedAction<Map<String, String>>()
024                {
025                        @Override
026                        public Map<String, String> run()
027                        {
028                                return builder.environment();
029                        }
030                };
031                return AccessController.doPrivileged(action);
032        }
033        
034        public static void run(final ProcessBuilder processBuilder) throws Exception
035        {
036                run(processBuilder, null);
037        }
038
039        public static void run(final ProcessBuilder processBuilder, final File input) throws Exception
040        {
041                processBuilder.redirectErrorStream(true);
042                
043                logger.log(Level.DEBUG, Strings.join(processBuilder.command(), " "));
044                
045                PrivilegedExceptionAction<Process> action = new PrivilegedExceptionAction<Process>()
046                {
047                        @Override
048                        public Process run() throws Exception
049                        {
050                                Process process = processBuilder.start();
051                                if (input != null)
052                                {
053                                        PrintWriter writer = new PrintWriter(process.getOutputStream());
054                                        BufferedReader reader = new BufferedReader(new FileReader(input));
055                                        try
056                                        {
057                                                String line = reader.readLine();
058                                                while (line != null)
059                                                {
060                                                        writer.println(line);
061                                                        line = reader.readLine();
062                                                }
063                                        }
064                                        finally
065                                        {
066                                                reader.close();
067                                        }
068                                }
069                                return process;
070                        }
071                };
072
073                Process process = AccessController.doPrivileged(action);
074
075                try
076                {
077                        int status = process.waitFor();
078                        
079                        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
080                        String line = reader.readLine();
081                        while (line != null)
082                        {
083                                logger.log(Level.DEBUG, line);
084                                line = reader.readLine();
085                        }
086                        
087                        if (status != 0)
088                        {
089                                throw new Exception(String.format("%s returned %d", processBuilder.command().get(0), status));
090                        }
091                }
092                catch (InterruptedException e)
093                {
094                        Thread.currentThread().interrupt();
095                        
096                        throw new Exception(processBuilder.toString(), e);
097                }
098        }
099
100        private Processes()
101        {
102                // Hide
103        }
104}