package org.ntlab.traceDebugger; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableColorProvider; import org.eclipse.jface.viewers.ITreeViewerListener; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.viewers.TreeNode; import org.eclipse.jface.viewers.TreeNodeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import org.ntlab.traceAnalysisPlatform.tracer.trace.TracePoint; import org.ntlab.traceDebugger.analyzerProvider.AbstractAnalyzer; import org.ntlab.traceDebugger.analyzerProvider.DeltaExtractionAnalyzer; import org.ntlab.traceDebugger.analyzerProvider.DeltaMarkerManager; public class VariableView extends ViewPart { private TreeViewer viewer; private IAction jumpAction; private IAction deltaAction; private Variable selectedVariable; private Variables variables = Variables.getInstance(); public static final String ID = "org.ntlab.traceDebugger.variableView"; public VariableView() { // TODO Auto-generated constructor stub System.out.println("VariableViewクラスが生成されたよ!"); } @Override public void createPartControl(Composite parent) { // TODO Auto-generated method stub System.out.println("VariableView#createPartControl(Composite)が呼ばれたよ!"); viewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); Tree tree = viewer.getTree(); tree.setHeaderVisible(true); tree.setLinesVisible(true); String[] treeColumnTexts = {"Name", "Value"}; int[] treeColumnWidth = {100, 200}; TreeColumn[] treeColumns = new TreeColumn[treeColumnTexts.length]; for (int i = 0; i < treeColumns.length; i++) { treeColumns[i] = new TreeColumn(tree, SWT.NULL); treeColumns[i].setText(treeColumnTexts[i]); treeColumns[i].setWidth(treeColumnWidth[i]); } viewer.setContentProvider(new TreeNodeContentProvider()); viewer.setLabelProvider(new VariableLabelProvider()); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection sel = (IStructuredSelection)event.getSelection(); Object element = sel.getFirstElement(); if (element instanceof TreeNode) { Object value = ((TreeNode)element).getValue(); if (value instanceof Variable) { selectedVariable = (Variable)value; } } } }); viewer.addTreeListener(new ITreeViewerListener() { @Override public void treeExpanded(TreeExpansionEvent event) { // ツリーを開いた後に実行される。 ここでは開いたノードから3つ先のノードを生成して追加する。 Object element = event.getElement(); if (!(element instanceof TreeNode)) return; TreeNode expandedNode = (TreeNode)element; Object value = expandedNode.getValue(); if (!(value instanceof Variable)) return; TreeNode[] childNodes = expandedNode.getChildren(); if (childNodes == null) return; for (TreeNode childNode : childNodes) { TreeNode[] grandChildNodes = childNode.getChildren(); if (grandChildNodes == null) continue; for (TreeNode grandChildNode : grandChildNodes) { Variable grandChildVariable = (Variable)grandChildNode.getValue(); grandChildVariable.createNextHierarchyState(); List<Variable> list = grandChildVariable.getChildren(); TreeNode[] nodes = new TreeNode[list.size()]; for (int i = 0; i < list.size(); i++) { nodes[i] = new TreeNode(list.get(i)); } grandChildNode.setChildren(nodes); } } viewer.refresh(); } @Override public void treeCollapsed(TreeExpansionEvent event) {} }); createActions(); createToolBar(); createMenuBar(); createPopupMenu(); } @Override public void setFocus() { // TODO Auto-generated method stub viewer.getControl().setFocus(); } private void createActions() { jumpAction = new Action() { public void run() { TracePoint tp = selectedVariable.getLastUpdatePoint(); if (tp == null) return; DebuggingController controller = DebuggingController.getInstance(); controller.jumpToTheTracePoint(tp); controller.stepOverAction(); } }; jumpAction.setText("Jump to Creation Point"); jumpAction.setToolTipText("Jump to Creation Point"); deltaAction = new Action() { @Override public void run() { AbstractAnalyzer analyzer = TraceDebuggerPlugin.getAnalyzer(); if (analyzer instanceof DeltaExtractionAnalyzer) { DeltaExtractionAnalyzer deltaAnalyzer = (DeltaExtractionAnalyzer)analyzer; deltaAnalyzer.extractDelta(selectedVariable); TracePoint coordinatorPoint = deltaAnalyzer.getCoordinatorPoint(); DebuggingController controller = DebuggingController.getInstance(); controller.jumpToTheTracePoint(coordinatorPoint); IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchPage workbenchPage = workbench.getActiveWorkbenchWindow().getActivePage(); try { // note: 同一ビューを複数開くテスト workbenchPage.showView("org.eclipse.ui.views.AllMarkersView", "tmp" + Math.random(), IWorkbenchPage.VIEW_ACTIVATE); } catch (PartInitException e) { e.printStackTrace(); } expandParticularNodes(); } } }; deltaAction.setText("Extract Delta"); deltaAction.setToolTipText("Extract Delta"); } private void expandParticularNodes() { Map<String, Set<String>> markerIdToObjectIdSet = DeltaMarkerManager.getInstance().getMarkerIdToObjectIdSet(); Set<String> srcSideIdSet = new HashSet<>(markerIdToObjectIdSet.get(DeltaMarkerManager.DELTA_MARKER_ID)); Set<String> dstSideIdSet = new HashSet<>(markerIdToObjectIdSet.get(DeltaMarkerManager.DELTA_MARKER_ID_2)); // Set<String> idSet = new HashSet<>(DeltaMarkerManager.getInstance().getIdSet()); Set<TreeNode> expandNodes = new HashSet<>(); Object obj = viewer.getTree().getTopItem().getData(); if (!(obj instanceof TreeNode)) return; TreeNode node = (TreeNode)obj; Object value = node.getValue(); if (!(value instanceof Variable)) return; expandParticularNodes(srcSideIdSet, dstSideIdSet, expandNodes, node); viewer.setExpandedElements(expandNodes.toArray(new Object[expandNodes.size()])); } private void expandParticularNodes(Set<String> srcSideIdSet, Set<String> dstSideIdSet, Set<TreeNode> expandNodes, TreeNode node) { // if (idSet.isEmpty()) return; Object value = node.getValue(); if (!(value instanceof Variable)) return; Variable variable = (Variable)value; String id = variable.getId(); if (srcSideIdSet.contains(id)) { variable.setSrcSideRelatedDelta(true); srcSideIdSet.remove(id); TreeNode parent = node.getParent(); if (parent != null) { expandNodes.add(node.getParent()); } } else if (dstSideIdSet.contains(id)) { variable.setDstSideRelatedDelta(true); dstSideIdSet.remove(id); TreeNode parent = node.getParent(); if (parent != null) { expandNodes.add(node.getParent()); } } TreeNode[] children = node.getChildren(); if (children == null) return; for (TreeNode child : children) { expandParticularNodes(srcSideIdSet, dstSideIdSet, expandNodes, child); } } private void createToolBar() { IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); } private void createMenuBar() { IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); } private void createPopupMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { manager.add(jumpAction); manager.add(deltaAction); manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } }); Menu menu = menuMgr.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, viewer); } public void reset() { variables.resetData(); viewer.setInput(variables.getVariablesTreeNodes()); viewer.refresh(); } public void updateVariablesByTracePoint(TracePoint tp, boolean isReturned) { variables.getAllObjectDataByTracePoint(tp, isReturned); viewer.setInput(variables.getVariablesTreeNodes()); } private IViewPart getOtherView(String viewId) { IWorkbenchPage workbenchPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { return workbenchPage.showView(viewId); } catch (PartInitException e) { throw new RuntimeException(e); } } }