1 37 90 package net.sourceforge.cruisecontrol.util; 91 92 import net.sourceforge.cruisecontrol.CruiseControlException; 93 import org.apache.log4j.Logger; 94 95 import java.io.File ; 96 import java.io.IOException ; 97 import java.util.StringTokenizer ; 98 import java.util.Vector ; 99 100 122 public class Commandline implements Cloneable { 123 124 private static final Logger LOG = Logger.getLogger(Commandline.class); 125 126 private Vector arguments = new Vector (); 127 private String executable = null; 128 private File workingDir = null; 129 130 public Commandline(String toProcess) { 131 super(); 132 String [] tmp = new String [0]; 133 try { 134 tmp = translateCommandline(toProcess); 135 } catch (CruiseControlException e) { 136 LOG.error("Error translating Commandline.", e); 137 } 138 if (tmp != null && tmp.length > 0) { 139 setExecutable(tmp[0]); 140 for (int i = 1; i < tmp.length; i++) { 141 createArgument().setValue(tmp[i]); 142 } 143 } 144 } 145 146 public Commandline() { 147 super(); 148 } 149 150 protected File getWorkingDir() { 151 return workingDir; 152 } 153 154 157 public static class Argument { 158 159 private String [] parts; 160 161 166 public void setValue(String value) { 167 parts = new String [] { value }; 168 } 169 170 175 public void setLine(String line) { 176 if (line == null) { 177 return; 178 } 179 try { 180 parts = translateCommandline(line); 181 } catch (CruiseControlException e) { 182 LOG.error("Error translating Commandline.", e); 183 } 184 } 185 186 192 public void setFile(File value) { 193 parts = new String [] { value.getAbsolutePath()}; 194 } 195 196 199 public String [] getParts() { 200 return parts; 201 } 202 } 203 204 207 public class Marker { 211 212 private int position; 213 private int realPos = -1; 214 215 Marker(int position) { 216 this.position = position; 217 } 218 219 225 public int getPosition() { 226 if (realPos == -1) { 227 realPos = (executable == null ? 0 : 1); 228 for (int i = 0; i < position; i++) { 229 Argument arg = (Argument) arguments.elementAt(i); 230 realPos += arg.getParts().length; 231 } 232 } 233 return realPos; 234 } 235 } 236 237 247 public Argument createArgument() { 248 return this.createArgument(false); 249 } 250 251 260 public Argument createArgument(boolean insertAtStart) { 261 Argument argument = new Argument(); 262 if (insertAtStart) { 263 arguments.insertElementAt(argument, 0); 264 } else { 265 arguments.addElement(argument); 266 } 267 return argument; 268 } 269 270 273 public void setExecutable(String executable) { 274 if (executable == null || executable.length() == 0) { 275 return; 276 } 277 this.executable = 278 executable.replace('/', File.separatorChar).replace('\\', File.separatorChar); 279 } 280 281 public String getExecutable() { 282 return executable; 283 } 284 285 public void addArguments(String [] line) { 286 for (int i = 0; i < line.length; i++) { 287 createArgument().setValue(line[i]); 288 } 289 } 290 291 294 public String [] getCommandline() { 295 final String [] args = getArguments(); 296 if (executable == null) { 297 return args; 298 } 299 final String [] result = new String [args.length + 1]; 300 result[0] = executable; 301 System.arraycopy(args, 0, result, 1, args.length); 302 return result; 303 } 304 305 309 public String [] getArguments() { 310 Vector result = new Vector (arguments.size() * 2); 311 for (int i = 0; i < arguments.size(); i++) { 312 Argument arg = (Argument) arguments.elementAt(i); 313 String [] s = arg.getParts(); 314 if (s != null) { 315 for (int j = 0; j < s.length; j++) { 316 result.addElement(s[j]); 317 } 318 } 319 } 320 321 String [] res = new String [result.size()]; 322 result.copyInto(res); 323 return res; 324 } 325 326 public String toString() { 327 return toString(getCommandline()); 328 } 329 330 340 public static String quoteArgument(String argument) throws CruiseControlException { 341 if (argument.indexOf("\"") > -1) { 342 if (argument.indexOf("\'") > -1) { 343 throw new CruiseControlException("Can't handle single and double quotes in same argument"); 344 } else { 345 return '\'' + argument + '\''; 346 } 347 } else if (argument.indexOf("\'") > -1 || argument.indexOf(" ") > -1) { 348 return '\"' + argument + '\"'; 349 } else { 350 return argument; 351 } 352 } 353 354 public static String toString(String [] line) { 355 if (line == null || line.length == 0) { 357 return ""; 358 } 359 360 final StringBuffer result = new StringBuffer (); 362 for (int i = 0; i < line.length; i++) { 363 if (i > 0) { 364 result.append(' '); 365 } 366 try { 367 result.append(quoteArgument(line[i])); 368 } catch (CruiseControlException e) { 369 LOG.error("Error quoting argument.", e); 370 } 371 } 372 return result.toString(); 373 } 374 375 public static String [] translateCommandline(String toProcess) throws CruiseControlException { 376 if (toProcess == null || toProcess.length() == 0) { 377 return new String [0]; 378 } 379 380 382 final int normal = 0; 383 final int inQuote = 1; 384 final int inDoubleQuote = 2; 385 int state = normal; 386 StringTokenizer tok = new StringTokenizer (toProcess, "\"\' ", true); 387 Vector v = new Vector (); 388 StringBuffer current = new StringBuffer (); 389 390 while (tok.hasMoreTokens()) { 391 String nextTok = tok.nextToken(); 392 switch (state) { 393 case inQuote : 394 if ("\'".equals(nextTok)) { 395 state = normal; 396 } else { 397 current.append(nextTok); 398 } 399 break; 400 case inDoubleQuote : 401 if ("\"".equals(nextTok)) { 402 state = normal; 403 } else { 404 current.append(nextTok); 405 } 406 break; 407 default : 408 if ("\'".equals(nextTok)) { 409 state = inQuote; 410 } else if ("\"".equals(nextTok)) { 411 state = inDoubleQuote; 412 } else if (" ".equals(nextTok)) { 413 if (current.length() != 0) { 414 v.addElement(current.toString()); 415 current.setLength(0); 416 } 417 } else { 418 current.append(nextTok); 419 } 420 break; 421 } 422 } 423 424 if (current.length() != 0) { 425 v.addElement(current.toString()); 426 } 427 428 if (state == inQuote || state == inDoubleQuote) { 429 throw new CruiseControlException("unbalanced quotes in " + toProcess); 430 } 431 432 String [] args = new String [v.size()]; 433 v.copyInto(args); 434 return args; 435 } 436 437 public int size() { 438 return getCommandline().length; 439 } 440 441 public Object clone() throws CloneNotSupportedException { 442 super.clone(); 443 444 Commandline c = new Commandline(); 445 c.setExecutable(executable); 446 c.addArguments(getArguments()); 447 return c; 448 } 449 450 452 public void clear() { 453 executable = null; 454 arguments.removeAllElements(); 455 } 456 457 460 public void clearArgs() { 461 arguments.removeAllElements(); 462 } 463 464 471 public Marker createMarker() { 472 return new Marker(arguments.size()); 473 } 474 475 478 public void setWorkingDirectory(String path) throws CruiseControlException { 479 if (path != null) { 480 File dir = new File (path); 481 checkWorkingDir(dir); 482 workingDir = dir; 483 } else { 484 workingDir = null; 485 } 486 } 487 488 491 public void setWorkingDir(File workingDir) throws CruiseControlException { 492 checkWorkingDir(workingDir); 493 this.workingDir = workingDir; 494 } 495 496 private void checkWorkingDir(File dir) throws CruiseControlException { 499 if (dir != null) { 500 if (!dir.exists()) { 501 throw new CruiseControlException( 502 "Working directory \"" + dir.getAbsolutePath() + "\" does not exist!"); 503 } else if (!dir.isDirectory()) { 504 throw new CruiseControlException( 505 "Path \"" + dir.getAbsolutePath() + "\" does not specify a directory."); 506 } 507 } 508 } 509 510 public File getWorkingDirectory() { 511 return workingDir; 512 } 513 514 517 public Process execute() throws IOException { 518 Process process; 519 520 if (workingDir == null) { 521 LOG.debug("Executing \"" + this + "\""); 522 process = Runtime.getRuntime().exec(getCommandline()); 523 } else { 524 LOG.debug( 525 "Executing \"" 526 + this 527 + "\" in directory " 528 + workingDir.getAbsolutePath()); 529 process = Runtime.getRuntime().exec(getCommandline(), null, workingDir); 530 } 531 532 return process; 533 } 534 535 } 536 | Popular Tags |