/** * Copyright 2015 Palantir Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.palantir.giraffe.command; import java.util.List; import com.google.common.collect.ImmutableList; /** * Represents an executable path and set of arguments that may be run by an * execution system. * <p> * Each {@code Command} is associated with an {@link ExecutionSystem} that can * execute it and implements system-dependent behavior, like argument escaping. * <p> * Implementations of this interface are immutable. * * @author pchen * @author bkeyes */ public interface Command { /** * Builds {@link Command} objects. For users, the builder is a convenient * way to add arguments dynamically or provide a base set of arguments that * can be extended by other code. Builders can be reused to create multiple * {@code Command} objects. * * <h3><a name="arg-handling">Argument Handling</a></h3> * <p> * Each argument is converted to a string by calling {@code toString} or * using the string {@code "null"} if the argument is {@code null}. * <p> * Escaping arguments is not required and may lead to unexpected behavior. * Any system-dependent escaping is handled by the execution system when the * resulting command is executed. */ interface Builder { // Include both addArgument and addArguments to avoid overload ambiguity // between addArguments(Object, Object...) and addArguments(Iterable<?>) /** * Adds an argument to this command. * * @param arg the argument to add * * @return this builder * * @see <a href="#arg-handling">Argument Handling</a> */ Builder addArgument(Object arg); /** * Adds arguments to this command. * * @param first the first argument to add * @param second the second argument to add * @param more any additional arguments to add * * @return this builder * * @see <a href="#arg-handling">Argument Handling</a> */ Builder addArguments(Object first, Object second, Object... more); /** * Adds arguments to this command. * * @param args the arguments to add * * @return this builder * * @see <a href="#arg-handling">Argument Handling</a> */ Builder addArguments(List<?> args); /** * Builds a new {@code Command} using the settings configured by this * builder. The builder may be reused to create more commands after * calling this method. */ Command build(); } /** * Returns the {@code ExecutionSystem} associated with this command. */ ExecutionSystem getExecutionSystem(); /** * Returns this command's executable. The value may be a string * representation of a path or a simple name. */ String getExecutable(); /** * Returns the arguments of this command. * <p> * Each element in the list corresponds to a single logical argument passed * to this command's executable. The arguments are the unmodified string * representations of the objects provided when this command was * constructed. The execution system may modify these arguments to escape * system-dependent special characters when this command is executed. */ ImmutableList<String> getArguments(); /** * Returns a human-readable string representation of this command. The * string is similar to the character sequence entered in a terminal to * manually execute this command, but may leave out necessary escape * characters. */ @Override String toString(); /** * Tests this {@code Command} for equality with another object. * <p> * If the other object is not a {@code Command} or is a {@code Command} * associated with a different execution system, this method returns * {@code false}. * <p> * Otherwise, two commands are equal if they have the same executable and * the same arguments. * <p> * This method satisfies the general contract of the * {@link java.lang.Object#equals(Object) Object.equals} method. */ @Override boolean equals(Object obj); /** * Returns a hash code for this {@code Command}. * <p> * The hash code combines the hash codes of the executable and the arguments * list. * <p> * This method satisfies the general contract of the * {@link java.lang.Object#hashCode() Object.hashCode} method. */ @Override int hashCode(); }