Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/serialver/SerialVer.java
38918 views
/*1* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.tools.serialver;2627import java.io.*;28import java.awt.*;29import java.applet.*;30import java.io.ObjectStreamClass;31import java.util.Properties;32import java.text.MessageFormat;33import java.util.ResourceBundle;34import java.util.MissingResourceException;35import java.net.URLClassLoader;36import java.net.URL;37import java.net.MalformedURLException;38import java.util.StringTokenizer;39import sun.net.www.ParseUtil;4041public class SerialVer extends Applet {42GridBagLayout gb;43TextField classname_t;44Button show_b;45TextField serialversion_t;46Label footer_l;4748private static final long serialVersionUID = 7666909783837760853L;4950public synchronized void init() {51gb = new GridBagLayout();52setLayout(gb);5354GridBagConstraints c = new GridBagConstraints();55c.fill = GridBagConstraints.BOTH;5657Label l1 = new Label(Res.getText("FullClassName"));58l1.setAlignment(Label.RIGHT);59gb.setConstraints(l1, c);60add(l1);6162classname_t = new TextField(20);63c.gridwidth = GridBagConstraints.RELATIVE;64c.weightx = 1.0;65gb.setConstraints(classname_t, c);66add(classname_t);6768show_b = new Button(Res.getText("Show"));69c.gridwidth = GridBagConstraints.REMAINDER;70c.weightx = 0.0; /* Don't grow the button */71gb.setConstraints(show_b, c);72add(show_b);7374Label l2 = new Label(Res.getText("SerialVersion"));75l2.setAlignment(Label.RIGHT);76c.gridwidth = 1;77gb.setConstraints(l2, c);78add(l2);7980serialversion_t = new TextField(50);81serialversion_t.setEditable(false);82c.gridwidth = GridBagConstraints.REMAINDER;83gb.setConstraints(serialversion_t, c);84add(serialversion_t);8586footer_l = new Label();87c.gridwidth = GridBagConstraints.REMAINDER;88gb.setConstraints(footer_l, c);89add(footer_l);9091/* Give the focus to the type-in area */92classname_t.requestFocus();93}9495public void start() {96/* Give the focus to the type-in area */97classname_t.requestFocus();98}99100@SuppressWarnings("deprecation")101public boolean action(Event ev, Object obj) {102if (ev.target == classname_t) {103show((String)ev.arg);104return true;105} else if (ev.target == show_b) {106show(classname_t.getText());107return true;108}109return false;110}111112113@SuppressWarnings("deprecation")114public boolean handleEvent(Event ev) {115boolean rc = super.handleEvent(ev);116return rc;117}118119/**120* Lookup the specified classname and display it.121*/122void show(String classname) {123try {124footer_l.setText(""); // Clear the message125serialversion_t.setText(""); // clear the last value126127if (classname.equals("")) {128return;129}130131String s = serialSyntax(classname);132if (s != null) {133serialversion_t.setText(s);134} else {135footer_l.setText(Res.getText("NotSerializable", classname));136}137} catch (ClassNotFoundException cnf) {138footer_l.setText(Res.getText("ClassNotFound", classname));139}140}141142/*143* A class loader that will load from the CLASSPATH environment144* variable set by the user.145*/146static URLClassLoader loader = null;147148/*149* Create a URL class loader that will load classes from the150* specified classpath.151*/152static void initializeLoader(String cp)153throws MalformedURLException, IOException {154URL[] urls;155StringTokenizer st = new StringTokenizer(cp, File.pathSeparator);156int count = st.countTokens();157urls = new URL[count];158for (int i = 0; i < count; i++) {159urls[i] = ParseUtil.fileToEncodedURL(160new File(new File(st.nextToken()).getCanonicalPath()));161}162loader = new URLClassLoader(urls);163}164165/*166* From the classname find the serialVersionUID string formatted167* for to be copied to a java class.168*/169static String serialSyntax(String classname) throws ClassNotFoundException {170String ret = null;171boolean classFound = false;172173// If using old style of qualifyling inner classes with '$'s.174if (classname.indexOf('$') != -1) {175ret = resolveClass(classname);176} else {177/* Try to resolve the fully qualified name and if that fails, start178* replacing the '.'s with '$'s starting from the last '.', until179* the class is resolved.180*/181try {182ret = resolveClass(classname);183classFound = true;184} catch (ClassNotFoundException e) {185/* Class not found so far */186}187if (!classFound) {188StringBuffer workBuffer = new StringBuffer(classname);189String workName = workBuffer.toString();190int i;191while ((i = workName.lastIndexOf('.')) != -1 && !classFound) {192workBuffer.setCharAt(i, '$');193try {194workName = workBuffer.toString();195ret = resolveClass(workName);196classFound = true;197} catch (ClassNotFoundException e) {198/* Continue searching */199}200}201}202if (!classFound) {203throw new ClassNotFoundException();204}205}206return ret;207}208209static String resolveClass(String classname) throws ClassNotFoundException {210Class<?> cl = Class.forName(classname, false, loader);211ObjectStreamClass desc = ObjectStreamClass.lookup(cl);212if (desc != null) {213return " private static final long serialVersionUID = " +214desc.getSerialVersionUID() + "L;";215} else {216return null;217}218}219220@SuppressWarnings("deprecation")221private static void showWindow(Window w) {222w.show();223}224225public static void main(String[] args) {226boolean show = false;227String envcp = null;228int i = 0;229230if (args.length == 0) {231usage();232System.exit(1);233}234235for (i = 0; i < args.length; i++) {236if (args[i].equals("-show")) {237show = true;238} else if (args[i].equals("-classpath")) {239if ((i+1 == args.length) || args[i+1].startsWith("-")) {240System.err.println(Res.getText("error.missing.classpath"));241usage();242System.exit(1);243}244envcp = new String(args[i+1]);245i++;246} else if (args[i].startsWith("-")) {247System.err.println(Res.getText("invalid.flag", args[i]));248usage();249System.exit(1);250} else {251break; // drop into processing class names252}253}254255256/*257* Get user's CLASSPATH environment variable, if the -classpath option258* is not defined, and make a loader that can read from that path.259*/260if (envcp == null) {261envcp = System.getProperty("env.class.path");262/*263* If environment variable not set, add current directory to path.264*/265if (envcp == null) {266envcp = ".";267}268}269270try {271initializeLoader(envcp);272} catch (MalformedURLException mue) {273System.err.println(Res.getText("error.parsing.classpath", envcp));274System.exit(2);275} catch (IOException ioe) {276System.err.println(Res.getText("error.parsing.classpath", envcp));277System.exit(3);278}279280if (!show) {281/*282* Check if there are any class names specified, if it is not a283* invocation with the -show option.284*/285if (i == args.length) {286usage();287System.exit(1);288}289290/*291* The rest of the parameters are classnames.292*/293boolean exitFlag = false;294for (i = i; i < args.length; i++ ) {295try {296String syntax = serialSyntax(args[i]);297if (syntax != null)298System.out.println(args[i] + ":" + syntax);299else {300System.err.println(Res.getText("NotSerializable",301args[i]));302exitFlag = true;303}304} catch (ClassNotFoundException cnf) {305System.err.println(Res.getText("ClassNotFound", args[i]));306exitFlag = true;307}308}309if (exitFlag) {310System.exit(1);311}312} else {313if (i < args.length) {314System.err.println(Res.getText("ignoring.classes"));315System.exit(1);316}317Frame f = new SerialVerFrame();318// f.setLayout(new FlowLayout());319SerialVer sv = new SerialVer();320sv.init();321322f.add("Center", sv);323f.pack();324showWindow(f);325}326}327328329/**330* Usage331*/332public static void usage() {333System.err.println(Res.getText("usage"));334}335336}337338/**339* Top level frame so serialVer can be run as an main program340* and have an exit menu item.341*/342class SerialVerFrame extends Frame {343MenuBar menu_mb;344Menu file_m;345MenuItem exit_i;346347private static final long serialVersionUID = -7248105987187532533L;348349/*350* Construct a new Frame with title and menu.351*/352SerialVerFrame() {353super(Res.getText("SerialVersionInspector"));354355/* Create the file menu */356file_m = new Menu(Res.getText("File"));357file_m.add(exit_i = new MenuItem(Res.getText("Exit")));358359/* Now add the file menu to the menu bar */360menu_mb = new MenuBar();361menu_mb.add(file_m);362363/* Add the menubar to the frame */364// Bug in JDK1.1 setMenuBar(menu_mb);365}366367/*368* Handle a window destroy event by exiting.369*/370@SuppressWarnings("deprecation")371public boolean handleEvent(Event e) {372if (e.id == Event.WINDOW_DESTROY) {373exit(0);374}375return super.handleEvent(e);376}377/*378* Handle an Exit event by exiting.379*/380@SuppressWarnings("deprecation")381public boolean action(Event ev, Object obj) {382if (ev.target == exit_i) {383exit(0);384}385return false;386}387388/*389* Cleanup and exit.390*/391void exit(int ret) {392System.exit(ret);393}394395}396397/**398* Utility for integrating with serialver and for localization.399* Handle Resources. Access to error and warning counts.400* Message formatting.401*402* @see java.util.ResourceBundle403* @see java.text.MessageFormat404*/405class Res {406407private static ResourceBundle messageRB;408409/**410* Initialize ResourceBundle411*/412static void initResource() {413try {414messageRB =415ResourceBundle.getBundle("sun.tools.serialver.resources.serialver");416} catch (MissingResourceException e) {417throw new Error("Fatal: Resource for serialver is missing");418}419}420421/**422* get and format message string from resource423*424* @param key selects message from resource425*/426static String getText(String key) {427return getText(key, (String)null);428}429430/**431* get and format message string from resource432*433* @param key selects message from resource434* @param a1 first argument435*/436static String getText(String key, String a1) {437return getText(key, a1, null);438}439440/**441* get and format message string from resource442*443* @param key selects message from resource444* @param a1 first argument445* @param a2 second argument446*/447static String getText(String key, String a1, String a2) {448return getText(key, a1, a2, null);449}450451/**452* get and format message string from resource453*454* @param key selects message from resource455* @param a1 first argument456* @param a2 second argument457* @param a3 third argument458*/459static String getText(String key, String a1, String a2, String a3) {460if (messageRB == null) {461initResource();462}463try {464String message = messageRB.getString(key);465return MessageFormat.format(message, a1, a2, a3);466} catch (MissingResourceException e) {467throw new Error("Fatal: Resource for serialver is broken. There is no " + key + " key in resource.");468}469}470}471472473