001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.common.util.service;
017
018import static org.kuali.common.util.log.Loggers.newLogger;
019
020import java.util.List;
021
022import org.codehaus.plexus.util.cli.CommandLineException;
023import org.codehaus.plexus.util.cli.CommandLineUtils;
024import org.codehaus.plexus.util.cli.Commandline;
025import org.codehaus.plexus.util.cli.StreamConsumer;
026import org.kuali.common.util.CollectionUtils;
027import org.kuali.common.util.log.LoggerLevel;
028import org.kuali.common.util.stream.LoggingStreamConsumer;
029import org.slf4j.Logger;
030
031public class DefaultExecService implements ExecService {
032
033        private static final Logger logger = newLogger();
034
035        @Override
036        public int execute(ExecContext context) {
037                Commandline cl = getCommandLine(context);
038                return execute(context, cl);
039        }
040
041        @Override
042        public int execute(String executable, List<String> args) {
043                DefaultExecContext context = new DefaultExecContext();
044                context.setExecutable(executable);
045                context.setArgs(args);
046                return execute(context);
047        }
048
049        protected int executeAndValidate(String executable, List<String> args) {
050                int exitValue = execute(executable, args);
051                validateExitValue(exitValue);
052                return exitValue;
053        }
054
055        protected int executeAndValidate(ExecContext context) {
056                int exitValue = execute(context);
057                validateExitValue(exitValue);
058                return exitValue;
059        }
060
061        protected int execute(ExecContext context, Commandline cl) {
062                try {
063                        logger.debug("[{}]", cl);
064                        StreamConsumer stdout = getConsumer(context.getStandardOutConsumer(), logger, LoggerLevel.INFO);
065                        StreamConsumer stderr = getConsumer(context.getStandardErrConsumer(), logger, LoggerLevel.WARN);
066                        return CommandLineUtils.executeCommandLine(cl, context.getInput(), stdout, stderr, context.getTimeoutInSeconds());
067                } catch (CommandLineException e) {
068                        throw new IllegalStateException(e);
069                }
070        }
071
072        protected StreamConsumer getConsumer(StreamConsumer provided, Logger logger, LoggerLevel level) {
073                if (provided != null) {
074                        return provided;
075                } else {
076                        return new LoggingStreamConsumer(logger, level);
077                }
078        }
079
080        /**
081         * @deprecated
082         */
083        @Deprecated
084        protected StreamConsumer getStreamConsumer(StreamConsumer provided, Logger logger, org.kuali.common.util.LoggerLevel level) {
085                if (provided != null) {
086                        return provided;
087                } else {
088                        return new org.kuali.common.util.LoggingStreamConsumer(logger, level);
089                }
090        }
091
092        protected void validateExitValue(int exitValue) {
093                if (exitValue != 0) {
094                        throw new IllegalStateException("Non-zero exit value - " + exitValue);
095                }
096        }
097
098        protected Commandline getCommandLine(ExecContext context) {
099                Commandline cl = new Commandline();
100                cl.setExecutable(context.getExecutable());
101                if (context.isAddSystemEnvironment()) {
102                        try {
103                                cl.addSystemEnvironment();
104                        } catch (Exception e) {
105                                throw new IllegalStateException(e);
106                        }
107                }
108                if (context.getArgs() != null) {
109                        cl.addArguments(CollectionUtils.toStringArray(context.getArgs()));
110                }
111                if (context.getWorkingDirectory() != null) {
112                        cl.setWorkingDirectory(context.getWorkingDirectory());
113                }
114                return cl;
115        }
116
117}