KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > loskutov > bco > views > BytecodeOutlineView


1 /*****************************************************************************************
2  * Copyright (c) 2004 Andrei Loskutov. All rights reserved. This program and the
3  * accompanying materials are made available under the terms of the BSD License which
4  * accompanies this distribution, and is available at
5  * http://www.opensource.org/licenses/bsd-license.php Contributor: Andrei Loskutov -
6  * initial API and implementation
7  ****************************************************************************************/

8 package de.loskutov.bco.views;
9
10 import java.io.IOException JavaDoc;
11 import java.io.InputStream JavaDoc;
12 import java.util.ArrayList JavaDoc;
13 import java.util.BitSet JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.ResourceBundle JavaDoc;
19
20 import org.eclipse.core.filebuffers.FileBuffers;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.jdt.core.IJavaElement;
23 import org.eclipse.jdt.core.IType;
24 import org.eclipse.jdt.core.JavaModelException;
25 import org.eclipse.jface.action.Action;
26 import org.eclipse.jface.action.IAction;
27 import org.eclipse.jface.action.IMenuListener;
28 import org.eclipse.jface.action.IMenuManager;
29 import org.eclipse.jface.action.IToolBarManager;
30 import org.eclipse.jface.action.MenuManager;
31 import org.eclipse.jface.action.Separator;
32 import org.eclipse.jface.action.StatusLineManager;
33 import org.eclipse.jface.preference.IPreferenceStore;
34 import org.eclipse.jface.text.BadLocationException;
35 import org.eclipse.jface.text.Document;
36 import org.eclipse.jface.text.IDocument;
37 import org.eclipse.jface.text.IFindReplaceTarget;
38 import org.eclipse.jface.text.IRegion;
39 import org.eclipse.jface.text.ITextListener;
40 import org.eclipse.jface.text.ITextOperationTarget;
41 import org.eclipse.jface.text.ITextSelection;
42 import org.eclipse.jface.text.TextEvent;
43 import org.eclipse.jface.text.TextViewer;
44 import org.eclipse.jface.util.IPropertyChangeListener;
45 import org.eclipse.jface.util.PropertyChangeEvent;
46 import org.eclipse.jface.viewers.ISelection;
47 import org.eclipse.jface.viewers.ISelectionChangedListener;
48 import org.eclipse.jface.viewers.SelectionChangedEvent;
49 import org.eclipse.jface.viewers.TableViewer;
50 import org.eclipse.swt.SWT;
51 import org.eclipse.swt.custom.SashForm;
52 import org.eclipse.swt.custom.StackLayout;
53 import org.eclipse.swt.custom.StyledText;
54 import org.eclipse.swt.events.ControlEvent;
55 import org.eclipse.swt.events.ControlListener;
56 import org.eclipse.swt.events.KeyEvent;
57 import org.eclipse.swt.events.KeyListener;
58 import org.eclipse.swt.events.MouseAdapter;
59 import org.eclipse.swt.events.MouseEvent;
60 import org.eclipse.swt.events.SelectionAdapter;
61 import org.eclipse.swt.events.SelectionEvent;
62 import org.eclipse.swt.graphics.Color;
63 import org.eclipse.swt.graphics.Point;
64 import org.eclipse.swt.layout.GridData;
65 import org.eclipse.swt.layout.GridLayout;
66 import org.eclipse.swt.widgets.Composite;
67 import org.eclipse.swt.widgets.Control;
68 import org.eclipse.swt.widgets.Menu;
69 import org.eclipse.swt.widgets.Table;
70 import org.eclipse.swt.widgets.TableColumn;
71 import org.eclipse.swt.widgets.TableItem;
72 import org.eclipse.swt.widgets.Widget;
73 import org.eclipse.ui.IActionBars;
74 import org.eclipse.ui.IEditorPart;
75 import org.eclipse.ui.IEditorReference;
76 import org.eclipse.ui.ISelectionService;
77 import org.eclipse.ui.ISharedImages;
78 import org.eclipse.ui.IViewSite;
79 import org.eclipse.ui.IWorkbenchActionConstants;
80 import org.eclipse.ui.IWorkbenchPart;
81 import org.eclipse.ui.PlatformUI;
82 import org.eclipse.ui.actions.ActionFactory;
83 import org.eclipse.ui.console.actions.TextViewerAction;
84 import org.eclipse.ui.part.ViewPart;
85 import org.eclipse.ui.plugin.AbstractUIPlugin;
86 import org.eclipse.ui.texteditor.FindReplaceAction;
87 import org.eclipse.ui.texteditor.ITextEditor;
88 import org.eclipse.ui.texteditor.IUpdate;
89 import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
90
91 import de.loskutov.bco.BytecodeOutlinePlugin;
92 import de.loskutov.bco.asm.DecompiledClass;
93 import de.loskutov.bco.asm.DecompilerClassVisitor;
94 import de.loskutov.bco.preferences.BCOConstants;
95 import de.loskutov.bco.ui.EclipseUtils;
96 import de.loskutov.bco.ui.JdtUtils;
97 import de.loskutov.bco.ui.actions.DefaultToggleAction;
98
99 /**
100  * This view shows decompiled java bytecode
101  * @author Andrei
102  */

103 public class BytecodeOutlineView extends ViewPart {
104     // orientations
105
static final int VIEW_ORIENTATION_VERTICAL = 0;
106     static final int VIEW_ORIENTATION_HORIZONTAL = 1;
107     static final int VIEW_ORIENTATION_AUTOMATIC = 2;
108
109     /**
110      * The current orientation; either <code>VIEW_ORIENTATION_HORIZONTAL</code>
111      * <code>VIEW_ORIENTATION_VERTICAL</code>, or <code>VIEW_ORIENTATION_AUTOMATIC</code>.
112      */

113     int orientation = VIEW_ORIENTATION_AUTOMATIC;
114     /**
115      * The current orientation; either <code>VIEW_ORIENTATION_HORIZONTAL</code>
116      * <code>VIEW_ORIENTATION_VERTICAL</code>.
117      */

118     private int currentOrientation;
119
120     protected ToggleOrientationAction[] toggleOrientationActions;
121
122     protected BitSet JavaDoc modes;
123
124     protected boolean inputChanged;
125     protected boolean bufferIsDirty;
126
127     private boolean isEnabled;
128     private boolean isActive;
129     private boolean isVisible;
130
131     protected Composite stackComposite;
132     protected StyledText textControl;
133     protected TextViewer textViewer;
134     protected SashForm verifyControl;
135     protected SashForm stackAndLvt;
136     protected Table tableControl;
137     protected TableViewer tableControlViewer;
138     protected Table stackTable;
139     protected Table lvtTable;
140
141     protected ITextEditor javaEditor;
142     private IJavaElement javaInput;
143     protected IJavaElement lastChildElement;
144     protected ITextSelection currentSelection;
145     protected EditorListener editorListener;
146     protected Action selectionChangedAction;
147     protected Action refreshVarsAndStackAction;
148     protected Action linkWithEditorAction;
149     protected Action showSelectedOnlyAction;
150     protected Action setRawModeAction;
151     protected Action toggleASMifierModeAction;
152     protected Action hideLineInfoAction;
153     protected Action hideLocalsAction;
154     protected Action hideStackMapAction;
155     protected Action expandStackMapAction;
156     protected Action toggleVerifierAction;
157     protected StatusLineManager statusLineManager;
158     protected BCOViewSelectionProvider viewSelectionProvider;
159
160     protected Color errorColor;
161
162     private DecompiledClass lastDecompiledResult;
163
164     protected Map JavaDoc globalActions;
165     protected List JavaDoc selectionActions;
166     private MenuManager contextMenuManager;
167     /** global class info, without current selection status */
168     protected String JavaDoc currentStatusMessage;
169     protected boolean hasAnalyzerError;
170     /*
171      * I don't know how to update the state of toolbar and menu managers because it seems
172      * that if we toggle the action state internally (not by user click) then either the
173      * managers or contribution items or whatever holds the old state of checked action.
174      * This flag is a workaround and allows us restore the state after internal toggling.
175      */

176     private boolean restoreVerify;
177     private static final String JavaDoc NLS_PREFIX = "BytecodeOutlineView.";
178
179     // updates the find replace action if the document length is > 0
180
private ITextListener textListener;
181
182     // see org.eclipse.ui.console.TextConsolePage for the reason to do this ;)
183
private ISelectionChangedListener textSelectionListener;
184     private Control statusControl;
185
186     // ------------------------------------------------------------------------
187

188     protected void setJavaInput(IJavaElement javaInput) {
189         this.javaInput = javaInput;
190         inputChanged = true;
191     }
192
193     /**
194      * The constructor.
195      */

196     public BytecodeOutlineView() {
197         super();
198         modes = new BitSet JavaDoc();
199         globalActions = new HashMap JavaDoc();
200         selectionActions = new ArrayList JavaDoc();
201     }
202
203     // ------------------------------------------------------------------------
204

205     /**
206      * Is this view state changes depending on editor changes?
207      * @return true if linked with editor
208      */

209     protected boolean isLinkedWithEditor() {
210         return modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR);
211     }
212
213     /**
214      * Are actions on toolbar active?
215      * @return Returns the isEnabled.
216      */

