1 16 17 package de.gulden.util.javasource.sourclet.standard; 18 19 import de.gulden.util.javasource.sourclet.*; 20 import de.gulden.util.javasource.Package; 21 import de.gulden.util.javasource.Class; 22 import de.gulden.util.javasource.Exception; 23 import de.gulden.util.javasource.*; 24 import de.gulden.util.Toolbox; 25 import java.io.*; 26 import java.util.*; 27 import java.text.*; 28 import java.lang.reflect.Modifier ; 29 30 37 public class StandardSourclet extends AbstractSourclet { 38 39 43 48 protected static String [] specialPrefixes = {"get","set","add","remove","is","init","parse","create","build"}; 49 50 54 protected static String defaultExceptionTexts = "IOException=if an i/o error occurs,SQLException=if a database error occurs,SAXException=if an XML parser error occurs,NumberFormatException=if the string cannot be parsed as a number"; 55 56 57 61 64 protected Properties exceptionTexts = null; 65 66 69 protected String headerfileText = null; 70 71 72 76 79 public StandardSourclet() { 80 81 } 82 83 84 88 96 public void buildStartSource(OutputStream out, SourceObjectDeclared o) throws IOException { 97 if (o instanceof Class ) { 98 Class clazz=(Class )o; 99 if (!(clazz instanceof ClassInner)) { 100 String headerfile=getHeaderfile(); 101 if (headerfile!=null) { 102 write(out,headerfile); 103 } else { 104 String opt; 105 write(out,"/*"+nl); 106 opt=getOption("project.name"); 107 if (opt!=null) { 108 write(out," * Project: "+opt+nl); 109 } 110 write(out," * Class: "+clazz.getName()+nl); 111 opt=getOption("project.version"); 112 if (opt!=null) { 113 write(out," * Version: "+opt+nl); 114 } 115 opt=getOption("project.date"); 116 if (opt!=null) { 117 String op=opt.trim(); 118 if (op.equalsIgnoreCase("now")||op.equalsIgnoreCase("today")) { 119 opt=isodate(); 120 } 121 write(out," *"+nl); 122 write(out," * Date: "+opt+nl); 123 } 124 opt=getOption("project.description"); 125 if (opt!=null) { 126 opt=replace(opt,"\\n","\n"); write(out," *"+nl); 128 write(out,startWithStars(opt,"")); 129 } 130 write(out," *"+nl); 131 opt=getOption("author.name"); 132 if (opt!=null) { 133 write(out," * Author: "+opt+nl); 134 } 135 opt=getOption("author.email"); 136 if (opt!=null) { 137 write(out," * Email: "+opt+nl); 138 } 139 write(out," */"+nl+nl); 140 } 141 if (!clazz.getPackage().isBasePackage()) { 143 write(out,"package "+clazz.getPackage().getName()+";"+nl); 144 } 145 146 NamedIterator it=clazz.getImports(); 148 if (it.hasMore()) { 149 write(out,nl); 150 while (it.hasMore()) { 151 Import im=(Import)it.next(); 152 write(out,"import "+im.getName()+";"+nl); 153 } 154 } 155 write(out,nl); 156 } 157 } 158 159 if ((o instanceof Member)||(o instanceof Class )) { 161 String type=getTypeCode(o); 162 163 String spaces; 164 if (o instanceof Class ) { 165 spaces=""; 166 } else { 167 spaces=indent(1); 168 } 169 170 DocumentationDeclared doc=(DocumentationDeclared)o.getDocumentation(); 171 String text=null; 172 DocumentationDeclared supDoc=tryGetDocumentationFromSuperclass(o); if ((doc!=null) &&(doc instanceof DocumentationDeclared)) { 175 if (!hasOption( type+".remove.text", "description")) { 176 text=doc.getText(); 177 if (text==null||text.equals("")) { 178 if (supDoc!=null) { 179 text=supDoc.getText(); 180 } 181 } 182 } 183 } else { if ((supDoc!=null)&&(!hasOption( type+".remove.text", "description"))) { 185 text=supDoc.getText(); 186 } 187 } 188 if ((text!=null)&&isDummy(text)&&(hasOption( type+".remove.dummy", "description"))) { 190 text=null; 191 } 192 193 if (text==null) { 195 String unqualifiedName=o.getUnqualifiedName(); 196 String specialPrefix=getSpecialPrefix(unqualifiedName); 197 if (hasOption( type+".create.text", "description")) { 198 if ((o instanceof Constructor)&&hasOption("method.create.text", "description")) { 199 text="Creates a new instance of "+unqualifiedName+"."; 200 } else if ((o instanceof Method)&&(specialPrefix!=null)&&hasOption("method.create.text", "description")) { 201 if (specialPrefix.equals("get")) { 202 text="Returns the "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 203 } else if (specialPrefix.equals("set")) { 204 text="Sets the "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 205 } else if (specialPrefix.equals("add")) { 206 text="Adds a "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 207 } else if (specialPrefix.equals("remove")) { 208 text="Removes a "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 209 } else if (specialPrefix.equals("init")) { 210 text="Inits the "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 211 } else if (specialPrefix.equals("parse")) { 212 text="Parses the "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 213 } else if (specialPrefix.equals("create")) { 214 text="Creates the "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 215 } else if (specialPrefix.equals("build")) { 216 text="Builds the "+toWords(unqualifiedName.substring(specialPrefix.length()))+"."; 217 } 218 } else if ((o instanceof Field)&&hasOption("field.create.text", "description")) { 219 if (Modifier.isFinal(o.getModifier())) { 220 text="Constant "+o.getUnqualifiedName()+SourceParser.repeat("[]",(((Field)o).getType().getDimension()))+"."; 221 } else { 222 text="The "+toWords(o.getUnqualifiedName())+(((Field)o).getType().getDimension()>0?" array":"")+"."; 223 } 224 } else if ((o instanceof Class )&&hasOption("class.create.text", "description")) { 225 text="Class "+o.getUnqualifiedName()+"."; 226 } 227 } 228 if ((text==null)&&hasOption( type+".create.dummy", "description")) { 230 if (specialPrefix!=null) { 231 if (specialPrefix.equals("is")) { 232 text="Tests if ..."; 233 } 234 } 235 if (text==null) { 236 text="..."; 237 } 238 } 239 } 240 241 boolean headDone=false; 242 243 if (text!=null) { 244 write(out,spaces+"/**"+nl); 245 headDone=true; 246 write(out,startWithStars(text,spaces)); 247 } 248 249 ByteArrayOutputStream buf=new ByteArrayOutputStream(); 250 buildTagDocumentation(buf,o,doc,supDoc); 251 if (buf.size()>0) { 252 if (!headDone) { 253 write(out,spaces+"/**"+nl); 254 headDone=true; 255 } 256 write(out,startWithStars(" ",spaces)); 257 buf.writeTo(out); 258 } 259 if (headDone) { 260 write(out,spaces+" */"+nl); 261 } 262 } 263 } 264 265 272 public void buildHeadSource(OutputStream out, SourceObjectDeclared o) throws IOException { 273 boolean fullQualify=isOption("code.qualify"); 274 275 if (o instanceof Member) { 276 write(out,indent(1)); 277 } 278 279 String mod=Modifier.toString(o.getModifier()); 280 if (mod.length()>0) { 281 write(out,mod+" "); 282 } 283 284 if (o instanceof Typed) { Typed typed=(Typed)o; 286 String t; 287 if (fullQualify) { 288 t = typed.getType().getFullTypeName(); 289 } else { 290 t = typed.getType().getFullUnqualifiedTypeName(); 291 String unqualifiedType = typed.getType().getUnqualifiedTypeName(); 292 String qualifiedType = typed.getType().getTypeName(); 293 Class declaringClass; 294 if ( ! (typed instanceof Parameter)) { 295 declaringClass = ((SourceObjectDeclared)typed).getDeclaringClass(); 296 } else { 297 declaringClass = ((Parameter)typed).getMemberExecutable().getDeclaringClass(); 298 } 299 if (makeSureIsQualifyable(declaringClass, unqualifiedType, qualifiedType).equals(qualifiedType)) { 300 t = typed.getType().getFullTypeName(); } 302 if (t.indexOf('.')!=-1) { 303 if (declaringClass != null) { 306 String thisClassname = declaringClass.getUnqualifiedName(); 307 if (t.startsWith(thisClassname+".")) { 308 t = t.substring(thisClassname.length()+1); 309 } 310 } 311 } 312 } 313 write(out,t+" "); 314 } 315 316 if (o instanceof Class ) { 317 Class clazz=(Class )o; 318 write(out,clazz.isInterface()?"interface ":"class "); 319 } 320 321 write(out,o.getUnqualifiedName()); 323 324 if (o instanceof Class ) { 325 Class clazz=(Class )o; 326 String sup=clazz.getSuperclassName(); 327 if (!sup.equals("java.lang.Object")) { 328 String s=sup; 329 if (!fullQualify) { 330 s = unqualifyClassname(clazz, s); 331 } 332 write(out," extends "+s); 333 } 334 335 Enumeration en=clazz.getInterfaceNames(); 337 if (en.hasMoreElements()) { 338 if (!clazz.isInterface()) { 339 write(out," implements "); 340 } else { 341 write(out," extends "); 342 } 343 while (en.hasMoreElements()) { 344 String in=(String )en.nextElement(); 345 if (!fullQualify) { 346 in = unqualifyClassname(clazz, in); 347 } 348 write(out,in+(en.hasMoreElements()?(", "):"")); 349 } 350 } 351 } 352 353 else if (o instanceof MemberExecutable) { 354 MemberExecutable mex=(MemberExecutable)o; 355 write(out,"("); 357 for (NamedIterator it=mex.getParameters();it.hasMore();) { 358 Parameter pa=(Parameter)it.next(); 359 buildSource(out,pa); 360 if (it.hasMore()) { 361 write(out,", "); 362 } 363 } 364 write(out,")"); 365 366 NamedIterator it=mex.getExceptions(); 368 if (it.hasMore()) { 369 write(out," throws "); 370 while (it.hasMore()) { 371 Exception ex=(Exception )it.next(); 372 String exx; 373 if (!fullQualify) { 374 exx=ex.getUnqualifiedName(); 375 exx = makeSureIsQualifyable(mex.getDeclaringClass(), exx, ex.getName()); 376 } else { 377 exx=ex.getName(); 378 } 379 380 write(out,exx+(it.hasMore()?", ":"")); 381 } 382 } 383 } 384 } 385 386 393 public void buildBodySource(OutputStream out, SourceObjectDeclared o) throws IOException { 394 395 boolean bracesLinebreak = isOption("code.braces.linebreak"); 396 397 399 if (o instanceof Class ) { 400 Class clazz=(Class )o; 401 NamedIterator it=clazz.getAllMembers(); 402 if (bracesLinebreak) { write(out, nl + "{"); 404 if ( ! isOption("code.separators")) { 405 write(out, nl); 406 } 407 } else { write(out," {"+nl); 409 } 410 411 Vector todo=new Vector(); 412 413 if (isOption("code.preserve.fields.order")) { 414 415 it.reset(); 416 boolean firstField = true; 417 while (it.hasMore()) { 418 Member m=(Member)it.next(); 419 if (m instanceof Field) { 420 todo.addElement(m); 421 } 423 } 424 425 buildHeader(out,'-',"field", "fields", todo.size()); 426 427 Vector singleTodo = new Vector(); 428 for (Enumeration e = todo.elements(); e.hasMoreElements(); ) { 429 singleTodo.removeAllElements(); 430 singleTodo.addElement( e.nextElement() ); 431 buildSourceAll(out,singleTodo,null); } 433 434 } else { 436 it.reset(); 437 while (it.hasMore()) { 438 Member m=(Member)it.next(); 439 if ( (m instanceof Field) && Modifier.isStatic(m.getModifier()) && Modifier.isFinal(m.getModifier()) ) { 440 todo.addElement(m); 441 } 442 } 443 buildSourceAll(out,todo,"final static field"); 444 445 it.reset(); 446 todo.removeAllElements(); 447 while (it.hasMore()) { 448 Member m=(Member)it.next(); 449 if ( (m instanceof Field) && Modifier.isStatic(m.getModifier() ) && (!Modifier.isFinal(m.getModifier()) ) ) { 450 todo.addElement(m); 451 } 452 } 453 buildSourceAll(out,todo,"static field"); 454 455 it.reset(); 456 todo.removeAllElements(); 457 while (it.hasMore()) { 458 Member m=(Member)it.next(); 459 if ((m instanceof Field)&&(!Modifier.isStatic(m.getModifier()))) { 460 todo.addElement(m); 461 } 462 } 463 buildSourceAll(out,todo,"field"); 464 465 } 466 467 469 Code[] initializers = clazz.getStaticInitializers(); 470 if (initializers.length>0) { 471 buildHeader(out,'-',"static initializer", initializers.length); 472 for (int i = 0; i < initializers.length; i++) { 473 String code = initializers[i].getRaw(); 474 code=applyCodeFormatting(code); 475 write(out,indent("static {",1)); 476 write(out,nl); 477 write(out,code); 478 write(out,nl); 479 write(out,indent("}",1)); 480 write(out,nl); 481 } 482 } 483 484 initializers = clazz.getInstanceInitializers(); 485 if (initializers.length>0) { 486 buildHeader(out,'-',"instance initializer", initializers.length); 487 for (int i = 0; i < initializers.length; i++) { 488 String code = initializers[i].getRaw(); 489 code=applyCodeFormatting(code); 490 write(out,indent("{",1)); 491 write(out,nl); 492 write(out,code); 493 write(out,nl); 494 write(out,indent("}",1)); 495 write(out,nl); 496 } 497 } 498 499 500 it.reset(); 501 todo.removeAllElements(); 502 while (it.hasMore()) { 503 Member m=(Member)it.next(); 504 if (m instanceof Constructor) { 505 todo.addElement(m); 506 } 507 } 508 buildSourceAll(out,todo,"constructor"); 509 510 it.reset(); 511 todo.removeAllElements(); 512 while (it.hasMore()) { 513 Member m=(Member)it.next(); 514 if ((m instanceof Method)&&(!Modifier.isStatic(m.getModifier()))) { 515 todo.addElement(m); 516 } 517 } 518 buildSourceAll(out,todo,"method"); 519 520 it.reset(); 521 todo.removeAllElements(); 522 while (it.hasMore()) { 523 Member m=(Member)it.next(); 524 if ((m instanceof Method)&&(Modifier.isStatic(m.getModifier()))) { 525 todo.addElement(m); 526 } 527 } 528 buildSourceAll(out,todo,"static method"); 529 530 531 533 it=clazz.getInnerClasses(); 534 if (it.size()>0) { 535 buildHeader(out,'*',(it.size()==1)?"inner class":"inner classes"); 536 while (it.hasMore()) { 537 Class c=(Class )it.next(); 538 ByteArrayOutputStream outInner=new ByteArrayOutputStream(); 539 buildSource(outInner,c); 540 String shifted=indent(new String (outInner.toByteArray()),1); 541 write(out,shifted+nl); 542 } 543 } 544 545 write(out,"} // end "+clazz.getUnqualifiedName()+nl); 546 } 547 548 550 else if ((o instanceof MemberExecutable)||(o instanceof Field)) { 551 Code code; 552 if (o instanceof MemberExecutable) { 553 code=((MemberExecutable)o).getCode(); 554 } 555 else { 556 code=((Field)o).getCode(); 557 } 558 559 if (code!=null) { 560 String c=code.getRaw(); 561 if (o instanceof MemberExecutable) { 562 if (isOption("code.braces.linebreak")) { write(out, nl); 564 write(out,indent("{", 1)+nl); 565 } else { write(out," {"+nl); 567 } 568 c=applyCodeFormatting(c); 569 write(out,c+nl); 570 write(out,indent("}",1)+nl); 571 } else { write(out," = "+c+";"+nl); 573 } 574 } 575 else { 576 write(out,";"+nl); 577 } 578 write(out,nl); 579 } 580 } 581 582 587 public void buildEndSource(OutputStream out, SourceObjectDeclared o) throws IOException { 588 } 590 591 594 protected String getExceptionText(String exc) { 595 if (exceptionTexts==null) { exceptionTexts=new Properties(); 597 String t=defaultExceptionTexts+getOption("exception.texts"); StringTokenizer st=new StringTokenizer(t,",",false); 599 while (st.hasMoreTokens()) { 600 String s=st.nextToken(); 601 StringTokenizer st2=new StringTokenizer(s,"=",false); 602 String exception=st2.nextToken(); 603 String text=st2.nextToken(); 604 if (!(exception==null||text==null||st2.hasMoreTokens())) { 605 exceptionTexts.setProperty(exception.trim(),text.trim()); 606 } else { 607 } 609 } 610 } 611 return exceptionTexts.getProperty(exc); 612 } 613 614 617 protected String getHeaderfile() { 618 if (headerfileText==null) { 619 String filename=getOption("project.headerfile"); 621 if (filename!=null) { 622 File file=new File(filename); 623 if (file.isFile()) { 624 try { 625 char[] c=new char[(int)file.length()]; 626 FileReader f=new FileReader(file); 627 f.read(c); 628 f.close(); 629 headerfileText=new String (c); 630 } catch (IOException e) { 631 headerfileText="/* ERROR READING HEADERFILE '"+filename+"' */"; 632 } 633 } 634 } 635 } 636 return headerfileText; } 638 639 644 protected void buildTagDocumentation(OutputStream out, SourceObjectDeclared o, DocumentationDeclared doc, DocumentationDeclared supDoc) throws IOException { 645 if (o instanceof Class ) { 647 Class clazz=(Class )o; 648 String opt; 650 opt=getOption("author.name"); 651 if (opt!=null) { 652 buildTagDocumentationSynthesize(out,"class","author",null,opt,doc,supDoc,"",true); 653 } 654 opt=getOption("project.version"); 656 if (opt!=null) { 657 buildTagDocumentationSynthesize(out,"class","version",null,opt,doc,supDoc,"",true); 658 } 659 } else if (o instanceof MemberExecutable) { 660 MemberExecutable mex=(MemberExecutable)o; 661 String unqualifiedName=o.getUnqualifiedName(); 662 String specialPrefix=getSpecialPrefix(unqualifiedName); 663 664 boolean createText=hasOption("method.create.text", "param"); 666 boolean createDummy=hasOption("method.create.dummy", "param"); 667 String type=getTypeCode(o); 668 for (NamedIterator it=mex.getParameters();it.hasMore();) { 669 Parameter pa=(Parameter)it.next(); 670 String def=null; 671 if (createText&&(specialPrefix!=null)&&(specialPrefix.equals("set"))) { 672 def="The "+toWords(unqualifiedName.substring(specialPrefix.length()))+(pa.getType().getDimension()>0?" array":"")+"."; 673 } else if (createText) { 674 String n=pa.getName(); 675 if (n.length()<3) { n=pa.getType().getUnqualifiedTypeName(); 677 } 678 def="The "+toWords(n) 679 +(pa.getType().getDimension()>0?" array":"") 680 +"."; 681 } else if (createDummy) { 682 def="The ..."; 683 } 684 buildTagDocumentationSynthesize(out,type,"param",pa.getName(),def,doc,supDoc,indent(1),true); 685 } 686 687 createText=hasOption("method.create.text", "throws"); 689 createDummy=hasOption("method.create.dummy", "throws"); 690 for (NamedIterator it=mex.getExceptions();it.hasMore();) { 691 Exception ex=(Exception )it.next(); 692 String exc=ex.getUnqualifiedName(); 693 String def=getExceptionText(exc); 695 if (createDummy&&(def==null)) { 697 def="if ..."; 698 } 699 buildTagDocumentationSynthesize(out,type,"throws",exc,def,doc,supDoc,indent(1),true); 700 } 701 702 if (o instanceof Method) { 704 Method met=(Method)o; 705 createText=hasOption("method.create.text", "return"); 706 createDummy=hasOption("method.create.text", "return"); 707 if (!(met.getType().getFullTypeName().equals("void"))) { 708 String def=null; 710 if (createText && (specialPrefix!=null) && specialPrefix.equals("get")) { 711 def="The "+toWords(unqualifiedName.substring(specialPrefix.length())) 712 +(met.getType().getDimension()>0?" array":"") 713 +"."; 714 } else if (createText) { 715 def="The "+toWords(met.getType().getUnqualifiedTypeName()) 716 +(met.getType().getDimension()>0?" array":"") 717 +"."; 718 } else if (createDummy) { 719 def="The ..."; 720 } 721 buildTagDocumentationSynthesize(out,"method","return",null,def,doc,supDoc,indent(1),true); 722 } 723 } 724 } 726 if (doc!=null) { 728 for (Enumeration e=doc.getTags();e.hasMoreElements();) { 729 DocumentationTagged dt=(DocumentationTagged)e.nextElement(); 730 if ((!dt.getTag().equals("@param")) 731 &&(!dt.getTag().equals("@throws")) 732 &&(!dt.getTag().equals("@return")) 733 &&(!((o instanceof Class )&&(dt.getTag().equals("@author")))) 734 &&(!((o instanceof Class )&&(dt.getTag().equals("@version"))))) { 735 buildDocumentationTagged(out,dt,(o instanceof Class )?"":indent(1)); 736 } 737 } 738 } else if (supDoc!=null) { 739 for (Enumeration e=supDoc.getTags();e.hasMoreElements();) { 740 DocumentationTagged dt=(DocumentationTagged)e.nextElement(); 741 if ((!dt.getTag().equals("@param")) 742 &&(!dt.getTag().equals("@throws")) 743 &&(!dt.getTag().equals("@return")) 744 &&(!((o instanceof Class )&&(dt.getTag().equals("@author")))) 745 &&(!((o instanceof Class )&&(dt.getTag().equals("@version"))))) { 746 buildDocumentationTagged(out,dt,(o instanceof Class )?"":indent(1)); 747 } 748 } 749 } 750 } 751 752 757 protected void buildTagDocumentationSynthesize(OutputStream out, String typeName, String tagName, String tagItem, String defaultValue, DocumentationDeclared doc, DocumentationDeclared supDoc, String spaces, boolean synthesize) throws IOException { 758 DocumentationTagged tag=null; 760 if (doc!=null) { 762 if (!hasOption( typeName+".remove.text", tagName)) { 763 tag=doc.findTag("@"+tagName,tagItem); 764 } 765 String text=null; 766 if (tag!=null) { 767 text=tag.getText(); 768 } 769 if ((text==null)||(text.trim().length()==0)) { 770 tag=null; 771 } 772 if ((tag!=null)&&isDummy(text)&&hasOption( typeName+".remove.dummy", tagName)) { 774 tag=null; 775 } 776 } 777 if (tag==null) { 779 if (supDoc!=null) { 780 tag=supDoc.findTag("@"+tagName,tagItem); 781 } 782 String text=null; 783 if (tag!=null) { 784 text=tag.getText(); 785 } 786 if ((text==null)||(text.trim().length()==0)) { 787 tag=null; 788 } 789 if ((tag!=null)&&(isDummy(text)&&(hasOption( typeName+".remove.dummy", tagName)))) { 791 tag=null; 792 } 793 } 794 if ((tag==null) && synthesize && (defaultValue!=null)) { 796 tag=new DocumentationTagged(); 797 tag.setTag("@"+tagName); 798 tag.setItem(tagItem); 799 tag.setText(defaultValue); 800 } 801 if (tag!=null) { 803 buildDocumentationTagged(out,tag,spaces); 804 } 805 } 806 807 823 protected void buildSourceAll(OutputStream out, Vector v, String header) throws IOException { 824 String headerPlural; 826 if (header != null) { 827 headerPlural = header + "s"; 828 } else { 829 headerPlural = null; 830 } 831 832 buildSourceAll( out, v, header, headerPlural ); 833 } 834 835 849 protected void buildSourceAll(OutputStream out, Vector v, String header, String headerPlural) throws IOException { 850 if (!v.isEmpty()) { 851 if ( (header != null) && (headerPlural != null) ) { 852 buildHeader(out,'-',header, headerPlural, v.size()); 853 } 854 for (Enumeration e=v.elements();e.hasMoreElements();) { 856 SourceObjectDeclared o=(SourceObjectDeclared)e.nextElement(); 857 if (Modifier.isPublic(o.getModifier())) { 858 buildSource(out,o); 859 } 860 } 861 for (Enumeration e=v.elements();e.hasMoreElements();) { 863 SourceObjectDeclared o=(SourceObjectDeclared)e.nextElement(); 864 if (Modifier.isProtected(o.getModifier())) { 865 buildSource(out,o); 866 } 867 } 868 for (Enumeration e=v.elements();e.hasMoreElements();) { 870 SourceObjectDeclared o=(SourceObjectDeclared)e.nextElement(); 871 if ((!Modifier.isPublic(o.getModifier()))&&(!Modifier.isProtected(o.getModifier()))&&(!Modifier.isPrivate(o.getModifier()))) { 872 buildSource(out,o); 873 } 874 } 875 for (Enumeration e=v.elements();e.hasMoreElements();) { 877 SourceObjectDeclared o=(SourceObjectDeclared)e.nextElement(); 878 if (Modifier.isPrivate(o.getModifier())) { 879 buildSource(out,o); 880 } 881 } 882 } 883 } 884 885 890 protected void buildHeader(OutputStream out, char mark, String header) throws IOException { 891 if (isOption("code.separators")) { 892 write(out,nl+indent("// "+chars(mark,72)+nl 893 +"// "+chars(mark,3)+" "+header+spaces(65-header.length())+chars(mark,3)+nl 894 +"// "+chars(mark,72)+nl,1)+nl); 895 } 896 } 897 898 904 protected void buildHeader(OutputStream out, char mark, String header, String headerPlural, int num) throws IOException { 905 if (num>0) { 906 buildHeader(out, mark, (num!=1 ? headerPlural : header)); 907 } 908 } 909 910 916 protected void buildHeader(OutputStream out, char mark, String header, int num) throws IOException { 917 buildHeader(out, mark, header, header+"s", num); 918 } 919 920 927 protected String indent(String text, int steps) { 928 StringTokenizer st=new StringTokenizer(text,"\n\r", true); 929 StringBuffer sb=new StringBuffer (); 930 int spaces=getIntOption("code.indent.spaces"); char lastBreak = (char)0; 932 933 while (st.hasMoreTokens()) { 934 String line=st.nextToken(); 935 char first = line.charAt(0); 936 if (first=='\n' || first=='\r') { if ( (lastBreak==(char)0) || lastBreak==first ) { 938 sb.append(nl); lastBreak = first; 940 } 941 } else { sb.append(spaces(steps*spaces)); 943 sb.append(line); 944 lastBreak = (char)0; 945 } 946 } 947 return sb.toString(); 948 } 949 950 953 protected String indent(int steps) { 954 int spaces=getIntOption("code.indent.spaces"); return spaces(steps*spaces); 956 } 957 958 961 protected String applyCodeFormatting(String code) { 962 if (isOption("code.clean")) { 963 code=cleanCode(code); 964 } 965 if (isOption("code.format")) { 966 code = format(code); 967 } 968 code = indent(code, 2); 969 return code; 970 } 971 972 980 protected String format(String code) { 981 int codeLength=code.length(); 982 if (codeLength>0) { 983 StringBuffer sb=new StringBuffer (); 984 StringBuffer line=new StringBuffer (); 985 char quoted=(char)0; 986 char comment=(char)0; 987 boolean escape=false; 988 int indentLevel=0; 989 int indentLevelDiff=0; 990 boolean newline=false; 991 boolean previousNewline=false; 992 int i=0; 993 char c=(char)0; 994 char prevC; 995 char nextC=code.charAt(0); 996 997 while (i<codeLength) { 998 prevC=c; 999 c=nextC; 1000 if (i<codeLength-1) { 1001 nextC=code.charAt(i+1); 1002 } else { 1003 nextC=(char)0; 1004 } 1005 1006 if (escape) { line.append(c); 1008 escape=false; 1009 1010 } else if (comment=='/') { if (c=='\n') { 1012 newline=true; 1013 previousNewline = true; 1014 comment=(char)0; 1015 } 1016 line.append(c); 1017 1018 } else if (comment=='*') { if (c=='/'&&prevC=='*') { 1020 comment=(char)0; 1021 } 1022 line.append(c); 1023 1024 } else if (quoted!=(char)0) { 1026 if (c=='\\') { 1027 escape=true; 1028 } else if (quoted==c) { quoted=(char)0; 1030 } 1031 line.append(c); 1032 1033 } else { 1035 switch (c) { 1036 case '\\': escape=true; 1037 break; 1038 case '/': if (nextC=='/'||nextC=='*') { 1039 comment=nextC; 1040 } 1041 break; 1042 case '\"': 1043 case '\'': quoted=c; 1044 break; 1045 case '\n': 1046 newline=previousNewline; previousNewline = true; 1048 break; 1049 case ';': String l=line.toString().trim(); 1050 if (!l.startsWith("for")) { newline=true; 1052 } 1053 break; 1054 case '{': newline=true; 1055 indentLevelDiff=+1; 1056 break; 1057 case '}': l=line.toString().trim(); 1058 if (l.length()>0) { sb.append(indent(l,indentLevel)+nl); 1060 line=new StringBuffer (); 1061 } 1062 indentLevel-=1; 1063 newline = (nextC=='\n'); break; 1065 } 1066 line.append(c); 1067 1068 } 1069 1070 i++; if (i>=codeLength) { newline=true; 1073 } 1074 if (newline) { 1075 sb.append(indent(line.toString().trim(),indentLevel)); 1076 if (i < codeLength) { sb.append(nl); 1078 indentLevel+=indentLevelDiff; 1079 indentLevelDiff=0; 1080 line=new StringBuffer (); 1081 newline=false; 1082 previousNewline = false; 1083 } 1084 } 1085 1086 } 1087 return sb.toString(); 1088 } else { 1089 return ""; 1090 } 1091 } 1092 1093 protected String unqualifyClassname(Class inClass, String name) { 1094 String result; 1095 if (name.indexOf('.')!=-1) { String u = unqualify(name); 1097 String rest = name.substring(0, name.length()-u.length()-1); 1098 if (Package.isSourcePackage(inClass.getPackage().getBasePackage(), rest)) { result = u; 1101 } else { 1102 String outer; 1103 try { 1104 outer = inClass.qualify(rest); 1105 result = unqualifyClassname(inClass, outer) + "." + u; 1106 } catch (NoClassDefFoundError ncdfe) { 1107 result = u; 1108 } 1109 } 1110 } else { 1111 result = name; 1112 } 1113 return makeSureIsQualifyable(inClass, result, name); 1114 } 1115 1116 1121 protected String makeSureIsQualifyable(Class inClass, String unqualified, String qualified) { 1122 try { 1123 inClass.qualify(unqualified); 1124 return unqualified; 1125 } catch (NoClassDefFoundError ncdfe) { 1126 if (isOption("code.qualify.auto")) { 1127 return qualified; 1129 } else { 1130 System.err.println("warning: in class "+inClass.getName()+": outputting unqualified classname '"+unqualified+"', although it seems to be not fully qualifyable. If this leads to problems when compiling, try option -code.qualify.auto, or use -code.qualify to always use fully qualified classnames."); 1131 return unqualified; 1132 } 1133 } 1134 } 1135 1136 1137 1141 1146 public static String startWithStars(String s, String spaces) { 1147 StringTokenizer st=new StringTokenizer(s,"\r\n"); 1148 StringBuffer sb=new StringBuffer (); 1149 while (st.hasMoreTokens()) { 1150 sb.append(spaces+" * "+st.nextToken()+nl); 1151 } 1152 return sb.toString(); 1153 } 1154 1155 1161 public static String unqualify(String n) { 1162 int pos=n.lastIndexOf('.'); 1163 if (pos!=-1) { 1164 return n.substring(pos+1); 1165 } 1166 else { 1167 return n; 1168 } 1169 } 1170 1171 1175 public static String chars(char mark, int count) { 1176 StringBuffer sb=new StringBuffer (); 1177 for (int i=0;i<count;i++) { 1178 sb.append(mark); 1179 } 1180 return sb.toString(); 1181 } 1182 1183 1187 public static String spaces(int count) { 1188 return chars(' ',count); 1189 } 1190 1191 1194 public static String replace(String s, String find, String repl) { 1195 int pos=s.indexOf(find); 1196 if (pos!=-1) { 1197 return s.substring(0,pos)+repl+replace(s.substring(pos+find.length()),find,repl); 1198 } else { 1199 return s; 1200 } 1201 } 1202 1203 1206 public static String isodate() { 1207 SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd"); 1208 return formatter.format(new Date()); 1209 } 1210 1211 1217 public static String getSpecialPrefix(String id) { 1218 for (int i=0;i<specialPrefixes.length;i++) { 1219 int l=specialPrefixes[i].length(); 1220 if ((id.length()>l) 1221 && id.startsWith(specialPrefixes[i]) 1222 && Character.isUpperCase(id.charAt(l)) ) { 1224 return specialPrefixes[i]; 1225 } 1226 } 1227 return null; 1228 } 1229 1230 1235 public static boolean hasSpecialPrefix(String id) { 1236 return getSpecialPrefix(id)!=null; 1237 } 1238 1239 1247 public static String toWords(String s) { 1248 if (s.length()>0) { 1249 int end=1; 1250 while ((end<s.length())&&(!Character.isUpperCase(s.charAt(end)))) { 1251 end++; 1252 } 1253 if (end==s.length()) { 1254 return s.toLowerCase(); 1255 } else { 1256 return s.substring(0,end).toLowerCase()+" "+toWords(s.substring(end)); } 1258 } else { 1259 return ""; 1260 } 1261 } 1262 1263 public static boolean isDummy(String text) { 1264 return text.indexOf("...")!=-1; } 1266 1267 1272 public static String cleanCode(String c) { 1273 BufferedReader b=new BufferedReader(new StringReader(c)); 1274 StringBuffer r=new StringBuffer (); 1275 try { 1276 String l=b.readLine(); 1277 while (l!=null) { 1278 String nextL = b.readLine(); 1279 if (!isDeadCodeLine(l)) { 1280 r.append(l); 1281 if (nextL != null) { 1282 r.append(nl); 1283 } 1284 } 1285 l = nextL; 1286 } 1287 } catch (IOException io) { 1288 r.append("// *** ERROR: IOException while cleaning code"); 1289 } 1290 return r.toString(); 1291 } 1292 1293 1297 public static boolean isDeadCodeLine(String l) { 1298 l=l.trim(); 1299 return l.startsWith("//") 1300 && (l.endsWith(";")||l.endsWith("{")||l.endsWith("}")); 1301 } 1302 1303 1306 public static String getTypeCode(SourceObject o) { 1307 String c=unqualify(o.getClass().getName()).toLowerCase(); 1308 if (c.equals("constructor")) { 1309 c="method"; } else if (c.equals("classinner")) { 1311 c="class"; 1312 } 1313 return c; 1314 } 1315 1316 1319 protected static String getParentQualifier(String name) { 1320 int pos=name.lastIndexOf('.'); 1321 if (pos!=-1) { 1322 name=name.substring(0,pos); 1323 } else { 1324 name=null; 1325 } 1326 return name; 1327 } 1328 1329 protected static DocumentationDeclared tryGetDocumentationFromSuperclass(SourceObjectDeclared o) { 1330 if (o instanceof MemberExecutable) { 1331 MemberExecutable mex=(MemberExecutable)o; 1332 Class c=mex.getDeclaringClass(); 1333 String supName=c.getSuperclassName(); 1334 Class sup=c.getPackage().getBasePackage().findClass(supName); 1335 while (sup!=null) { 1336 for (NamedIterator it=sup.getAllMembers();it.hasMore();) { 1337 Member m=(Member)it.next(); 1338 if (m instanceof MemberExecutable) { 1339 if (m.equals(mex)) { 1340 Documentation d=m.getDocumentation(); 1341 if ((d!=null) 1342 &&(d instanceof DocumentationDeclared)) { 1343 return (DocumentationDeclared)d; 1344 } 1345 } 1346 } 1347 } 1348 if (!sup.getName().equals("java.lang.Object")) { 1349 supName=sup.getSuperclassName(); 1350 sup=c.getPackage().getBasePackage().findClass(supName); 1351 } else { 1352 sup=null; 1353 } 1354 } 1355 } 1356 return null; 1357 } 1358 1359 1364 protected static void buildDocumentationTagged(OutputStream out, DocumentationTagged tag, String spaces) throws IOException { 1365 write(out,startWithStars(tag.getTag()+" "+(((tag.getItem()!=null)?tag.getItem():"")+" "+tag.getText()),spaces)); 1366 } 1367 1368} | Popular Tags |