View Javadoc

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