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 /** Machine-generated. */ 148 public VerifyDialog(final Dialog owner) { 149 super(owner); 150 } 151 152 /** Machine-generated. */ 153 public VerifyDialog(final Dialog owner, final boolean modal) { 154 super(owner, modal); 155 } 156 157 /** Machine-generated. */ 158 public VerifyDialog(final Dialog owner, final String title) { 159 super(owner, title); 160 } 161 162 /** Machine-generated. */ 163 public VerifyDialog(final Dialog owner, final String title, final boolean modal) { 164 super(owner, title, modal); 165 } 166 167 /** Machine-generated. */ 168 public VerifyDialog(final Frame owner) { 169 super(owner); 170 } 171 172 /** Machine-generated. */ 173 public VerifyDialog(final Frame owner, final boolean modal) { 174 super(owner, modal); 175 } 176 177 /** Machine-generated. */ 178 public VerifyDialog(final Frame owner, final String title) { 179 super(owner, title); 180 } 181 182 /** Machine-generated. */ 183 public VerifyDialog(final Frame owner, final String title, final boolean modal) { 184 super(owner, title, modal); 185 } 186 187 /** 188 * Use this constructor if you want a possibility to verify other class files than {@link Object}. 189 * 190 * @param fullyQualifiedClassName "java.lang.String". 191 */ 192 public VerifyDialog(String fullyQualifiedClassName) { 193 final int dotclasspos = fullyQualifiedClassName.lastIndexOf(JavaClass.EXTENSION); 194 if (dotclasspos != -1) { 195 fullyQualifiedClassName = fullyQualifiedClassName.substring(0, dotclasspos); 196 } 197 fullyQualifiedClassName = Utility.pathToPackage(fullyQualifiedClassName); 198 this.className = fullyQualifiedClassName; 199 initialize(); 200 } 201 202 /** Machine-generated. */ 203 private void connEtoC1(final ActionEvent arg1) { 204 try { 205 // user code begin {1} 206 // user code end 207 pass1Button_ActionPerformed(arg1); 208 // user code begin {2} 209 // user code end 210 } catch (final Throwable ivjExc) { 211 // user code begin {3} 212 // user code end 213 handleException(ivjExc); 214 } 215 } 216 217 /** Machine-generated. */ 218 private void connEtoC2(final ActionEvent arg1) { 219 try { 220 // user code begin {1} 221 // user code end 222 pass2Button_ActionPerformed(arg1); 223 // user code begin {2} 224 // user code end 225 } catch (final Throwable ivjExc) { 226 // user code begin {3} 227 // user code end 228 handleException(ivjExc); 229 } 230 } 231 232 /** Machine-generated. */ 233 private void connEtoC3(final ActionEvent arg1) { 234 try { 235 // user code begin {1} 236 // user code end 237 pass4Button_ActionPerformed(arg1); 238 // user code begin {2} 239 // user code end 240 } catch (final Throwable ivjExc) { 241 // user code begin {3} 242 // user code end 243 handleException(ivjExc); 244 } 245 } 246 247 /** Machine-generated. */ 248 private void connEtoC4(final ActionEvent arg1) { 249 try { 250 // user code begin {1} 251 // user code end 252 flushButton_ActionPerformed(arg1); 253 // user code begin {2} 254 // user code end 255 } catch (final Throwable ivjExc) { 256 // user code begin {3} 257 // user code end 258 handleException(ivjExc); 259 } 260 } 261 262 /** Machine-generated. */ 263 public void flushButton_ActionPerformed(final ActionEvent actionEvent) { 264 VerifierFactory.getVerifier(className).flush(); 265 Repository.removeClass(className); // Make sure it will be reloaded. 266 getPass1Panel().setBackground(Color.gray); 267 getPass1Panel().repaint(); 268 getPass2Panel().setBackground(Color.gray); 269 getPass2Panel().repaint(); 270 getPass3Panel().setBackground(Color.gray); 271 getPass3Panel().repaint(); 272 } 273 274 /** Machine-generated. */ 275 private JButton getFlushButton() { 276 if (ivjFlushButton == null) { 277 try { 278 ivjFlushButton = new JButton(); 279 ivjFlushButton.setName("FlushButton"); 280 ivjFlushButton.setText("Flush: Forget old verification results"); 281 ivjFlushButton.setBackground(SystemColor.controlHighlight); 282 ivjFlushButton.setBounds(60, 215, 300, 30); 283 ivjFlushButton.setForeground(Color.red); 284 ivjFlushButton.setActionCommand("FlushButton"); 285 // user code begin {1} 286 // user code end 287 } catch (final Throwable ivjExc) { 288 // user code begin {2} 289 // user code end 290 handleException(ivjExc); 291 } 292 } 293 return ivjFlushButton; 294 } 295 296 /** Machine-generated. */ 297 private JPanel getJDialogContentPane() { 298 if (ivjJDialogContentPane == null) { 299 try { 300 ivjJDialogContentPane = new JPanel(); 301 ivjJDialogContentPane.setName("JDialogContentPane"); 302 ivjJDialogContentPane.setLayout(null); 303 getJDialogContentPane().add(getPass1Panel(), getPass1Panel().getName()); 304 getJDialogContentPane().add(getPass3Panel(), getPass3Panel().getName()); 305 getJDialogContentPane().add(getPass2Panel(), getPass2Panel().getName()); 306 getJDialogContentPane().add(getPass1Button(), getPass1Button().getName()); 307 getJDialogContentPane().add(getPass2Button(), getPass2Button().getName()); 308 getJDialogContentPane().add(getPass3Button(), getPass3Button().getName()); 309 getJDialogContentPane().add(getFlushButton(), getFlushButton().getName()); 310 // user code begin {1} 311 // user code end 312 } catch (final Throwable ivjExc) { 313 // user code begin {2} 314 // user code end 315 handleException(ivjExc); 316 } 317 } 318 return ivjJDialogContentPane; 319 } 320 321 /** Machine-generated. */ 322 private JButton getPass1Button() { 323 if (ivjPass1Button == null) { 324 try { 325 ivjPass1Button = new JButton(); 326 ivjPass1Button.setName("Pass1Button"); 327 ivjPass1Button.setText("Pass1: Verify binary layout of .class file"); 328 ivjPass1Button.setBackground(SystemColor.controlHighlight); 329 ivjPass1Button.setBounds(100, 40, 300, 30); 330 ivjPass1Button.setActionCommand("Button1"); 331 // user code begin {1} 332 // user code end 333 } catch (final Throwable ivjExc) { 334 // user code begin {2} 335 // user code end 336 handleException(ivjExc); 337 } 338 } 339 return ivjPass1Button; 340 } 341 342 /** Machine-generated. */ 343 private JPanel getPass1Panel() { 344 if (ivjPass1Panel == null) { 345 try { 346 ivjPass1Panel = new JPanel(); 347 ivjPass1Panel.setName("Pass1Panel"); 348 ivjPass1Panel.setLayout(null); 349 ivjPass1Panel.setBackground(SystemColor.controlShadow); 350 ivjPass1Panel.setBounds(30, 30, 50, 50); 351 // user code begin {1} 352 // user code end 353 } catch (final Throwable ivjExc) { 354 // user code begin {2} 355 // user code end 356 handleException(ivjExc); 357 } 358 } 359 return ivjPass1Panel; 360 } 361 362 /** Machine-generated. */ 363 private JButton getPass2Button() { 364 if (ivjPass2Button == null) { 365 try { 366 ivjPass2Button = new JButton(); 367 ivjPass2Button.setName("Pass2Button"); 368 ivjPass2Button.setText("Pass 2: Verify static .class file constraints"); 369 ivjPass2Button.setBackground(SystemColor.controlHighlight); 370 ivjPass2Button.setBounds(100, 100, 300, 30); 371 ivjPass2Button.setActionCommand("Button2"); 372 // user code begin {1} 373 // user code end 374 } catch (final Throwable ivjExc) { 375 // user code begin {2} 376 // user code end 377 handleException(ivjExc); 378 } 379 } 380 return ivjPass2Button; 381 } 382 383 /** Machine-generated. */ 384 private JPanel getPass2Panel() { 385 if (ivjPass2Panel == null) { 386 try { 387 ivjPass2Panel = new JPanel(); 388 ivjPass2Panel.setName("Pass2Panel"); 389 ivjPass2Panel.setLayout(null); 390 ivjPass2Panel.setBackground(SystemColor.controlShadow); 391 ivjPass2Panel.setBounds(30, 90, 50, 50); 392 // user code begin {1} 393 // user code end 394 } catch (final Throwable ivjExc) { 395 // user code begin {2} 396 // user code end 397 handleException(ivjExc); 398 } 399 } 400 return ivjPass2Panel; 401 } 402 403 /** Machine-generated. */ 404 private JButton getPass3Button() { 405 if (ivjPass3Button == null) { 406 try { 407 ivjPass3Button = new JButton(); 408 ivjPass3Button.setName("Pass3Button"); 409 ivjPass3Button.setText("Passes 3a+3b: Verify code arrays"); 410 ivjPass3Button.setBackground(SystemColor.controlHighlight); 411 ivjPass3Button.setBounds(100, 160, 300, 30); 412 ivjPass3Button.setActionCommand("Button2"); 413 // user code begin {1} 414 // user code end 415 } catch (final Throwable ivjExc) { 416 // user code begin {2} 417 // user code end 418 handleException(ivjExc); 419 } 420 } 421 return ivjPass3Button; 422 } 423 424 /** Machine-generated. */ 425 private JPanel getPass3Panel() { 426 if (ivjPass3Panel == null) { 427 try { 428 ivjPass3Panel = new JPanel(); 429 ivjPass3Panel.setName("Pass3Panel"); 430 ivjPass3Panel.setLayout(null); 431 ivjPass3Panel.setBackground(SystemColor.controlShadow); 432 ivjPass3Panel.setBounds(30, 150, 50, 50); 433 // user code begin {1} 434 // user code end 435 } catch (final Throwable ivjExc) { 436 // user code begin {2} 437 // user code end 438 handleException(ivjExc); 439 } 440 } 441 return ivjPass3Panel; 442 } 443 444 /** Machine-generated. */ 445 private void handleException(final Throwable exception) { 446 /* Uncomment the following lines to print uncaught exceptions to stdout */ 447 System.out.println("--------- UNCAUGHT EXCEPTION ---------"); 448 exception.printStackTrace(System.out); 449 // manually added code 450 if (exception instanceof ThreadDeath) { 451 throw (ThreadDeath) exception; 452 } 453 if (exception instanceof VirtualMachineError) { 454 throw (VirtualMachineError) exception; 455 } 456 } 457 458 /** Machine-generated. */ 459 private void initConnections() { 460 // user code begin {1} 461 // user code end 462 getPass1Button().addActionListener(ivjEventHandler); 463 getPass2Button().addActionListener(ivjEventHandler); 464 getPass3Button().addActionListener(ivjEventHandler); 465 getFlushButton().addActionListener(ivjEventHandler); 466 } 467 468 /** Machine-generated. */ 469 private void initialize() { 470 try { 471 // user code begin {1} 472 // user code end 473 setName("VerifyDialog"); 474 setDefaultCloseOperation(DISPOSE_ON_CLOSE); 475 setSize(430, 280); 476 setVisible(true); 477 setModal(true); 478 setResizable(false); 479 setContentPane(getJDialogContentPane()); 480 initConnections(); 481 } catch (final Throwable ivjExc) { 482 handleException(ivjExc); 483 } 484 // user code begin {2} 485 setTitle("'" + className + "' verification - JustIce / BCEL"); 486 // user code end 487 } 488 489 /** Machine-generated. */ 490 public void pass1Button_ActionPerformed(final ActionEvent actionEvent) { 491 final Verifier v = VerifierFactory.getVerifier(className); 492 final VerificationResult vr = v.doPass1(); 493 if (vr.getStatus() == VerificationResult.VERIFIED_OK) { 494 getPass1Panel().setBackground(Color.green); 495 getPass1Panel().repaint(); 496 } 497 if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { 498 getPass1Panel().setBackground(Color.red); 499 getPass1Panel().repaint(); 500 } 501 } 502 503 /** Machine-generated. */ 504 public void pass2Button_ActionPerformed(final ActionEvent actionEvent) { 505 pass1Button_ActionPerformed(actionEvent); 506 final Verifier v = VerifierFactory.getVerifier(className); 507 final VerificationResult vr = v.doPass2(); 508 if (vr.getStatus() == VerificationResult.VERIFIED_OK) { 509 getPass2Panel().setBackground(Color.green); 510 getPass2Panel().repaint(); 511 } 512 if (vr.getStatus() == VerificationResult.VERIFIED_NOTYET) { 513 getPass2Panel().setBackground(Color.yellow); 514 getPass2Panel().repaint(); 515 } 516 if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { 517 getPass2Panel().setBackground(Color.red); 518 getPass2Panel().repaint(); 519 } 520 } 521 522 /** Machine-generated. */ 523 public void pass4Button_ActionPerformed(final ActionEvent actionEvent) { 524 pass2Button_ActionPerformed(actionEvent); 525 Color color = Color.green; 526 final Verifier v = VerifierFactory.getVerifier(className); 527 VerificationResult vr = v.doPass2(); 528 if (vr.getStatus() == VerificationResult.VERIFIED_OK) { 529 JavaClass jc = null; 530 try { 531 jc = Repository.lookupClass(className); 532 final int nr = jc.getMethods().length; 533 for (int i = 0; i < nr; i++) { 534 vr = v.doPass3b(i); 535 if (vr.getStatus() != VerificationResult.VERIFIED_OK) { 536 color = Color.red; 537 break; 538 } 539 } 540 } catch (final ClassNotFoundException ex) { 541 // FIXME: report the error 542 ex.printStackTrace(); 543 } 544 } else { 545 color = Color.yellow; 546 } 547 getPass3Panel().setBackground(color); 548 getPass3Panel().repaint(); 549 } 550}