KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > gulden > util > javasource > sourclet > standard > StandardSourclet


1 /*
2  * Project: BeautyJ - Customizable Java Source Code Transformer
3  * Class: de.gulden.util.javasource.sourclet.standard.StandardSourclet
4  * Version: 1.1
5  *
6  * Date: 2004-09-29
7  *
8  * Note: Contains auto-generated Javadoc comments created by BeautyJ.
9  *
10  * This is licensed under the GNU General Public License (GPL)
11  * and comes with NO WARRANTY. See file license.txt for details.
12  *
13  * Author: Jens Gulden
14  * Email: beautyj@jensgulden.de
15  */

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 JavaDoc;
29
30 /**
31  * The StandardSourclet used by BeautyJ.
32  * See documentation of Beauty and the Java Sourclet API.
33  *
34  * @author Jens Gulden
35  * @version 1.1
36  */

37 public class StandardSourclet extends AbstractSourclet {
38
39     // ------------------------------------------------------------------------
40
// --- static fields ---
41
// ------------------------------------------------------------------------
42

43     /**
44      *
45      * @see #getSpecialPrefix
46      * @see #hasSpecialPrefix
47      */

48     protected static String JavaDoc[] specialPrefixes = {"get","set","add","remove","is","init","parse","create","build"};
49
50     /**
51      * These defaults are also named for option doc.exception.texts in the configuration XML File.
52      * But if they are overwritten by the user, they still get used, so keep here as constant and always add to user's texts.
53      */

54     protected static String JavaDoc 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     // ------------------------------------------------------------------------
58
// --- fields ---
59
// ------------------------------------------------------------------------
60

61     /**
62      * The exception texts.
63      */

64     protected Properties exceptionTexts = null;
65
66     /**
67      * The headerfile text.
68      */

69     protected String JavaDoc headerfileText = null;
70
71
72     // ------------------------------------------------------------------------
73
// --- constructor ---
74
// ------------------------------------------------------------------------
75

76     /**
77      * Creates a new instance of StandardSourclet.
78      */

79     public StandardSourclet() {
80
81     }
82
83
84     // ------------------------------------------------------------------------
85
// --- methods ---
86
// ------------------------------------------------------------------------
87

88     /**
89      * Outputs the start part of a source object.
90      * This is the part which comes before the 'normal' head
91      * (e.g. before a method's signature), so usually this is
92      * the place where to output Javadoc comments.
93      *
94      * @throws IOException if an i/o error occurs
95      */

96     public void buildStartSource(OutputStream out, SourceObjectDeclared o) throws IOException {
97         if (o instanceof Class JavaDoc) {
98             Class JavaDoc clazz=(Class JavaDoc)o;
99             if (!(clazz instanceof ClassInner)) {
100                 String JavaDoc headerfile=getHeaderfile();
101                 if (headerfile!=null) {
102                     write(out,headerfile);
103                 } else {
104                     String JavaDoc 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 JavaDoc 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"); // allow line breaks expressed as "\n"
127
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                 // package
142
if (!clazz.getPackage().isBasePackage()) {
143                     write(out,"package "+clazz.getPackage().getName()+";"+nl);
144                 }
145
146                 // imports
147
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         // fields, methods, constructors, classes
160
if ((o instanceof Member)||(o instanceof Class JavaDoc)) {
161             String JavaDoc type=getTypeCode(o);
162
163             String JavaDoc spaces;
164             if (o instanceof Class JavaDoc) {
165                 spaces="";
166             } else {
167                 spaces=indent(1);
168             }
169
170             DocumentationDeclared doc=(DocumentationDeclared)o.getDocumentation();
171             String JavaDoc text=null;
172             DocumentationDeclared supDoc=tryGetDocumentationFromSuperclass(o); // inheriting documentation doesn't work properly yet is still undocumented
173
if ((doc!=null) // documentation exists
174
&&(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 { // documentation doesn't exist yet, try to find in a superclass
184
if ((supDoc!=null)&&(!hasOption( type+".remove.text", "description"))) {
185                     text=supDoc.getText();
186                 }
187             }
188             // if it's a dummy, remove if option is set to do so
189
if ((text!=null)&&isDummy(text)&&(hasOption( type+".remove.dummy", "description"))) {
190                 text=null;
191             }
192
193             // if no documentation found by now (or has been removed by option), maybe auto-generate
194
if (text==null) {
195                 String JavaDoc unqualifiedName=o.getUnqualifiedName();
196                 String JavaDoc 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 JavaDoc)&&hasOption("class.create.text", "description")) {
225                         text="Class "+o.getUnqualifiedName()+".";
226                     }
227                 }
228                 // if no text found or generated, maybe generate a dummy
229
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     /**
266      * Outputs the head part of a source object.
267      * This is the actual Java code that declares the source object,
268      * for example a method's signature.
269      *
270      * @throws IOException if an i/o error occurs
271      */

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 JavaDoc mod=Modifier.toString(o.getModifier());
280         if (mod.length()>0) {
281             write(out,mod+" ");
282         }
283
284         if (o instanceof Typed) { // Method, Field or Parameter
285
Typed typed=(Typed)o;
286             String JavaDoc t;
287             if (fullQualify) {
288                 t = typed.getType().getFullTypeName();
289             } else {
290                 t = typed.getType().getFullUnqualifiedTypeName();
291                 String JavaDoc unqualifiedType = typed.getType().getUnqualifiedTypeName();
292                 String JavaDoc qualifiedType = typed.getType().getTypeName();
293                 Class JavaDoc 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(); // 'fallback' to fully qualified
301
}
302                 if (t.indexOf('.')!=-1) {
303                     // Although unqualified, inner classes will be lead by classname-prefix.
304
// Remove this prefix if it is the current class.
305
if (declaringClass != null) {
306                         String JavaDoc 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 JavaDoc) {
317             Class JavaDoc clazz=(Class JavaDoc)o;
318             write(out,clazz.isInterface()?"interface ":"class ");
319         }
320
321         // name
322
write(out,o.getUnqualifiedName());
323
324         if (o instanceof Class JavaDoc) {
325             Class JavaDoc clazz=(Class JavaDoc)o;
326             String JavaDoc sup=clazz.getSuperclassName();
327             if (!sup.equals("java.lang.Object")) {
328                 String JavaDoc s=sup;
329                 if (!fullQualify) {
330                     s = unqualifyClassname(clazz, s);
331                 }
332                 write(out," extends "+s);
333             }
334
335             // implemented interfaces
336
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 JavaDoc in=(String JavaDoc)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             // parameters
356
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             // exceptions
367
NamedIterator it=mex.getExceptions();
368             if (it.hasMore()) {
369                 write(out," throws ");
370                 while (it.hasMore()) {
371                     Exception JavaDoc ex=(Exception JavaDoc)it.next();
372                     String JavaDoc 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     /**
387      * Outputs the body content of the source object. For example,
388      * in case of methods this is Java code, in case of classes this recursively
389      * contains other SourceObjects' code.
390      *
391      * @throws IOException if an i/o error occurs
392      */

393     public void buildBodySource(OutputStream out, SourceObjectDeclared o) throws IOException {
394
395         boolean bracesLinebreak = isOption("code.braces.linebreak");
396
397         // --- class
398

399            if (o instanceof Class JavaDoc) {
400                Class JavaDoc clazz=(Class JavaDoc)o;
401                NamedIterator it=clazz.getAllMembers();
402             if (bracesLinebreak) { // start with curly brace on individual line
403
write(out, nl + "{");
404                    if ( ! isOption("code.separators")) {
405                     write(out, nl);
406                    }
407             } else { // output curly brace at the end of the method's declaration
408
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                            //buildSourceAll(out,todo,(Modifier.isFinal(m.getModifier()) ? "final ":"") + "static field"); // will generate a header for each field, but that doesn't do any harm (called individually for each element to preserve order)
422
}
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); // build single elements
432
}
433
434             } else { // normal beautification: order by final-static / static / non-static and public / protected / friendly / private
435

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                // initializers (must appear after field declarations to avoid forward references)
468

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 JavaDoc 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 JavaDoc 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                // inner classes and interfaces
532

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 JavaDoc c=(Class JavaDoc)it.next();
538                        ByteArrayOutputStream outInner=new ByteArrayOutputStream();
539                        buildSource(outInner,c);
540                        String JavaDoc shifted=indent(new String JavaDoc(outInner.toByteArray()),1);
541                        write(out,shifted+nl);
542                    }
543                }
544
545                write(out,"} // end "+clazz.getUnqualifiedName()+nl);
546            }
547
548            // --- method / field
549

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 JavaDoc c=code.getRaw();
561                    if (o instanceof MemberExecutable) {
562                     if (isOption("code.braces.linebreak")) { // start with curly brace on individual line
563
write(out, nl);
564                            write(out,indent("{", 1)+nl);
565                     } else { // output curly brace at the end of the method's declaration
566
write(out," {"+nl);
567                     }
568                        c=applyCodeFormatting(c);
569                        write(out,c+nl);
570                        write(out,indent("}",1)+nl);
571                    } else { // Field
572
write(out," = "+c+";"+nl);
573                    }
574                }
575                else {
576                    write(out,";"+nl);
577                }
578                write(out,nl);
579            }
580     }
581
582     /**
583      * Outputs everything that occurs after the SourceObject.
584      *
585      * @throws IOException if an i/o error occurs
586      */

587     public void buildEndSource(OutputStream out, SourceObjectDeclared o) throws IOException {
588         //nop
589
}
590
591     /**
592      * Returns the associated description for the exception class name specified by <code>exc</code>.
593      */

594     protected String JavaDoc getExceptionText(String JavaDoc exc) {
595         if (exceptionTexts==null) { // auto-init on first call
596
exceptionTexts=new Properties();
597             String JavaDoc t=defaultExceptionTexts+getOption("exception.texts"); // repeat defaultExceptionTexts to make sure that defaults are contained if the user sets own value, append in front to make user settings able to overwrite defaults
598
StringTokenizer st=new StringTokenizer(t,",",false);
599             while (st.hasMoreTokens()) {
600                 String JavaDoc s=st.nextToken();
601                 StringTokenizer st2=new StringTokenizer(s,"=",false);
602                 String JavaDoc exception=st2.nextToken();
603                 String JavaDoc text=st2.nextToken();
604                 if (!(exception==null||text==null||st2.hasMoreTokens())) {
605                     exceptionTexts.setProperty(exception.trim(),text.trim());
606                 } else {
607                     // illegal option format, ignore
608
}
609             }
610         }
611         return exceptionTexts.getProperty(exc);
612     }
613
614     /**
615      * If a headerfile is specified, get the content as string.
616      */

617     protected String JavaDoc getHeaderfile() {
618         if (headerfileText==null) {
619             // auto-init from project.headerfile
620
String JavaDoc 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 JavaDoc(c);
630                     } catch (IOException e) {
631                         headerfileText="/* ERROR READING HEADERFILE '"+filename+"' */";
632                     }
633                 }
634             }
635         }
636         return headerfileText; // null if no headerfile
637
}
638
639     /**
640      * Builds the tag documentation.
641      *
642      * @throws IOException if an i/o error occurs
643      */

644     protected void buildTagDocumentation(OutputStream out, SourceObjectDeclared o, DocumentationDeclared doc, DocumentationDeclared supDoc) throws IOException {
645         // parameters doc, supDoc may be null
646
if (o instanceof Class JavaDoc) {
647             Class JavaDoc clazz=(Class JavaDoc)o;
648             // @author
649
String JavaDoc opt;
650             opt=getOption("author.name");
651             if (opt!=null) {
652                 buildTagDocumentationSynthesize(out,"class","author",null,opt,doc,supDoc,"",true);
653             }
654             // @version
655
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 JavaDoc unqualifiedName=o.getUnqualifiedName();
662             String JavaDoc specialPrefix=getSpecialPrefix(unqualifiedName);
663
664             // @param
665
boolean createText=hasOption("method.create.text", "param");
666             boolean createDummy=hasOption("method.create.dummy", "param");
667             String JavaDoc type=getTypeCode(o);
668             for (NamedIterator it=mex.getParameters();it.hasMore();) {
669                 Parameter pa=(Parameter)it.next();
670                 String JavaDoc 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 JavaDoc n=pa.getName();
675                     if (n.length()<3) { // use type name if too short identifier
676
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             // @throws
688
createText=hasOption("method.create.text", "throws");
689             createDummy=hasOption("method.create.dummy", "throws");
690             for (NamedIterator it=mex.getExceptions();it.hasMore();) {
691                 Exception JavaDoc ex=(Exception JavaDoc)it.next();
692                 String JavaDoc exc=ex.getUnqualifiedName();
693                 // is there a text given for that particular exception?
694
String JavaDoc def=getExceptionText(exc);
695                 // if no text given, synthesize dummy (if dummy option enabled)
696
if (createDummy&&(def==null)) {
697                     def="if ...";
698                 }
699                 buildTagDocumentationSynthesize(out,type,"throws",exc,def,doc,supDoc,indent(1),true);
700             }
701
702             // @return
703
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                     // get default text
709
String JavaDoc 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             // @see - not useful
725
}
726         // copy all other tags
727
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 JavaDoc)&&(dt.getTag().equals("@author"))))
734                 &&(!((o instanceof Class JavaDoc)&&(dt.getTag().equals("@version"))))) {
735                     buildDocumentationTagged(out,dt,(o instanceof Class JavaDoc)?"":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 JavaDoc)&&(dt.getTag().equals("@author"))))
745                 &&(!((o instanceof Class JavaDoc)&&(dt.getTag().equals("@version"))))) {
746                     buildDocumentationTagged(out,dt,(o instanceof Class JavaDoc)?"":indent(1));
747                 }
748             }
749         }
750     }
751
752     /**
753      * Builds the tag documentation synthesize.
754      *
755      * @throws IOException if an i/o error occurs
756      */

