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