Questo programma riformatta un sorgente java in modo da renderlo pių leggibile, inoltre č possibile eliminare i commenti dal sorgente java, estrarre le stringhe contenute nel sorgente java e trasformare il sorgente java in html. Download pretty.jar


Ecco il risultato di Pretty applicato al sorgente stesso:

/* Program pretty: used to reformat a java program in order to look better
05-11-2005	Version 0.1: initial release
05-11-2006	Version 0.2: minor changes
10-11-2007	Version 0.3: conversion to html now supported

Usage: java Pretty [-notabs] [-nocomment] [-strings] [-html] [-help] <filename> [<outfile>]

-notabs     use blanks instead of tabs
-nocomment  remove every comment
-strings    print-out strings
-html       convert java source to html, colorize java source
-help       print this help message

Requires Java 1.5

javalc6
*/
import java.io.*;
import parser.*;
import java.util.ArrayList;

enum State { SOURCE, STRING, COMMENT, SHORT_COMMENT, CHAR }

interface callback {
    void print(String s, State state);
    void println(String s, State state);
}

public class Pretty {
    boolean notabs, nocomment, strings, html;
    PrintWriter out = null;
    boolean newline;
    int column;
    final String blanks = new blanks().generate(1000);
    String color; // used only for html


    final boolean testmode = false; // testmode, normally false


    private class blanks {
        String generate(int num) {
            String result ="";
            for (int i = 0; i < num; i++) result += " ";
            return (result);
        }
    };

    private class HandleSource implements callback {
        public void print(String s, State state) { 
            StringBuffer str = new StringBuffer();
            if (s.length() == 0) return;
            if ((state == State.SOURCE) && newline) {  
                // source in newline
                String ss = removeLeadingChars(s);
                
                if ((ss.length() > 0) && (ss.charAt(0) == '}')) column--;

                if (notabs) str.append(blanks.substring(0,column*4));
                else for (int i =0; i < column; i++)
                { str.append("\t"); }
                str.append(ss);

                for (int i = 0; i < ss.length(); i++) {   
                    if (ss.charAt(i) == '{') column++;
                    if ((i > 0)&&(ss.charAt(i) == '}')) column--;
                }
            }
            else { 
                if (!nocomment) str.append(s);
                else if (state != State.COMMENT) // comment
                str.append(s);

                if (state == State.SOURCE) // source
                for (int i = 0; i < s.length(); i++) {   
                    if (s.charAt(i) == '{') column++;
                    if (s.charAt(i) == '}') column--;
                }
            }
            if (html)	printHTML(str, state);
            else out.print(str);
            newline = false;
        }
        public void println(String s, State state) { 
            print(s, state);
            out.println();
            newline = true;
        }
    }


    Pretty (String [] files, boolean notabs, boolean nocomment, boolean strings, boolean html) {
        this.notabs = notabs;
        this.nocomment = nocomment;
        this.strings = strings;
        this.html = html;

        java.util.Arrays.sort(Java.keywords);
        newline = true;
        column = 0;
        try	{
            String result;
            if (files.length == 2)	result = files[1];
            else	if (html) result = files[0]+".html";
            else result = files[0]+".new";
            LineNumberReader in = new LineNumberReader(new FileReader(files[0]));
            long zz = System.currentTimeMillis();
            out = open(result, files[0]);
            syntax(in, new HandleSource());
            close(out);
            if (testmode) {	
                System.out.println("Result: "+lazyCompare(new File(files[0]), new File(result))+"       Elapsed time (ms): "+(System.currentTimeMillis() - zz));
            }
            else System.out.println("Elapsed time (ms): "+(System.currentTimeMillis() - zz));
        }
        catch (IOException ex)	{  
            System.err.println(ex.toString());
            if (out != null)
            out.close();
        }
    }
    
    void syntax (LineNumberReader in, callback cb) throws IOException {
        String s;
        State state = State.SOURCE;
        while ((s = in.readLine()) != null) {
            int marker = 0;

            main: // for each char in string
            for (int i = 0; i < s.length(); i++)
            {
                switch (state)
                {   
                    case SOURCE : // source 
                    if (s.startsWith("//", i))
                    {	cb.print(s.substring(marker, i), state);  // source
                        marker = i;
                        state = State.SHORT_COMMENT; // short_comment
                        break main;
                    }
                    if (s.startsWith("/*", i))
                    {	cb.print(s.substring(marker, i), state);  // source
                        marker = i;
                        state = State.COMMENT; // comment
                        break;
                    }
                    if (s.charAt(i) == '\"')
                    {	cb.print(s.substring(marker, i), state);  // source
                        marker = i;
                        state = State.STRING; // string
                        break;
                    }
                    if (s.charAt(i) == '\'')
                    {	cb.print(s.substring(marker, i), state);  // source
                        marker = i;
                        state = State.CHAR; // char
                        break;
                    }
                    break;
                    case STRING: // string
                    if (s.charAt(i) == '\"')
                    {	cb.print(s.substring(marker, i), state);  // string
                        if (strings) System.out.println(s.substring(marker, i+1));
                        marker = i;
                        state = State.SOURCE; // source
                    }
                    if (s.charAt(i) == '\\') i++; // escape, skip
                    break;
                    case COMMENT: // comment
                    if (s.startsWith("*/", i))
                    {	cb.print(s.substring(marker, i+2), state);  // comment
                        marker = i+2;
                        state = State.SOURCE; // source
                    } // else if (s.indexOf("*/", i) == -1) break main;
                    break;
                    case SHORT_COMMENT: // short_comment
                    throw new RuntimeException("Assert failed");
                    case CHAR: // char
                    if (s.charAt(i) == '\'')
                    {	cb.print(s.substring(marker, i), State.STRING);  // string ???
                        marker = i;
                        state = State.SOURCE; // source
                    }
                    if (s.charAt(i) == '\\') i++; // escape, skip
                    break;
                }
            }
// all chars in the current line were analysed
            switch (state)
            {   
                case SOURCE : // source 
                cb.println(s.substring(marker), state);  // source
                break;
                case STRING: // string
                throw new IOException("Wrong syntax: string not terminated correctly at line "+in.getLineNumber());
                case COMMENT: // comment
                cb.println(s.substring(marker), state);  // comment
                break;
                case SHORT_COMMENT: // short_comment
                cb.println(s.substring(marker), State.COMMENT);  // comment (even if it is short...)
                state = State.SOURCE; // source
                break;
                case CHAR: // char
                throw new IOException("Wrong syntax: char not terminated correctly at line "+in.getLineNumber());
            }


// main while
        }
        in.close();	
    }
    
