001: package liquibase.change;
002:
003: import liquibase.database.Database;
004: import liquibase.database.sql.SqlStatement;
005: import liquibase.database.structure.DatabaseObject;
006: import liquibase.exception.UnsupportedChangeException;
007: import liquibase.log.LogFactory;
008: import liquibase.util.StreamUtil;
009: import liquibase.util.StringUtils;
010: import org.w3c.dom.Document;
011: import org.w3c.dom.Element;
012:
013: import java.io.IOException;
014: import java.util.ArrayList;
015: import java.util.List;
016: import java.util.Set;
017:
018: /**
019: * Executes a given shell executable.
020: */
021: public class ExecuteShellCommandChange extends AbstractChange {
022:
023: private String executable;
024: private List<String> os;
025: private List<String> args = new ArrayList<String>();
026:
027: public ExecuteShellCommandChange() {
028: super ("executeCommand", "Execute Shell Command");
029: }
030:
031: public String getExecutable() {
032: return executable;
033: }
034:
035: public void setExecutable(String executable) {
036: this .executable = executable;
037: }
038:
039: public void addArg(String arg) {
040: this .args.add(arg);
041: }
042:
043: public void setOs(String os) {
044: this .os = StringUtils.splitAndTrim(os, ",");
045: }
046:
047: public SqlStatement[] generateStatements(Database database)
048: throws UnsupportedChangeException {
049: boolean shouldRun = true;
050: if (os != null && os.size() > 0) {
051: String currentOS = System.getProperty("os.name");
052: if (!os.contains(currentOS)) {
053: shouldRun = false;
054: LogFactory.getLogger().info(
055: "Not executing on os " + currentOS + " when "
056: + os + " was specified");
057: }
058: }
059:
060: if (shouldRun) {
061: List<String> commandArray = new ArrayList<String>();
062: commandArray.add(executable);
063: commandArray.addAll(args);
064:
065: try {
066: ProcessBuilder pb = new ProcessBuilder(commandArray);
067: pb.redirectErrorStream(true);
068: Process p = pb.start();
069: int returnCode = 0;
070: try {
071: returnCode = p.waitFor();
072: } catch (InterruptedException e) {
073: ;
074: }
075: StreamUtil.copy(p.getErrorStream(), System.err);
076: StreamUtil.copy(p.getInputStream(), System.err);
077:
078: if (returnCode != 0) {
079: throw new RuntimeException(getCommandString()
080: + " returned an code of " + returnCode);
081: }
082: } catch (IOException e) {
083: throw new UnsupportedChangeException(
084: "Error executing command: " + e);
085: }
086:
087: }
088: return new SqlStatement[0];
089: }
090:
091: public String getConfirmationMessage() {
092: return "Shell command '" + getCommandString() + "' executed";
093: }
094:
095: private String getCommandString() {
096: return executable + " " + StringUtils.join(args, " ");
097: }
098:
099: public Element createNode(Document currentChangeLogDOM) {
100: Element root = currentChangeLogDOM.createElement(getTagName());
101: root.setAttribute("executable", getExecutable());
102:
103: for (String arg : args) {
104: Element argElement = currentChangeLogDOM
105: .createElement("arg");
106: argElement.setAttribute("value", arg);
107: root.appendChild(argElement);
108: }
109:
110: return root;
111:
112: }
113:
114: public Set<DatabaseObject> getAffectedDatabaseObjects() {
115: return null;
116: }
117: }
|