757     protected void buildTagDocumentationSynthesize(OutputStream out, String JavaDoc typeName, String JavaDoc tagName, String JavaDoc tagItem, String JavaDoc defaultValue, DocumentationDeclared doc, DocumentationDeclared supDoc, String JavaDoc spaces, boolean synthesize) throws IOException {
758         // parameters defaultValue, doc, supDoc may be null
759
DocumentationTagged tag=null;
760         // tag already there?
761
if (doc!=null) {
762             if (!hasOption( typeName+".remove.text", tagName)) {
763                 tag=doc.findTag("@"+tagName,tagItem);
764             }
765             String JavaDoc text=null;
766             if (tag!=null) {
767                 text=tag.getText();
768             }
769             if ((text==null)||(text.trim().length()==0)) {
770                 tag=null;
771             }
772             // remove dummy if activated
773
if ((tag!=null)&&isDummy(text)&&hasOption( typeName+".remove.dummy", tagName)) {
774                 tag=null;
775             }
776         }
777         // is there a matching documentation tag in superclass documentation?
778
if (tag==null) {
779             if (supDoc!=null) {
780                 tag=supDoc.findTag("@"+tagName,tagItem);
781             }
782             String JavaDoc text=null;
783             if (tag!=null) {
784                 text=tag.getText();
785             }
786             if ((text==null)||(text.trim().length()==0)) {
787                 tag=null;
788             }
789             // remove dummy if activated
790
if ((tag!=null)&&(isDummy(text)&&(hasOption( typeName+".remove.dummy", tagName)))) {
791                 tag=null;
792             }
793         }
794         // auto-generate
795
if ((tag==null) && synthesize && (defaultValue!=null)) {
796             tag=new DocumentationTagged();
797             tag.setTag("@"+tagName);
798             tag.setItem(tagItem);
799             tag.setText(defaultValue);
800         }
801         // output if something found or generated
802
if (tag!=null) {
803             buildDocumentationTagged(out,tag,spaces);
804         }
805     }
806
807     /**
808      * Builds all source objects in Vector <code>v</code>, sorted by
809      * <ul>
810      * <li><b>public</b></li>
811      * <li><b>protected</b></li>
812      * <li><b>package-private</b></li>
813      * <li><b>private</b></li>
814      * </ul>
815      * modifiers.<br>
816      * In front of the generated code, a header is attached which names the type
817      * of the source objects, distinguishing between singular (if v.size()==1) and plural (f v.size()>1) form.<br>
818      * Here, the plural form is derived from simply adding an 's', which works for
819      * most english words.
820      *
821      * @throws IOException if an i/o error occurs
822      */

