Source Code Cross Referenced for StandardSourclet.java in  » Code-Analyzer » beautyJ » de » gulden » util » javasource » sourclet » standard » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » beautyJ » de.gulden.util.javasource.sourclet.standard 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Project: BeautyJ - Customizable Java Source Code Transformer
0003:         * Class:   de.gulden.util.javasource.sourclet.standard.StandardSourclet
0004:         * Version: 1.1
0005:         *
0006:         * Date:    2004-09-29
0007:         *
0008:         * Note:    Contains auto-generated Javadoc comments created by BeautyJ.
0009:         *  
0010:         * This is licensed under the GNU General Public License (GPL)
0011:         * and comes with NO WARRANTY. See file license.txt for details.
0012:         *
0013:         * Author:  Jens Gulden
0014:         * Email:   beautyj@jensgulden.de
0015:         */
0016:
0017:        package de.gulden.util.javasource.sourclet.standard;
0018:
0019:        import de.gulden.util.javasource.sourclet.*;
0020:        import de.gulden.util.javasource.Package;
0021:        import de.gulden.util.javasource.Class;
0022:        import de.gulden.util.javasource.Exception;
0023:        import de.gulden.util.javasource.*;
0024:        import de.gulden.util.Toolbox;
0025:        import java.io.*;
0026:        import java.util.*;
0027:        import java.text.*;
0028:        import java.lang.reflect.Modifier;
0029:
0030:        /**
0031:         * The StandardSourclet used by BeautyJ.
0032:         * See documentation of Beauty and the Java Sourclet API.
0033:         *  
0034:         * @author  Jens Gulden
0035:         * @version  1.1
0036:         */
0037:        public class StandardSourclet extends AbstractSourclet {
0038:
0039:            // ------------------------------------------------------------------------
0040:            // --- static fields                                                    ---
0041:            // ------------------------------------------------------------------------
0042:
0043:            /**
0044:             *  
0045:             * @see  #getSpecialPrefix
0046:             * @see  #hasSpecialPrefix
0047:             */
0048:            protected static String[] specialPrefixes = { "get", "set", "add",
0049:                    "remove", "is", "init", "parse", "create", "build" };
0050:
0051:            /**
0052:             * These defaults are also named for option doc.exception.texts in the configuration XML File.
0053:             * But if they are overwritten by the user, they still get used, so keep here as constant and always add to user's texts.
0054:             */
0055:            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";
0056:
0057:            // ------------------------------------------------------------------------
0058:            // --- fields                                                           ---
0059:            // ------------------------------------------------------------------------
0060:
0061:            /**
0062:             * The exception texts.
0063:             */
0064:            protected Properties exceptionTexts = null;
0065:
0066:            /**
0067:             * The headerfile text.
0068:             */
0069:            protected String headerfileText = null;
0070:
0071:            // ------------------------------------------------------------------------
0072:            // --- constructor                                                      ---
0073:            // ------------------------------------------------------------------------
0074:
0075:            /**
0076:             * Creates a new instance of StandardSourclet.
0077:             */
0078:            public StandardSourclet() {
0079:
0080:            }
0081:
0082:            // ------------------------------------------------------------------------
0083:            // --- methods                                                          ---
0084:            // ------------------------------------------------------------------------
0085:
0086:            /**
0087:             * Outputs the start part of a source object.
0088:             * This is the part which comes before the 'normal' head
0089:             * (e.g. before a method's signature), so usually this is
0090:             * the place where to output Javadoc comments.
0091:             *  
0092:             * @throws IOException if an i/o error occurs
0093:             */
0094:            public void buildStartSource(OutputStream out,
0095:                    SourceObjectDeclared o) throws IOException {
0096:                if (o instanceof  Class) {
0097:                    Class clazz = (Class) o;
0098:                    if (!(clazz instanceof  ClassInner)) {
0099:                        String headerfile = getHeaderfile();
0100:                        if (headerfile != null) {
0101:                            write(out, headerfile);
0102:                        } else {
0103:                            String opt;
0104:                            write(out, "/*" + nl);
0105:                            opt = getOption("project.name");
0106:                            if (opt != null) {
0107:                                write(out, " * Project: " + opt + nl);
0108:                            }
0109:                            write(out, " * Class:   " + clazz.getName() + nl);
0110:                            opt = getOption("project.version");
0111:                            if (opt != null) {
0112:                                write(out, " * Version: " + opt + nl);
0113:                            }
0114:                            opt = getOption("project.date");
0115:                            if (opt != null) {
0116:                                String op = opt.trim();
0117:                                if (op.equalsIgnoreCase("now")
0118:                                        || op.equalsIgnoreCase("today")) {
0119:                                    opt = isodate();
0120:                                }
0121:                                write(out, " *" + nl);
0122:                                write(out, " * Date:    " + opt + nl);
0123:                            }
0124:                            opt = getOption("project.description");
0125:                            if (opt != null) {
0126:                                opt = replace(opt, "\\n", "\n"); // allow line breaks expressed as "\n"
0127:                                write(out, " *" + nl);
0128:                                write(out, startWithStars(opt, ""));
0129:                            }
0130:                            write(out, " *" + nl);
0131:                            opt = getOption("author.name");
0132:                            if (opt != null) {
0133:                                write(out, " * Author:  " + opt + nl);
0134:                            }
0135:                            opt = getOption("author.email");
0136:                            if (opt != null) {
0137:                                write(out, " * Email:   " + opt + nl);
0138:                            }
0139:                            write(out, " */" + nl + nl);
0140:                        }
0141:                        // package
0142:                        if (!clazz.getPackage().isBasePackage()) {
0143:                            write(out, "package "
0144:                                    + clazz.getPackage().getName() + ";" + nl);
0145:                        }
0146:
0147:                        // imports
0148:                        NamedIterator it = clazz.getImports();
0149:                        if (it.hasMore()) {
0150:                            write(out, nl);
0151:                            while (it.hasMore()) {
0152:                                Import im = (Import) it.next();
0153:                                write(out, "import " + im.getName() + ";" + nl);
0154:                            }
0155:                        }
0156:                        write(out, nl);
0157:                    }
0158:                }
0159:
0160:                // fields, methods, constructors, classes
0161:                if ((o instanceof  Member) || (o instanceof  Class)) {
0162:                    String type = getTypeCode(o);
0163:
0164:                    String spaces;
0165:                    if (o instanceof  Class) {
0166:                        spaces = "";
0167:                    } else {
0168:                        spaces = indent(1);
0169:                    }
0170:
0171:                    DocumentationDeclared doc = (DocumentationDeclared) o
0172:                            .getDocumentation();
0173:                    String text = null;
0174:                    DocumentationDeclared supDoc = tryGetDocumentationFromSuperclass(o); // inheriting documentation doesn't work properly yet is still undocumented
0175:                    if ((doc != null) // documentation exists
0176:                            && (doc instanceof  DocumentationDeclared)) {
0177:                        if (!hasOption(type + ".remove.text", "description")) {
0178:                            text = doc.getText();
0179:                            if (text == null || text.equals("")) {
0180:                                if (supDoc != null) {
0181:                                    text = supDoc.getText();
0182:                                }
0183:                            }
0184:                        }
0185:                    } else { // documentation doesn't exist yet, try to find in a superclass
0186:                        if ((supDoc != null)
0187:                                && (!hasOption(type + ".remove.text",
0188:                                        "description"))) {
0189:                            text = supDoc.getText();
0190:                        }
0191:                    }
0192:                    // if it's a dummy, remove if option is set to do so
0193:                    if ((text != null)
0194:                            && isDummy(text)
0195:                            && (hasOption(type + ".remove.dummy", "description"))) {
0196:                        text = null;
0197:                    }
0198:
0199:                    // if no documentation found by now (or has been removed by option), maybe auto-generate
0200:                    if (text == null) {
0201:                        String unqualifiedName = o.getUnqualifiedName();
0202:                        String specialPrefix = getSpecialPrefix(unqualifiedName);
0203:                        if (hasOption(type + ".create.text", "description")) {
0204:                            if ((o instanceof  Constructor)
0205:                                    && hasOption("method.create.text",
0206:                                            "description")) {
0207:                                text = "Creates a new instance of "
0208:                                        + unqualifiedName + ".";
0209:                            } else if ((o instanceof  Method)
0210:                                    && (specialPrefix != null)
0211:                                    && hasOption("method.create.text",
0212:                                            "description")) {
0213:                                if (specialPrefix.equals("get")) {
0214:                                    text = "Returns the "
0215:                                            + toWords(unqualifiedName
0216:                                                    .substring(specialPrefix
0217:                                                            .length())) + ".";
0218:                                } else if (specialPrefix.equals("set")) {
0219:                                    text = "Sets the "
0220:                                            + toWords(unqualifiedName
0221:                                                    .substring(specialPrefix
0222:                                                            .length())) + ".";
0223:                                } else if (specialPrefix.equals("add")) {
0224:                                    text = "Adds a "
0225:                                            + toWords(unqualifiedName
0226:                                                    .substring(specialPrefix
0227:                                                            .length())) + ".";
0228:                                } else if (specialPrefix.equals("remove")) {
0229:                                    text = "Removes a "
0230:                                            + toWords(unqualifiedName
0231:                                                    .substring(specialPrefix
0232:                                                            .length())) + ".";
0233:                                } else if (specialPrefix.equals("init")) {
0234:                                    text = "Inits the "
0235:                                            + toWords(unqualifiedName
0236:                                                    .substring(specialPrefix
0237:                                                            .length())) + ".";
0238:                                } else if (specialPrefix.equals("parse")) {
0239:                                    text = "Parses the "
0240:                                            + toWords(unqualifiedName
0241:                                                    .substring(specialPrefix
0242:                                                            .length())) + ".";
0243:                                } else if (specialPrefix.equals("create")) {
0244:                                    text = "Creates the "
0245:                                            + toWords(unqualifiedName
0246:                                                    .substring(specialPrefix
0247:                                                            .length())) + ".";
0248:                                } else if (specialPrefix.equals("build")) {
0249:                                    text = "Builds the "
0250:                                            + toWords(unqualifiedName
0251:                                                    .substring(specialPrefix
0252:                                                            .length())) + ".";
0253:                                }
0254:                            } else if ((o instanceof  Field)
0255:                                    && hasOption("field.create.text",
0256:                                            "description")) {
0257:                                if (Modifier.isFinal(o.getModifier())) {
0258:                                    text = "Constant "
0259:                                            + o.getUnqualifiedName()
0260:                                            + SourceParser.repeat("[]",
0261:                                                    (((Field) o).getType()
0262:                                                            .getDimension()))
0263:                                            + ".";
0264:                                } else {
0265:                                    text = "The "
0266:                                            + toWords(o.getUnqualifiedName())
0267:                                            + (((Field) o).getType()
0268:                                                    .getDimension() > 0 ? " array"
0269:                                                    : "") + ".";
0270:                                }
0271:                            } else if ((o instanceof  Class)
0272:                                    && hasOption("class.create.text",
0273:                                            "description")) {
0274:                                text = "Class " + o.getUnqualifiedName() + ".";
0275:                            }
0276:                        }
0277:                        // if no text found or generated, maybe generate a dummy
0278:                        if ((text == null)
0279:                                && hasOption(type + ".create.dummy",
0280:                                        "description")) {
0281:                            if (specialPrefix != null) {
0282:                                if (specialPrefix.equals("is")) {
0283:                                    text = "Tests if ...";
0284:                                }
0285:                            }
0286:                            if (text == null) {
0287:                                text = "...";
0288:                            }
0289:                        }
0290:                    }
0291:
0292:                    boolean headDone = false;
0293:
0294:                    if (text != null) {
0295:                        write(out, spaces + "/**" + nl);
0296:                        headDone = true;
0297:                        write(out, startWithStars(text, spaces));
0298:                    }
0299:
0300:                    ByteArrayOutputStream buf = new ByteArrayOutputStream();
0301:                    buildTagDocumentation(buf, o, doc, supDoc);
0302:                    if (buf.size() > 0) {
0303:                        if (!headDone) {
0304:                            write(out, spaces + "/**" + nl);
0305:                            headDone = true;
0306:                        }
0307:                        write(out, startWithStars(" ", spaces));
0308:                        buf.writeTo(out);
0309:                    }
0310:                    if (headDone) {
0311:                        write(out, spaces + " */" + nl);
0312:                    }
0313:                }
0314:            }
0315:
0316:            /**
0317:             * Outputs the head part of a source object.
0318:             * This is the actual Java code that declares the source object,
0319:             * for example a method's signature.
0320:             *  
0321:             * @throws IOException if an i/o error occurs
0322:             */
0323:            public void buildHeadSource(OutputStream out, SourceObjectDeclared o)
0324:                    throws IOException {
0325:                boolean fullQualify = isOption("code.qualify");
0326:
0327:                if (o instanceof  Member) {
0328:                    write(out, indent(1));
0329:                }
0330:
0331:                String mod = Modifier.toString(o.getModifier());
0332:                if (mod.length() > 0) {
0333:                    write(out, mod + " ");
0334:                }
0335:
0336:                if (o instanceof  Typed) { // Method, Field or Parameter
0337:                    Typed typed = (Typed) o;
0338:                    String t;
0339:                    if (fullQualify) {
0340:                        t = typed.getType().getFullTypeName();
0341:                    } else {
0342:                        t = typed.getType().getFullUnqualifiedTypeName();
0343:                        String unqualifiedType = typed.getType()
0344:                                .getUnqualifiedTypeName();
0345:                        String qualifiedType = typed.getType().getTypeName();
0346:                        Class declaringClass;
0347:                        if (!(typed instanceof  Parameter)) {
0348:                            declaringClass = ((SourceObjectDeclared) typed)
0349:                                    .getDeclaringClass();
0350:                        } else {
0351:                            declaringClass = ((Parameter) typed)
0352:                                    .getMemberExecutable().getDeclaringClass();
0353:                        }
0354:                        if (makeSureIsQualifyable(declaringClass,
0355:                                unqualifiedType, qualifiedType).equals(
0356:                                qualifiedType)) {
0357:                            t = typed.getType().getFullTypeName(); // 'fallback' to fully qualified
0358:                        }
0359:                        if (t.indexOf('.') != -1) {
0360:                            // Although unqualified, inner classes will be lead by classname-prefix.
0361:                            // Remove this prefix if it is the current class.
0362:                            if (declaringClass != null) {
0363:                                String this Classname = declaringClass
0364:                                        .getUnqualifiedName();
0365:                                if (t.startsWith(this Classname + ".")) {
0366:                                    t = t.substring(this Classname.length() + 1);
0367:                                }
0368:                            }
0369:                        }
0370:                    }
0371:                    write(out, t + " ");
0372:                }
0373:
0374:                if (o instanceof  Class) {
0375:                    Class clazz = (Class) o;
0376:                    write(out, clazz.isInterface() ? "interface " : "class ");
0377:                }
0378:
0379:                // name
0380:                write(out, o.getUnqualifiedName());
0381:
0382:                if (o instanceof  Class) {
0383:                    Class clazz = (Class) o;
0384:                    String sup = clazz.getSuperclassName();
0385:                    if (!sup.equals("java.lang.Object")) {
0386:                        String s = sup;
0387:                        if (!fullQualify) {
0388:                            s = unqualifyClassname(clazz, s);
0389:                        }
0390:                        write(out, " extends " + s);
0391:                    }
0392:
0393:                    // implemented interfaces
0394:                    Enumeration en = clazz.getInterfaceNames();
0395:                    if (en.hasMoreElements()) {
0396:                        if (!clazz.isInterface()) {
0397:                            write(out, " implements ");
0398:                        } else {
0399:                            write(out, " extends ");
0400:                        }
0401:                        while (en.hasMoreElements()) {
0402:                            String in = (String) en.nextElement();
0403:                            if (!fullQualify) {
0404:                                in = unqualifyClassname(clazz, in);
0405:                            }
0406:                            write(out, in
0407:                                    + (en.hasMoreElements() ? (", ") : ""));
0408:                        }
0409:                    }
0410:                }
0411:
0412:                else if (o instanceof  MemberExecutable) {
0413:                    MemberExecutable mex = (MemberExecutable) o;
0414:                    // parameters
0415:                    write(out, "(");
0416:                    for (NamedIterator it = mex.getParameters(); it.hasMore();) {
0417:                        Parameter pa = (Parameter) it.next();
0418:                        buildSource(out, pa);
0419:                        if (it.hasMore()) {
0420:                            write(out, ", ");
0421:                        }
0422:                    }
0423:                    write(out, ")");
0424:
0425:                    // exceptions
0426:                    NamedIterator it = mex.getExceptions();
0427:                    if (it.hasMore()) {
0428:                        write(out, " throws ");
0429:                        while (it.hasMore()) {
0430:                            Exception ex = (Exception) it.next();
0431:                            String exx;
0432:                            if (!fullQualify) {
0433:                                exx = ex.getUnqualifiedName();
0434:                                exx = makeSureIsQualifyable(mex
0435:                                        .getDeclaringClass(), exx, ex.getName());
0436:                            } else {
0437:                                exx = ex.getName();
0438:                            }
0439:
0440:                            write(out, exx + (it.hasMore() ? ", " : ""));
0441:                        }
0442:                    }
0443:                }
0444:            }
0445:
0446:            /**
0447:             * Outputs the body content of the source object. For example,
0448:             * in case of methods this is Java code, in case of classes this recursively
0449:             * contains other SourceObjects' code.
0450:             *  
0451:             * @throws IOException if an i/o error occurs
0452:             */
0453:            public void buildBodySource(OutputStream out, SourceObjectDeclared o)
0454:                    throws IOException {
0455:
0456:                boolean bracesLinebreak = isOption("code.braces.linebreak");
0457:
0458:                // --- class
0459:
0460:                if (o instanceof  Class) {
0461:                    Class clazz = (Class) o;
0462:                    NamedIterator it = clazz.getAllMembers();
0463:                    if (bracesLinebreak) { // start with curly brace on individual line
0464:                        write(out, nl + "{");
0465:                        if (!isOption("code.separators")) {
0466:                            write(out, nl);
0467:                        }
0468:                    } else { // output curly brace at the end of the method's declaration
0469:                        write(out, " {" + nl);
0470:                    }
0471:
0472:                    Vector todo = new Vector();
0473:
0474:                    if (isOption("code.preserve.fields.order")) {
0475:
0476:                        it.reset();
0477:                        boolean firstField = true;
0478:                        while (it.hasMore()) {
0479:                            Member m = (Member) it.next();
0480:                            if (m instanceof  Field) {
0481:                                todo.addElement(m);
0482:                                //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)
0483:                            }
0484:                        }
0485:
0486:                        buildHeader(out, '-', "field", "fields", todo.size());
0487:
0488:                        Vector singleTodo = new Vector();
0489:                        for (Enumeration e = todo.elements(); e
0490:                                .hasMoreElements();) {
0491:                            singleTodo.removeAllElements();
0492:                            singleTodo.addElement(e.nextElement());
0493:                            buildSourceAll(out, singleTodo, null); // build single elements
0494:                        }
0495:
0496:                    } else { // normal beautification: order by final-static / static / non-static and public / protected / friendly / private
0497:
0498:                        it.reset();
0499:                        while (it.hasMore()) {
0500:                            Member m = (Member) it.next();
0501:                            if ((m instanceof  Field)
0502:                                    && Modifier.isStatic(m.getModifier())
0503:                                    && Modifier.isFinal(m.getModifier())) {
0504:                                todo.addElement(m);
0505:                            }
0506:                        }
0507:                        buildSourceAll(out, todo, "final static field");
0508:
0509:                        it.reset();
0510:                        todo.removeAllElements();
0511:                        while (it.hasMore()) {
0512:                            Member m = (Member) it.next();
0513:                            if ((m instanceof  Field)
0514:                                    && Modifier.isStatic(m.getModifier())
0515:                                    && (!Modifier.isFinal(m.getModifier()))) {
0516:                                todo.addElement(m);
0517:                            }
0518:                        }
0519:                        buildSourceAll(out, todo, "static field");
0520:
0521:                        it.reset();
0522:                        todo.removeAllElements();
0523:                        while (it.hasMore()) {
0524:                            Member m = (Member) it.next();
0525:                            if ((m instanceof  Field)
0526:                                    && (!Modifier.isStatic(m.getModifier()))) {
0527:                                todo.addElement(m);
0528:                            }
0529:                        }
0530:                        buildSourceAll(out, todo, "field");
0531:
0532:                    }
0533:
0534:                    // initializers (must appear after field declarations to avoid forward references)
0535:
0536:                    Code[] initializers = clazz.getStaticInitializers();
0537:                    if (initializers.length > 0) {
0538:                        buildHeader(out, '-', "static initializer",
0539:                                initializers.length);
0540:                        for (int i = 0; i < initializers.length; i++) {
0541:                            String code = initializers[i].getRaw();
0542:                            code = applyCodeFormatting(code);
0543:                            write(out, indent("static {", 1));
0544:                            write(out, nl);
0545:                            write(out, code);
0546:                            write(out, nl);
0547:                            write(out, indent("}", 1));
0548:                            write(out, nl);
0549:                        }
0550:                    }
0551:
0552:                    initializers = clazz.getInstanceInitializers();
0553:                    if (initializers.length > 0) {
0554:                        buildHeader(out, '-', "instance initializer",
0555:                                initializers.length);
0556:                        for (int i = 0; i < initializers.length; i++) {
0557:                            String code = initializers[i].getRaw();
0558:                            code = applyCodeFormatting(code);
0559:                            write(out, indent("{", 1));
0560:                            write(out, nl);
0561:                            write(out, code);
0562:                            write(out, nl);
0563:                            write(out, indent("}", 1));
0564:                            write(out, nl);
0565:                        }
0566:                    }
0567:
0568:                    it.reset();
0569:                    todo.removeAllElements();
0570:                    while (it.hasMore()) {
0571:                        Member m = (Member) it.next();
0572:                        if (m instanceof  Constructor) {
0573:                            todo.addElement(m);
0574:                        }
0575:                    }
0576:                    buildSourceAll(out, todo, "constructor");
0577:
0578:                    it.reset();
0579:                    todo.removeAllElements();
0580:                    while (it.hasMore()) {
0581:                        Member m = (Member) it.next();
0582:                        if ((m instanceof  Method)
0583:                                && (!Modifier.isStatic(m.getModifier()))) {
0584:                            todo.addElement(m);
0585:                        }
0586:                    }
0587:                    buildSourceAll(out, todo, "method");
0588:
0589:                    it.reset();
0590:                    todo.removeAllElements();
0591:                    while (it.hasMore()) {
0592:                        Member m = (Member) it.next();
0593:                        if ((m instanceof  Method)
0594:                                && (Modifier.isStatic(m.getModifier()))) {
0595:                            todo.addElement(m);
0596:                        }
0597:                    }
0598:                    buildSourceAll(out, todo, "static method");
0599:
0600:                    // inner classes and interfaces
0601:
0602:                    it = clazz.getInnerClasses();
0603:                    if (it.size() > 0) {
0604:                        buildHeader(out, '*', (it.size() == 1) ? "inner class"
0605:                                : "inner classes");
0606:                        while (it.hasMore()) {
0607:                            Class c = (Class) it.next();
0608:                            ByteArrayOutputStream outInner = new ByteArrayOutputStream();
0609:                            buildSource(outInner, c);
0610:                            String shifted = indent(new String(outInner
0611:                                    .toByteArray()), 1);
0612:                            write(out, shifted + nl);
0613:                        }
0614:                    }
0615:
0616:                    write(out, "} // end " + clazz.getUnqualifiedName() + nl);
0617:                }
0618:
0619:                // --- method / field
0620:
0621:                else if ((o instanceof  MemberExecutable)
0622:                        || (o instanceof  Field)) {
0623:                    Code code;
0624:                    if (o instanceof  MemberExecutable) {
0625:                        code = ((MemberExecutable) o).getCode();
0626:                    } else {
0627:                        code = ((Field) o).getCode();
0628:                    }
0629:
0630:                    if (code != null) {
0631:                        String c = code.getRaw();
0632:                        if (o instanceof  MemberExecutable) {
0633:                            if (isOption("code.braces.linebreak")) { // start with curly brace on individual line
0634:                                write(out, nl);
0635:                                write(out, indent("{", 1) + nl);
0636:                            } else { // output curly brace at the end of the method's declaration
0637:                                write(out, " {" + nl);
0638:                            }
0639:                            c = applyCodeFormatting(c);
0640:                            write(out, c + nl);
0641:                            write(out, indent("}", 1) + nl);
0642:                        } else { // Field
0643:                            write(out, " = " + c + ";" + nl);
0644:                        }
0645:                    } else {
0646:                        write(out, ";" + nl);
0647:                    }
0648:                    write(out, nl);
0649:                }
0650:            }
0651:
0652:            /**
0653:             * Outputs everything that occurs after the SourceObject.
0654:             *  
0655:             * @throws IOException if an i/o error occurs
0656:             */
0657:            public void buildEndSource(OutputStream out, SourceObjectDeclared o)
0658:                    throws IOException {
0659:                //nop
0660:            }
0661:
0662:            /**
0663:             * Returns the associated description for the exception class name specified by <code>exc</code>.
0664:             */
0665:            protected String getExceptionText(String exc) {
0666:                if (exceptionTexts == null) { // auto-init on first call
0667:                    exceptionTexts = new Properties();
0668:                    String t = defaultExceptionTexts
0669:                            + 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
0670:                    StringTokenizer st = new StringTokenizer(t, ",", false);
0671:                    while (st.hasMoreTokens()) {
0672:                        String s = st.nextToken();
0673:                        StringTokenizer st2 = new StringTokenizer(s, "=", false);
0674:                        String exception = st2.nextToken();
0675:                        String text = st2.nextToken();
0676:                        if (!(exception == null || text == null || st2
0677:                                .hasMoreTokens())) {
0678:                            exceptionTexts.setProperty(exception.trim(), text
0679:                                    .trim());
0680:                        } else {
0681:                            // illegal option format, ignore
0682:                        }
0683:                    }
0684:                }
0685:                return exceptionTexts.getProperty(exc);
0686:            }
0687:
0688:            /**
0689:             * If a headerfile is specified, get the content as string.
0690:             */
0691:            protected String getHeaderfile() {
0692:                if (headerfileText == null) {
0693:                    // auto-init from project.headerfile
0694:                    String filename = getOption("project.headerfile");
0695:                    if (filename != null) {
0696:                        File file = new File(filename);
0697:                        if (file.isFile()) {
0698:                            try {
0699:                                char[] c = new char[(int) file.length()];
0700:                                FileReader f = new FileReader(file);
0701:                                f.read(c);
0702:                                f.close();
0703:                                headerfileText = new String(c);
0704:                            } catch (IOException e) {
0705:                                headerfileText = "/* ERROR READING HEADERFILE '"
0706:                                        + filename + "' */";
0707:                            }
0708:                        }
0709:                    }
0710:                }
0711:                return headerfileText; // null if no headerfile
0712:            }
0713:
0714:            /**
0715:             * Builds the tag documentation.
0716:             *  
0717:             * @throws IOException if an i/o error occurs
0718:             */
0719:            protected void buildTagDocumentation(OutputStream out,
0720:                    SourceObjectDeclared o, DocumentationDeclared doc,
0721:                    DocumentationDeclared supDoc) throws IOException {
0722:                // parameters doc, supDoc may be null
0723:                if (o instanceof  Class) {
0724:                    Class clazz = (Class) o;
0725:                    // @author
0726:                    String opt;
0727:                    opt = getOption("author.name");
0728:                    if (opt != null) {
0729:                        buildTagDocumentationSynthesize(out, "class", "author",
0730:                                null, opt, doc, supDoc, "", true);
0731:                    }
0732:                    // @version
0733:                    opt = getOption("project.version");
0734:                    if (opt != null) {
0735:                        buildTagDocumentationSynthesize(out, "class",
0736:                                "version", null, opt, doc, supDoc, "", true);
0737:                    }
0738:                } else if (o instanceof  MemberExecutable) {
0739:                    MemberExecutable mex = (MemberExecutable) o;
0740:                    String unqualifiedName = o.getUnqualifiedName();
0741:                    String specialPrefix = getSpecialPrefix(unqualifiedName);
0742:
0743:                    // @param
0744:                    boolean createText = hasOption("method.create.text",
0745:                            "param");
0746:                    boolean createDummy = hasOption("method.create.dummy",
0747:                            "param");
0748:                    String type = getTypeCode(o);
0749:                    for (NamedIterator it = mex.getParameters(); it.hasMore();) {
0750:                        Parameter pa = (Parameter) it.next();
0751:                        String def = null;
0752:                        if (createText && (specialPrefix != null)
0753:                                && (specialPrefix.equals("set"))) {
0754:                            def = "The "
0755:                                    + toWords(unqualifiedName
0756:                                            .substring(specialPrefix.length()))
0757:                                    + (pa.getType().getDimension() > 0 ? " array"
0758:                                            : "") + ".";
0759:                        } else if (createText) {
0760:                            String n = pa.getName();
0761:                            if (n.length() < 3) { // use type name if too short identifier
0762:                                n = pa.getType().getUnqualifiedTypeName();
0763:                            }
0764:                            def = "The "
0765:                                    + toWords(n)
0766:                                    + (pa.getType().getDimension() > 0 ? " array"
0767:                                            : "") + ".";
0768:                        } else if (createDummy) {
0769:                            def = "The ...";
0770:                        }
0771:                        buildTagDocumentationSynthesize(out, type, "param", pa
0772:                                .getName(), def, doc, supDoc, indent(1), true);
0773:                    }
0774:
0775:                    // @throws
0776:                    createText = hasOption("method.create.text", "throws");
0777:                    createDummy = hasOption("method.create.dummy", "throws");
0778:                    for (NamedIterator it = mex.getExceptions(); it.hasMore();) {
0779:                        Exception ex = (Exception) it.next();
0780:                        String exc = ex.getUnqualifiedName();
0781:                        // is there a text given for that particular exception?
0782:                        String def = getExceptionText(exc);
0783:                        // if no text given, synthesize dummy (if dummy option enabled)
0784:                        if (createDummy && (def == null)) {
0785:                            def = "if ...";
0786:                        }
0787:                        buildTagDocumentationSynthesize(out, type, "throws",
0788:                                exc, def, doc, supDoc, indent(1), true);
0789:                    }
0790:
0791:                    // @return
0792:                    if (o instanceof  Method) {
0793:                        Method met = (Method) o;
0794:                        createText = hasOption("method.create.text", "return");
0795:                        createDummy = hasOption("method.create.text", "return");
0796:                        if (!(met.getType().getFullTypeName().equals("void"))) {
0797:                            // get default text
0798:                            String def = null;
0799:                            if (createText && (specialPrefix != null)
0800:                                    && specialPrefix.equals("get")) {
0801:                                def = "The "
0802:                                        + toWords(unqualifiedName
0803:                                                .substring(specialPrefix
0804:                                                        .length()))
0805:                                        + (met.getType().getDimension() > 0 ? " array"
0806:                                                : "") + ".";
0807:                            } else if (createText) {
0808:                                def = "The "
0809:                                        + toWords(met.getType()
0810:                                                .getUnqualifiedTypeName())
0811:                                        + (met.getType().getDimension() > 0 ? " array"
0812:                                                : "") + ".";
0813:                            } else if (createDummy) {
0814:                                def = "The ...";
0815:                            }
0816:                            buildTagDocumentationSynthesize(out, "method",
0817:                                    "return", null, def, doc, supDoc,
0818:                                    indent(1), true);
0819:                        }
0820:                    }
0821:                    // @see - not useful
0822:                }
0823:                // copy all other tags
0824:                if (doc != null) {
0825:                    for (Enumeration e = doc.getTags(); e.hasMoreElements();) {
0826:                        DocumentationTagged dt = (DocumentationTagged) e
0827:                                .nextElement();
0828:                        if ((!dt.getTag().equals("@param"))
0829:                                && (!dt.getTag().equals("@throws"))
0830:                                && (!dt.getTag().equals("@return"))
0831:                                && (!((o instanceof  Class) && (dt.getTag()
0832:                                        .equals("@author"))))
0833:                                && (!((o instanceof  Class) && (dt.getTag()
0834:                                        .equals("@version"))))) {
0835:                            buildDocumentationTagged(out, dt,
0836:                                    (o instanceof  Class) ? "" : indent(1));
0837:                        }
0838:                    }
0839:                } else if (supDoc != null) {
0840:                    for (Enumeration e = supDoc.getTags(); e.hasMoreElements();) {
0841:                        DocumentationTagged dt = (DocumentationTagged) e
0842:                                .nextElement();
0843:                        if ((!dt.getTag().equals("@param"))
0844:                                && (!dt.getTag().equals("@throws"))
0845:                                && (!dt.getTag().equals("@return"))
0846:                                && (!((o instanceof  Class) && (dt.getTag()
0847:                                        .equals("@author"))))
0848:                                && (!((o instanceof  Class) && (dt.getTag()
0849:                                        .equals("@version"))))) {
0850:                            buildDocumentationTagged(out, dt,
0851:                                    (o instanceof  Class) ? "" : indent(1));
0852:                        }
0853:                    }
0854:                }
0855:            }
0856:
0857:            /**
0858:             * Builds the tag documentation synthesize.
0859:             *  
0860:             * @throws IOException if an i/o error occurs
0861:             */
0862:            protected void buildTagDocumentationSynthesize(OutputStream out,
0863:                    String typeName, String tagName, String tagItem,
0864:                    String defaultValue, DocumentationDeclared doc,
0865:                    DocumentationDeclared supDoc, String spaces,
0866:                    boolean synthesize) throws IOException {
0867:                // parameters defaultValue, doc, supDoc may be null
0868:                DocumentationTagged tag = null;
0869:                // tag already there?
0870:                if (doc != null) {
0871:                    if (!hasOption(typeName + ".remove.text", tagName)) {
0872:                        tag = doc.findTag("@" + tagName, tagItem);
0873:                    }
0874:                    String text = null;
0875:                    if (tag != null) {
0876:                        text = tag.getText();
0877:                    }
0878:                    if ((text == null) || (text.trim().length() == 0)) {
0879:                        tag = null;
0880:                    }
0881:                    // remove dummy if activated
0882:                    if ((tag != null) && isDummy(text)
0883:                            && hasOption(typeName + ".remove.dummy", tagName)) {
0884:                        tag = null;
0885:                    }
0886:                }
0887:                // is there a matching documentation tag in superclass documentation?
0888:                if (tag == null) {
0889:                    if (supDoc != null) {
0890:                        tag = supDoc.findTag("@" + tagName, tagItem);
0891:                    }
0892:                    String text = null;
0893:                    if (tag != null) {
0894:                        text = tag.getText();
0895:                    }
0896:                    if ((text == null) || (text.trim().length() == 0)) {
0897:                        tag = null;
0898:                    }
0899:                    // remove dummy if activated
0900:                    if ((tag != null)
0901:                            && (isDummy(text) && (hasOption(typeName
0902:                                    + ".remove.dummy", tagName)))) {
0903:                        tag = null;
0904:                    }
0905:                }
0906:                // auto-generate
0907:                if ((tag == null) && synthesize && (defaultValue != null)) {
0908:                    tag = new DocumentationTagged();
0909:                    tag.setTag("@" + tagName);
0910:                    tag.setItem(tagItem);
0911:                    tag.setText(defaultValue);
0912:                }
0913:                // output if something found or generated
0914:                if (tag != null) {
0915:                    buildDocumentationTagged(out, tag, spaces);
0916:                }
0917:            }
0918:
0919:            /**
0920:             * Builds all source objects in Vector <code>v</code>, sorted by
0921:             * <ul>
0922:             * <li><b>public</b></li>
0923:             * <li><b>protected</b></li>
0924:             * <li><b>package-private</b></li>
0925:             * <li><b>private</b></li>
0926:             * </ul>
0927:             * modifiers.<br>
0928:             * In front of the generated code, a header is attached which names the type
0929:             * of the source objects, distinguishing between singular (if v.size()==1) and plural (f v.size()>1) form.<br>
0930:             * Here, the plural form is derived from simply adding an 's', which works for
0931:             * most english words.
0932:             *  
0933:             * @throws IOException if an i/o error occurs
0934:             */
0935:            protected void buildSourceAll(OutputStream out, Vector v,
0936:                    String header) throws IOException {
0937:                //, InvalidOptionException
0938:                String headerPlural;
0939:                if (header != null) {
0940:                    headerPlural = header + "s";
0941:                } else {
0942:                    headerPlural = null;
0943:                }
0944:
0945:                buildSourceAll(out, v, header, headerPlural);
0946:            }
0947:
0948:            /**
0949:             * Builds all source objects in Vector <code>v</code>, sorted by
0950:             * <ul>
0951:             * <li><b>public</b></li>
0952:             * <li><b>protected</b></li>
0953:             * <li><b>package-private</b></li>
0954:             * <li><b>private</b></li>
0955:             * </ul>
0956:             * modifiers.<br>
0957:             * In front of the generated code, a header is attached which names the type
0958:             * of the source objects, distinguishing between singular (if v.size()==1) and plural (f v.size()>1) form.
0959:             *  
0960:             * @throws IOException if an i/o error occurs
0961:             */
0962:            protected void buildSourceAll(OutputStream out, Vector v,
0963:                    String header, String headerPlural) throws IOException {
0964:                if (!v.isEmpty()) {
0965:                    if ((header != null) && (headerPlural != null)) {
0966:                        buildHeader(out, '-', header, headerPlural, v.size());
0967:                    }
0968:                    // public
0969:                    for (Enumeration e = v.elements(); e.hasMoreElements();) {
0970:                        SourceObjectDeclared o = (SourceObjectDeclared) e
0971:                                .nextElement();
0972:                        if (Modifier.isPublic(o.getModifier())) {
0973:                            buildSource(out, o);
0974:                        }
0975:                    }
0976:                    // protected
0977:                    for (Enumeration e = v.elements(); e.hasMoreElements();) {
0978:                        SourceObjectDeclared o = (SourceObjectDeclared) e
0979:                                .nextElement();
0980:                        if (Modifier.isProtected(o.getModifier())) {
0981:                            buildSource(out, o);
0982:                        }
0983:                    }
0984:                    // friendly
0985:                    for (Enumeration e = v.elements(); e.hasMoreElements();) {
0986:                        SourceObjectDeclared o = (SourceObjectDeclared) e
0987:                                .nextElement();
0988:                        if ((!Modifier.isPublic(o.getModifier()))
0989:                                && (!Modifier.isProtected(o.getModifier()))
0990:                                && (!Modifier.isPrivate(o.getModifier()))) {
0991:                            buildSource(out, o);
0992:                        }
0993:                    }
0994:                    // private
0995:                    for (Enumeration e = v.elements(); e.hasMoreElements();) {
0996:                        SourceObjectDeclared o = (SourceObjectDeclared) e
0997:                                .nextElement();
0998:                        if (Modifier.isPrivate(o.getModifier())) {
0999:                            buildSource(out, o);
1000:                        }
1001:                    }
1002:                }
1003:            }
1004:
1005:            /**
1006:             * Outputs a seperating header, if the corresponding option is set.
1007:             *  
1008:             * @throws IOException if an i/o error occurs
1009:             */
1010:            protected void buildHeader(OutputStream out, char mark,
1011:                    String header) throws IOException {
1012:                if (isOption("code.separators")) {
1013:                    write(out, nl
1014:                            + indent("// " + chars(mark, 72) + nl + "// "
1015:                                    + chars(mark, 3) + " " + header
1016:                                    + spaces(65 - header.length())
1017:                                    + chars(mark, 3) + nl + "// "
1018:                                    + chars(mark, 72) + nl, 1) + nl);
1019:                }
1020:            }
1021:
1022:            /**
1023:             * Outputs a seperating header, if the corresponding option is set. Depending on <code>num</code>,
1024:             * the plural or singular form is used (or nothing, if num==0).
1025:             *  
1026:             * @throws IOException if an i/o error occurs
1027:             */
1028:            protected void buildHeader(OutputStream out, char mark,
1029:                    String header, String headerPlural, int num)
1030:                    throws IOException {
1031:                if (num > 0) {
1032:                    buildHeader(out, mark, (num != 1 ? headerPlural : header));
1033:                }
1034:            }
1035:
1036:            /**
1037:             * Outputs a seperating header, if the corresponding option is set. Depending on <code>num</code>,
1038:             * a plural or singular form is used (or nothing, if num==0). The plural is auto-generated by adding an 's'.
1039:             *  
1040:             * @throws IOException if an i/o error occurs
1041:             */
1042:            protected void buildHeader(OutputStream out, char mark,
1043:                    String header, int num) throws IOException {
1044:                buildHeader(out, mark, header, header + "s", num);
1045:            }
1046:
1047:            /**
1048:             * Indents a given block of text by the given number of steps.
1049:             * The size of each step in 'number of spaces' is set by option
1050:             * code.indent.spaces.
1051:             *  
1052:             * @return  Indented text.
1053:             */
1054:            protected String indent(String text, int steps) {
1055:                StringTokenizer st = new StringTokenizer(text, "\n\r", true);
1056:                StringBuffer sb = new StringBuffer();
1057:                int spaces = getIntOption("code.indent.spaces"); // TODO: optimize
1058:                char lastBreak = (char) 0;
1059:
1060:                while (st.hasMoreTokens()) {
1061:                    String line = st.nextToken();
1062:                    char first = line.charAt(0);
1063:                    if (first == '\n' || first == '\r') { // delimiter token
1064:                        if ((lastBreak == (char) 0) || lastBreak == first) {
1065:                            sb.append(nl); // etxtra blank line
1066:                            lastBreak = first;
1067:                        }
1068:                    } else { // full line token
1069:                        sb.append(spaces(steps * spaces));
1070:                        sb.append(line);
1071:                        lastBreak = (char) 0;
1072:                    }
1073:                }
1074:                return sb.toString();
1075:            }
1076:
1077:            /**
1078:             * Returns a string with spaces. The number is determined by steps*option('code.indent.spaces').
1079:             */
1080:            protected String indent(int steps) {
1081:                int spaces = getIntOption("code.indent.spaces"); // TODO: optimize
1082:                return spaces(steps * spaces);
1083:            }
1084:
1085:            /**
1086:             * Apply code transformations according to options set by the user.
1087:             */
1088:            protected String applyCodeFormatting(String code) {
1089:                if (isOption("code.clean")) {
1090:                    code = cleanCode(code);
1091:                }
1092:                if (isOption("code.format")) {
1093:                    code = format(code);
1094:                }
1095:                code = indent(code, 2);
1096:                return code;
1097:            }
1098:
1099:            /**
1100:             * Format a code block according to standard auto-indentation rules.
1101:             * This is a quick solution and could be done much more sophisticated.
1102:             * (The current version of the StandardSourclet puts focus in the overall
1103:             * organization of .java files, not primarily on the code blocks.)
1104:             * Maybe later versions should incorporate mature code from other OpenSource
1105:             * beautifier projects here - volunteers welcome!
1106:             */
1107:            protected String format(String code) {
1108:                int codeLength = code.length();
1109:                if (codeLength > 0) {
1110:                    StringBuffer sb = new StringBuffer();
1111:                    StringBuffer line = new StringBuffer();
1112:                    char quoted = (char) 0;
1113:                    char comment = (char) 0;
1114:                    boolean escape = false;
1115:                    int indentLevel = 0;
1116:                    int indentLevelDiff = 0;
1117:                    boolean newline = false;
1118:                    boolean previousNewline = false;
1119:                    int i = 0;
1120:                    char c = (char) 0;
1121:                    char prevC;
1122:                    char nextC = code.charAt(0);
1123:
1124:                    while (i < codeLength) {
1125:                        prevC = c;
1126:                        c = nextC;
1127:                        if (i < codeLength - 1) {
1128:                            nextC = code.charAt(i + 1);
1129:                        } else {
1130:                            nextC = (char) 0;
1131:                        }
1132:
1133:                        if (escape) { // escaped char
1134:                            line.append(c);
1135:                            escape = false;
1136:
1137:                        } else if (comment == '/') { // line comment
1138:                            if (c == '\n') {
1139:                                newline = true;
1140:                                previousNewline = true;
1141:                                comment = (char) 0;
1142:                            }
1143:                            line.append(c);
1144:
1145:                        } else if (comment == '*') { // block comment
1146:                            if (c == '/' && prevC == '*') {
1147:                                comment = (char) 0;
1148:                            }
1149:                            line.append(c);
1150:
1151:                        } else if (quoted != (char) 0) { // quoted text, either ".." or '..'
1152:
1153:                            if (c == '\\') {
1154:                                escape = true;
1155:                            } else if (quoted == c) { // quote char again: end quoting
1156:                                quoted = (char) 0;
1157:                            }
1158:                            line.append(c);
1159:
1160:                        } else { // normal code
1161:
1162:                            switch (c) {
1163:                            case '\\':
1164:                                escape = true;
1165:                                break;
1166:                            case '/':
1167:                                if (nextC == '/' || nextC == '*') {
1168:                                    comment = nextC;
1169:                                }
1170:                                break;
1171:                            case '\"':
1172:                            case '\'':
1173:                                quoted = c;
1174:                                break;
1175:                            case '\n':
1176:                                newline = previousNewline; // explicit newline only if no other (auto-generated) newline since last explicit newline
1177:                                previousNewline = true;
1178:                                break;
1179:                            case ';':
1180:                                String l = line.toString().trim();
1181:                                if (!l.startsWith("for")) { // special: no line break after ; in for-loop declaration
1182:                                    newline = true;
1183:                                }
1184:                                break;
1185:                            case '{':
1186:                                newline = true;
1187:                                indentLevelDiff = +1;
1188:                                break;
1189:                            case '}':
1190:                                l = line.toString().trim();
1191:                                if (l.length() > 0) { // already something there in current line: write as own line
1192:                                    sb.append(indent(l, indentLevel) + nl);
1193:                                    line = new StringBuffer();
1194:                                }
1195:                                indentLevel -= 1;
1196:                                newline = (nextC == '\n'); // cheap trick  to make sure we don't loose blank lines after } (will fail if e.g. "} \n" )
1197:                                break;
1198:                            }
1199:                            line.append(c);
1200:
1201:                        }
1202:
1203:                        i++; // next char
1204:                        if (i >= codeLength) { // always output last line if end reached
1205:                            newline = true;
1206:                        }
1207:                        if (newline) {
1208:                            sb.append(indent(line.toString().trim(),
1209:                                    indentLevel));
1210:                            if (i < codeLength) { // prepare for next line if end not reached,also output nl only in that case
1211:                                sb.append(nl);
1212:                                indentLevel += indentLevelDiff;
1213:                                indentLevelDiff = 0;
1214:                                line = new StringBuffer();
1215:                                newline = false;
1216:                                previousNewline = false;
1217:                            }
1218:                        }
1219:
1220:                    }
1221:                    return sb.toString();
1222:                } else {
1223:                    return "";
1224:                }
1225:            }
1226:
1227:            protected String unqualifyClassname(Class inClass, String name) {
1228:                String result;
1229:                if (name.indexOf('.') != -1) { // not unqualified already
1230:                    String u = unqualify(name);
1231:                    String rest = name.substring(0, name.length() - u.length()
1232:                            - 1);
1233:                    // is parent-identifier a class? (not package) - then it is an inner class
1234:                    if (Package.isSourcePackage(inClass.getPackage()
1235:                            .getBasePackage(), rest)) { // optimization, but will not find a package if from classpath
1236:                        result = u;
1237:                    } else {
1238:                        String outer;
1239:                        try {
1240:                            outer = inClass.qualify(rest);
1241:                            result = unqualifyClassname(inClass, outer) + "."
1242:                                    + u;
1243:                        } catch (NoClassDefFoundError ncdfe) {
1244:                            result = u;
1245:                        }
1246:                    }
1247:                } else {
1248:                    result = name;
1249:                }
1250:                return makeSureIsQualifyable(inClass, result, name);
1251:            }
1252:
1253:            /**
1254:             * Tests if an unqulified class name can be fully qualified inside a class declaration.
1255:             * If this is not the case, depending on the user-option '-code.auto.import' an import statement
1256:             * is generated, or just a warning message is output.
1257:             */
1258:            protected String makeSureIsQualifyable(Class inClass,
1259:                    String unqualified, String qualified) {
1260:                try {
1261:                    inClass.qualify(unqualified);
1262:                    return unqualified;
1263:                } catch (NoClassDefFoundError ncdfe) {
1264:                    if (isOption("code.qualify.auto")) {
1265:                        // auto-generate import statement
1266:                        return qualified;
1267:                    } else {
1268:                        System.err
1269:                                .println("warning: in class "
1270:                                        + inClass.getName()
1271:                                        + ": outputting unqualified classname '"
1272:                                        + unqualified
1273:                                        + "', 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.");
1274:                        return unqualified;
1275:                    }
1276:                }
1277:            }
1278:
1279:            // ------------------------------------------------------------------------
1280:            // --- static methods                                                   ---
1281:            // ------------------------------------------------------------------------
1282:
1283:            /**
1284:             * Appends a vertical line of star characters in front of <code>s</code>.
1285:             * <code>s</code> may contain multiple lines, seperated by either \n or \r,
1286:             * in that case a multi-line result is returned.
1287:             */
1288:            public static String startWithStars(String s, String spaces) {
1289:                StringTokenizer st = new StringTokenizer(s, "\r\n");
1290:                StringBuffer sb = new StringBuffer();
1291:                while (st.hasMoreTokens()) {
1292:                    sb.append(spaces + " * " + st.nextToken() + nl);
1293:                }
1294:                return sb.toString();
1295:            }
1296:
1297:            /**
1298:             * Return the name part of an identifier behind the last '.' occurrence.
1299:             *  
1300:             * @param n The qualified (or already unqualified) identifier name.
1301:             * @return  The unqualified identifier name.
1302:             */
1303:            public static String unqualify(String n) {
1304:                int pos = n.lastIndexOf('.');
1305:                if (pos != -1) {
1306:                    return n.substring(pos + 1);
1307:                } else {
1308:                    return n;
1309:                }
1310:            }
1311:
1312:            /**
1313:             * Returns a string repeating the character <code>mark</code>
1314:             * for <code>count</code> times.
1315:             */
1316:            public static String chars(char mark, int count) {
1317:                StringBuffer sb = new StringBuffer();
1318:                for (int i = 0; i < count; i++) {
1319:                    sb.append(mark);
1320:                }
1321:                return sb.toString();
1322:            }
1323:
1324:            /**
1325:             * Returns a string repeating the space character
1326:             * for <code>count</code> times.
1327:             */
1328:            public static String spaces(int count) {
1329:                return chars(' ', count);
1330:            }
1331:
1332:            /**
1333:             * Replaces all occurrences of string <code>find</code> in <code>s</code> by <code>repl</code>.
1334:             */
1335:            public static String replace(String s, String find, String repl) {
1336:                int pos = s.indexOf(find);
1337:                if (pos != -1) {
1338:                    return s.substring(0, pos)
1339:                            + repl
1340:                            + replace(s.substring(pos + find.length()), find,
1341:                                    repl);
1342:                } else {
1343:                    return s;
1344:                }
1345:            }
1346:
1347:            /**
1348:             * Returns the current date in ISO date format yyyy-MM-dd.
1349:             */
1350:            public static String isodate() {
1351:                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
1352:                return formatter.format(new Date());
1353:            }
1354:
1355:            /**
1356:             * Returns the special prefix of the identifer, if there is any.
1357:             * Otherwise <code>null</code> is returned.
1358:             *  
1359:             * @see  #specialPrefixes
1360:             */
1361:            public static String getSpecialPrefix(String id) {
1362:                for (int i = 0; i < specialPrefixes.length; i++) {
1363:                    int l = specialPrefixes[i].length();
1364:                    if ((id.length() > l) && id.startsWith(specialPrefixes[i])
1365:                            && Character.isUpperCase(id.charAt(l)) // next char after prefix must be upper case
1366:                    ) {
1367:                        return specialPrefixes[i];
1368:                    }
1369:                }
1370:                return null;
1371:            }
1372:
1373:            /**
1374:             * Tests whether the identifier has a special prefix.
1375:             *  
1376:             * @see  #specialPrefixes
1377:             */
1378:            public static boolean hasSpecialPrefix(String id) {
1379:                return getSpecialPrefix(id) != null;
1380:            }
1381:
1382:            /**
1383:             * Convert a string of format "xxxYyyyZzzz" to "xxx yyyy zzzz".
1384:             * This is a simple mechanism to retrieve english language
1385:             * for auto-generating Javadoc comments from semantically rich identifier names.
1386:             *  
1387:             * @param s The identifier name.
1388:             * @return  English language fragment retrieved from identifier name.
1389:             */
1390:            public static String toWords(String s) {
1391:                if (s.length() > 0) {
1392:                    int end = 1;
1393:                    while ((end < s.length())
1394:                            && (!Character.isUpperCase(s.charAt(end)))) {
1395:                        end++;
1396:                    }
1397:                    if (end == s.length()) {
1398:                        return s.toLowerCase();
1399:                    } else {
1400:                        return s.substring(0, end).toLowerCase() + " "
1401:                                + toWords(s.substring(end)); // recursion
1402:                    }
1403:                } else {
1404:                    return "";
1405:                }
1406:            }
1407:
1408:            public static boolean isDummy(String text) {
1409:                return text.indexOf("...") != -1; // Strings like "The result is..." are also dummies.
1410:            }
1411:
1412:            /**
1413:             * Removes out-commented dead lines of from a block of Java code.
1414:             *  
1415:             * @see  #isDeadCodeLine
1416:             */
1417:            public static String cleanCode(String c) {
1418:                BufferedReader b = new BufferedReader(new StringReader(c));
1419:                StringBuffer r = new StringBuffer();
1420:                try {
1421:                    String l = b.readLine();
1422:                    while (l != null) {
1423:                        String nextL = b.readLine();
1424:                        if (!isDeadCodeLine(l)) {
1425:                            r.append(l);
1426:                            if (nextL != null) {
1427:                                r.append(nl);
1428:                            }
1429:                        }
1430:                        l = nextL;
1431:                    }
1432:                } catch (IOException io) {
1433:                    r.append("// *** ERROR: IOException while cleaning code");
1434:                }
1435:                return r.toString();
1436:            }
1437:
1438:            /**
1439:             * Tests whether a line of Java code is an out-commented dead line of code.
1440:             * This is the case when it starts with "//" and end with either ';', '{' or '}'.
1441:             */
1442:            public static boolean isDeadCodeLine(String l) {
1443:                l = l.trim();
1444:                return l.startsWith("//")
1445:                        && (l.endsWith(";") || l.endsWith("{") || l
1446:                                .endsWith("}"));
1447:            }
1448:
1449:            /**
1450:             * Returns the canonical string representation of a SourceObject's type.
1451:             */
1452:            public static String getTypeCode(SourceObject o) {
1453:                String c = unqualify(o.getClass().getName()).toLowerCase();
1454:                if (c.equals("constructor")) {
1455:                    c = "method"; // use same parameters for constructors and methods
1456:                } else if (c.equals("classinner")) {
1457:                    c = "class";
1458:                }
1459:                return c;
1460:            }
1461:
1462:            /**
1463:             * Returns the parent part of a fully qualified identifier name.
1464:             */
1465:            protected static String getParentQualifier(String name) {
1466:                int pos = name.lastIndexOf('.');
1467:                if (pos != -1) {
1468:                    name = name.substring(0, pos);
1469:                } else {
1470:                    name = null;
1471:                }
1472:                return name;
1473:            }
1474:
1475:            protected static DocumentationDeclared tryGetDocumentationFromSuperclass(
1476:                    SourceObjectDeclared o) {
1477:                if (o instanceof  MemberExecutable) {
1478:                    MemberExecutable mex = (MemberExecutable) o;
1479:                    Class c = mex.getDeclaringClass();
1480:                    String supName = c.getSuperclassName();
1481:                    Class sup = c.getPackage().getBasePackage().findClass(
1482:                            supName);
1483:                    while (sup != null) {
1484:                        for (NamedIterator it = sup.getAllMembers(); it
1485:                                .hasMore();) {
1486:                            Member m = (Member) it.next();
1487:                            if (m instanceof  MemberExecutable) {
1488:                                if (m.equals(mex)) {
1489:                                    Documentation d = m.getDocumentation();
1490:                                    if ((d != null)
1491:                                            && (d instanceof  DocumentationDeclared)) {
1492:                                        return (DocumentationDeclared) d;
1493:                                    }
1494:                                }
1495:                            }
1496:                        }
1497:                        if (!sup.getName().equals("java.lang.Object")) {
1498:                            supName = sup.getSuperclassName();
1499:                            sup = c.getPackage().getBasePackage().findClass(
1500:                                    supName);
1501:                        } else {
1502:                            sup = null;
1503:                        }
1504:                    }
1505:                }
1506:                return null;
1507:            }
1508:
1509:            /**
1510:             * Builds the documentation tagged.
1511:             *  
1512:             * @throws IOException if an i/o error occurs
1513:             */
1514:            protected static void buildDocumentationTagged(OutputStream out,
1515:                    DocumentationTagged tag, String spaces) throws IOException {
1516:                write(out, startWithStars(
1517:                        tag.getTag()
1518:                                + " "
1519:                                + (((tag.getItem() != null) ? tag.getItem()
1520:                                        : "")
1521:                                        + " " + tag.getText()), spaces));
1522:            }
1523:
1524:        } // end StandardSourclet
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.