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