    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 *   https://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019
    020package org.apache.bcel.verifier;
    021
    022import java.awt.Color;
    023import java.awt.Dialog;
    024import java.awt.Frame;
    025import java.awt.SystemColor;
    026import java.awt.event.ActionEvent;
    027import java.awt.event.ActionListener;
    028import java.awt.event.WindowAdapter;
    029import java.awt.event.WindowEvent;
    030
    031import javax.swing.JButton;
    032import javax.swing.JDialog;
    033import javax.swing.JPanel;
    034
    035import org.apache.bcel.Repository;
    036import org.apache.bcel.classfile.JavaClass;
    037import org.apache.bcel.classfile.Utility;
    038
    039/**
    040 * A class for simple graphical class file verification. Use the main(String []) method with fully qualified class names
    041 * as arguments to use it as a stand-alone application. Use the VerifyDialog(String) constructor to use this class in
    042 * your application. [This class was created using VisualAge for Java, but it does not work under VAJ itself (Version
    043 * 3.02 JDK 1.2)]
    044 *
    045 * @see #main(String[])
    046 * @see #VerifyDialog(String)
    047 */
    048public class VerifyDialog extends JDialog {
    049
    050    /** Machine-generated, made final. */
    051    final class IvjEventHandler implements ActionListener {
    052
    053        @Override
    054        public void actionPerformed(final ActionEvent e) {
    055            if (e.getSource() == getPass1Button()) {
    056                connEtoC1(e);
    057            }
    058            if (e.getSource() == getPass2Button()) {
    059                connEtoC2(e);
    060            }
    061            if (e.getSource() == getPass3Button()) {
    062                connEtoC3(e);
    063            }
    064            if (e.getSource() == getFlushButton()) {
    065                connEtoC4(e);
    066            }
    067        }
    068    }
    069
    070    private static final long serialVersionUID = -6374807677043142313L;
    071
    072    /**
    073     * This field is here to count the number of open VerifyDialog instances so the JVM can be exited afer every Dialog had
    074     * been closed.
    075     */
    076    private static int classesToVerify;
    077
    078    /**
    079     * Verifies one or more class files. Verification results are presented graphically: Red means 'rejected', green means
    080     * 'passed' while yellow means 'could not be verified yet'.
    081     *
    082     * @param args String[] fully qualified names of classes to verify.
    083     */
    084    public static void main(final String[] args) {
    085        classesToVerify = args.length;
    086        for (final String arg : args) {
    087            try {
    088                final VerifyDialog aVerifyDialog;
    089                aVerifyDialog = new VerifyDialog(arg);
    090                aVerifyDialog.setModal(true);
    091                aVerifyDialog.addWindowListener(new WindowAdapter() {
    092
    093                    @Override
    094                    public void windowClosing(final WindowEvent e) {
    095                        classesToVerify--;
    096                        if (classesToVerify == 0) {
    097                            System.exit(0);
    098                        }
    099                    }
    100                });
    101                aVerifyDialog.setVisible(true);
    102            } catch (final Throwable exception) {
    103                System.err.println("Exception occurred in main() of JDialog");
    104                exception.printStackTrace(System.out);
    105            }
    106        }
    107    }
    108
    109    /** Machine-generated. */
    110    private JPanel ivjJDialogContentPane;
    111
    112    /** Machine-generated. */
    113    private JPanel ivjPass1Panel;
    114
    115    /** Machine-generated. */
    116    private JPanel ivjPass2Panel;
    117
    118    /** Machine-generated. */
    119    private JPanel ivjPass3Panel;
    120
    121    /** Machine-generated. */
    122    private JButton ivjPass1Button;
    123
    124    /** Machine-generated. */
    125    private JButton ivjPass2Button;
    126
    127    /** Machine-generated. */
    128    private JButton ivjPass3Button;
    129
    130    /** Machine-generated. */
    131    private final IvjEventHandler ivjEventHandler = new IvjEventHandler();
    132
    133    /**
    134     * The class to verify. Default set to 'java.lang.Object' in case this class is instantiated via one of the many
    135     * machine-generated constructors.
    136     */
    137    private String className = "java.lang.Object";
    138
    139    /** Machine-generated. */
    140    private JButton ivjFlushButton;
    141
    142    /** Machine-generated. */
    143    public VerifyDialog() {
    144        initialize();
    145    }
    146
    147    /** Machine-generated. */
    148    public VerifyDialog(final Dialog owner) {
    149        super(owner);
    150    }
    151
    152    /** Machine-generated. */
    153    public VerifyDialog(final Dialog owner, final boolean modal) {
    154        super(owner, modal);
    155    }
    156
    157    /** Machine-generated. */
    158    public VerifyDialog(final Dialog owner, final String title) {
    159        super(owner, title);
    160    }
    161
    162    /** Machine-generated. */
    163    public VerifyDialog(final Dialog owner, final String title, final boolean modal) {
    164        super(owner, title, modal);
    165    }
    166
    167    /** Machine-generated. */
    168    public VerifyDialog(final Frame owner) {
    169        super(owner);
    170    }
    171
    172    /** Machine-generated. */
    173    public VerifyDialog(final Frame owner, final boolean modal) {
    174        super(owner, modal);
    175    }
    176
    177    /** Machine-generated. */
    178    public VerifyDialog(final Frame owner, final String title) {
    179        super(owner, title);
    180    }
    181
    182    /** Machine-generated. */
    183    public VerifyDialog(final Frame owner, final String title, final boolean modal) {
    184        super(owner, title, modal);
    185    }
    186
    187    /**
    188     * Use this constructor if you want a possibility to verify other class files than {@link Object}.
    189     *
    190     * @param fullyQualifiedClassName "java.lang.String".
    191     */
    192    public VerifyDialog(String fullyQualifiedClassName) {
    193        final int dotclasspos = fullyQualifiedClassName.lastIndexOf(JavaClass.EXTENSION);
    194        if (dotclasspos != -1) {
    195            fullyQualifiedClassName = fullyQualifiedClassName.substring(0, dotclasspos);
    196        }
    197        fullyQualifiedClassName = Utility.pathToPackage(fullyQualifiedClassName);
    198        this.className = fullyQualifiedClassName;
    199        initialize();
    200    }
    201
    202    /** Machine-generated. */
    203    private void connEtoC1(final ActionEvent arg1) {
    204        try {
    205            // user code begin {1}
    206            // user code end
    207            pass1Button_ActionPerformed(arg1);
    208            // user code begin {2}
    209            // user code end
    210        } catch (final Throwable ivjExc) {
    211            // user code begin {3}
    212            // user code end
    213            handleException(ivjExc);
    214        }
    215    }
    216
    217    /** Machine-generated. */
    218    private void connEtoC2(final ActionEvent arg1) {
    219        try {
    220            // user code begin {1}
    221            // user code end
    222            pass2Button_ActionPerformed(arg1);
    223            // user code begin {2}
    224            // user code end
    225        } catch (final Throwable ivjExc) {
    226            // user code begin {3}
    227            // user code end
    228            handleException(ivjExc);
    229        }
    230    }
    231
    232    /** Machine-generated. */
    233    private void connEtoC3(final ActionEvent arg1) {
    234        try {
    235            // user code begin {1}
    236            // user code end
    237            pass4Button_ActionPerformed(arg1);
    238            // user code begin {2}
    239            // user code end
    240        } catch (final Throwable ivjExc) {
    241            // user code begin {3}
    242            // user code end
    243            handleException(ivjExc);
    244        }
    245    }
    246
    247    /** Machine-generated. */
    248    private void connEtoC4(final ActionEvent arg1) {
    249        try {
    250            // user code begin {1}
    251            // user code end
    252            flushButton_ActionPerformed(arg1);
    253            // user code begin {2}
    254            // user code end
    255        } catch (final Throwable ivjExc) {
    256            // user code begin {3}
    257            // user code end
    258            handleException(ivjExc);
    259        }
    260    }
    261
    262    /** Machine-generated. */
    263    public void flushButton_ActionPerformed(final ActionEvent actionEvent) {
    264        VerifierFactory.getVerifier(className).flush();
    265        Repository.removeClass(className); // Make sure it will be reloaded.
    266        getPass1Panel().setBackground(Color.gray);
    267        getPass1Panel().repaint();
    268        getPass2Panel().setBackground(Color.gray);
    269        getPass2Panel().repaint();
    270        getPass3Panel().setBackground(Color.gray);
    271        getPass3Panel().repaint();
    272    }
    273
    274    /** Machine-generated. */
    275    private JButton getFlushButton() {
    276        if (ivjFlushButton == null) {
    277            try {
    278                ivjFlushButton = new JButton();
    279                ivjFlushButton.setName("FlushButton");
    280                ivjFlushButton.setText("Flush: Forget old verification results");
    281                ivjFlushButton.setBackground(SystemColor.controlHighlight);
    282                ivjFlushButton.setBounds(60, 215, 300, 30);
    283                ivjFlushButton.setForeground(Color.red);
    284                ivjFlushButton.setActionCommand("FlushButton");
    285                // user code begin {1}
    286                // user code end
    287            } catch (final Throwable ivjExc) {
    288                // user code begin {2}
    289                // user code end
    290                handleException(ivjExc);
    291            }
    292        }
    293        return ivjFlushButton;
    294    }
    295
    296    /** Machine-generated. */
    297    private JPanel getJDialogContentPane() {
    298        if (ivjJDialogContentPane == null) {
    299            try {
    300                ivjJDialogContentPane = new JPanel();
    301                ivjJDialogContentPane.setName("JDialogContentPane");
    302                ivjJDialogContentPane.setLayout(null);
    303                getJDialogContentPane().add(getPass1Panel(), getPass1Panel().getName());
    304                getJDialogContentPane().add(getPass3Panel(), getPass3Panel().getName());
    305                getJDialogContentPane().add(getPass2Panel(), getPass2Panel().getName());
    306                getJDialogContentPane().add(getPass1Button(), getPass1Button().getName());
    307                getJDialogContentPane().add(getPass2Button(), getPass2Button().getName());
    308                getJDialogContentPane().add(getPass3Button(), getPass3Button().getName());
    309                getJDialogContentPane().add(getFlushButton(), getFlushButton().getName());
    310                // user code begin {1}
    311                // user code end
    312            } catch (final Throwable ivjExc) {
    313                // user code begin {2}
    314                // user code end
    315                handleException(ivjExc);
    316            }
    317        }
    318        return ivjJDialogContentPane;
    319    }
    320
    321    /** Machine-generated. */
    322    private JButton getPass1Button() {
    323        if (ivjPass1Button == null) {
    324            try {
    325                ivjPass1Button = new JButton();
    326                ivjPass1Button.setName("Pass1Button");
    327                ivjPass1Button.setText("Pass1: Verify binary layout of .class file");
    328                ivjPass1Button.setBackground(SystemColor.controlHighlight);
    329                ivjPass1Button.setBounds(100, 40, 300, 30);
    330                ivjPass1Button.setActionCommand("Button1");
    331                // user code begin {1}
    332                // user code end
    333            } catch (final Throwable ivjExc) {
    334                // user code begin {2}
    335                // user code end
    336                handleException(ivjExc);
    337            }
    338        }
    339        return ivjPass1Button;
    340    }
    341
    342    /** Machine-generated. */
    343    private JPanel getPass1Panel() {
    344        if (ivjPass1Panel == null) {
    345            try {
    346                ivjPass1Panel = new JPanel();
    347                ivjPass1Panel.setName("Pass1Panel");
    348                ivjPass1Panel.setLayout(null);
    349                ivjPass1Panel.setBackground(SystemColor.controlShadow);
    350                ivjPass1Panel.setBounds(30, 30, 50, 50);
    351                // user code begin {1}
    352                // user code end
    353            } catch (final Throwable ivjExc) {
    354                // user code begin {2}
    355                // user code end
    356                handleException(ivjExc);
    357            }
    358        }
    359        return ivjPass1Panel;
    360    }
    361
    362    /** Machine-generated. */
    363    private JButton getPass2Button() {
    364        if (ivjPass2Button == null) {
    365            try {
    366                ivjPass2Button = new JButton();
    367                ivjPass2Button.setName("Pass2Button");
    368                ivjPass2Button.setText("Pass 2: Verify static .class file constraints");
    369                ivjPass2Button.setBackground(SystemColor.controlHighlight);
    370                ivjPass2Button.setBounds(100, 100, 300, 30);
    371                ivjPass2Button.setActionCommand("Button2");
    372                // user code begin {1}
    373                // user code end
    374            } catch (final Throwable ivjExc) {
    375                // user code begin {2}
    376                // user code end
    377                handleException(ivjExc);
    378            }
    379        }
    380        return ivjPass2Button;
    381    }
    382
    383    /** Machine-generated. */
    384    private JPanel getPass2Panel() {
    385        if (ivjPass2Panel == null) {
    386            try {
    387                ivjPass2Panel = new JPanel();
    388                ivjPass2Panel.setName("Pass2Panel");
    389                ivjPass2Panel.setLayout(null);
    390                ivjPass2Panel.setBackground(SystemColor.controlShadow);
    391                ivjPass2Panel.setBounds(30, 90, 50, 50);
    392                // user code begin {1}
    393                // user code end
    394            } catch (final Throwable ivjExc) {
    395                // user code begin {2}
    396                // user code end
    397                handleException(ivjExc);
    398            }
    399        }
    400        return ivjPass2Panel;
    401    }
    402
    403    /** Machine-generated. */
    404    private JButton getPass3Button() {
    405        if (ivjPass3Button == null) {
    406            try {
    407                ivjPass3Button = new JButton();
    408                ivjPass3Button.setName("Pass3Button");
    409                ivjPass3Button.setText("Passes 3a+3b: Verify code arrays");
    410                ivjPass3Button.setBackground(SystemColor.controlHighlight);
    411                ivjPass3Button.setBounds(100, 160, 300, 30);
    412                ivjPass3Button.setActionCommand("Button2");
    413                // user code begin {1}
    414                // user code end
    415            } catch (final Throwable ivjExc) {
    416                // user code begin {2}
    417                // user code end
    418                handleException(ivjExc);
    419            }
    420        }
    421        return ivjPass3Button;
    422    }
    423
    424    /** Machine-generated. */
    425    private JPanel getPass3Panel() {
    426        if (ivjPass3Panel == null) {
    427            try {
    428                ivjPass3Panel = new JPanel();
    429                ivjPass3Panel.setName("Pass3Panel");
    430                ivjPass3Panel.setLayout(null);
    431                ivjPass3Panel.setBackground(SystemColor.controlShadow);
    432                ivjPass3Panel.setBounds(30, 150, 50, 50);
    433                // user code begin {1}
    434                // user code end
    435            } catch (final Throwable ivjExc) {
    436                // user code begin {2}
    437                // user code end
    438                handleException(ivjExc);
    439            }
    440        }
    441        return ivjPass3Panel;
    442    }
    443
    444    /** Machine-generated. */
    445    private void handleException(final Throwable exception) {
    446        /* Uncomment the following lines to print uncaught exceptions to stdout */
    447        System.out.println("--------- UNCAUGHT EXCEPTION ---------");
    448        exception.printStackTrace(System.out);
    449        // manually added code
    450        if (exception instanceof ThreadDeath) {
    451            throw (ThreadDeath) exception;
    452        }
    453        if (exception instanceof VirtualMachineError) {
    454            throw (VirtualMachineError) exception;
    455        }
    456    }
    457
    458    /** Machine-generated. */
    459    private void initConnections() {
    460        // user code begin {1}
    461        // user code end
    462        getPass1Button().addActionListener(ivjEventHandler);
    463        getPass2Button().addActionListener(ivjEventHandler);
    464        getPass3Button().addActionListener(ivjEventHandler);
    465        getFlushButton().addActionListener(ivjEventHandler);
    466    }
    467
    468    /** Machine-generated. */
    469    private void initialize() {
    470        try {
    471            // user code begin {1}
    472            // user code end
    473            setName("VerifyDialog");
    474            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    475            setSize(430, 280);
    476            setVisible(true);
    477            setModal(true);
    478            setResizable(false);
    479            setContentPane(getJDialogContentPane());
    480            initConnections();
    481        } catch (final Throwable ivjExc) {
    482            handleException(ivjExc);
    483        }
    484        // user code begin {2}
    485        setTitle("'" + className + "' verification - JustIce / BCEL");
    486        // user code end
    487    }
    488
    489    /** Machine-generated. */
    490    public void pass1Button_ActionPerformed(final ActionEvent actionEvent) {
    491        final Verifier v = VerifierFactory.getVerifier(className);
    492        final VerificationResult vr = v.doPass1();
    493        if (vr.getStatus() == VerificationResult.VERIFIED_OK) {
    494            getPass1Panel().setBackground(Color.green);
    495            getPass1Panel().repaint();
    496        }
    497        if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) {
    498            getPass1Panel().setBackground(Color.red);
    499            getPass1Panel().repaint();
    500        }
    501    }
    502
    503    /** Machine-generated. */
    504    public void pass2Button_ActionPerformed(final ActionEvent actionEvent) {
    505        pass1Button_ActionPerformed(actionEvent);
    506        final Verifier v = VerifierFactory.getVerifier(className);
    507        final VerificationResult vr = v.doPass2();
    508        if (vr.getStatus() == VerificationResult.VERIFIED_OK) {
    509            getPass2Panel().setBackground(Color.green);
    510            getPass2Panel().repaint();
    511        }
    512        if (vr.getStatus() == VerificationResult.VERIFIED_NOTYET) {
    513            getPass2Panel().setBackground(Color.yellow);
    514            getPass2Panel().repaint();
    515        }
    516        if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) {
    517            getPass2Panel().setBackground(Color.red);
    518            getPass2Panel().repaint();
    519        }
    520    }
    521
    522    /** Machine-generated. */
    523    public void pass4Button_ActionPerformed(final ActionEvent actionEvent) {
    524        pass2Button_ActionPerformed(actionEvent);
    525        Color color = Color.green;
    526        final Verifier v = VerifierFactory.getVerifier(className);
    527        VerificationResult vr = v.doPass2();
    528        if (vr.getStatus() == VerificationResult.VERIFIED_OK) {
    529            JavaClass jc = null;
    530            try {
    531                jc = Repository.lookupClass(className);
    532                final int nr = jc.getMethods().length;
    533                for (int i = 0; i < nr; i++) {
    534                    vr = v.doPass3b(i);
    535                    if (vr.getStatus() != VerificationResult.VERIFIED_OK) {
    536                        color = Color.red;
    537                        break;
    538                    }
    539                }
    540            } catch (final ClassNotFoundException ex) {
    541                // FIXME: report the error
    542                ex.printStackTrace();
    543            }
    544        } else {
    545            color = Color.yellow;
    546        }
    547        getPass3Panel().setBackground(color);
    548        getPass3Panel().repaint();
    549    }
    550}