1 18 19 package org.apache.tools.ant.types; 20 21 import java.io.File ; 22 import java.util.StringTokenizer ; 23 import java.util.Vector ; 24 import java.util.ArrayList ; 25 import java.util.List ; 26 import java.util.ListIterator ; 27 import java.util.LinkedList ; 28 import java.util.Iterator ; 29 30 import org.apache.tools.ant.BuildException; 31 import org.apache.tools.ant.ProjectComponent; 32 import org.apache.tools.ant.util.StringUtils; 33 import org.apache.tools.ant.taskdefs.condition.Os; 34 35 55 public class Commandline implements Cloneable { 56 57 private static final boolean IS_WIN_9X = Os.isFamily("win9x"); 58 59 62 private Vector arguments = new Vector (); 63 64 67 private String executable = null; 68 69 protected static final String DISCLAIMER = 70 StringUtils.LINE_SEP 71 + "The \' characters around the executable and arguments are" 72 + StringUtils.LINE_SEP 73 + "not part of the command." 74 + StringUtils.LINE_SEP; 75 76 81 public Commandline(String toProcess) { 82 super(); 83 String [] tmp = translateCommandline(toProcess); 84 if (tmp != null && tmp.length > 0) { 85 setExecutable(tmp[0]); 86 for (int i = 1; i < tmp.length; i++) { 87 createArgument().setValue(tmp[i]); 88 } 89 } 90 } 91 92 95 public Commandline() { 96 super(); 97 } 98 99 102 public static class Argument extends ProjectComponent { 103 104 private String [] parts; 105 106 111 public void setValue(String value) { 112 parts = new String [] {value}; 113 } 114 115 120 public void setLine(String line) { 121 if (line == null) { 122 return; 123 } 124 parts = translateCommandline(line); 125 } 126 127 134 public void setPath(Path value) { 135 parts = new String [] {value.toString()}; 136 } 137 138 145 public void setPathref(Reference value) { 146 Path p = new Path(getProject()); 147 p.setRefid(value); 148 parts = new String [] {p.toString()}; 149 } 150 151 157 public void setFile(File value) { 158 parts = new String [] {value.getAbsolutePath()}; 159 } 160 161 165 public String [] getParts() { 166 return parts; 167 } 168 } 169 170 176 public class Marker { 177 178 private int position; 179 private int realPos = -1; 180 181 185 Marker(int position) { 186 this.position = position; 187 } 188 189 196 public int getPosition() { 197 if (realPos == -1) { 198 realPos = (executable == null ? 0 : 1); 199 for (int i = 0; i < position; i++) { 200 Argument arg = (Argument) arguments.elementAt(i); 201 realPos += arg.getParts().length; 202 } 203 } 204 return realPos; 205 } 206 } 207 208 218 public Argument createArgument() { 219 return this.createArgument(false); 220 } 221 222 232 public Argument createArgument(boolean insertAtStart) { 233 Argument argument = new Argument(); 234 if (insertAtStart) { 235 arguments.insertElementAt(argument, 0); 236 } else { 237 arguments.addElement(argument); 238 } 239 return argument; 240 } 241 242 247 public void setExecutable(String executable) { 248 if (executable == null || executable.length() == 0) { 249 return; 250 } 251 this.executable = executable.replace('/', File.separatorChar) 252 .replace('\\', File.separatorChar); 253 } 254 255 259 public String getExecutable() { 260 return executable; 261 } 262 263 267 public void addArguments(String [] line) { 268 for (int i = 0; i < line.length; i++) { 269 createArgument().setValue(line[i]); 270 } 271 } 272 273 277 public String [] getCommandline() { 278 List commands = new LinkedList (); 279 ListIterator list = commands.listIterator(); 280 addCommandToList(list); 281 final String [] result = new String [commands.size()]; 282 return (String []) commands.toArray(result); 283 } 284 285 290 public void addCommandToList(ListIterator list) { 291 if (executable != null) { 292 list.add(executable); 293 } 294 addArgumentsToList(list); 295 } 296 297 302 public String [] getArguments() { 303 List result = new ArrayList (arguments.size() * 2); 304 addArgumentsToList(result.listIterator()); 305 String [] res = new String [result.size()]; 306 return (String []) result.toArray(res); 307 } 308 309 314 public void addArgumentsToList(ListIterator list) { 315 for (int i = 0; i < arguments.size(); i++) { 316 Argument arg = (Argument) arguments.elementAt(i); 317 String [] s = arg.getParts(); 318 if (s != null) { 319 for (int j = 0; j < s.length; j++) { 320 list.add(s[j]); 321 } 322 } 323 } 324 } 325 326 330 public String toString() { 331 return toString(getCommandline()); 332 } 333 334 345 public static String quoteArgument(String argument) { 346 if (argument.indexOf("\"") > -1) { 347 if (argument.indexOf("\'") > -1) { 348 throw new BuildException("Can\'t handle single and double" 349 + " quotes in same argument"); 350 } else { 351 return '\'' + argument + '\''; 352 } 353 } else if (argument.indexOf("\'") > -1 354 || argument.indexOf(" ") > -1 355 || (IS_WIN_9X && argument.indexOf(';') != -1)) { 357 return '\"' + argument + '\"'; 358 } else { 359 return argument; 360 } 361 } 362 363 370 public static String toString(String [] line) { 371 if (line == null || line.length == 0) { 373 return ""; 374 } 375 final StringBuffer result = new StringBuffer (); 377 for (int i = 0; i < line.length; i++) { 378 if (i > 0) { 379 result.append(' '); 380 } 381 result.append(quoteArgument(line[i])); 382 } 383 return result.toString(); 384 } 385 386 392 public static String [] translateCommandline(String toProcess) { 393 if (toProcess == null || toProcess.length() == 0) { 394 return new String [0]; 396 } 397 399 final int normal = 0; 400 final int inQuote = 1; 401 final int inDoubleQuote = 2; 402 int state = normal; 403 StringTokenizer tok = new StringTokenizer (toProcess, "\"\' ", true); 404 Vector v = new Vector (); 405 StringBuffer current = new StringBuffer (); 406 boolean lastTokenHasBeenQuoted = false; 407 408 while (tok.hasMoreTokens()) { 409 String nextTok = tok.nextToken(); 410 switch (state) { 411 case inQuote: 412 if ("\'".equals(nextTok)) { 413 lastTokenHasBeenQuoted = true; 414 state = normal; 415 } else { 416 current.append(nextTok); 417 } 418 break; 419 case inDoubleQuote: 420 if ("\"".equals(nextTok)) { 421 lastTokenHasBeenQuoted = true; 422 state = normal; 423 } else { 424 current.append(nextTok); 425 } 426 break; 427 default: 428 if ("\'".equals(nextTok)) { 429 state = inQuote; 430 } else if ("\"".equals(nextTok)) { 431 state = inDoubleQuote; 432 } else if (" ".equals(nextTok)) { 433 if (lastTokenHasBeenQuoted || current.length() != 0) { 434 v.addElement(current.toString()); 435 current = new StringBuffer (); 436 } 437 } else { 438 current.append(nextTok); 439 } 440 lastTokenHasBeenQuoted = false; 441 break; 442 } 443 } 444 if (lastTokenHasBeenQuoted || current.length() != 0) { 445 v.addElement(current.toString()); 446 } 447 if (state == inQuote || state == inDoubleQuote) { 448 throw new BuildException("unbalanced quotes in " + toProcess); 449 } 450 String [] args = new String [v.size()]; 451 v.copyInto(args); 452 return args; 453 } 454 455 460 public int size() { 461 return getCommandline().length; 462 } 463 464 468 public Object clone() { 469 try { 470 Commandline c = (Commandline) super.clone(); 471 c.arguments = (Vector ) arguments.clone(); 472 return c; 473 } catch (CloneNotSupportedException e) { 474 throw new BuildException(e); 475 } 476 } 477 478 481 public void clear() { 482 executable = null; 483 arguments.removeAllElements(); 484 } 485 486 490 public void clearArgs() { 491 arguments.removeAllElements(); 492 } 493 494 502 public Marker createMarker() { 503 return new Marker(arguments.size()); 504 } 505 506 512 public String describeCommand() { 513 return describeCommand(this); 514 } 515 516 522 public String describeArguments() { 523 return describeArguments(this); 524 } 525 526 533 public static String describeCommand(Commandline line) { 534 return describeCommand(line.getCommandline()); 535 } 536 537 544 public static String describeArguments(Commandline line) { 545 return describeArguments(line.getArguments()); 546 } 547 548 558 public static String describeCommand(String [] args) { 559 if (args == null || args.length == 0) { 560 return ""; 561 } 562 StringBuffer buf = new StringBuffer ("Executing \'"); 563 buf.append(args[0]); 564 buf.append("\'"); 565 if (args.length > 1) { 566 buf.append(" with "); 567 buf.append(describeArguments(args, 1)); 568 } else { 569 buf.append(DISCLAIMER); 570 } 571 return buf.toString(); 572 } 573 574 581 public static String describeArguments(String [] args) { 582 return describeArguments(args, 0); 583 } 584 585 595 protected static String describeArguments(String [] args, int offset) { 596 if (args == null || args.length <= offset) { 597 return ""; 598 } 599 StringBuffer buf = new StringBuffer ("argument"); 600 if (args.length > offset) { 601 buf.append("s"); 602 } 603 buf.append(":").append(StringUtils.LINE_SEP); 604 for (int i = offset; i < args.length; i++) { 605 buf.append("\'").append(args[i]).append("\'") 606 .append(StringUtils.LINE_SEP); 607 } 608 buf.append(DISCLAIMER); 609 return buf.toString(); 610 } 611 612 617 public Iterator iterator() { 618 return arguments.iterator(); 619 } 620 } 621 | Popular Tags |