View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.bcel.verifier;
19  
20  import java.awt.Color;
21  import java.awt.Dialog;
22  import java.awt.Frame;
23  import java.awt.SystemColor;
24  import java.awt.event.ActionEvent;
25  import java.awt.event.ActionListener;
26  import java.awt.event.WindowAdapter;
27  import java.awt.event.WindowEvent;
28  
29  import javax.swing.JButton;
30  import javax.swing.JDialog;
31  import javax.swing.JPanel;
32  
33  import org.apache.bcel.Repository;
34  import org.apache.bcel.classfile.JavaClass;
35  import org.apache.bcel.classfile.Utility;
36  
37  /**
38   * A class for simple graphical class file verification. Use the main(String []) method with fully qualified class names
39   * as arguments to use it as a stand-alone application. Use the VerifyDialog(String) constructor to use this class in
40   * your application. [This class was created using VisualAge for Java, but it does not work under VAJ itself (Version
41   * 3.02 JDK 1.2)]
42   *
43   * @see #main(String[])
44   * @see #VerifyDialog(String)
45   */
46  public class VerifyDialog extends JDialog {
47  
48      /** Machine-generated, made final. */
49      final class IvjEventHandler implements ActionListener {
50  
51          @Override
52          public void actionPerformed(final ActionEvent e) {
53              if (e.getSource() == getPass1Button()) {
54                  connEtoC1(e);
55              }
56              if (e.getSource() == getPass2Button()) {
57                  connEtoC2(e);
58              }
59              if (e.getSource() == getPass3Button()) {
60                  connEtoC3(e);
61              }
62              if (e.getSource() == getFlushButton()) {
63                  connEtoC4(e);
64              }
65          }
66      }
67  
68      private static final long serialVersionUID = -6374807677043142313L;
69  
70      /**
71       * This field is here to count the number of open VerifyDialog instances so the JVM can be exited afer every Dialog had
72       * been closed.
73       */
74      private static int classesToVerify;
75  
76      /**
77       * Verifies one or more class files. Verification results are presented graphically: Red means 'rejected', green means
78       * 'passed' while yellow means 'could not be verified yet'.
79       *
80       * @param args String[] fully qualified names of classes to verify.
81       */
82      public static void main(final String[] args) {
83          classesToVerify = args.length;
84          for (final String arg : args) {
85              try {
86                  final VerifyDialog aVerifyDialog;
87                  aVerifyDialog = new VerifyDialog(arg);
88                  aVerifyDialog.setModal(true);
89                  aVerifyDialog.addWindowListener(new WindowAdapter() {
90  
91                      @Override
92                      public void windowClosing(final WindowEvent e) {
93                          classesToVerify--;
94                          if (classesToVerify == 0) {
95                              System.exit(0);
96                          }
97                      }
98                  });
99                  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 }