217     private boolean isEnabled() {
218         return isEnabled;
219     }
220
221     private void setEnabled(boolean on) {
222         this.isEnabled = on;
223         if (tableControl != null && !tableControl.isDisposed()) {
224             tableControl.setEnabled(on);
225         }
226         if(stackTable != null && !stackTable.isDisposed()){
227             stackTable.setEnabled(on);
228         }
229         if(lvtTable != null && !lvtTable.isDisposed()){
230             lvtTable.setEnabled(on);
231         }
232         showSelectedOnlyAction.setEnabled(on);
233         linkWithEditorAction.setEnabled(on);
234         selectionChangedAction.setEnabled(on);
235         toggleVerifierAction.setEnabled(on);
236         hideLocalsAction.setEnabled(on);
237         hideLineInfoAction.setEnabled(on);
238         hideStackMapAction.setEnabled(on);
239         toggleASMifierModeAction.setEnabled(on);
240         setRawModeAction.setEnabled(on && !toggleASMifierModeAction.isChecked());
241         boolean showAnalyzer = on && toggleVerifierAction.isChecked();
242         for (int i = 0; i < toggleOrientationActions.length; ++i) {
243             toggleOrientationActions[i].setEnabled(showAnalyzer);
244         }
245     }
246
247     /**
248      * Is this view monitoring workspace changes?
249      * @return Returns the isActive.
250      */

251     private boolean isActive() {
252         return isActive;
253     }
254
255     /**
256      * @param bufferIsDirty The bufferIsDirty to set.
257      */

258     private void setBufferIsDirty(boolean bufferIsDirty) {
259         this.bufferIsDirty = bufferIsDirty;
260     }
261
262     private void setInput(ITextEditor editor) {
263         javaEditor = null;
264         setJavaInput(null);
265         lastDecompiledResult = null;
266         if (editor != null) {
267             IJavaElement javaElem = EclipseUtils.getJavaInput(editor);
268             if (javaElem == null) {
269                 return;
270             }
271             setJavaInput(javaElem);
272             javaEditor = editor;
273
274             checkVerifyMode();
275
276             updateSelection(EclipseUtils.getSelection(javaEditor
277                 .getSelectionProvider()));
278             setBufferIsDirty(editor.isDirty());
279         }
280     }
281
282     private void checkVerifyMode() {
283         boolean aoi = JdtUtils.isAbstractOrInterface(javaInput);
284
285         if(!toggleVerifierAction.isChecked()){
286             // deactivate verify button, but only if *not* in verify mode
287
toggleVerifierAction.setEnabled(!aoi);
288             restoreVerify = false;
289         } else {
290             if(aoi){
291                 // swith verify mode off, because it is not applicable to selected element
292
inputChanged = true;
293                 toggleVerifyMode(getViewSite().getActionBars().getMenuManager(), false);
294                 // remember last state, to match the state of the toolbars and menus
295
restoreVerify = true;
296             } else {
297                 if(restoreVerify) {
298                     inputChanged = true;
299                     toggleVerifierAction.setEnabled(true);
300                     toggleVerifyMode(getViewSite().getActionBars().getMenuManager(), true);
301                 }
302                 restoreVerify = false;
303             }
304         }
305     }
306
307     private boolean updateSelection(ITextSelection sel) {
308         if (sel != null
309             && (sel.equals(currentSelection)
310                 || (currentSelection != null &&
311                  sel.getStartLine() == currentSelection
312                 .getStartLine() && sel.getEndLine() == currentSelection
313                 .getEndLine()))) {
314
315             /* getStartLine/getEndLine is probably not sensitive enough - but
316              * in case of java classes/methods which fits in one selection but
317              * not in the other, then I think we can ignore them here - this is
318              * not the 99% of use cases.
319              */

320             return false;
321         }
322
323         currentSelection = sel;
324         return true;
325     }
326
327     // ------------------------------------------------------------------------
328

329     /**
330      * @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite)
331      */

332     public void init(IViewSite site) {
333         super.setSite(site);
334         if (editorListener == null) {
335             editorListener = new EditorListener(this);
336             getSite().getWorkbenchWindow().getPartService().addPartListener(
337                 editorListener);
338         }
339     }
340
341     /**
342      * This is a callback that will allow us to create the viewer and initialize it.
343      * @param parent
344      */

