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