1 61 62 package org.apache.commons.cli; 63 64 import java.io.PrintWriter ; 65 import java.util.ArrayList ; 66 import java.util.Collection ; 67 import java.util.Collections ; 68 import java.util.Comparator ; 69 import java.util.Iterator ; 70 import java.util.List ; 71 72 78 public class HelpFormatter 79 { 80 82 public static final int DEFAULT_WIDTH = 74; 83 public static final int DEFAULT_LEFT_PAD = 1; 84 public static final int DEFAULT_DESC_PAD = 3; 85 public static final String DEFAULT_SYNTAX_PREFIX = "usage: "; 86 public static final String DEFAULT_OPT_PREFIX = "-"; 87 public static final String DEFAULT_LONG_OPT_PREFIX = "--"; 88 public static final String DEFAULT_ARG_NAME = "arg"; 89 90 92 94 public int defaultWidth; 95 public int defaultLeftPad; 96 public int defaultDescPad; 97 public String defaultSyntaxPrefix; 98 public String defaultNewLine; 99 public String defaultOptPrefix; 100 public String defaultLongOptPrefix; 101 public String defaultArgName; 102 103 public HelpFormatter() 105 { 106 defaultWidth = DEFAULT_WIDTH; 107 defaultLeftPad = DEFAULT_LEFT_PAD; 108 defaultDescPad = DEFAULT_DESC_PAD; 109 defaultSyntaxPrefix = DEFAULT_SYNTAX_PREFIX; 110 defaultNewLine = System.getProperty("line.separator"); 111 defaultOptPrefix = DEFAULT_OPT_PREFIX; 112 defaultLongOptPrefix = DEFAULT_LONG_OPT_PREFIX; 113 defaultArgName = DEFAULT_ARG_NAME; 114 } 115 116 118 public void printHelp( String cmdLineSyntax, 119 Options options ) 120 { 121 printHelp( defaultWidth, cmdLineSyntax, null, options, null, false ); 122 } 123 124 public void printHelp( String cmdLineSyntax, 125 Options options, 126 boolean autoUsage ) 127 { 128 printHelp( defaultWidth, cmdLineSyntax, null, options, null, autoUsage ); 129 } 130 131 public void printHelp( String cmdLineSyntax, 132 String header, 133 Options options, 134 String footer ) 135 { 136 printHelp( cmdLineSyntax, header, options, footer, false ); 137 } 138 139 public void printHelp( String cmdLineSyntax, 140 String header, 141 Options options, 142 String footer, 143 boolean autoUsage ) 144 { 145 printHelp(defaultWidth, cmdLineSyntax, header, options, footer, autoUsage ); 146 } 147 148 public void printHelp( int width, 149 String cmdLineSyntax, 150 String header, 151 Options options, 152 String footer ) 153 { 154 printHelp( width, cmdLineSyntax, header, options, footer, false ); 155 } 156 157 public void printHelp( int width, 158 String cmdLineSyntax, 159 String header, 160 Options options, 161 String footer, 162 boolean autoUsage ) 163 { 164 PrintWriter pw = new PrintWriter (System.out); 165 printHelp( pw, width, cmdLineSyntax, header, 166 options, defaultLeftPad, defaultDescPad, footer, autoUsage ); 167 pw.flush(); 168 } 169 public void printHelp( PrintWriter pw, 170 int width, 171 String cmdLineSyntax, 172 String header, 173 Options options, 174 int leftPad, 175 int descPad, 176 String footer ) 177 throws IllegalArgumentException 178 { 179 printHelp( pw, width, cmdLineSyntax, header, options, leftPad, descPad, footer, false ); 180 } 181 182 public void printHelp( PrintWriter pw, 183 int width, 184 String cmdLineSyntax, 185 String header, 186 Options options, 187 int leftPad, 188 int descPad, 189 String footer, 190 boolean autoUsage ) 191 throws IllegalArgumentException 192 { 193 if ( cmdLineSyntax == null || cmdLineSyntax.length() == 0 ) 194 { 195 throw new IllegalArgumentException ("cmdLineSyntax not provided"); 196 } 197 198 if ( autoUsage ) { 199 printUsage( pw, width, cmdLineSyntax, options ); 200 } 201 else { 202 printUsage( pw, width, cmdLineSyntax ); 203 } 204 205 if ( header != null && header.trim().length() > 0 ) 206 { 207 printWrapped( pw, width, header ); 208 } 209 printOptions( pw, width, options, leftPad, descPad ); 210 if ( footer != null && footer.trim().length() > 0 ) 211 { 212 printWrapped( pw, width, footer ); 213 } 214 } 215 216 225 public void printUsage( PrintWriter pw, int width, String app, Options options ) 226 { 227 StringBuffer buff = new StringBuffer ( defaultSyntaxPrefix ).append( app ).append( " " ); 229 230 ArrayList list = new ArrayList (); 232 233 Option option; 235 236 for ( Iterator i = options.getOptions().iterator(); i.hasNext(); ) 238 { 239 option = (Option) i.next(); 241 242 OptionGroup group = options.getOptionGroup( option ); 244 245 if( group != null && !list.contains(group)) { 248 249 list.add( group ); 251 252 Collection names = group.getNames(); 254 255 buff.append( "[" ); 256 257 for( Iterator iter = names.iterator(); iter.hasNext(); ) { 259 buff.append( iter.next() ); 260 if( iter.hasNext() ) { 261 buff.append( " | " ); 262 } 263 } 264 buff.append( "]" ); 265 } 266 else { 268 if( !option.isRequired() ) { 270 buff.append( "[" ); 271 } 272 273 if( !" ".equals( option.getOpt() ) ) { 274 buff.append( "-" ).append( option.getOpt() ); 275 } 276 else { 277 buff.append( "--" ).append( option.getLongOpt() ); 278 } 279 280 if( option.hasArg() ){ 281 buff.append( " " ); 282 } 283 284 if( option.hasArg() ) { 286 buff.append( option.getArgName() ); 287 } 288 289 if( !option.isRequired() ) { 291 buff.append( "]" ); 292 } 293 buff.append( " " ); 294 } 295 } 296 297 printWrapped( pw, width, buff.toString().indexOf(' ')+1, 299 buff.toString() ); 300 } 301 302 public void printUsage( PrintWriter pw, int width, String cmdLineSyntax ) 303 { 304 int argPos = cmdLineSyntax.indexOf(' ') + 1; 305 printWrapped(pw, width, defaultSyntaxPrefix.length() + argPos, 306 defaultSyntaxPrefix + cmdLineSyntax); 307 } 308 309 public void printOptions( PrintWriter pw, int width, Options options, int leftPad, int descPad ) 310 { 311 StringBuffer sb = new StringBuffer (); 312 renderOptions(sb, width, options, leftPad, descPad); 313 pw.println(sb.toString()); 314 } 315 316 public void printWrapped( PrintWriter pw, int width, String text ) 317 { 318 printWrapped(pw, width, 0, text); 319 } 320 321 public void printWrapped( PrintWriter pw, int width, int nextLineTabStop, String text ) 322 { 323 StringBuffer sb = new StringBuffer (text.length()); 324 renderWrappedText(sb, width, nextLineTabStop, text); 325 pw.println(sb.toString()); 326 } 327 328 330 protected StringBuffer renderOptions( StringBuffer sb, 331 int width, 332 Options options, 333 int leftPad, 334 int descPad ) 335 { 336 final String lpad = createPadding(leftPad); 337 final String dpad = createPadding(descPad); 338 339 int max = 0; 343 StringBuffer optBuf; 344 List prefixList = new ArrayList (); 345 Option option; 346 List optList = options.helpOptions(); 347 Collections.sort( optList, new StringBufferComparator() ); 348 for ( Iterator i = optList.iterator(); i.hasNext(); ) 349 { 350 option = (Option) i.next(); 351 optBuf = new StringBuffer (8); 352 353 if (option.getOpt().equals(" ")) 354 { 355 optBuf.append(lpad).append(" " + defaultLongOptPrefix).append(option.getLongOpt()); 356 } 357 else 358 { 359 optBuf.append(lpad).append(defaultOptPrefix).append(option.getOpt()); 360 if ( option.hasLongOpt() ) 361 { 362 optBuf.append(',').append(defaultLongOptPrefix).append(option.getLongOpt()); 363 } 364 365 } 366 367 if( option.hasArg() ) { 368 if( option.hasArgName() ) { 369 optBuf.append(" <").append( option.getArgName() ).append( '>' ); 370 } 371 else { 372 optBuf.append(' '); 373 } 374 } 375 376 prefixList.add(optBuf); 377 max = optBuf.length() > max ? optBuf.length() : max; 378 } 379 int x = 0; 380 for ( Iterator i = optList.iterator(); i.hasNext(); ) 381 { 382 option = (Option) i.next(); 383 optBuf = new StringBuffer ( prefixList.get( x++ ).toString() ); 384 385 if ( optBuf.length() < max ) 386 { 387 optBuf.append(createPadding(max - optBuf.length())); 388 } 389 optBuf.append( dpad ); 390 391 int nextLineTabStop = max + descPad; 392 renderWrappedText(sb, width, nextLineTabStop, 393 optBuf.append(option.getDescription()).toString()); 394 if ( i.hasNext() ) 395 { 396 sb.append(defaultNewLine); 397 } 398 } 399 400 return sb; 401 } 402 403 protected StringBuffer renderWrappedText( StringBuffer sb, 404 int width, 405 int nextLineTabStop, 406 String text ) 407 { 408 int pos = findWrapPos( text, width, 0); 409 if ( pos == -1 ) 410 { 411 sb.append(rtrim(text)); 412 return sb; 413 } 414 else 415 { 416 sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine); 417 } 418 419 final String padding = createPadding(nextLineTabStop); 421 422 while ( true ) 423 { 424 text = padding + text.substring(pos).trim(); 425 pos = findWrapPos( text, width, nextLineTabStop ); 426 if ( pos == -1 ) 427 { 428 sb.append(text); 429 return sb; 430 } 431 432 sb.append(rtrim(text.substring(0, pos))).append(defaultNewLine); 433 } 434 435 } 436 437 449 protected int findWrapPos( String text, int width, int startPos ) 450 { 451 int pos = -1; 452 if ( ((pos = text.indexOf('\n', startPos)) != -1 && pos <= width) || 454 ((pos = text.indexOf('\t', startPos)) != -1 && pos <= width) ) 455 { 456 return pos; 457 } 458 else if ( (startPos + width) >= text.length() ) 459 { 460 return -1; 461 } 462 463 pos = startPos + width; 465 char c; 466 while ( pos >= startPos && (c = text.charAt(pos)) != ' ' && c != '\n' && c != '\r' ) 467 { 468 --pos; 469 } 470 if ( pos > startPos ) 472 { 473 return pos; 474 } 475 else 476 { 477 pos = startPos + width; 479 while ( pos <= text.length() && (c = text.charAt(pos)) != ' ' && c != '\n' && c != '\r' ) 480 { 481 ++pos; 482 } 483 return pos == text.length() ? -1 : pos; 484 } 485 } 486 487 protected String createPadding(int len) 488 { 489 StringBuffer sb = new StringBuffer (len); 490 for ( int i = 0; i < len; ++i ) 491 { 492 sb.append(' '); 493 } 494 return sb.toString(); 495 } 496 497 protected String rtrim( String s ) 498 { 499 if ( s == null || s.length() == 0 ) 500 { 501 return s; 502 } 503 504 int pos = s.length(); 505 while ( pos >= 0 && Character.isWhitespace(s.charAt(pos-1)) ) 506 { 507 --pos; 508 } 509 return s.substring(0, pos); 510 } 511 512 514 516 518 private static class StringBufferComparator 519 implements Comparator 520 { 521 public int compare( Object o1, Object o2 ) 522 { 523 String str1 = stripPrefix(o1.toString()); 524 String str2 = stripPrefix(o2.toString()); 525 return (str1.compareTo(str2)); 526 } 527 528 private String stripPrefix(String strOption) 529 { 530 int iStartIndex = strOption.lastIndexOf('-'); 532 if (iStartIndex == -1) 533 { 534 iStartIndex = 0; 535 } 536 return strOption.substring(iStartIndex); 537 538 } 539 } 540 } 541 | Popular Tags |