/*
 * Copyright 1996-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.tools.serialver;

import java.io.*;
import java.awt.*;
import java.applet.*;
import java.io.ObjectStreamClass;
import java.util.Properties;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import java.net.URLClassLoader;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.StringTokenizer;
import sun.net.www.ParseUtil;

public class SerialVer extends Applet {
    GridBagLayout gb;
    TextField classname_t;
    Button show_b;
    TextField serialversion_t;
    Label footer_l;

    private static final long serialVersionUID = 7666909783837760853L;

    public synchronized void init() {
        gb = new GridBagLayout();
        setLayout(gb);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;

        Label l1 = new Label(Res.getText("FullClassName"));
        l1.setAlignment(Label.RIGHT);
        gb.setConstraints(l1, c);
        add(l1);

        classname_t = new TextField(20);
        c.gridwidth = GridBagConstraints.RELATIVE;
        c.weightx = 1.0;
        gb.setConstraints(classname_t, c);
        add(classname_t);

        show_b = new Button(Res.getText("Show"));
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.weightx = 0.0;        /* Don't grow the button */
        gb.setConstraints(show_b, c);
        add(show_b);

        Label l2 = new Label(Res.getText("SerialVersion"));
        l2.setAlignment(Label.RIGHT);
        c.gridwidth = 1;
        gb.setConstraints(l2, c);
        add(l2);

        serialversion_t = new TextField(50);
        serialversion_t.setEditable(false);
        c.gridwidth = GridBagConstraints.REMAINDER;
        gb.setConstraints(serialversion_t, c);
        add(serialversion_t);

        footer_l = new Label();
        c.gridwidth = GridBagConstraints.REMAINDER;
        gb.setConstraints(footer_l, c);
        add(footer_l);

        /* Give the focus to the type-in area */
        classname_t.requestFocus();
    }

    public void start() {
        /* Give the focus to the type-in area */
        classname_t.requestFocus();
    }

    public boolean action(Event ev, Object obj) {
        if (ev.target == classname_t) {
            show((String)ev.arg);
            return true;
        } else if (ev.target == show_b) {
            show(classname_t.getText());
            return true;
        }
        return false;
    }


    public boolean handleEvent(Event ev) {
        boolean rc = super.handleEvent(ev);
        return rc;
    }

    /**
     * Lookup the specified classname and display it.
     */
    void show(String classname) {
        try {
            footer_l.setText(""); // Clear the message
            serialversion_t.setText(""); // clear the last value

            if (classname.equals("")) {
                return;
            }

            String s = serialSyntax(classname);
            if (s != null) {
                serialversion_t.setText(s);
            } else {
                footer_l.setText(Res.getText("NotSerializable", classname));
            }
        } catch (ClassNotFoundException cnf) {
            footer_l.setText(Res.getText("ClassNotFound", classname));
        }
    }

    /*
     * A class loader that will load from the CLASSPATH environment
     * variable set by the user.
     */
    static URLClassLoader loader = null;

    /*
     * Create a URL class loader that will load classes from the
     * specified classpath.
     */
    static void initializeLoader(String cp)
                                throws MalformedURLException, IOException {
        URL[] urls;
        StringTokenizer st = new StringTokenizer(cp, File.pathSeparator);
        int count = st.countTokens();
        urls = new URL[count];
        for (int i = 0; i < count; i++) {
            urls[i] = ParseUtil.fileToEncodedURL(
                new File(new File(st.nextToken()).getCanonicalPath()));
        }
        loader = new URLClassLoader(urls);
    }

    /*
     * From the classname find the serialVersionUID string formatted
     * for to be copied to a java class.
     */
    static String serialSyntax(String classname) throws ClassNotFoundException {
        String ret = null;
        boolean classFound = false;

        // If using old style of qualifyling inner classes with '$'s.
        if (classname.indexOf('$') != -1) {
            ret = resolveClass(classname);
        } else {
            /* Try to resolve the fully qualified name and if that fails, start
             * replacing the '.'s with '$'s starting from the last '.', until
             * the class is resolved.
             */
            try {
                ret = resolveClass(classname);
                classFound = true;
            } catch (ClassNotFoundException e) {
                /* Class not found so far */
            }
            if (!classFound) {
                StringBuffer workBuffer = new StringBuffer(classname);
                String workName = workBuffer.toString();
                int i;
                while ((i = workName.lastIndexOf('.')) != -1 && !classFound) {
                    workBuffer.setCharAt(i, '$');
                    try {
                        workName = workBuffer.toString();
                        ret = resolveClass(workName);
                        classFound = true;
                    } catch (ClassNotFoundException e) {
                        /* Continue searching */
                    }
                }
            }
            if (!classFound) {
                throw new ClassNotFoundException();
            }
        }
        return ret;
    }

    static String resolveClass(String classname) throws ClassNotFoundException {
        Class cl = Class.forName(classname, false, loader);
        ObjectStreamClass desc = ObjectStreamClass.lookup(cl);
        if (desc != null) {
            return "    static final long serialVersionUID = " +
                desc.getSerialVersionUID() + "L;";
        } else {
            return null;
        }
    }


    public static void main(String[] args) {
        boolean show = false;
        String envcp = null;
        int i = 0;

        if (args.length == 0) {
            usage();
            System.exit(1);
        }

        for (i = 0; i < args.length; i++) {
            if (args[i].equals("-show")) {
                show = true;
            } else if (args[i].equals("-classpath")) {
                if ((i+1 == args.length) || args[i+1].startsWith("-")) {
                    System.err.println(Res.getText("error.missing.classpath"));
                    usage();
                    System.exit(1);
                }
                envcp = new String(args[i+1]);
                i++;
            }  else if (args[i].startsWith("-")) {
                System.err.println(Res.getText("invalid.flag", args[i]));
                usage();
                System.exit(1);
            } else {
                break;          // drop into processing class names
            }
        }


        /*
         * Get user's CLASSPATH environment variable, if the -classpath option
         * is not defined, and make a loader that can read from that path.
         */
        if (envcp == null) {
            envcp = System.getProperty("env.class.path");
            /*
             * If environment variable not set, add current directory to path.
             */
            if (envcp == null) {
                envcp = ".";
            }
        }

        try {
            initializeLoader(envcp);
        } catch (MalformedURLException mue) {
            System.err.println(Res.getText("error.parsing.classpath", envcp));
            System.exit(2);
        } catch (IOException ioe) {
            System.err.println(Res.getText("error.parsing.classpath", envcp));
            System.exit(3);
        }

        if (!show) {
            /*
             * Check if there are any class names specified, if it is not a
             * invocation with the -show option.
             */
            if (i == args.length) {
                usage();
                System.exit(1);
            }

            /*
             * The rest of the parameters are classnames.
             */
            boolean exitFlag = false;
            for (i = i; i < args.length; i++ ) {
                try {
                    String syntax = serialSyntax(args[i]);
                    if (syntax != null)
                        System.out.println(args[i] + ":" + syntax);
                    else {
                        System.err.println(Res.getText("NotSerializable",
                            args[i]));
                        exitFlag = true;
                    }
                } catch (ClassNotFoundException cnf) {
                    System.err.println(Res.getText("ClassNotFound", args[i]));
                    exitFlag = true;
                }
            }
            if (exitFlag) {
                System.exit(1);
            }
        } else {
            if (i < args.length) {
                System.err.println(Res.getText("ignoring.classes"));
                System.exit(1);
            }
            Frame f =  new SerialVerFrame();
            //  f.setLayout(new FlowLayout());
            SerialVer sv = new SerialVer();
            sv.init();

            f.add("Center", sv);
            f.pack();
            f.show();
        }
    }


    /**
     * Usage
     */
    public static void usage() {
        System.err.println(Res.getText("usage"));
    }

}

