001package org.unix4j.builder; 002 003import org.unix4j.command.Command; 004import org.unix4j.command.ExitValueException; 005import org.unix4j.command.NoOp; 006import org.unix4j.context.DefaultExecutionContext; 007import org.unix4j.context.ExecutionContextFactory; 008import org.unix4j.io.BufferedOutput; 009import org.unix4j.io.FileOutput; 010import org.unix4j.io.NullOutput; 011import org.unix4j.io.Output; 012import org.unix4j.io.StdOutput; 013import org.unix4j.io.StreamOutput; 014import org.unix4j.io.StringOutput; 015import org.unix4j.io.WriterOutput; 016import org.unix4j.line.Line; 017import org.unix4j.operation.AdHocCommand; 018import org.unix4j.operation.LineOperation; 019 020import java.io.File; 021import java.io.OutputStream; 022import java.io.Writer; 023import java.util.ArrayList; 024import java.util.List; 025import java.util.stream.Stream; 026 027/** 028 * Default implementation for a {@link CommandBuilder}. Builds a {@link NoOp} 029 * command if no command is {@link #join(Command) joined} to the command chain 030 * of this builder. 031 */ 032public class DefaultCommandBuilder implements CommandBuilder { 033 034 private final ExecutionContextFactory contextFactory; 035 private Command<?> command = NoOp.INSTANCE; 036 037 /** 038 * Default constructor initialized to build a {@link NoOp} command if no 039 * command is {@link #join(Command) joined} to this builder's command chain. 040 * Uses a {@link DefaultExecutionContext} to execute commands. 041 */ 042 public DefaultCommandBuilder() { 043 this(DefaultExecutionContext.FACTORY); 044 } 045 046 /** 047 * Constructor using the specified factory to create contexts for command 048 * execution. The builder is initialized with a {@link NoOp} command which 049 * will be replaced by the first command {@link #join(Command) joined} to 050 * this builder's command chain. 051 * 052 * @param contextFactory 053 * the factory used to create execution contexts that are passed 054 * to the execute method when a command is executed 055 */ 056 public DefaultCommandBuilder(ExecutionContextFactory contextFactory) { 057 this.contextFactory = contextFactory; 058 } 059 060 /** 061 * Returns the context factory used to create contexts for command 062 * execution. The returned factory has usually been passed to the 063 * constructor of this builder. 064 * 065 * @return the factory used to create execution contexts that are passed to 066 * the execute method when a command is executed 067 */ 068 public ExecutionContextFactory getContextFactory() { 069 return contextFactory; 070 } 071 072 @Override 073 public CommandBuilder join(Command<?> command) { 074 if (command == null) { 075 throw new NullPointerException("command argument cannot be null"); 076 } 077 this.command = this.command.join(command); 078 return this; 079 } 080 081 @Override 082 public CommandBuilder apply(LineOperation operation) { 083 return join(new AdHocCommand(operation)); 084 } 085 086 @Override 087 public CommandBuilder reset() { 088 command = NoOp.INSTANCE; 089 return this; 090 } 091 092 @Override 093 public Command<?> build() { 094 return command; 095 } 096 097 @Override 098 public String toString() { 099 return command.toString(); 100 } 101 102 @Override 103 public void toStdOut() { 104 toOutput(new StdOutput()); 105 } 106 107 @Override 108 public List<Line> toLineList() { 109 final List<Line> lines = new ArrayList<Line>(); 110 toOutput(new BufferedOutput(lines)); 111 return lines; 112 } 113 114 @Override 115 public List<String> toStringList() { 116 final List<String> lines = new ArrayList<String>(); 117 toOutput(new Output() { 118 @Override 119 public boolean processLine(Line line) { 120 lines.add(line.getContent()); 121 return true;// we want more lines 122 } 123 124 @Override 125 public void finish() { 126 // no op 127 } 128 }); 129 return lines; 130 } 131 132 @Override 133 public Stream<Line> toLineStream() { 134 return toLineList().stream(); 135 } 136 137 @Override 138 public Stream<String> toStringStream() { 139 return toStringList().stream(); 140 } 141 142 @Override 143 public void toOutput(Output output) { 144 final Command<?> command = build(); 145 command.execute(getContextFactory().createExecutionContext(), output).finish(); 146 } 147 148 @Override 149 public void toFile(String file) { 150 toFile(new File(file)); 151 } 152 153 @Override 154 public void toFile(File file) { 155 toOutput(new FileOutput(file)); 156 } 157 158 @Override 159 public void toOutputStream(OutputStream stream) { 160 toOutput(new StreamOutput(stream)); 161 } 162 163 @Override 164 public void toWriter(Writer writer) { 165 toOutput(new WriterOutput(writer)); 166 } 167 168 @Override 169 public void toDevNull() { 170 toOutput(NullOutput.DEFAULT); 171 } 172 173 @Override 174 public String toStringResult() { 175 final StringOutput out = new StringOutput(); 176 toOutput(out); 177 return out.toString(); 178 } 179 180 @Override 181 public int toExitValue() { 182 try { 183 toDevNull(); 184 return 0; 185 } catch (ExitValueException e) { 186 return e.getExitValue(); 187 } 188 } 189}