823     protected void buildSourceAll(OutputStream out, Vector v, String JavaDoc header) throws IOException {
824         //, InvalidOptionException
825
String JavaDoc 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     /**
836      * Builds all source objects in Vector <code>v</code>, sorted by
837      * <ul>
838      * <li><b>public</b></li>
839      * <li><b>protected</b></li>
840      * <li><b>package-private</b></li>
841      * <li><b>private</b></li>
842      * </ul>
843      * modifiers.<br>
844      * In front of the generated code, a header is attached which names the type
845      * of the source objects, distinguishing between singular (if v.size()==1) and plural (f v.size()>1) form.
846      *
847      * @throws IOException if an i/o error occurs
848      */

849     protected void buildSourceAll(OutputStream out, Vector v, String JavaDoc header, String JavaDoc headerPlural) throws IOException {
850         if (!v.isEmpty()) {
851             if ( (header != null) && (headerPlural != null) ) {
852                 buildHeader(out,'-',header, headerPlural, v.size());
853             }
854             // public
855
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             // protected
862
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             // friendly
869
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             // private
876
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     /**
886      * Outputs a seperating header, if the corresponding option is set.
887      *
888      * @throws IOException if an i/o error occurs
889      */

890     protected void buildHeader(OutputStream out, char mark, String JavaDoc 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     /**
899      * Outputs a seperating header, if the corresponding option is set. Depending on <code>num</code>,
900      * the plural or singular form is used (or nothing, if num==0).
901      *
902      * @throws IOException if an i/o error occurs
903      */

904     protected void buildHeader(OutputStream out, char mark, String JavaDoc header, String JavaDoc headerPlural, int num) throws IOException {
905         if (num>0) {
906             buildHeader(out, mark, (num!=1 ? headerPlural : header));
907         }
908     }
909
910     /**
911      * Outputs a seperating header, if the corresponding option is set. Depending on <code>num</code>,
912      * a plural or singular form is used (or nothing, if num==0). The plural is auto-generated by adding an 's'.
913      *
914      * @throws IOException if an i/o error occurs
915      */

916     protected void buildHeader(OutputStream out, char mark, String JavaDoc header, int num) throws IOException {
917         buildHeader(out, mark, header, header+"s", num);
918     }
919
920     /**
921      * Indents a given block of text by the given number of steps.
922      * The size of each step in 'number of spaces' is set by option
923      * code.indent.spaces.
924      *
925      * @return Indented text.
926      */

927     protected String JavaDoc indent(String JavaDoc text, int steps) {
928         StringTokenizer st=new StringTokenizer(text,"\n\r", true);
929         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
930         int spaces=getIntOption("code.indent.spaces"); // TODO: optimize
931
char lastBreak = (char)0;
932
933         while (st.hasMoreTokens()) {
934             String JavaDoc line=st.nextToken();
935             char first = line.charAt(0);
936             if (first=='\n' || first=='\r') { // delimiter token
937
if ( (lastBreak==(char)0) || lastBreak==first ) {
938                         sb.append(nl); // etxtra blank line
939
lastBreak = first;
940                     }
941             } else { // full line token
942
sb.append(spaces(steps*spaces));
943                 sb.append(line);
944                 lastBreak = (char)0;
945             }
946         }
947         return sb.toString();
948     }
949
950     /**
951      * Returns a string with spaces. The number is determined by steps*option('code.indent.spaces').
952      */

953     protected String JavaDoc indent(int steps) {
954         int spaces=getIntOption("code.indent.spaces"); // TODO: optimize
955
return spaces(steps*spaces);
956     }
957
958     /**
959      * Apply code transformations according to options set by the user.
960      */

961     protected String JavaDoc applyCodeFormatting(String JavaDoc 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     /**
973      * Format a code block according to standard auto-indentation rules.
974      * This is a quick solution and could be done much more sophisticated.
975      * (The current version of the StandardSourclet puts focus in the overall
976      * organization of .java files, not primarily on the code blocks.)
977      * Maybe later versions should incorporate mature code from other OpenSource
978      * beautifier projects here - volunteers welcome!
979      */

980     protected String JavaDoc format(String JavaDoc code) {
981         int codeLength=code.length();
982         if (codeLength>0) {
983             StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
984             StringBuffer JavaDoc line=new StringBuffer JavaDoc();
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) { // escaped char
1007
line.append(c);
1008                   escape=false;
1009
1010                } else if (comment=='/') { // line comment
1011
if (c=='\n') {
1012                        newline=true;
1013                        previousNewline = true;
1014                        comment=(char)0;
1015                    }
1016                    line.append(c);
1017
1018                } else if (comment=='*') { // block comment
1019
if (c=='/'&&prevC=='*') {
1020                        comment=(char)0;
1021                    }
1022                    line.append(c);
1023
1024                } else if (quoted!=(char)0) { // quoted text, either ".." or '..'
1025

1026                    if (c=='\\') {
1027                        escape=true;
1028                    } else if (quoted==c) { // quote char again: end quoting
1029
quoted=(char)0;
1030                    }
1031                    line.append(c);
1032
1033                } else { // normal code
1034

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; // explicit newline only if no other (auto-generated) newline since last explicit newline
1047
previousNewline = true;
1048                                   break;
1049                        case ';': String JavaDoc l=line.toString().trim();
1050                                   if (!l.startsWith("for")) { // special: no line break after ; in for-loop declaration
1051
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) { // already something there in current line: write as own line
1059
sb.append(indent(l,indentLevel)+nl);
1060                                       line=new StringBuffer JavaDoc();
1061                                   }
1062                                   indentLevel-=1;
1063                                   newline = (nextC=='\n'); // cheap trick to make sure we don't loose blank lines after } (will fail if e.g. "} \n" )
1064
break;
1065                    }
1066                    line.append(c);
1067
1068                }
1069
1070                i++; // next char
1071
if (i>=codeLength) { // always output last line if end reached
1072
newline=true;
1073                }
1074                if (newline) {
1075                    sb.append(indent(line.toString().trim(),indentLevel));
1076                    if (i < codeLength) { // prepare for next line if end not reached,also output nl only in that case
1077
sb.append(nl);
1078                        indentLevel+=indentLevelDiff;
1079                        indentLevelDiff=0;
1080                        line=new StringBuffer JavaDoc();
1081                        newline=false;
1082                        previousNewline = false;
1083                    }
1084                }
1085
1086            }
1087            return sb.toString();
1088        } else {
1089            return "";
1090        }
1091    }
1092
1093    protected String JavaDoc unqualifyClassname(Class JavaDoc inClass, String JavaDoc name) {
1094        String JavaDoc result;
1095        if (name.indexOf('.')!=-1) { // not unqualified already
1096
String JavaDoc u = unqualify(name);
1097            String JavaDoc rest = name.substring(0, name.length()-u.length()-1);
1098            // is parent-identifier a class? (not package) - then it is an inner class
1099
if (Package.isSourcePackage(inClass.getPackage().getBasePackage(), rest)) { // optimization, but will not find a package if from classpath
1100
result = u;
1101            } else {
1102                String JavaDoc outer;
1103                try {
1104                    outer = inClass.qualify(rest);
1105                    result = unqualifyClassname(inClass, outer) + "." + u;
1106                } catch (NoClassDefFoundError JavaDoc ncdfe) {
1107                    result = u;
1108                }
1109            }
1110        } else {
1111            result = name;
1112        }
1113        return makeSureIsQualifyable(inClass, result, name);
1114    }
1115
1116    /**
1117     * Tests if an unqulified class name can be fully qualified inside a class declaration.
1118     * If this is not the case, depending on the user-option '-code.auto.import' an import statement
1119     * is generated, or just a warning message is output.
1120     */

1121    protected String JavaDoc makeSureIsQualifyable(Class JavaDoc inClass, String JavaDoc unqualified, String JavaDoc qualified) {
1122                try {
1123                    inClass.qualify(unqualified);
1124                    return unqualified;
1125                } catch (NoClassDefFoundError JavaDoc ncdfe) {
1126                    if (isOption("code.qualify.auto")) {
1127                        // auto-generate import statement
1128
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    // ------------------------------------------------------------------------
1138
// --- static methods ---
1139
// ------------------------------------------------------------------------
1140

1141    /**
1142     * Appends a vertical line of star characters in front of <code>s</code>.
1143     * <code>s</code> may contain multiple lines, seperated by either \n or \r,
1144     * in that case a multi-line result is returned.
1145     */

1146    public static String JavaDoc startWithStars(String JavaDoc s, String JavaDoc spaces) {
1147        StringTokenizer st=new StringTokenizer(s,"\r\n");
1148        StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
1149        while (st.hasMoreTokens()) {
1150            sb.append(spaces+" * "+st.nextToken()+nl);
1151        }
1152        return sb.toString();
1153    }
1154
1155    /**
1156     * Return the name part of an identifier behind the last '.' occurrence.
1157     *
1158     * @param n The qualified (or already unqualified) identifier name.
1159     * @return The unqualified identifier name.
1160     */

1161    public static String JavaDoc unqualify(String JavaDoc 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    /**
1172     * Returns a string repeating the character <code>mark</code>
1173     * for <code>count</code> times.
1174     */

1175    public static String JavaDoc chars(char mark, int count) {
1176        StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
1177        for (int i=0;i<count;i++) {
1178            sb.append(mark);
1179        }
1180        return sb.toString();
1181    }
1182
1183    /**
1184     * Returns a string repeating the space character
1185     * for <code>count</code> times.
1186     */

1187    public static String JavaDoc spaces(int count) {
1188        return chars(' ',count);
1189    }
1190
1191    /**
1192     * Replaces all occurrences of string <code>find</code> in <code>s</code> by <code>repl</code>.
1193     */

1194    public static String JavaDoc replace(String JavaDoc s, String JavaDoc find, String JavaDoc 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    /**
1204     * Returns the current date in ISO date format yyyy-MM-dd.
1205     */

1206    public static String JavaDoc isodate() {
1207        SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd");
1208        return formatter.format(new Date());
1209    }
1210
1211    /**
1212     * Returns the special prefix of the identifer, if there is any.
1213     * Otherwise <code>null</code> is returned.
1214     *
1215     * @see #specialPrefixes
1216     */

1217    public static String JavaDoc getSpecialPrefix(String JavaDoc 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)) // next char after prefix must be upper case
1223
) {
1224                return specialPrefixes[i];
1225            }
1226        }
1227        return null;
1228    }
1229
1230    /**
1231     * Tests whether the identifier has a special prefix.
1232     *
1233     * @see #specialPrefixes
1234     */

1235    public static boolean hasSpecialPrefix(String JavaDoc id) {
1236        return getSpecialPrefix(id)!=null;
1237    }
1238
1239    /**
1240     * Convert a string of format "xxxYyyyZzzz" to "xxx yyyy zzzz".
1241     * This is a simple mechanism to retrieve english language
1242     * for auto-generating Javadoc comments from semantically rich identifier names.
1243     *
1244     * @param s The identifier name.
1245     * @return English language fragment retrieved from identifier name.
1246     */

1247    public static String JavaDoc toWords(String JavaDoc 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)); // recursion
1257
}
1258        } else {
1259            return "";
1260        }
1261    }
1262
1263    public static boolean isDummy(String JavaDoc text) {
1264        return text.indexOf("...")!=-1; // Strings like "The result is..." are also dummies.
1265
}
1266
1267    /**
1268     * Removes out-commented dead lines of from a block of Java code.
1269     *
1270     * @see #isDeadCodeLine
1271     */