/**
 * Top level frame so serialVer can be run as an main program
 * and have an exit menu item.
 */
class SerialVerFrame extends Frame {
    MenuBar menu_mb;
    Menu file_m;
    MenuItem exit_i;

    private static final long serialVersionUID = -7248105987187532533L;

    /*
     * Construct a new Frame with title and menu.
     */
    SerialVerFrame() {
        super(Res.getText("SerialVersionInspector"));

        /* Create the file menu */
        file_m = new Menu(Res.getText("File"));
        file_m.add(exit_i = new MenuItem(Res.getText("Exit")));

        /* Now add the file menu to the menu bar  */
        menu_mb = new MenuBar();
        menu_mb.add(file_m);

        /* Add the menubar to the frame */
        // Bug in JDK1.1        setMenuBar(menu_mb);
    }

    /*
     * Handle a window destroy event by exiting.
     */
    public boolean handleEvent(Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
            exit(0);
        }
        return super.handleEvent(e);
    }
    /*
     * Handle an Exit event by exiting.
     */
    public boolean action(Event ev, Object obj) {
        if (ev.target == exit_i) {
            exit(0);
        }
        return false;
    }

    /*
     * Cleanup and exit.
     */
    void exit(int ret) {
        System.exit(ret);
    }

}

/**
 * Utility for integrating with serialver and for localization.
 * Handle Resources. Access to error and warning counts.
 * Message formatting.
 *
 * @see java.util.ResourceBundle
 * @see java.text.MessageFormat
 */
class Res {

    private static ResourceBundle messageRB;

    /**
     * Initialize ResourceBundle
     */
    static void initResource() {
        try {
            messageRB =
                ResourceBundle.getBundle("sun.tools.serialver.resources.serialver");
        } catch (MissingResourceException e) {
            throw new Error("Fatal: Resource for serialver is missing");
        }
    }

    /**
     * get and format message string from resource
     *
     * @param key selects message from resource
     */
    static String getText(String key) {
        return getText(key, (String)null);
    }

    /**
     * get and format message string from resource
     *
     * @param key selects message from resource
     * @param a1 first argument
     */
    static String getText(String key, String a1) {
        return getText(key, a1, null);
    }

    /**
     * get and format message string from resource
     *
     * @param key selects message from resource
     * @param a1 first argument
     * @param a2 second argument
     */
    static String getText(String key, String a1, String a2) {
        return getText(key, a1, a2, null);
    }

    /**
     * get and format message string from resource
     *
     * @param key selects message from resource
     * @param a1 first argument
     * @param a2 second argument
     * @param a3 third argument
     */
    static String getText(String key, String a1, String a2, String a3) {
        if (messageRB == null) {
            initResource();
        }
        try {
            String message = messageRB.getString(key);
            String[] args = new String[3];
            args[0] = a1;
            args[1] = a2;
            args[2] = a3;
            return MessageFormat.format(message, args);
        } catch (MissingResourceException e) {
            throw new Error("Fatal: Resource for serialver is broken. There is no " + key + " key in resource.");
        }
    }
}
