1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package org.apache.bcel.verifier; 19 20 import java.awt.AWTEvent; 21 import java.awt.CardLayout; 22 import java.awt.Color; 23 import java.awt.Dimension; 24 import java.awt.GridLayout; 25 import java.awt.event.ActionEvent; 26 import java.awt.event.InputEvent; 27 import java.awt.event.WindowEvent; 28 import javax.swing.BorderFactory; 29 import javax.swing.JFrame; 30 import javax.swing.JList; 31 import javax.swing.JMenu; 32 import javax.swing.JMenuBar; 33 import javax.swing.JMenuItem; 34 import javax.swing.JOptionPane; 35 import javax.swing.JPanel; 36 import javax.swing.JScrollPane; 37 import javax.swing.JSplitPane; 38 import javax.swing.JTextPane; 39 import javax.swing.ListSelectionModel; 40 import javax.swing.event.ListSelectionEvent; 41 42 import org.apache.bcel.Repository; 43 import org.apache.bcel.classfile.JavaClass; 44 45 /** 46 * This class implements a machine-generated frame for use with 47 * the GraphicalVerfifier. 48 * 49 * @version $Id$ 50 * @see GraphicalVerifier 51 */ 52 public class VerifierAppFrame extends JFrame { 53 54 private static final long serialVersionUID = -542458133073307640L; 55 private static final String JUSTICE_VERSION = "JustIce by Enver Haase"; 56 57 private JPanel contentPane; 58 private final JSplitPane jSplitPane1 = new JSplitPane(); 59 private final JPanel jPanel1 = new JPanel(); 60 private final JPanel jPanel2 = new JPanel(); 61 private final JSplitPane jSplitPane2 = new JSplitPane(); 62 private final JPanel jPanel3 = new JPanel(); 63 private final JList<String> classNamesJList = new JList<>(); 64 private final GridLayout gridLayout1 = new GridLayout(); 65 private final JPanel messagesPanel = new JPanel(); 66 private final GridLayout gridLayout2 = new GridLayout(); 67 private final JMenuBar jMenuBar1 = new JMenuBar(); 68 private final JMenu jMenu1 = new JMenu(); 69 private final JScrollPane jScrollPane1 = new JScrollPane(); 70 private final JScrollPane messagesScrollPane = new JScrollPane(); 71 private final JScrollPane jScrollPane3 = new JScrollPane(); 72 private final GridLayout gridLayout4 = new GridLayout(); 73 private final JScrollPane jScrollPane4 = new JScrollPane(); 74 private final CardLayout cardLayout1 = new CardLayout(); 75 private String current_class; 76 private final GridLayout gridLayout3 = new GridLayout(); 77 private final JTextPane pass1TextPane = new JTextPane(); 78 private final JTextPane pass2TextPane = new JTextPane(); 79 private final JTextPane messagesTextPane = new JTextPane(); 80 private final JMenuItem newFileMenuItem = new JMenuItem(); 81 private final JSplitPane jSplitPane3 = new JSplitPane(); 82 private final JSplitPane jSplitPane4 = new JSplitPane(); 83 private final JScrollPane jScrollPane2 = new JScrollPane(); 84 private final JScrollPane jScrollPane5 = new JScrollPane(); 85 private final JScrollPane jScrollPane6 = new JScrollPane(); 86 private final JScrollPane jScrollPane7 = new JScrollPane(); 87 private final JList<String> pass3aJList = new JList<>(); 88 private final JList<String> pass3bJList = new JList<>(); 89 private final JTextPane pass3aTextPane = new JTextPane(); 90 private final JTextPane pass3bTextPane = new JTextPane(); 91 private final JMenu jMenu2 = new JMenu(); 92 private final JMenuItem whatisMenuItem = new JMenuItem(); 93 private final JMenuItem aboutMenuItem = new JMenuItem(); 94 95 96 /** Constructor. */ VerifierAppFrame()97 public VerifierAppFrame() { 98 enableEvents(AWTEvent.WINDOW_EVENT_MASK); 99 try { 100 jbInit(); 101 } catch (final Exception e) { 102 e.printStackTrace(); 103 } 104 } 105 106 107 /** Initizalization of the components. */ jbInit()108 private void jbInit() throws Exception { 109 //setIconImage(Toolkit.getDefaultToolkit().createImage(Frame1.class.getResource("[Ihr Symbol]"))); 110 contentPane = (JPanel) this.getContentPane(); 111 contentPane.setLayout(cardLayout1); 112 this.setJMenuBar(jMenuBar1); 113 this.setSize(new Dimension(708, 451)); 114 this.setTitle("JustIce"); 115 jPanel1.setMinimumSize(new Dimension(100, 100)); 116 jPanel1.setPreferredSize(new Dimension(100, 100)); 117 jPanel1.setLayout(gridLayout1); 118 jSplitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT); 119 jPanel2.setLayout(gridLayout2); 120 jPanel3.setMinimumSize(new Dimension(200, 100)); 121 jPanel3.setPreferredSize(new Dimension(400, 400)); 122 jPanel3.setLayout(gridLayout4); 123 messagesPanel.setMinimumSize(new Dimension(100, 100)); 124 messagesPanel.setLayout(gridLayout3); 125 jPanel2.setMinimumSize(new Dimension(200, 100)); 126 jMenu1.setText("File"); 127 jScrollPane1.getViewport().setBackground(Color.red); 128 messagesScrollPane.getViewport().setBackground(Color.red); 129 messagesScrollPane.setPreferredSize(new Dimension(10, 10)); 130 classNamesJList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { 131 132 @Override 133 public void valueChanged( final ListSelectionEvent e ) { 134 classNamesJList_valueChanged(e); 135 } 136 }); 137 classNamesJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 138 jScrollPane3.setBorder(BorderFactory.createLineBorder(Color.black)); 139 jScrollPane3.setPreferredSize(new Dimension(100, 100)); 140 gridLayout4.setRows(4); 141 gridLayout4.setColumns(1); 142 gridLayout4.setHgap(1); 143 jScrollPane4.setBorder(BorderFactory.createLineBorder(Color.black)); 144 jScrollPane4.setPreferredSize(new Dimension(100, 100)); 145 pass1TextPane.setBorder(BorderFactory.createRaisedBevelBorder()); 146 pass1TextPane.setToolTipText(""); 147 pass1TextPane.setEditable(false); 148 pass2TextPane.setBorder(BorderFactory.createRaisedBevelBorder()); 149 pass2TextPane.setEditable(false); 150 messagesTextPane.setBorder(BorderFactory.createRaisedBevelBorder()); 151 messagesTextPane.setEditable(false); 152 newFileMenuItem.setText("New..."); 153 newFileMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(78, 154 InputEvent.CTRL_MASK, true)); 155 newFileMenuItem.addActionListener(new java.awt.event.ActionListener() { 156 157 @Override 158 public void actionPerformed( final ActionEvent e ) { 159 newFileMenuItem_actionPerformed(e); 160 } 161 }); 162 pass3aTextPane.setEditable(false); 163 pass3bTextPane.setEditable(false); 164 pass3aJList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { 165 166 @Override 167 public void valueChanged( final ListSelectionEvent e ) { 168 pass3aJList_valueChanged(e); 169 } 170 }); 171 pass3bJList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { 172 173 @Override 174 public void valueChanged( final ListSelectionEvent e ) { 175 pass3bJList_valueChanged(e); 176 } 177 }); 178 jMenu2.setText("Help"); 179 whatisMenuItem.setText("What is..."); 180 whatisMenuItem.addActionListener(new java.awt.event.ActionListener() { 181 182 @Override 183 public void actionPerformed( final ActionEvent e ) { 184 whatisMenuItem_actionPerformed(e); 185 } 186 }); 187 aboutMenuItem.setText("About"); 188 aboutMenuItem.addActionListener(new java.awt.event.ActionListener() { 189 190 @Override 191 public void actionPerformed( final ActionEvent e ) { 192 aboutMenuItem_actionPerformed(e); 193 } 194 }); 195 jSplitPane2.add(messagesPanel, JSplitPane.BOTTOM); 196 messagesPanel.add(messagesScrollPane, null); 197 messagesScrollPane.getViewport().add(messagesTextPane, null); 198 jSplitPane2.add(jPanel3, JSplitPane.TOP); 199 jPanel3.add(jScrollPane3, null); 200 jScrollPane3.getViewport().add(pass1TextPane, null); 201 jPanel3.add(jScrollPane4, null); 202 jPanel3.add(jSplitPane3, null); 203 jSplitPane3.add(jScrollPane2, JSplitPane.LEFT); 204 jScrollPane2.getViewport().add(pass3aJList, null); 205 jSplitPane3.add(jScrollPane5, JSplitPane.RIGHT); 206 jScrollPane5.getViewport().add(pass3aTextPane, null); 207 jPanel3.add(jSplitPane4, null); 208 jSplitPane4.add(jScrollPane6, JSplitPane.LEFT); 209 jScrollPane6.getViewport().add(pass3bJList, null); 210 jSplitPane4.add(jScrollPane7, JSplitPane.RIGHT); 211 jScrollPane7.getViewport().add(pass3bTextPane, null); 212 jScrollPane4.getViewport().add(pass2TextPane, null); 213 jSplitPane1.add(jPanel2, JSplitPane.TOP); 214 jPanel2.add(jScrollPane1, null); 215 jSplitPane1.add(jPanel1, JSplitPane.BOTTOM); 216 jPanel1.add(jSplitPane2, null); 217 jScrollPane1.getViewport().add(classNamesJList, null); 218 jMenuBar1.add(jMenu1); 219 jMenuBar1.add(jMenu2); 220 contentPane.add(jSplitPane1, "jSplitPane1"); 221 jMenu1.add(newFileMenuItem); 222 jMenu2.add(whatisMenuItem); 223 jMenu2.add(aboutMenuItem); 224 jSplitPane2.setDividerLocation(300); 225 jSplitPane3.setDividerLocation(150); 226 jSplitPane4.setDividerLocation(150); 227 } 228 229 230 /** Overridden to stop the application on a closing window. */ 231 @Override processWindowEvent( final WindowEvent e )232 protected void processWindowEvent( final WindowEvent e ) { 233 super.processWindowEvent(e); 234 if (e.getID() == WindowEvent.WINDOW_CLOSING) { 235 System.exit(0); 236 } 237 } 238 239 classNamesJList_valueChanged( final ListSelectionEvent e )240 synchronized void classNamesJList_valueChanged( final ListSelectionEvent e ) { 241 if (e.getValueIsAdjusting()) { 242 return; 243 } 244 current_class = classNamesJList.getSelectedValue(); 245 try { 246 verify(); 247 } catch (final ClassNotFoundException ex) { 248 // FIXME: report the error using the GUI 249 ex.printStackTrace(); 250 } 251 classNamesJList.setSelectedValue(current_class, true); 252 } 253 254 verify()255 private void verify() throws ClassNotFoundException { 256 setTitle("PLEASE WAIT"); 257 final Verifier v = VerifierFactory.getVerifier(current_class); 258 v.flush(); // Don't cache the verification result for this class. 259 VerificationResult vr; 260 vr = v.doPass1(); 261 if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { 262 pass1TextPane.setText(vr.getMessage()); 263 pass1TextPane.setBackground(Color.red); 264 pass2TextPane.setText(""); 265 pass2TextPane.setBackground(Color.yellow); 266 pass3aTextPane.setText(""); 267 pass3aJList.setListData(new String[0]); 268 pass3aTextPane.setBackground(Color.yellow); 269 pass3bTextPane.setText(""); 270 pass3bJList.setListData(new String[0]); 271 pass3bTextPane.setBackground(Color.yellow); 272 } else { // Must be VERIFIED_OK, Pass 1 does not know VERIFIED_NOTYET 273 pass1TextPane.setBackground(Color.green); 274 pass1TextPane.setText(vr.getMessage()); 275 vr = v.doPass2(); 276 if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { 277 pass2TextPane.setText(vr.getMessage()); 278 pass2TextPane.setBackground(Color.red); 279 pass3aTextPane.setText(""); 280 pass3aTextPane.setBackground(Color.yellow); 281 pass3aJList.setListData(new String[0]); 282 pass3bTextPane.setText(""); 283 pass3bTextPane.setBackground(Color.yellow); 284 pass3bJList.setListData(new String[0]); 285 } else { // must be Verified_OK, because Pass1 was OK (cannot be Verified_NOTYET). 286 pass2TextPane.setText(vr.getMessage()); 287 pass2TextPane.setBackground(Color.green); 288 final JavaClass jc = Repository.lookupClass(current_class); 289 /* 290 boolean all3aok = true; 291 boolean all3bok = true; 292 String all3amsg = ""; 293 String all3bmsg = ""; 294 */ 295 final String[] methodnames = new String[jc.getMethods().length]; 296 for (int i = 0; i < jc.getMethods().length; i++) { 297 methodnames[i] = jc.getMethods()[i].toString().replace('\n', ' ').replace('\t', 298 ' '); 299 } 300 pass3aJList.setListData(methodnames); 301 pass3aJList.setSelectionInterval(0, jc.getMethods().length - 1); 302 pass3bJList.setListData(methodnames); 303 pass3bJList.setSelectionInterval(0, jc.getMethods().length - 1); 304 } 305 } 306 final String[] msgs = v.getMessages(); 307 messagesTextPane.setBackground(msgs.length == 0 ? Color.green : Color.yellow); 308 final StringBuilder allmsgs = new StringBuilder(); 309 for (int i = 0; i < msgs.length; i++) { 310 msgs[i] = msgs[i].replace('\n', ' '); 311 allmsgs.append(msgs[i]).append("\n\n"); 312 } 313 messagesTextPane.setText(allmsgs.toString()); 314 setTitle(current_class + " - " + JUSTICE_VERSION); 315 } 316 317 newFileMenuItem_actionPerformed( final ActionEvent e )318 void newFileMenuItem_actionPerformed( final ActionEvent e ) { 319 final String classname = JOptionPane 320 .showInputDialog("Please enter the fully qualified name of a class or interface to verify:"); 321 if ((classname == null) || (classname.isEmpty())) { 322 return; 323 } 324 VerifierFactory.getVerifier(classname); // let observers do the rest. 325 classNamesJList.setSelectedValue(classname, true); 326 } 327 328 pass3aJList_valueChanged( final ListSelectionEvent e )329 synchronized void pass3aJList_valueChanged( final ListSelectionEvent e ) { 330 if (e.getValueIsAdjusting()) { 331 return; 332 } 333 final Verifier v = VerifierFactory.getVerifier(current_class); 334 final StringBuilder all3amsg = new StringBuilder(); 335 boolean all3aok = true; 336 boolean rejected = false; 337 for (int i = 0; i < pass3aJList.getModel().getSize(); i++) { 338 if (pass3aJList.isSelectedIndex(i)) { 339 final VerificationResult vr = v.doPass3a(i); 340 if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { 341 all3aok = false; 342 rejected = true; 343 } 344 JavaClass jc = null; 345 try { 346 jc = Repository.lookupClass(v.getClassName()); 347 all3amsg.append("Method '").append(jc.getMethods()[i]).append("': ") 348 .append(vr.getMessage().replace('\n', ' ') ).append("\n\n"); 349 } catch (final ClassNotFoundException ex) { 350 // FIXME: handle the error 351 ex.printStackTrace(); 352 } 353 } 354 } 355 pass3aTextPane.setText(all3amsg.toString()); 356 pass3aTextPane.setBackground(all3aok ? Color.green : (rejected ? Color.red : Color.yellow)); 357 } 358 359 pass3bJList_valueChanged( final ListSelectionEvent e )360 synchronized void pass3bJList_valueChanged( final ListSelectionEvent e ) { 361 if (e.getValueIsAdjusting()) { 362 return; 363 } 364 final Verifier v = VerifierFactory.getVerifier(current_class); 365 final StringBuilder all3bmsg = new StringBuilder(); 366 boolean all3bok = true; 367 boolean rejected = false; 368 for (int i = 0; i < pass3bJList.getModel().getSize(); i++) { 369 if (pass3bJList.isSelectedIndex(i)) { 370 final VerificationResult vr = v.doPass3b(i); 371 if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { 372 all3bok = false; 373 rejected = true; 374 } 375 JavaClass jc = null; 376 try { 377 jc = Repository.lookupClass(v.getClassName()); 378 all3bmsg.append("Method '").append(jc.getMethods()[i]).append("': ") 379 .append(vr.getMessage().replace('\n', ' ')).append("\n\n"); 380 } catch (final ClassNotFoundException ex) { 381 // FIXME: handle the error 382 ex.printStackTrace(); 383 } 384 } 385 } 386 pass3bTextPane.setText(all3bmsg.toString()); 387 pass3bTextPane.setBackground(all3bok ? Color.green : (rejected ? Color.red : Color.yellow)); 388 } 389 390 aboutMenuItem_actionPerformed( final ActionEvent e )391 void aboutMenuItem_actionPerformed( final ActionEvent e ) { 392 JOptionPane 393 .showMessageDialog( 394 this, 395 "JustIce is a Java class file verifier.\n"+ 396 "It was implemented by Enver Haase in 2001, 2002.\n<http://commons.apache.org/bcel/>", 397 JUSTICE_VERSION, JOptionPane.INFORMATION_MESSAGE); 398 } 399 400 whatisMenuItem_actionPerformed( final ActionEvent e )401 void whatisMenuItem_actionPerformed( final ActionEvent e ) { 402 JOptionPane 403 .showMessageDialog( 404 this, 405 "The upper four boxes to the right reflect verification passes according to"+ 406 " The Java Virtual Machine Specification.\nThese are (in that order):"+ 407 " Pass one, Pass two, Pass three (before data flow analysis), Pass three (data flow analysis).\n"+ 408 "The bottom box to the right shows (warning) messages; warnings do not cause a class to be rejected.", 409 JUSTICE_VERSION, JOptionPane.INFORMATION_MESSAGE); 410 } 411 412 413 /** 414 * @return the classNamesJList 415 */ getClassNamesJList()416 JList<String> getClassNamesJList() { 417 return classNamesJList; 418 } 419 420 421 } 422