View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.bcel.verifier;
21  
22  import java.awt.Color;
23  import java.awt.Dialog;
24  import java.awt.Frame;
25  import java.awt.SystemColor;
26  import java.awt.event.ActionEvent;
27  import java.awt.event.ActionListener;
28  import java.awt.event.WindowAdapter;
29  import java.awt.event.WindowEvent;
30  
31  import javax.swing.JButton;
32  import javax.swing.JDialog;
33  import javax.swing.JPanel;
34  
35  import org.apache.bcel.Repository;
36  import org.apache.bcel.classfile.JavaClass;
37  import org.apache.bcel.classfile.Utility;
38  
39  /**
40   * A class for simple graphical class file verification. Use the main(String []) method with fully qualified class names
41   * as arguments to use it as a stand-alone application. Use the VerifyDialog(String) constructor to use this class in
42   * your application. [This class was created using VisualAge for Java, but it does not work under VAJ itself (Version
43   * 3.02 JDK 1.2)]
44   *
45   * @see #main(String[])
46   * @see #VerifyDialog(String)
47   */
48  public class VerifyDialog extends JDialog {
49  
50      /** Machine-generated, made final. */
51      final class IvjEventHandler implements ActionListener {
52  
53          @Override
54          public void actionPerformed(final ActionEvent e) {
55              if (e.getSource() == getPass1Button()) {
56                  connEtoC1(e);
57              }
58              if (e.getSource() == getPass2Button()) {
59                  connEtoC2(e);
60              }
61              if (e.getSource() == getPass3Button()) {
62                  connEtoC3(e);
63              }
64              if (e.getSource() == getFlushButton()) {
65                  connEtoC4(e);
66              }
67          }
68      }
69  
70      private static final long serialVersionUID = -6374807677043142313L;
71  
72      /**
73       * This field is here to count the number of open VerifyDialog instances so the JVM can be exited afer every Dialog had
74       * been closed.
75       */
76      private static int classesToVerify;
77  
78      /**
79       * Verifies one or more class files. Verification results are presented graphically: Red means 'rejected', green means
80       * 'passed' while yellow means 'could not be verified yet'.
81       *
82       * @param args String[] fully qualified names of classes to verify.
83       */
84      public static void main(final String[] args) {
85          classesToVerify = args.length;
86          for (final String arg : args) {
87              try {
88                  final VerifyDialog aVerifyDialog;
89                  aVerifyDialog = new VerifyDialog(arg);
90                  aVerifyDialog.setModal(true);
91                  aVerifyDialog.addWindowListener(new WindowAdapter() {
92  
93                      @Override
94                      public void windowClosing(final WindowEvent e) {
95                          classesToVerify--;
96                          if (classesToVerify == 0) {
97                              System.exit(0);
98                          }
99                      }
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     /** Machine-generated. */
112     private JPanel ivjPass1Panel;
113     /** Machine-generated. */
114     private JPanel ivjPass2Panel;
115     /** Machine-generated. */
116     private JPanel ivjPass3Panel;
117     /** Machine-generated. */
118     private JButton ivjPass1Button;
119     /** Machine-generated. */
120     private JButton ivjPass2Button;
121     /** Machine-generated. */
122     private JButton ivjPass3Button;
123 
124     /** Machine-generated. */
125     private final IvjEventHandler ivjEventHandler = new IvjEventHandler();
126 
127     /**
128      * The class to verify. Default set to 'java.lang.Object' in case this class is instantiated via one of the many
129      * machine-generated constructors.
130      */
131     private String className = "java.lang.Object";
132 
133     /** Machine-generated. */
134     private JButton ivjFlushButton;
135 
136     /** Machine-generated. */
137     public VerifyDialog() {
138         initialize();
139     }
140 
141     /** Machine-generated. */
142     public VerifyDialog(final Dialog owner) {
143         super(owner);
144     }
145 
146     /** Machine-generated. */
147     public VerifyDialog(final Dialog owner, final boolean modal) {
148         super(owner, modal);
149     }
150 
151     /** Machine-generated. */
152     public VerifyDialog(final Dialog owner, final String title) {
153         super(owner, title);
154     }
155 
156     /** Machine-generated. */
157     public VerifyDialog(final Dialog owner, final String title, final boolean modal) {
158         super(owner, title, modal);
159     }
160 
161     /** Machine-generated. */
162     public VerifyDialog(final Frame owner) {
163         super(owner);
164     }
165 
166     /** Machine-generated. */
167     public VerifyDialog(final Frame owner, final boolean modal) {
168         super(owner, modal);
169     }
170 
171     /** Machine-generated. */
172     public VerifyDialog(final Frame owner, final String title) {
173         super(owner, title);
174     }
175 
176     /** Machine-generated. */
177     public VerifyDialog(final Frame owner, final String title, final boolean modal) {
178         super(owner, title, modal);
179     }
180 
181     /**
182      * Use this constructor if you want a possibility to verify other class files than {@link Object}.
183      *
184      * @param fullyQualifiedClassName "java.lang.String"
185      */
186     public VerifyDialog(String fullyQualifiedClassName) {
187         final int dotclasspos = fullyQualifiedClassName.lastIndexOf(JavaClass.EXTENSION);
188         if (dotclasspos != -1) {
189             fullyQualifiedClassName = fullyQualifiedClassName.substring(0, dotclasspos);
190         }
191         fullyQualifiedClassName = Utility.pathToPackage(fullyQualifiedClassName);
192         this.className = fullyQualifiedClassName;
193         initialize();
194     }
195 
196     /** Machine-generated. */
197     private void connEtoC1(final ActionEvent arg1) {
198         try {
199             // user code begin {1}
200             // user code end
201             pass1Button_ActionPerformed(arg1);
202             // user code begin {2}
203             // user code end
204         } catch (final Throwable ivjExc) {
205             // user code begin {3}
206             // user code end
207             handleException(ivjExc);
208         }
209     }
210 
211     /** Machine-generated. */
212     private void connEtoC2(final ActionEvent arg1) {
213         try {
214             // user code begin {1}
215             // user code end
216             pass2Button_ActionPerformed(arg1);
217             // user code begin {2}
218             // user code end
219         } catch (final Throwable ivjExc) {
220             // user code begin {3}
221             // user code end
222             handleException(ivjExc);
223         }
224     }
225 
226     /** Machine-generated. */
227     private void connEtoC3(final ActionEvent arg1) {
228         try {
229             // user code begin {1}
230             // user code end
231             pass4Button_ActionPerformed(arg1);
232             // user code begin {2}
233             // user code end
234         } catch (final Throwable ivjExc) {
235             // user code begin {3}
236             // user code end
237             handleException(ivjExc);
238         }
239     }
240 
241     /** Machine-generated. */
242     private void connEtoC4(final ActionEvent arg1) {
243         try {
244             // user code begin {1}
245             // user code end
246             flushButton_ActionPerformed(arg1);
247             // user code begin {2}
248             // user code end
249         } catch (final Throwable ivjExc) {
250             // user code begin {3}
251             // user code end
252             handleException(ivjExc);
253         }
254     }
255 
256     /** Machine-generated. */
257     public void flushButton_ActionPerformed(final ActionEvent actionEvent) {
258         VerifierFactory.getVerifier(className).flush();
259         Repository.removeClass(className); // Make sure it will be reloaded.
260         getPass1Panel().setBackground(Color.gray);
261         getPass1Panel().repaint();
262         getPass2Panel().setBackground(Color.gray);
263         getPass2Panel().repaint();
264         getPass3Panel().setBackground(Color.gray);
265         getPass3Panel().repaint();
266     }
267 
268     /** Machine-generated. */
269     private JButton getFlushButton() {
270         if (ivjFlushButton == null) {
271             try {
272                 ivjFlushButton = new JButton();
273                 ivjFlushButton.setName("FlushButton");
274                 ivjFlushButton.setText("Flush: Forget old verification results");
275                 ivjFlushButton.setBackground(SystemColor.controlHighlight);
276                 ivjFlushButton.setBounds(60, 215, 300, 30);
277                 ivjFlushButton.setForeground(Color.red);
278                 ivjFlushButton.setActionCommand("FlushButton");
279                 // user code begin {1}
280                 // user code end
281             } catch (final Throwable ivjExc) {
282                 // user code begin {2}
283                 // user code end
284                 handleException(ivjExc);
285             }
286         }
287         return ivjFlushButton;
288     }
289 
290     /** Machine-generated. */
291     private JPanel getJDialogContentPane() {
292         if (ivjJDialogContentPane == null) {
293             try {
294                 ivjJDialogContentPane = new JPanel();
295                 ivjJDialogContentPane.setName("JDialogContentPane");
296                 ivjJDialogContentPane.setLayout(null);
297                 getJDialogContentPane().add(getPass1Panel(), getPass1Panel().getName());
298                 getJDialogContentPane().add(getPass3Panel(), getPass3Panel().getName());
299                 getJDialogContentPane().add(getPass2Panel(), getPass2Panel().getName());
300                 getJDialogContentPane().add(getPass1Button(), getPass1Button().getName());
301                 getJDialogContentPane().add(getPass2Button(), getPass2Button().getName());
302                 getJDialogContentPane().add(getPass3Button(), getPass3Button().getName());
303                 getJDialogContentPane().add(getFlushButton(), getFlushButton().getName());
304                 // user code begin {1}
305                 // user code end
306             } catch (final Throwable ivjExc) {
307                 // user code begin {2}
308                 // user code end
309                 handleException(ivjExc);
310             }
311         }
312         return ivjJDialogContentPane;
313     }
314 
315     /** Machine-generated. */
316     private JButton getPass1Button() {
317         if (ivjPass1Button == null) {
318             try {
319                 ivjPass1Button = new JButton();
320                 ivjPass1Button.setName("Pass1Button");
321                 ivjPass1Button.setText("Pass1: Verify binary layout of .class file");
322                 ivjPass1Button.setBackground(SystemColor.controlHighlight);
323                 ivjPass1Button.setBounds(100, 40, 300, 30);
324                 ivjPass1Button.setActionCommand("Button1");
325                 // user code begin {1}
326                 // user code end
327             } catch (final Throwable ivjExc) {
328                 // user code begin {2}
329                 // user code end
330                 handleException(ivjExc);
331             }
332         }
333         return ivjPass1Button;
334     }
335 
336     /** Machine-generated. */
337     private JPanel getPass1Panel() {
338         if (ivjPass1Panel == null) {
339             try {
340                 ivjPass1Panel = new JPanel();
341                 ivjPass1Panel.setName("Pass1Panel");
342                 ivjPass1Panel.setLayout(null);
343                 ivjPass1Panel.setBackground(SystemColor.controlShadow);
344                 ivjPass1Panel.setBounds(30, 30, 50, 50);
345                 // user code begin {1}
346                 // user code end
347             } catch (final Throwable ivjExc) {
348                 // user code begin {2}
349                 // user code end
350                 handleException(ivjExc);
351             }
352         }
353         return ivjPass1Panel;
354     }
355 
356     /** Machine-generated. */
357     private JButton getPass2Button() {
358         if (ivjPass2Button == null) {
359             try {
360                 ivjPass2Button = new JButton();
361                 ivjPass2Button.setName("Pass2Button");
362                 ivjPass2Button.setText("Pass 2: Verify static .class file constraints");
363                 ivjPass2Button.setBackground(SystemColor.controlHighlight);
364                 ivjPass2Button.setBounds(100, 100, 300, 30);
365                 ivjPass2Button.setActionCommand("Button2");
366                 // user code begin {1}
367                 // user code end
368             } catch (final Throwable ivjExc) {
369                 // user code begin {2}
370                 // user code end
371                 handleException(ivjExc);
372             }
373         }
374         return ivjPass2Button;
375     }
376 
377     /** Machine-generated. */
378     private JPanel getPass2Panel() {
379         if (ivjPass2Panel == null) {
380             try {
381                 ivjPass2Panel = new JPanel();
382                 ivjPass2Panel.setName("Pass2Panel");
383                 ivjPass2Panel.setLayout(null);
384                 ivjPass2Panel.setBackground(SystemColor.controlShadow);
385                 ivjPass2Panel.setBounds(30, 90, 50, 50);
386                 // user code begin {1}
387                 // user code end
388             } catch (final Throwable ivjExc) {
389                 // user code begin {2}
390                 // user code end
391                 handleException(ivjExc);
392             }
393         }
394         return ivjPass2Panel;
395     }
396 
397     /** Machine-generated. */
398     private JButton getPass3Button() {
399         if (ivjPass3Button == null) {
400             try {
401                 ivjPass3Button = new JButton();
402                 ivjPass3Button.setName("Pass3Button");
403                 ivjPass3Button.setText("Passes 3a+3b: Verify code arrays");
404                 ivjPass3Button.setBackground(SystemColor.controlHighlight);
405                 ivjPass3Button.setBounds(100, 160, 300, 30);
406                 ivjPass3Button.setActionCommand("Button2");
407                 // user code begin {1}
408                 // user code end
409             } catch (final Throwable ivjExc) {
410                 // user code begin {2}
411                 // user code end
412                 handleException(ivjExc);
413             }
414         }
415         return ivjPass3Button;
416     }
417 
418     /** Machine-generated. */
419     private JPanel getPass3Panel() {
420         if (ivjPass3Panel == null) {
421             try {
422                 ivjPass3Panel = new JPanel();
423                 ivjPass3Panel.setName("Pass3Panel");
424                 ivjPass3Panel.setLayout(null);
425                 ivjPass3Panel.setBackground(SystemColor.controlShadow);
426                 ivjPass3Panel.setBounds(30, 150, 50, 50);
427                 // user code begin {1}
428                 // user code end
429             } catch (final Throwable ivjExc) {
430                 // user code begin {2}
431                 // user code end
432                 handleException(ivjExc);
433             }
434         }
435         return ivjPass3Panel;
436     }
437 
438     /** Machine-generated. */
439     private void handleException(final Throwable exception) {
440         /* Uncomment the following lines to print uncaught exceptions to stdout */
441         System.out.println("--------- UNCAUGHT EXCEPTION ---------");
442         exception.printStackTrace(System.out);
443         // manually added code
444         if (exception instanceof ThreadDeath) {
445             throw (ThreadDeath) exception;
446         }
447         if (exception instanceof VirtualMachineError) {
448             throw (VirtualMachineError) exception;
449         }
450     }
451 
452     /** Machine-generated. */
453     private void initConnections() {
454         // user code begin {1}
455         // user code end
456         getPass1Button().addActionListener(ivjEventHandler);
457         getPass2Button().addActionListener(ivjEventHandler);
458         getPass3Button().addActionListener(ivjEventHandler);
459         getFlushButton().addActionListener(ivjEventHandler);
460     }
461 
462     /** Machine-generated. */
463     private void initialize() {
464         try {
465             // user code begin {1}
466             // user code end
467             setName("VerifyDialog");
468             setDefaultCloseOperation(DISPOSE_ON_CLOSE);
469             setSize(430, 280);
470             setVisible(true);
471             setModal(true);
472             setResizable(false);
473             setContentPane(getJDialogContentPane());
474             initConnections();
475         } catch (final Throwable ivjExc) {
476             handleException(ivjExc);
477         }
478         // user code begin {2}
479         setTitle("'" + className + "' verification - JustIce / BCEL");
480         // user code end
481     }
482 
483     /** Machine-generated. */
484     public void pass1Button_ActionPerformed(final ActionEvent actionEvent) {
485         final Verifier v = VerifierFactory.getVerifier(className);
486         final VerificationResult vr = v.doPass1();
487         if (vr.getStatus() == VerificationResult.VERIFIED_OK) {
488             getPass1Panel().setBackground(Color.green);
489             getPass1Panel().repaint();
490         }
491         if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) {
492             getPass1Panel().setBackground(Color.red);
493             getPass1Panel().repaint();
494         }
495     }
496 
497     /** Machine-generated. */
498     public void pass2Button_ActionPerformed(final ActionEvent actionEvent) {
499         pass1Button_ActionPerformed(actionEvent);
500         final Verifier v = VerifierFactory.getVerifier(className);
501         final VerificationResult vr = v.doPass2();
502         if (vr.getStatus() == VerificationResult.VERIFIED_OK) {
503             getPass2Panel().setBackground(Color.green);
504             getPass2Panel().repaint();
505         }
506         if (vr.getStatus() == VerificationResult.VERIFIED_NOTYET) {
507             getPass2Panel().setBackground(Color.yellow);
508             getPass2Panel().repaint();
509         }
510         if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) {
511             getPass2Panel().setBackground(Color.red);
512             getPass2Panel().repaint();
513         }
514     }
515 
516     /** Machine-generated. */
517     public void pass4Button_ActionPerformed(final ActionEvent actionEvent) {
518         pass2Button_ActionPerformed(actionEvent);
519         Color color = Color.green;
520         final Verifier v = VerifierFactory.getVerifier(className);
521         VerificationResult vr = v.doPass2();
522         if (vr.getStatus() == VerificationResult.VERIFIED_OK) {
523             JavaClass jc = null;
524             try {
525                 jc = Repository.lookupClass(className);
526                 final int nr = jc.getMethods().length;
527                 for (int i = 0; i < nr; i++) {
528                     vr = v.doPass3b(i);
529                     if (vr.getStatus() != VerificationResult.VERIFIED_OK) {
530                         color = Color.red;
531                         break;
532                     }
533                 }
534             } catch (final ClassNotFoundException ex) {
535                 // FIXME: report the error
536                 ex.printStackTrace();
537             }
538         } else {
539             color = Color.yellow;
540         }
541         getPass3Panel().setBackground(color);
542         getPass3Panel().repaint();
543     }
544 }