    String removeLeadingChars(String line) {
        int i=0;
        while ((i < line.length())&&((line.charAt(i) == ' ')||(line.charAt(i) == '\t'))) i++;
        return (line.substring(i));
        
    }


    PrintWriter open(String filename, String source) throws IOException {
        PrintWriter out = new PrintWriter(new FileWriter(new File(filename)));
        if (html) {
            out.println();
            out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
            out.println("<html>");
            out.println("<head>");
            out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1252\">");
            out.println("<meta name=\"description\" content=\"Programmi Java\">");
            out.println("<title>"+encodeHTML(new StringBuffer(source))+"</title>");
            out.println("</head>");
            out.println("<body><pre><font color=\"#000000\">");
            color = "#000000"; // used only for html
        }
        return out;
    }

    void close(PrintWriter out) {
        if (html) {
            out.println("</font></pre></body>");
            out.println("</html>");
        }
        out.close();
    }

    boolean testAlfa(char ch) {
        return ((ch >= 'a')&&(ch <= 'z'))||((ch >= 'A')&&(ch <= 'Z'));
    }

    boolean testDigit(char ch) {
        return ((ch >= '0')&&(ch <= '9'));
    }

    void printHTML(StringBuffer str, State state) {
        String oldcolor = color;
        switch (state)	{   
            case SOURCE : color = "#000000";
            break;
            case COMMENT : color = "#339966";
            break;
            default: color = "#0033CC";
        }
        if (!color.equals(oldcolor)) {
            out.print("</font><font color=\""+color+"\">");
        }
        if (state == State.SOURCE) {
            int i = 0;
            while (i < str.length())	{
// skips blank and tabs
                char ch = str.charAt(i);
                if (testAlfa(ch)||(ch == '_')||(ch == '$'))	{
                    StringBuffer id = new StringBuffer();
                    do {
                        id.append(ch);
                        i++;
                        if (i >= str.length()) break;
                        ch = str.charAt(i);
                    }
                    while (testAlfa(ch)||(ch == '_')||(ch == '$') || testDigit(ch));
                    if (java.util.Arrays.binarySearch(Java.keywords, id.toString()) >= 0)
                    out.print("<b>"+encodeHTML(id)+"</b>");
                    else out.print(encodeHTML(id));
                }
                if (i >= str.length()) break;
                out.print(encodeHTML(new StringBuffer(str.substring(i,i+1))));
                i++;
            }
        } else	out.print(encodeHTML(str));
    }

    public StringBuffer encodeHTML(StringBuffer s)	{
        StringBuffer out = new StringBuffer();
        for(int i=0; i<s.length(); i++)
        {
            char c = s.charAt(i);
            if(c > 127 || c=='"' || c=='<' || c=='>') {
                out.append("&#"+(int)c+";");
            }
            else if (c=='"') out.append("&quot;");
            else if (c=='<') out.append("&lt;");
            else if (c=='>') out.append("&gt;");
            else if (c=='&') out.append("&amp;");
            else {
                out.append(c);
            }
        }
        return out;
    }

    public static boolean lazyCompare(File file1, File file2) throws IOException {
        InputStream bufferedInput1 = new BufferedInputStream(new java.io.FileInputStream(file1));
        InputStream bufferedInput2 = new BufferedInputStream(new java.io.FileInputStream(file2));
        int ch = bufferedInput1.read();
        int ch2 = bufferedInput2.read();
        while(true)	{
            while ((-1 != ch)&&(" \t\n\r".indexOf(ch) != -1)) {
                ch = bufferedInput1.read();
            }
            while ((-1 != ch2)&&(" \t\n\r".indexOf(ch2) != -1)) {
                ch2 = bufferedInput2.read();
            }
            if (ch == -1) return -1 == ch2;
//			System.err.println(ch+"<->"+ch2);
            if( ch != ch2 ) return false;
            ch = bufferedInput1.read();
            ch2 = bufferedInput2.read();
        }
    }

//main	
    public static void main(String[] args) throws ParserException
    {
        Parser cli = new Parser();
        Option notabs = cli.addOption("-notabs", false, null,"use blanks instead of tabs");
        Option nocomment = cli.addOption("-nocomment", false, null,"remove every comment");
        Option strings = cli.addOption("-strings", false, null,"print-out strings");
        Option html = cli.addOption("-html", false, null,"convert java to html");
        cli.addOption("-help", false, null,"print this help message");
        String [] result = cli.parse(args);
        if ((result.length > 0)&&(result.length < 3)) {
            if (new File(result[0]).isDirectory()) System.err.println("Error: "+result[0]+" is a directory!");
            else new Pretty(result, cli.hasOption(notabs), cli.hasOption(nocomment), cli.hasOption(strings), cli.hasOption(html));
        }
        else System.err.println("Usage: java Pretty"+cli.getUsage("<filename> [<outfile>]"));
    }
}