1272    public static String JavaDoc cleanCode(String JavaDoc c) {
1273        BufferedReader b=new BufferedReader(new StringReader(c));
1274        StringBuffer JavaDoc r=new StringBuffer JavaDoc();
1275        try {
1276            String JavaDoc l=b.readLine();
1277            while (l!=null) {
1278                String JavaDoc 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    /**
1294     * Tests whether a line of Java code is an out-commented dead line of code.
1295     * This is the case when it starts with "//" and end with either ';', '{' or '}'.
1296     */

1297    public static boolean isDeadCodeLine(String JavaDoc l) {
1298        l=l.trim();
1299        return l.startsWith("//")
1300        && (l.endsWith(";")||l.endsWith("{")||l.endsWith("}"));
1301    }
1302
1303    /**
1304     * Returns the canonical string representation of a SourceObject's type.
1305     */

1306    public static String JavaDoc getTypeCode(SourceObject o) {
1307        String JavaDoc c=unqualify(o.getClass().getName()).toLowerCase();
1308        if (c.equals("constructor")) {
1309            c="method"; // use same parameters for constructors and methods
1310
} else if (c.equals("classinner")) {
1311            c="class";
1312        }
1313        return c;
1314    }
1315
1316    /**
1317     * Returns the parent part of a fully qualified identifier name.
1318     */

1319    protected static String JavaDoc getParentQualifier(String JavaDoc 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 JavaDoc c=mex.getDeclaringClass();
1333            String JavaDoc supName=c.getSuperclassName();
1334            Class JavaDoc 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    /**
1360     * Builds the documentation tagged.
1361     *
1362     * @throws IOException if an i/o error occurs
1363     */

1364    protected static void buildDocumentationTagged(OutputStream out, DocumentationTagged tag, String JavaDoc spaces) throws IOException {
1365        write(out,startWithStars(tag.getTag()+" "+(((tag.getItem()!=null)?tag.getItem():"")+" "+tag.getText()),spaces));
1366    }
1367
1368} // end StandardSourclet
1369
Popular Tags