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 /** 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}