345     public void createPartControl(Composite parent) {
346         errorColor = parent.getDisplay().getSystemColor(SWT.COLOR_RED);
347         parent.addControlListener(new ControlListener() {
348             public void controlMoved(ControlEvent e) {
349                 //
350
}
351             public void controlResized(ControlEvent e) {
352                 computeOrientation();
353             }
354         });
355
356         GridLayout parentLayout = new GridLayout();
357         parentLayout.numColumns = 1;
358         parentLayout.marginBottom = -5;
359         parentLayout.marginTop = -5;
360         parentLayout.marginLeft = -5;
361         parentLayout.marginRight = -5;
362
363         parent.setLayout(parentLayout);
364
365         stackComposite = new Composite(parent, SWT.NONE);
366         stackComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
367         stackComposite.setLayout(new StackLayout());
368
369         statusLineManager = new StatusLineManager();
370         statusControl = statusLineManager.createControl(parent, SWT.NONE);
371         statusControl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
372
373         createTextControl();
374
375         createTextContextMenu();
376
377         createVerifyControl();
378
379         ((StackLayout) stackComposite.getLayout()).topControl = textControl;
380
381         createSelectionProvider();
382
383         initModes();
384
385         createToolbarActions();
386
387         setEnabled(false);
388     }
389
390     private void initModes() {
391         IPreferenceStore store = BytecodeOutlinePlugin.getDefault().getPreferenceStore();
392         modes.set(BCOConstants.F_LINK_VIEW_TO_EDITOR, store.getBoolean(BCOConstants.LINK_VIEW_TO_EDITOR));
393         modes.set(BCOConstants.F_SHOW_ONLY_SELECTED_ELEMENT, store.getBoolean(BCOConstants.SHOW_ONLY_SELECTED_ELEMENT));
394         modes.set(BCOConstants.F_SHOW_RAW_BYTECODE, store.getBoolean(BCOConstants.SHOW_RAW_BYTECODE));
395         modes.set(BCOConstants.F_SHOW_LINE_INFO, store.getBoolean(BCOConstants.SHOW_LINE_INFO));
396         modes.set(BCOConstants.F_SHOW_VARIABLES, store.getBoolean(BCOConstants.SHOW_VARIABLES));
397         modes.set(BCOConstants.F_SHOW_STACKMAP, store.getBoolean(BCOConstants.SHOW_STACKMAP));
398         modes.set(BCOConstants.F_EXPAND_STACKMAP, store.getBoolean(BCOConstants.EXPAND_STACKMAP));
399         modes.set(BCOConstants.F_SHOW_ASMIFIER_CODE, store.getBoolean(BCOConstants.SHOW_ASMIFIER_CODE));
400         modes.set(BCOConstants.F_SHOW_ANALYZER, store.getBoolean(BCOConstants.SHOW_ANALYZER));
401     }
402
403     private void createToolbarActions() {
404         createTextActions();
405
406         final IActionBars bars = getViewSite().getActionBars();
407         final IToolBarManager tmanager = bars.getToolBarManager();
408         final IMenuManager mmanager = bars.getMenuManager();
409
410         selectionChangedAction = new Action() {
411             public void run() {
412                 Point selection = textControl.getSelection();
413                 setSelectionInJavaEditor(selection);
414             }
415         };
416
417         refreshVarsAndStackAction = new Action() {
418             public void run() {
419                 int decompiledLine = tableControl.getSelectionIndex();
420                 updateVerifierControl(decompiledLine);
421             }
422         };
423
424         linkWithEditorAction = new DefaultToggleAction(BCOConstants.LINK_VIEW_TO_EDITOR,
425             new IPropertyChangeListener() {
426                 public void propertyChange(PropertyChangeEvent event) {
427                     if (IAction.CHECKED.equals(event.getProperty())) {
428                         modes.set(BCOConstants.F_LINK_VIEW_TO_EDITOR, Boolean.TRUE == event.getNewValue());
429                         if(modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR)) {
430                             showSelectedOnlyAction.setEnabled(true);
431                             toggleVerifierAction.setEnabled(true);
432                             hideLineInfoAction.setEnabled(true);
433                             hideLocalsAction.setEnabled(true);
434                             toggleASMifierModeAction.setEnabled(true);
435                             if(!toggleASMifierModeAction.isChecked()) {
436                                 setRawModeAction.setEnabled(true);
437                             }
438                             checkOpenEditors(true);
439                             // refreshView();
440
}
441                     }
442                 }
443             });
444
445         showSelectedOnlyAction = new DefaultToggleAction(BCOConstants.SHOW_ONLY_SELECTED_ELEMENT,
446             new IPropertyChangeListener() {
447                 public void propertyChange(PropertyChangeEvent event) {
448                     if (IAction.CHECKED.equals(event.getProperty())) {
449                         modes.set(BCOConstants.F_SHOW_ONLY_SELECTED_ELEMENT, Boolean.TRUE == event.getNewValue());
450                         inputChanged = true;
451                         refreshView();
452                     }
453                 }
454             });
455
456         setRawModeAction = new DefaultToggleAction(BCOConstants.SHOW_RAW_BYTECODE,
457             new IPropertyChangeListener() {
458                 public void propertyChange(PropertyChangeEvent event) {
459                     if (IAction.CHECKED.equals(event.getProperty())) {
460                         modes.set(BCOConstants.F_SHOW_RAW_BYTECODE, Boolean.TRUE == event.getNewValue());
461                         inputChanged = true;
462                         refreshView();
463                     }
464                 }
465             });
466
467         hideLineInfoAction = new DefaultToggleAction(BCOConstants.SHOW_LINE_INFO,
468             new IPropertyChangeListener() {
469                 public void propertyChange(PropertyChangeEvent event) {
470                     if (IAction.CHECKED.equals(event.getProperty())) {
471                         modes.set(BCOConstants.F_SHOW_LINE_INFO, Boolean.TRUE == event.getNewValue());
472                         inputChanged = true;
473                         refreshView();
474                     }
475                 }
476             });
477
478         hideLocalsAction = new DefaultToggleAction(BCOConstants.SHOW_VARIABLES,
479             new IPropertyChangeListener() {
480                 public void propertyChange(PropertyChangeEvent event) {
481                     if (IAction.CHECKED.equals(event.getProperty())) {
482                         modes.set(BCOConstants.F_SHOW_VARIABLES, Boolean.TRUE == event.getNewValue());
483                         inputChanged = true;
484                         refreshView();
485                     }
486                 }
487             });
488
489         hideStackMapAction = new DefaultToggleAction(BCOConstants.SHOW_STACKMAP,
490             new IPropertyChangeListener() {
491                 public void propertyChange(PropertyChangeEvent event) {
492                     if (IAction.CHECKED.equals(event.getProperty())) {
493                         modes.set(BCOConstants.F_SHOW_STACKMAP, Boolean.TRUE == event.getNewValue());
494                         inputChanged = true;
495                         refreshView();
496                     }
497                 }
498             });
499
500         expandStackMapAction = new DefaultToggleAction(BCOConstants.EXPAND_STACKMAP,
501             new IPropertyChangeListener() {
502             public void propertyChange(PropertyChangeEvent event) {
503                 if (IAction.CHECKED.equals(event.getProperty())) {
504                     modes.set(BCOConstants.F_EXPAND_STACKMAP, Boolean.TRUE == event.getNewValue());
505                     inputChanged = true;
506                     refreshView();
507                 }
508             }
509         });
510
511         toggleASMifierModeAction = new DefaultToggleAction(BCOConstants.SHOW_ASMIFIER_CODE,
512             new IPropertyChangeListener() {
513                 public void propertyChange(PropertyChangeEvent event) {
514                     if (IAction.CHECKED.equals(event.getProperty())) {
515                         boolean checked = Boolean.TRUE == event.getNewValue();
516                         modes.set(BCOConstants.F_SHOW_ASMIFIER_CODE, checked);
517                         if(checked) {
518                             modes.set(BCOConstants.F_SHOW_RAW_BYTECODE, true);
519                             setRawModeAction.setEnabled(false);
520                         } else {
521                             setRawModeAction.setEnabled(true);
522                         }
523                         inputChanged = true;
524                         refreshView();
525                     }
526                 }
527             });
528
529         toggleVerifierAction = new DefaultToggleAction(BCOConstants.SHOW_ANALYZER,
530             new IPropertyChangeListener() {
531                 public void propertyChange(PropertyChangeEvent event) {
532                     if(IAction.CHECKED.equals(event.getProperty())) {
533                         boolean showAnalyzer = Boolean.TRUE == event.getNewValue();
534                         toggleVerifyMode(mmanager, showAnalyzer);
535                         inputChanged = true;
536                         refreshView();
537                     }
538                 }
539             });
540
541         mmanager.add(linkWithEditorAction);
542         mmanager.add(showSelectedOnlyAction);
543         mmanager.add(setRawModeAction);
544         mmanager.add(hideLineInfoAction);
545         mmanager.add(hideLocalsAction);
546         mmanager.add(hideStackMapAction);
547         mmanager.add(expandStackMapAction);
548         mmanager.add(toggleASMifierModeAction);
549         mmanager.add(toggleVerifierAction);
550
551         mmanager.add(new Separator());
552
553         toggleOrientationActions = new ToggleOrientationAction[] {
554             new ToggleOrientationAction(this, VIEW_ORIENTATION_VERTICAL),
555             new ToggleOrientationAction(this, VIEW_ORIENTATION_HORIZONTAL),
556             new ToggleOrientationAction(this, VIEW_ORIENTATION_AUTOMATIC)};
557         for (int i = 0; i < toggleOrientationActions.length; ++i) {
558             mmanager.add(toggleOrientationActions[i]);
559         }
560
561         tmanager.add(linkWithEditorAction);
562         tmanager.add(showSelectedOnlyAction);
563         tmanager.add(setRawModeAction);
564         // tmanager.add(hideLineInfoAction);
565
// tmanager.add(hideLocalsAction);
566
tmanager.add(toggleASMifierModeAction);
567         tmanager.add(toggleVerifierAction);
568     }
569
570     private void createVerifyControl() {
571         verifyControl = new SashForm(stackComposite, SWT.VERTICAL);
572
573         tableControl = new Table(verifyControl, SWT.SINGLE | SWT.FULL_SELECTION);
574         tableControlViewer = new TableViewer(tableControl);
575
576         new TableColumn(tableControl, SWT.LEFT).setText( BytecodeOutlinePlugin.getResourceString(NLS_PREFIX + "lvt.header"));
577         new TableColumn(tableControl, SWT.LEFT).setText( BytecodeOutlinePlugin.getResourceString(NLS_PREFIX + "stack.header"));
578         new TableColumn(tableControl, SWT.LEFT);
579         new TableColumn(tableControl, SWT.LEFT);
580         tableControl.setLinesVisible(false);
581         tableControl.setHeaderVisible(true);
582
583
584         stackAndLvt = new SashForm(verifyControl, SWT.HORIZONTAL);
585
586         lvtTable = new Table( stackAndLvt, SWT.SINGLE | SWT.FULL_SELECTION);
587         lvtTable.setLinesVisible(false);
588         lvtTable.setHeaderVisible(true);
589
590         new TableColumn( lvtTable, SWT.LEFT).setText( "#");
591         new TableColumn( lvtTable, SWT.LEFT).setText( "Var Type");
592         new TableColumn( lvtTable, SWT.LEFT).setText( "Name");
593
594         stackTable = new Table( stackAndLvt, SWT.SINGLE | SWT.FULL_SELECTION);
595         stackTable.setLinesVisible(false);
596         stackTable.setHeaderVisible(true);
597         new TableColumn( stackTable, SWT.LEFT).setText( "#");
598         new TableColumn( stackTable, SWT.LEFT).setText( "Stack Type");
599
600         stackAndLvt.setWeights(new int[]{50, 50});
601
602
603         verifyControl.setWeights(new int[]{75, 25});
604
605
606
607
608         tableControl.addSelectionListener(new SelectionAdapter() {
609             public void widgetSelected(SelectionEvent e) {
610                 if (modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR)) {
611                     selectionChangedAction.run();
612                 }
613                 refreshVarsAndStackAction.run();
614             }
615         });
616
617     }
618
619     private void createSelectionProvider() {
620         viewSelectionProvider = new BCOViewSelectionProvider();
621         viewSelectionProvider.registerSelectionProvider(textViewer);
622         viewSelectionProvider.registerSelectionProvider(tableControlViewer);
623
624         // initially selection provider is the textControl, but this could be changed by user
625
// to the tableControl, if bco will be switched to the verify mode
626
viewSelectionProvider.setCurrentSelectionProvider(textViewer);
627         getSite().setSelectionProvider(viewSelectionProvider);
628     }
629
630     /**
631      * create/register context menu on text control
632      */

