001package org.unix4j.unix.cd; 002 003 004import org.unix4j.command.Arguments; 005import org.unix4j.context.ExecutionContext; 006import org.unix4j.convert.ValueConverter; 007import org.unix4j.util.ArrayUtil; 008import org.unix4j.variable.Arg; 009import org.unix4j.variable.VariableContext; 010 011import org.unix4j.unix.Cd; 012 013/** 014 * Arguments and options for the {@link Cd cd} command. 015 */ 016public final class CdArguments implements Arguments<CdArguments> { 017 018 019 020 // operand: <file> 021 private java.io.File file; 022 private boolean fileIsSet = false; 023 024 // operand: <path> 025 private String path; 026 private boolean pathIsSet = false; 027 028 /** 029 * Constructor to use if no options are specified. 030 */ 031 public CdArguments() { 032 super(); 033 } 034 035 private Object resolveVariable(VariableContext context, String variable) { 036 final Object value = context.getValue(variable); 037 if (value != null) { 038 return value; 039 } 040 throw new IllegalArgumentException("cannot resolve variable " + variable + 041 " in command: cd " + this); 042 } 043 private <V> V convert(ExecutionContext context, String operandName, Class<V> operandType, Object value) { 044 final ValueConverter<V> converter = context.getValueConverterFor(operandType); 045 final V convertedValue; 046 if (converter != null) { 047 convertedValue = converter.convert(value); 048 } else { 049 convertedValue = null; 050 } 051 if (convertedValue != null) { 052 return convertedValue; 053 } 054 throw new IllegalArgumentException("cannot convert --" + operandName + 055 " value '" + value + "' into the type " + operandType.getName() + 056 " for cd command"); 057 } 058 059 @Override 060 public CdArguments getForContext(ExecutionContext context) { 061 if (context == null) { 062 throw new NullPointerException("context cannot be null"); 063 } 064 //no String... args for this command, hence nothing to resolve 065 return this; 066 } 067 068 /** 069 * Returns the {@code <file>} operand value: the file to use as input; relative paths are not resolved (use the 070 string path argument to enable relative path resolving based on the 071 current working directory). 072 * 073 * @return the {@code <file>} operand value (variables are not resolved) 074 * @throws IllegalStateException if this operand has never been set 075 * 076 */ 077 public java.io.File getFile() { 078 if (fileIsSet) { 079 return file; 080 } 081 throw new IllegalStateException("operand has not been set: " + file); 082 } 083 084 /** 085 * Returns true if the {@code <file>} operand has been set. 086 * <p> 087 * Note that this method returns true even if {@code null} was passed to the 088 * {@link #setFile(java.io.File)} method. 089 * 090 * @return true if the setter for the {@code <file>} operand has 091 * been called at least once 092 */ 093 public boolean isFileSet() { 094 return fileIsSet; 095 } 096 /** 097 * Sets {@code <file>}: the file to use as input; relative paths are not resolved (use the 098 string path argument to enable relative path resolving based on the 099 current working directory). 100 * 101 * @param file the value for the {@code <file>} operand 102 */ 103 public void setFile(java.io.File file) { 104 this.file = file; 105 this.fileIsSet = true; 106 } 107 /** 108 * Returns the {@code <path>} operand value (variables are NOT resolved): the directory to become the new current working directory; 109 wildcards * and ? are supported; relative paths are resolved on the 110 basis of the current working directory. 111 * 112 * @return the {@code <path>} operand value (variables are not resolved) 113 * @throws IllegalStateException if this operand has never been set 114 * @see #getPath(ExecutionContext) 115 */ 116 public String getPath() { 117 if (pathIsSet) { 118 return path; 119 } 120 throw new IllegalStateException("operand has not been set: " + path); 121 } 122 /** 123 * Returns the {@code <path>} (variables are resolved): the directory to become the new current working directory; 124 wildcards * and ? are supported; relative paths are resolved on the 125 basis of the current working directory. 126 * 127 * @param context the execution context used to resolve variables 128 * @return the {@code <path>} operand value after resolving variables 129 * @throws IllegalStateException if this operand has never been set 130 * @see #getPath() 131 */ 132 public String getPath(ExecutionContext context) { 133 final String value = getPath(); 134 if (Arg.isVariable(value)) { 135 final Object resolved = resolveVariable(context.getVariableContext(), value); 136 final String converted = convert(context, "path", String.class, resolved); 137 return converted; 138 } 139 return value; 140 } 141 142 /** 143 * Returns true if the {@code <path>} operand has been set. 144 * <p> 145 * Note that this method returns true even if {@code null} was passed to the 146 * {@link #setPath(String)} method. 147 * 148 * @return true if the setter for the {@code <path>} operand has 149 * been called at least once 150 */ 151 public boolean isPathSet() { 152 return pathIsSet; 153 } 154 /** 155 * Sets {@code <path>}: the directory to become the new current working directory; 156 wildcards * and ? are supported; relative paths are resolved on the 157 basis of the current working directory. 158 * 159 * @param path the value for the {@code <path>} operand 160 */ 161 public void setPath(String path) { 162 this.path = path; 163 this.pathIsSet = true; 164 } 165 166 167 @Override 168 public String toString() { 169 // ok, we have options or arguments or both 170 final StringBuilder sb = new StringBuilder(); 171 172{ 173 // operand: <file> 174 if (fileIsSet) { 175 if (sb.length() > 0) sb.append(' '); 176 sb.append("--").append("file"); 177 sb.append(" ").append(toString(getFile())); 178 } 179 // operand: <path> 180 if (pathIsSet) { 181 if (sb.length() > 0) sb.append(' '); 182 sb.append("--").append("path"); 183 sb.append(" ").append(toString(getPath())); 184 } 185 } 186 187 return sb.toString(); 188 } 189 private static String toString(Object value) { 190 if (value != null && value.getClass().isArray()) { 191 return ArrayUtil.toString(value); 192 } 193 return String.valueOf(value); 194 } 195}