package org.ntlab.traceanalyzer; import java.io.File; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import org.ntlab.trace.ClassInfo; import org.ntlab.trace.Trace; public class CallTreeView extends ViewPart { private TreeViewer viewer; private IAction openAction; private IAction markAction; private IAction highlightAction; private MarkedTrace markedTrace; private Shell shell; @Override public void createPartControl(Composite parent) { shell = parent.getShell(); viewer = new TreeViewer(parent); viewer.setContentProvider(new CallTreeContentProvider()); viewer.setLabelProvider(new CallTreeLabelProvider()); viewer.setInput(null); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection sel = (IStructuredSelection)event.getSelection(); Object element = sel.getFirstElement(); if (element instanceof MarkedMethodExecution) { String className = ((MarkedMethodExecution)element).getDeclaringClassName(); String methodSignature = ((MarkedMethodExecution)element).getSignature(); ClassInfo classInfo = markedTrace.getClassInfo(className); if (classInfo == null) { className = ((MarkedMethodExecution)element).getReceiverClassName(); classInfo = markedTrace.getClassInfo(className); } if (classInfo != null) { String projectPath = classInfo.getLoaderPath(); IJavaProject javaProject = findJavaProject(projectPath); if (javaProject != null) { openInJavaEditor(javaProject, className, methodSignature); } } } } }); getSite().setSelectionProvider(viewer); createActions(); createToolBar(); createMenuBar(); } /** アクションを作成 */ private void createActions(){ // トレースファイルを開くアクションを作成 ImageDescriptor openIcon = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER); openAction = new Action("Open Trace File...", openIcon){ public void run(){ // トレース出力先参照ウィザード FileDialog dialog = new FileDialog(shell, SWT.OPEN); dialog.setText("Open Trace File"); dialog.setFilterExtensions(new String[]{"*.*"}); String path = dialog.open(); if (path == null) { return; } markedTrace = new MarkedTrace(path); viewer.setInput(markedTrace); viewer.refresh(); highlightAction.setChecked(false); } }; // トレースにマークするアクションを作成 ImageDescriptor markIcon = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OPEN_MARKER); markAction = new Action("Mark Trace...", markIcon){ public void run(){ final Shell traceMarkShell = new Shell(SWT.TITLE | SWT.ON_TOP | SWT.CLOSE); // マーク指定画面 traceMarkShell.setText("Mark Trace"); traceMarkShell.setSize(250, 150); traceMarkShell.setLayout(new FormLayout()); // 開始時間(ラベル) Label startTimeLabel = new Label(traceMarkShell, SWT.NULL); startTimeLabel.setText("Start Time:"); FormData startTimeLabelForm = new FormData(); startTimeLabelForm.top = new FormAttachment(10, 5); startTimeLabelForm.left = new FormAttachment(5, 5); startTimeLabel.setLayoutData(startTimeLabelForm); // 開始時間(テキストボックス) final Text startTimeText = new Text(traceMarkShell, SWT.BORDER | SWT.SINGLE | SWT.WRAP); startTimeText.setText(Long.toString(markedTrace.getMarkStart())); FormData startTimeTextForm = new FormData(); startTimeTextForm.top = new FormAttachment(10, 5); startTimeTextForm.left = new FormAttachment(35, 10); startTimeTextForm.right = new FormAttachment(95, -5); startTimeText.setLayoutData(startTimeTextForm); // 終了時間(ラベル) Label endTimeLabel = new Label(traceMarkShell, SWT.NULL); endTimeLabel.setText("End Time:"); FormData endTimeLabelForm = new FormData(); endTimeLabelForm.top = new FormAttachment(30, 5); endTimeLabelForm.left = new FormAttachment(5, 5); endTimeLabel.setLayoutData(endTimeLabelForm); // 終了時間入力(テキストボックス) final Text endTimeText = new Text(traceMarkShell, SWT.BORDER | SWT.SINGLE | SWT.WRAP); endTimeText.setText(Long.toString(markedTrace.getMarkEnd())); FormData endTimeTextForm = new FormData(); endTimeTextForm.top = new FormAttachment(30, 5); endTimeTextForm.left = new FormAttachment(35, 10); endTimeTextForm.right = new FormAttachment(95, -5); endTimeText.setLayoutData(endTimeTextForm); //OKボタン Button okButton = new Button(traceMarkShell, SWT.PUSH); okButton.setText("OK"); FormData okButtonForm = new FormData(); okButtonForm.bottom = new FormAttachment(100, -5); okButtonForm.right = new FormAttachment(95, -5); okButton.setLayoutData(okButtonForm); okButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e){ if (markedTrace != null) { String startText = startTimeText.getText(); String endText = endTimeText.getText(); try { long start = Long.parseLong(startText); long end = Long.parseLong(endText); traceMarkShell.close(); markedTrace.mark(start, end); viewer.setInput(markedTrace); viewer.refresh(); highlightAction.setChecked(false); } catch (NumberFormatException ex) { } } else { traceMarkShell.close(); } } }); traceMarkShell.open(); } }; // マーク固有のメソッドを強調するアクションを作成 ImageRegistry registry = Activator.getDefault().getImageRegistry(); ImageDescriptor highlightIcon = registry.getDescriptor("TraceAnalyzer.HIGHLIGHT_UNIQUE_IMAGE"); highlightAction = new Action("Highlight Unique Methods", Action.AS_CHECK_BOX){ public void run(){ if (markedTrace != null) { if (isChecked()) { markedTrace.setHighlightUniqueMethods(true); viewer.setInput(markedTrace); viewer.refresh(); } else { markedTrace.setHighlightUniqueMethods(false); viewer.setInput(markedTrace); viewer.refresh(); } } } }; highlightAction.setImageDescriptor(highlightIcon); } /** ツールバーにアクションを追加 */ private void createToolBar(){ IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); mgr.add(openAction); mgr.add(markAction); mgr.add(highlightAction); } /** メニューバーにアクションを追加 */ private void createMenuBar(){ IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); mgr.add(openAction); mgr.add(markAction); } public void setFocus() { viewer.getTree().setFocus(); } private IJavaProject findJavaProject(String projectPath) { IJavaProject javaProject = null; IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IProject[] projects = root.getProjects(); for (IProject project: projects) { if (projectPath.startsWith(project.getLocation().toString())) { javaProject = JavaCore.create(project); break; } } return javaProject; } private void openInJavaEditor(IJavaProject javaProject, String className, String methodSignature) { try { IType type = javaProject.findType(className); if (type != null) { IEditorPart editor = JavaUI.openInEditor(type); if (!type.isLocal() && !type.isMember()) { for (IMethod method: type.getMethods()) { if (methodSignature.contains(method.getElementName())) { JavaUI.revealInEditor(editor, (IJavaElement)method); } } } } } catch (PartInitException | JavaModelException e) { e.printStackTrace(); } } }