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}