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