633     private void createTextContextMenu() {
634         String JavaDoc id = "de.loskutov.bco.views.BytecodeOutlineView#ContextMenu"; //$NON-NLS-1$
635
contextMenuManager= new MenuManager("#ContextMenu", id); //$NON-NLS-1$//$NON-NLS-2$
636
contextMenuManager.setRemoveAllWhenShown(true);
637         contextMenuManager.addMenuListener(new IMenuListener() {
638             public void menuAboutToShow(IMenuManager m) {
639                 contextMenuAboutToShow(m);
640             }
641         });
642         Menu menu = contextMenuManager.createContextMenu(textControl);
643         textControl.setMenu(menu);
644
645         getSite().registerContextMenu(id, contextMenuManager, textViewer); //$NON-NLS-1$
646
}
647
648     private void createTextControl() {
649         textViewer = new TextViewer(stackComposite, SWT.H_SCROLL | SWT.V_SCROLL);
650         textViewer.setEditable(false);
651         //textViewer.setHoverControlCreator(null)
652

653         textControl = textViewer.getTextWidget();
654         IDocument document= new Document("");
655         textViewer.setDocument(document);
656
657         textSelectionListener =
658             new ISelectionChangedListener() {
659             public void selectionChanged(SelectionChangedEvent event) {
660                 // Updates selection dependent actions like find/copy.
661
Iterator JavaDoc iterator= selectionActions.iterator();
662                 while (iterator.hasNext()) {
663                     updateAction((String JavaDoc)iterator.next());
664                 }
665             }
666         };
667
668         textListener = new ITextListener() {
669             public void textChanged(TextEvent event) {
670                 IUpdate findReplace = (IUpdate) globalActions
671                     .get(ActionFactory.FIND.getId());
672                 if (findReplace != null) {
673                     findReplace.update();
674                 }
675             }
676         };
677
678         textViewer.getSelectionProvider().addSelectionChangedListener(
679             textSelectionListener);
680         textViewer.addTextListener(textListener);
681
682         textControl.addMouseListener(new MouseAdapter() {
683             public void mouseDown(MouseEvent e) {
684                 if (modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR)) {
685                     selectionChangedAction.run();
686                 }
687             }
688         });
689
690         textControl.addKeyListener(new KeyListener(){
691             public void keyPressed(KeyEvent e) {
692                 // ignored
693
}
694             public void keyReleased(KeyEvent e) {
695                 if (modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR)) {
696                     selectionChangedAction.run();
697                 }
698             }
699         });
700     }
701
702     /**
703      * @see org.eclipse.ui.IWorkbenchPart#dispose()
704      */

