001/**
002 * Copyright 2010-2013 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 java.util.List;
019
020import org.codehaus.plexus.util.cli.CommandLineException;
021import org.codehaus.plexus.util.cli.CommandLineUtils;
022import org.codehaus.plexus.util.cli.Commandline;
023import org.codehaus.plexus.util.cli.StreamConsumer;
024import org.kuali.common.util.CollectionUtils;
025import org.kuali.common.util.log.LoggerLevel;
026import org.kuali.common.util.stream.LoggingStreamConsumer;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030public class DefaultExecService implements ExecService {
031
032        private static final Logger logger = LoggerFactory.getLogger(DefaultExecService.class);
033
034        @Override
035        public int execute(ExecContext context) {
036                Commandline cl = getCommandLine(context);
037                return execute(context, cl);
038        }
039
040        @Override
041        public int execute(String executable, List<String> args) {
042                DefaultExecContext context = new DefaultExecContext();
043                context.setExecutable(executable);
044                context.setArgs(args);
045                return execute(context);
046        }
047
048        protected int executeAndValidate(String executable, List<String> args) {
049                int exitValue = execute(executable, args);
050                validateExitValue(exitValue);
051                return exitValue;
052        }
053
054        protected int executeAndValidate(ExecContext context) {
055                int exitValue = execute(context);
056                validateExitValue(exitValue);
057                return exitValue;
058        }
059
060        protected int execute(ExecContext context, Commandline cl) {
061                try {
062                        logger.debug("[{}]", cl);
063                        StreamConsumer stdout = getConsumer(context.getStandardOutConsumer(), logger, LoggerLevel.INFO);
064                        StreamConsumer stderr = getConsumer(context.getStandardErrConsumer(), logger, LoggerLevel.WARN);
065                        return CommandLineUtils.executeCommandLine(cl, context.getInput(), stdout, stderr, context.getTimeoutInSeconds());
066                } catch (CommandLineException e) {
067                        throw new IllegalStateException(e);
068                }
069        }
070
071        protected StreamConsumer getConsumer(StreamConsumer provided, Logger logger, LoggerLevel level) {
072                if (provided != null) {
073                        return provided;
074                } else {
075                        return new LoggingStreamConsumer(logger, level);
076                }
077        }
078
079        /**
080         * @deprecated
081         */
082        @Deprecated
083        protected StreamConsumer getStreamConsumer(StreamConsumer provided, Logger logger, org.kuali.common.util.LoggerLevel level) {
084                if (provided != null) {
085                        return provided;
086                } else {
087                        return new org.kuali.common.util.LoggingStreamConsumer(logger, level);
088                }
089        }
090
091        protected void validateExitValue(int exitValue) {
092                if (exitValue != 0) {
093                        throw new IllegalStateException("Non-zero exit value - " + exitValue);
094                }
095        }
096
097        protected Commandline getCommandLine(ExecContext context) {
098                Commandline cl = new Commandline();
099                cl.setExecutable(context.getExecutable());
100                if (context.isAddSystemEnvironment()) {
101                        try {
102                                cl.addSystemEnvironment();
103                        } catch (Exception e) {
104                                throw new IllegalStateException(e);
105                        }
106                }
107                if (context.getArgs() != null) {
108                        cl.addArguments(CollectionUtils.toStringArray(context.getArgs()));
109                }
110                if (context.getWorkingDirectory() != null) {
111                        cl.setWorkingDirectory(context.getWorkingDirectory());
112                }
113                return cl;
114        }
115
116}