705     public void dispose() {
706         deActivateView();
707         if (editorListener != null) {
708             getSite().getWorkbenchWindow().getPartService().removePartListener(
709                 editorListener);
710             editorListener.dispose();
711             editorListener = null;
712         }
713
714         if (contextMenuManager != null) {
715             contextMenuManager.dispose();
716         }
717
718         selectionActions.clear();
719         globalActions.clear();
720
721         textViewer.getSelectionProvider().removeSelectionChangedListener(
722             textSelectionListener);
723         textViewer.removeTextListener(textListener);
724         textViewer = null;
725         viewSelectionProvider = null;
726
727         if (textControl != null) {
728             textControl.dispose();
729             textControl = null;
730         }
731         if (verifyControl != null) {
732             verifyControl.dispose();
733             verifyControl = null;
734             tableControl = null;
735             stackTable = null;
736             lvtTable = null;
737             tableControlViewer = null;
738         }
739         currentSelection = null;
740         javaEditor = null;
741         setJavaInput(null);
742         lastChildElement = null;
743         linkWithEditorAction = null;
744         selectionChangedAction = null;
745         refreshVarsAndStackAction = null;
746         showSelectedOnlyAction = null;
747         setRawModeAction = null;
748         toggleASMifierModeAction = null;
749         hideLineInfoAction = null;
750         hideLocalsAction = null;
751         hideStackMapAction = null;
752         expandStackMapAction = null;
753         toggleVerifierAction = null;
754         lastDecompiledResult = null;
755         super.dispose();
756     }
757
758
759     /**
760      * Fill the context menu
761      *
762      * @param menuManager menu
763      */

764     protected void contextMenuAboutToShow(IMenuManager menuManager) {
765         IDocument doc= textViewer.getDocument();
766         if (doc == null) {
767             return;
768         }
769
770         menuManager.add((IAction)globalActions.get(ActionFactory.COPY.getId()));
771         menuManager.add((IAction)globalActions.get(ActionFactory.SELECT_ALL.getId()));
772
773         menuManager.add(new Separator("FIND")); //$NON-NLS-1$
774
menuManager.add((IAction)globalActions.get(ActionFactory.FIND.getId()));
775
776         menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
777     }
778
779     // -----------------------------------------------------------------------
780

781     /**
782      * Passing the focus request to the viewer's control.
783      */

784     public void setFocus() {
785         if (!modes.get(BCOConstants.F_SHOW_ANALYZER)) {
786             if (textViewer != null) {
787                 textViewer.getTextWidget().setFocus();
788             }
789         } else {
790             if (tableControl != null) {
791                 tableControl.setFocus();
792             }
793         }
794     }
795
796     protected void handleBufferIsDirty(boolean isDirty) {
797         if (!modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR) || !isActive()) {
798             return;
799         }
800         if (isDirty) {
801             setBufferIsDirty(isDirty);
802         } else {
803             if (!bufferIsDirty) {
804                 // second time calling with same argument -
805
// cause new bytecode should be written now
806
inputChanged = true;
807                 refreshView();
808             } else {
809                 // first time - set the flag only - cause
810
// bytecode is not yet written
811
setBufferIsDirty(false);
812             }
813         }
814     }
815
816     protected void handlePartHidden(IWorkbenchPart part) {
817         if (!modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR)) {
818             return;
819         }
820         if (this == part) {
821             isVisible = false;
822             deActivateView();
823         } else if (isActive() && (part instanceof IEditorPart)) {
824             // check if at least one editor is open
825
checkOpenEditors(false);
826         }
827     }
828
829     protected void handlePartVisible(IWorkbenchPart part) {
830         if (!modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR)) {
831             return;
832         }
833         if (this == part) {
834             if (isVisible) {
835                 return;
836             }
837             isVisible = true;
838             // check if java editor is already open
839
IEditorPart activeEditor = EclipseUtils.getActiveEditor();
840             if (!(activeEditor instanceof ITextEditor)) {
841                 // start monitoring again, even if current editor is not
842
// supported - but we at front now
843
activateView();
844                 return;
845             }
846             part = activeEditor;
847             // continue with setting input
848
}
849         if (isVisible && part instanceof ITextEditor) {
850             if (isActive() && part == javaEditor) {
851                 return;
852             }
853             activateView();
854             setEnabled(true);
855             setInput((ITextEditor) part);
856             refreshView();
857         } else if (part instanceof IEditorPart) {
858             if (isActive()) {
859                 deActivateView();
860             }
861         }
862     }
863
864     protected void handleSelectionChanged(IWorkbenchPart part,
865         ISelection selection) {
866         if (!modes.get(BCOConstants.F_LINK_VIEW_TO_EDITOR) || !isActive() || !isVisible
867             || !(part instanceof IEditorPart)) {
868             return;
869         }
870         if (!(part instanceof ITextEditor)) {
871             deActivateView();
872             return;
873         }
874         if (!isEnabled()) {
875             setEnabled(true);
876         }
877         if (part != javaEditor) {
878             setInput((ITextEditor) part);
879         } else {
880             if( ! updateSelection((ITextSelection) selection)){
881                 return;
882             }
883         }
884         refreshView();
885     }
886
887     /**
888      * Does nothing if view is already active
889      */

890     private void activateView() {
891         if (isActive()) {
892             return;
893         }
894         isActive = true;
895         getSite().getWorkbenchWindow().getSelectionService()
896             .addPostSelectionListener(editorListener);
897         FileBuffers.getTextFileBufferManager().addFileBufferListener(
898             editorListener);
899     }
900
901     /**
902      * Does nothing if view is already deactivated
903      */

904     private void deActivateView() {
905         if (!isActive()) {
906             return;
907         }
908         setEnabled(false);
909         if (editorListener != null) {
910             ISelectionService service = getSite().getWorkbenchWindow()
911                 .getSelectionService();
912             if(service != null){
913                 service.removePostSelectionListener(editorListener);
914             }
915             FileBuffers.getTextFileBufferManager().removeFileBufferListener(
916                 editorListener);
917
918         }
919         if (textViewer != null && textViewer.getTextWidget() != null
920             && !textViewer.getTextWidget().isDisposed()) {
921             IDocument document= new Document("");
922             textViewer.setDocument(document);
923         }
924         if (tableControl != null && !tableControl.isDisposed()) {
925             setVerifyTableItems(null);
926         }
927         /*
928         if(stackControl != null && !stackControl.isDisposed()){
929             stackControl.setText("");
930         }
931         if(lvtControl != null && !lvtControl.isDisposed()){
932             lvtControl.setText("");
933         }
934         */

935         if(stackTable != null && !stackTable.isDisposed()){
936             stackTable.removeAll();
937         }
938         if(lvtTable != null && !lvtTable.isDisposed()){
939             lvtTable.removeAll();
940         }
941         if(statusControl != null && !statusControl.isDisposed() ){
942             updateStatus(null, -1);
943         }
944         currentSelection = null;
945         lastDecompiledResult = null;
946         javaEditor = null;
947         setJavaInput(null);
948         lastChildElement = null;
949         setBufferIsDirty(false);
950         isActive = false;
951     }
952
953     protected void refreshView() {
954         if (!isActive()) {
955             return;
956         }
957
958         IJavaElement childEl = getCurrentJavaElement();
959         if(childEl == null && javaInput == null){
960             setInput(javaEditor);
961             childEl = javaInput;
962         }
963
964         // after getCurrentJavaElement() call it is possible that java type is disappear
965
// because corresponding type is not more exist in model
966
if (javaInput == null) {
967             deActivateView();
968             return;
969         }
970
971         boolean clearOutput = false;
972
973         if (inputChanged || isSelectedElementChanged(childEl)) {
974
975             DecompiledClass result = decompileBytecode(childEl);
976             if (result == null) {
977                 clearOutput = true;
978             } else {
979                 if (modes.get(BCOConstants.F_SHOW_ANALYZER)
980                     && !result.isAbstractOrInterface()) {
981                     refreshVerifyView(result);
982                 } else {
983                     toggleVerifierAction.setEnabled(!result.isAbstractOrInterface());
984                     refreshTextView(result);
985                 }
986             }
987             lastDecompiledResult = result;
988         } else if (childEl == null
989             && modes.get(BCOConstants.F_SHOW_ONLY_SELECTED_ELEMENT)) {
990             clearOutput = true;
991         }
992
993         lastChildElement = childEl;
994         if(clearOutput){
995             if (!modes.get(BCOConstants.F_SHOW_ANALYZER)) {
996                 IDocument document= new Document("");
997                 textViewer.setDocument(document);
998             } else {
999                 setVerifyTableItems(null);
1000            }
1001        }
1002        setSelectionInBytecodeView();
1003        inputChanged = false;
1004    }
1005
1006    private void refreshTextView(DecompiledClass result) {
1007        IDocument document= new Document(result.getText());
1008        textViewer.setDocument(document);
1009        // we are in verify mode but we can't show content because
1010
// current element is abstract, so we clean table content
1011
if(modes.get(BCOConstants.F_SHOW_ANALYZER)) {
1012            setVerifyTableItems(null);
1013        }
1014        hasAnalyzerError = false;
1015    }
1016
1017    private void refreshVerifyView(DecompiledClass result) {
1018        setVerifyTableItems(result.getTextTable());
1019        List JavaDoc errors = result.getErrorLines();
1020        if(errors.size() > 0){
1021            // TODO this only changes color of status line -
1022
// but it is possible also to provide useful info here...
1023
hasAnalyzerError = true;
1024            //currentErrorMessage = ...
1025
}
1026        for (int i = 0; i < errors.size(); ++i) {
1027            int l = ((Integer JavaDoc) errors.get(i)).intValue();
1028            tableControl.getItem(l).setForeground(errorColor);
1029        }
1030        toggleVerifierAction.setEnabled(true);
1031    }
1032
1033    /**
1034     * @param result
1035     */

1036    private void updateStatus(DecompiledClass result, int bytecodeOffset) {
1037        // clear error messages, if any
1038
statusLineManager.setErrorMessage(null);
1039        if(result != null){
1040            currentStatusMessage = "Java:" + result.getAttribute("java.version")
1041            + " | class size:" + result.getAttribute("class.size");
1042        } else {
1043            currentStatusMessage = "";
1044        }
1045        String JavaDoc selectionInfo = "";
1046        if(bytecodeOffset >= 0){
1047            selectionInfo = " | offset:" + bytecodeOffset;
1048        }
1049        if(hasAnalyzerError){
1050            statusLineManager.setErrorMessage(currentStatusMessage + selectionInfo);
1051        } else {
1052            statusLineManager.setMessage( currentStatusMessage + selectionInfo);
1053        }
1054    }
1055
1056    public int getBytecodeInstructionAtLine (int line) {
1057        if (lastDecompiledResult != null) {
1058            return lastDecompiledResult.getBytecodeInsn(line);
1059        }
1060        return -1;
1061    }
1062
1063    /**
1064     * @return IJavaElement which fits in the current selection in java editor
1065     */

1066    private IJavaElement getCurrentJavaElement() {
1067        IJavaElement childEl = null;
1068        try {
1069            childEl = JdtUtils.getElementAtOffset(javaInput, currentSelection);
1070            if (childEl != null) {
1071                switch (childEl.getElementType()) {
1072                    case IJavaElement.METHOD :
1073                    case IJavaElement.FIELD :
1074                    case IJavaElement.INITIALIZER :
1075                    case IJavaElement.TYPE :
1076                        break;
1077                    case IJavaElement.LOCAL_VARIABLE :
1078                        childEl = childEl.getAncestor(IJavaElement.METHOD);
1079                        break;
1080                    default :
1081                        childEl = null;
1082                        break;
1083                }
1084            }
1085        } catch (JavaModelException e) {
1086            // the exception is mostly occured if java structure was
1087
// changed and current element is not more exist in model
1088
// e.g. on rename/delete/move operation.
1089
// so it is not an error for user, but info for us
1090
BytecodeOutlinePlugin.log(e, IStatus.INFO);
1091            setJavaInput(null);
1092            lastChildElement = null;
1093        }
1094        return childEl;
1095    }
1096
1097    private void setSelectionInBytecodeView() {
1098        if (lastDecompiledResult == null) {
1099            return;
1100        }
1101
1102        int sourceLine = currentSelection.getStartLine() + 1;
1103        int decompiledLine = lastDecompiledResult.getDecompiledLine(sourceLine);
1104
1105        if (decompiledLine > 0) {
1106            try {
1107                if (modes.get(BCOConstants.F_SHOW_ANALYZER)) {
1108                    updateVerifierControl( decompiledLine);
1109                } else {
1110                    int lineCount = textControl.getLineCount();
1111                    if(decompiledLine < lineCount){
1112                        int offsetAtLine = textControl
1113                            .getOffsetAtLine(decompiledLine);
1114                        int offsetEnd = textControl.getText().indexOf(
1115                            '\n', offsetAtLine);
1116                        textControl.setSelection(offsetAtLine, offsetEnd);
1117                    }
1118                }
1119            } catch (IllegalArgumentException JavaDoc e) {
1120                BytecodeOutlinePlugin.error(null, e);
1121            }
1122        } else if (modes.get(BCOConstants.F_SHOW_ANALYZER)) {
1123            lvtTable.removeAll();
1124            stackTable.removeAll();
1125        }
1126        int bytecodeOffest = lastDecompiledResult.getBytecodeOffest(decompiledLine);
1127        updateStatus(lastDecompiledResult, bytecodeOffest);
1128    }
1129
1130    protected void updateVerifierControl(int decompiledLine) {
1131        lvtTable.removeAll();
1132        stackTable.removeAll();
1133        String JavaDoc[][][] frame = lastDecompiledResult.getFrameTables(
1134            decompiledLine, !modes.get(BCOConstants.F_SHOW_RAW_BYTECODE));
1135        if (frame != null) {
1136            for (int i = 0; i < frame[0].length; ++i) {
1137                if (frame[0][i] != null) {
1138                    new TableItem(lvtTable, SWT.NONE).setText(frame[0][i]);
1139                }
1140            }
1141            for (int i = 0; i < frame[1].length; ++i) {
1142                if (frame[1][i] != null) {
1143                    new TableItem(stackTable, SWT.NONE).setText(frame[1][i]);
1144                }
1145            }
1146
1147            lvtTable.getColumn(0).pack();
1148            lvtTable.getColumn(1).pack();
1149            lvtTable.getColumn(2).pack();
1150            stackTable.getColumn(0).pack();
1151            stackTable.getColumn(1).pack();
1152
1153        } else {
1154            // lvtControl.setText("");
1155
// stackControl.setText("");
1156
}
1157        tableControl.setSelection(decompiledLine);
1158    }
1159
1160
1161    protected void setSelectionInJavaEditor(Point selection) {
1162        if (javaEditor != null && javaEditor.getEditorInput() == null) {
1163            // editor was closed - we should clean the reference
1164
javaEditor = null;
1165            setJavaInput(null);
1166        }
1167        if (javaEditor == null || lastDecompiledResult == null) {
1168            deActivateView();
1169            return;
1170        }
1171
1172        int decompiledLine;
1173        if (modes.get(BCOConstants.F_SHOW_ANALYZER)) {
1174            decompiledLine = tableControl.getSelectionIndex();
1175        } else {
1176            decompiledLine = textControl.getLineAtOffset(selection.x);
1177        }
1178        int sourceLine = lastDecompiledResult.getSourceLine(decompiledLine);
1179
1180        try {
1181            if (sourceLine > 0) {
1182                IDocument document = javaEditor.getDocumentProvider()
1183                    .getDocument(javaEditor.getEditorInput());
1184                try {
1185                    IRegion lineInfo = document
1186                        .getLineInformation(sourceLine - 1);
1187                    EclipseUtils.selectInEditor(javaEditor, lineInfo
1188                        .getOffset(), lineInfo.getLength());
1189                } catch (BadLocationException e) {
1190                    // do nothing. This could happens e.g. if editor does not contain
1191
// full source code etc, so that line info is not exist in editor
1192
}
1193            }
1194        } catch (Exception JavaDoc e) {
1195            BytecodeOutlinePlugin.log(e, IStatus.ERROR);
1196        }
1197
1198        int bytecodeOffest = lastDecompiledResult.getBytecodeOffest(decompiledLine);
1199        updateStatus(lastDecompiledResult, bytecodeOffest);
1200    }
1201
1202    // ------------------------------------------------------------------------
1203

1204    /**
1205     * check if at least one java editor is open - if not, deactivate me
1206     * @param checkNewSelection
1207     */

1208    protected void checkOpenEditors(boolean checkNewSelection) {
1209        IEditorReference[] editorReferences = getSite().getPage()
1210            .getEditorReferences();
1211        if (editorReferences == null || editorReferences.length == 0) {
1212            deActivateView();
1213        } else if (checkNewSelection) {
1214            IEditorPart activeEditor = EclipseUtils.getActiveEditor();
1215            if (activeEditor instanceof ITextEditor) {
1216                ITextSelection selection = EclipseUtils
1217                    .getSelection(((ITextEditor) activeEditor)
1218                        .getSelectionProvider());
1219                handleSelectionChanged(activeEditor, selection);
1220            } else {
1221                deActivateView();
1222            }
1223        }
1224    }
1225
1226    /**
1227     * @param childEl
1228     * @return true if java element selection was changed (means, that previous
1229     * selection do not match to the given element)
1230     */

1231    private boolean isSelectedElementChanged(IJavaElement childEl) {
1232
1233        if (lastChildElement == null && childEl == null) {
1234            // no selected child before - and no new selection now => no changes
1235
return false;
1236        }
1237
1238        if(modes.get(BCOConstants.F_SHOW_ONLY_SELECTED_ELEMENT)){
1239            if (lastChildElement == null ||
1240                (lastChildElement != null && !lastChildElement.equals(childEl))){
1241                return true;
1242            }
1243        }
1244
1245        /*
1246         * the check if we changed from inner class to outer class or vice versa
1247         */

1248        if (lastChildElement != null && childEl != null) {
1249            IType newEnclosingType = JdtUtils.getEnclosingType(childEl);
1250            IType oldEnclosingType = JdtUtils.getEnclosingType(lastChildElement);
1251            return newEnclosingType == null || !newEnclosingType.equals(oldEnclosingType);
1252        }
1253        return false;
1254    }
1255
1256    /**
1257     * @param childEl
1258     * @return return null if type is not known or bytecode is not written
1259     * or cannot be found
1260     */

1261    private DecompiledClass decompileBytecode(IJavaElement childEl) {
1262        // check here for inner classes too
1263
IJavaElement type = JdtUtils.getEnclosingType(childEl);
1264        if (type == null) {
1265            type = javaInput;
1266        }
1267        if (type == null) {
1268            return null;
1269        }
1270        InputStream JavaDoc is = JdtUtils.createInputStream(type);
1271        if (is == null) {
1272            return null;
1273        }
1274        DecompiledClass decompiledClass = null;
1275        int available = 0;
1276        try {
1277            ClassLoader JavaDoc cl = null;
1278            if (modes.get(BCOConstants.F_SHOW_ANALYZER)) {
1279                cl = JdtUtils.getClassLoader(type);
1280            }
1281
1282            String JavaDoc fieldName = null;
1283            String JavaDoc methodName = null;
1284            /*
1285             * find out, which name we should use for selected element
1286             */

1287            if (modes.get(BCOConstants.F_SHOW_ONLY_SELECTED_ELEMENT) && childEl != null) {
1288                if (childEl.getElementType() == IJavaElement.FIELD) {
1289                    fieldName = childEl.getElementName();
1290                } else {
1291                    methodName = JdtUtils.getMethodSignature(childEl);
1292                }
1293            }
1294            available = is.available();
1295            decompiledClass = DecompilerClassVisitor.getDecompiledClass(
1296                is, fieldName, methodName, modes, cl);
1297        } catch (Exception JavaDoc e) {
1298            try {
1299                // check if compilation unit is ok - then this is the user problem
1300
if (type.isStructureKnown()) {
1301                    BytecodeOutlinePlugin.error("Cannot decompile: " + type, e);
1302                } else {
1303                    BytecodeOutlinePlugin.log(e, IStatus.ERROR);
1304                }
1305            } catch (JavaModelException e1) {
1306                // this is compilation problem - don't show the message
1307
BytecodeOutlinePlugin.log(e1, IStatus.WARNING);
1308            }
1309        } catch (UnsupportedClassVersionError JavaDoc e) {
1310            BytecodeOutlinePlugin
1311                .error("Cannot decompile: " + type + ". Error was caused by attempt to " +
1312                        "load a class compiled with the Java version which is not " +
1313                        "supported by the current JVM. ", e);
1314        } finally {
1315            try {
1316                is.close();
1317            } catch (IOException JavaDoc e) {
1318                BytecodeOutlinePlugin.log(e, IStatus.WARNING);
1319            }
1320        }
1321        // remember class file size to show it later in UI
1322
if(decompiledClass != null){
1323            decompiledClass.setAttribute(DecompiledClass.ATTR_CLAS_SIZE, "" + available);
1324        }
1325        return decompiledClass;
1326    }
1327
1328    private void setVerifyTableItems(String JavaDoc[][] items) {
1329        tableControl.removeAll();
1330        if (items != null) {
1331            for (int i = 0; i < items.length; ++i) {
1332                TableItem item = new TableItem(tableControl, SWT.NONE);
1333                for (int j = 0; j < items[i].length; ++j) {
1334                    String JavaDoc s = items[i][j];
1335                    if (s.endsWith("\n")) {
1336                        s = s.substring(0, s.length() - 1);
1337                        // this is the "cookie" for the bytecode reference, which could be
1338
// mapped later to the sourcecode line on selection event in the table
1339
item.setData(new Integer JavaDoc(i));
1340                    }
1341                    item.setText(j, s);
1342                }
1343            }
1344            tableControl.getColumn(0).pack();
1345            tableControl.getColumn(1).pack();
1346            tableControl.getColumn(2).pack();
1347            tableControl.getColumn(3).pack();
1348        }
1349    }
1350
1351    public Object JavaDoc getAdapter(Class JavaDoc adapter) {
1352        if (IFindReplaceTarget.class.equals(adapter)) {
1353            return textViewer.getFindReplaceTarget();
1354        }
1355        if (Widget.class.equals(adapter)) {
1356            return textViewer.getTextWidget();
1357        }
1358        if (TextViewer.class.equals(adapter)) {
1359            return textViewer;
1360        }
1361        return super.getAdapter(adapter);
1362    }
1363    /**
1364     * Configures an action for key bindings.
1365     *
1366     * @param actionBars action bars for this page
1367     * @param actionID action definition id
1368     * @param action associated action
1369     */

1370    protected void setGlobalAction(IActionBars actionBars, String JavaDoc actionID,
1371        IAction action) {
1372        globalActions.put(actionID, action);
1373        actionBars.setGlobalActionHandler(actionID, action);
1374    }
1375
1376    /**
1377     * Updates the global action with the given id
1378     *
1379     * @param actionId action definition id
1380     */

1381    protected void updateAction(String JavaDoc actionId) {
1382        IAction action= (IAction)globalActions.get(actionId);
1383        if (action instanceof IUpdate) {
1384            ((IUpdate) action).update();
1385        }
1386    }
1387
1388    protected void createTextActions() {
1389        IActionBars actionBars = getViewSite().getActionBars();
1390        TextViewerAction action = new TextViewerAction(
1391            textViewer, ITextOperationTarget.SELECT_ALL);
1392
1393        action.configureAction(
1394            BytecodeOutlinePlugin.getResourceString(NLS_PREFIX
1395                + "select_all.label"), BytecodeOutlinePlugin
1396                .getResourceString(NLS_PREFIX + "select_all.tooltip"),
1397            BytecodeOutlinePlugin.getResourceString(NLS_PREFIX
1398                + "select_all.description"));
1399        setGlobalAction(actionBars, ActionFactory.SELECT_ALL.getId(), action);
1400
1401        action = new TextViewerAction(textViewer, ITextOperationTarget.COPY);
1402        action.configureAction(
1403            BytecodeOutlinePlugin.getResourceString(NLS_PREFIX + "copy.label"),
1404            BytecodeOutlinePlugin
1405                .getResourceString(NLS_PREFIX + "copy.tooltip"),
1406            BytecodeOutlinePlugin.getResourceString(NLS_PREFIX
1407                + "copy.description"));
1408        action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages()
1409            .getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
1410        action.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY);
1411        setGlobalAction(actionBars, ActionFactory.COPY.getId(), action);
1412
1413        ResourceBundle JavaDoc bundle = BytecodeOutlinePlugin.getDefault().getResourceBundle();
1414
1415        setGlobalAction(
1416            actionBars, ActionFactory.FIND.getId(), new FindReplaceAction(
1417                bundle, NLS_PREFIX + "find_replace.", this)); //$NON-NLS-1$
1418

1419        selectionActions.add(ActionFactory.COPY.getId());
1420        selectionActions.add(ActionFactory.FIND.getId());
1421
1422        actionBars.updateActionBars();
1423    }
1424
1425
1426    // orientation
1427

1428    private void setOrientation(int orientation) {
1429        if (verifyControl == null || verifyControl.isDisposed()) {
1430            return;
1431        }
1432
1433        boolean horizontal = orientation == VIEW_ORIENTATION_HORIZONTAL;
1434        verifyControl.setOrientation(horizontal
1435            ? SWT.HORIZONTAL
1436            : SWT.VERTICAL);
1437
1438        for (int i = 0; i < toggleOrientationActions.length; ++i) {
1439            toggleOrientationActions[i]
1440                .setChecked(orientation == toggleOrientationActions[i]
1441                    .getOrientation());
1442        }
1443
1444        currentOrientation = orientation;
1445        // GridLayout layout= (GridLayout) fCounterComposite.getLayout();
1446
// setCounterColumns(layout);
1447
stackComposite.getParent().layout();
1448    }
1449
1450    protected void computeOrientation() {
1451        if (orientation != VIEW_ORIENTATION_AUTOMATIC) {
1452            currentOrientation = orientation;
1453            setOrientation(currentOrientation);
1454        } else {
1455            Point size = stackComposite.getParent().getSize();
1456            if (size.x != 0 && size.y != 0) {
1457                setOrientation(size.x > size.y
1458                    ? VIEW_ORIENTATION_HORIZONTAL
1459                    : VIEW_ORIENTATION_VERTICAL);
1460            }
1461        }
1462    }
1463
1464    protected void toggleVerifyMode(final IMenuManager mmanager, boolean showAnalyzer) {
1465        modes.set(BCOConstants.F_SHOW_ANALYZER, showAnalyzer);
1466        if(modes.get(BCOConstants.F_SHOW_ANALYZER)) {
1467            ((StackLayout) stackComposite.getLayout()).topControl = verifyControl;
1468            viewSelectionProvider.setCurrentSelectionProvider(tableControlViewer);
1469        } else {
1470            ((StackLayout) stackComposite.getLayout()).topControl = textControl;
1471            viewSelectionProvider.setCurrentSelectionProvider(textViewer);
1472        }
1473        stackComposite.layout();
1474
1475        for (int i = 0; i < toggleOrientationActions.length; ++i) {
1476            toggleOrientationActions[i].setEnabled(showAnalyzer);
1477        }
1478        mmanager.markDirty();
1479        mmanager.update();
1480    }
1481
1482    private class ToggleOrientationAction extends Action {
1483
1484        private final int actionOrientation;
1485
1486        public ToggleOrientationAction(BytecodeOutlineView v, int orientation) {
1487            super("", AS_RADIO_BUTTON); //$NON-NLS-1$
1488

1489            String JavaDoc symbolicName = BytecodeOutlinePlugin.getDefault()
1490                .getBundle().getSymbolicName();
1491            if (orientation == VIEW_ORIENTATION_HORIZONTAL) {
1492                setText(BytecodeOutlinePlugin.getResourceString(NLS_PREFIX
1493                    + "toggle.horizontal.label")); //$NON-NLS-1$
1494
setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
1495                    symbolicName, "icons/th_horizontal.gif")); //$NON-NLS-1$
1496
} else if (orientation == VIEW_ORIENTATION_VERTICAL) {
1497                setText(BytecodeOutlinePlugin.getResourceString(NLS_PREFIX
1498                    + "toggle.vertical.label")); //$NON-NLS-1$
1499
setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
1500                    symbolicName, "icons/th_vertical.gif")); //$NON-NLS-1$
1501
} else if (orientation == VIEW_ORIENTATION_AUTOMATIC) {
1502                setText(BytecodeOutlinePlugin.getResourceString(NLS_PREFIX
1503                    + "toggle.automatic.label")); //$NON-NLS-1$
1504
setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
1505                    symbolicName, "icons/th_automatic.gif")); //$NON-NLS-1$
1506
}
1507            actionOrientation = orientation;
1508            // WorkbenchHelp.setHelp(this, IJUnitHelpContextIds.RESULTS_VIEW_TOGGLE_ORIENTATION_ACTION);
1509
}
1510
1511        public int getOrientation() {
1512            return actionOrientation;
1513        }
1514
1515        public void run() {
1516            if (isChecked()) {
1517                orientation = actionOrientation;
1518                computeOrientation();
1519            }
1520        }
1521    }
1522
1523}
Popular Tags