/* * Copyright (C) 2012 Nagoya University All rights reserved. */ package net.dependableos.dcase.diagram.editor.ui; import net.dependableos.dcase.Argument; import net.dependableos.dcase.diagram.common.util.MessageTypeImpl; import net.dependableos.dcase.diagram.common.util.Messages; import net.dependableos.dcase.diagram.edit.parts.ArgumentEditPart; import net.dependableos.dcase.diagram.editor.command.ModuleDeleteAction; import net.dependableos.dcase.diagram.editor.command.ModuleOpenAction; import net.dependableos.dcase.diagram.editor.common.util.DcaseEditorUtil; import net.dependableos.dcase.diagram.editor.common.util.MessageWriter; import net.dependableos.dcase.diagram.editor.common.util.ModuleUtil; import net.dependableos.dcase.diagram.part.DcaseDiagramEditor; import java.util.List; import java.util.ArrayList; import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.action.IAction; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.common.ui.resources.FileChangeManager; import org.eclipse.gmf.runtime.common.ui.resources.IFileObserver; import org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory; import org.eclipse.gmf.runtime.notation.Diagram; /** * A view part to show Modules. */ public class ModuleViewPart extends ViewPart { /** * the horizontal grid number. */ private static final int GRID_NR = 4; /** * the width for each grid. */ private static final int[] GRID_WIDTHS = { 320, 64, 64, 240 }; /** * the title string for each grid. */ private static final String[] TITLE_NAMES = { net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Label0, net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Label1, net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Label2, net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Label3, }; private static final int NORMAL = 0; private static final int CHANGED = 1; private static final int DELETED = 2; /** * the module infomation list. */ private Map<String, String> moduleList; /** * the table viewer. */ private TableViewer viewer; /** * the current file. */ private IFile currentFile; /** * the file observer. */ private IFileObserver fileObserver; /** * the page listener. */ private ISelectionListener pageListener; /** * the constructor. */ public ModuleViewPart() { super(); } /** * Creates the controls. * * @param parent * the parent composite. */ @Override public void createPartControl(Composite parent) { viewer = new TableViewer(parent, SWT.FULL_SELECTION); Table table = viewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(false); for (int i = 0; i < GRID_NR; i++) { TableColumn col = new TableColumn(table, SWT.NULL); col.setText(TITLE_NAMES[i]); col.setWidth(GRID_WIDTHS[i]); } table.addMouseListener(new MouseListener() { // nop. public void mouseDown(MouseEvent e) { } // nop. public void mouseUp(MouseEvent e) { } // open module. public void mouseDoubleClick(MouseEvent e) { String moduleName = getSelectedModuleFile(); if (!ModuleUtil.isPublicNodeName(moduleName)) { ModuleUtil.openModuleEditor(moduleName); } } }); // register file observer and page listener. removeObservers(); fileObserver = new ModuleFileObserver(); FileChangeManager.getInstance().addFileObserver(fileObserver); IWorkbenchPage page = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); pageListener = new ModuleSelectionListener(); page.addSelectionListener(pageListener); viewer.setLabelProvider(new ModuleLabelProvider()); viewer.setContentProvider(new ArrayContentProvider()); viewer.setInput(getModuleItems(null, NORMAL)); registerAction(); } /** * Returns the module info. * * @return the module info. */ private List<ModuleModel> getModuleItems(IFile file, int type) { List<ModuleModel> input = new ArrayList<ModuleModel>(); switch (type) { case DELETED: Object orgInput = viewer.getInput(); String delName = ModuleUtil.getModuleName(file); if (orgInput instanceof List) { for (ModuleModel elem : (List<ModuleModel>) orgInput) { if (!delName .equals(ModuleUtil.getModuleName(elem.getName()))) { input.add(elem); } } } return input; case CHANGED: if (isSameProject(currentFile, file)) { break; } // fall-through... case NORMAL: try { if (file != null) { moduleList = ModuleUtil.getModulesAndNodes(file, true); } else { ArgumentEditPart argumentEditPart = DcaseEditorUtil .getCurrentArgumentEditPart(); moduleList = ModuleUtil.getModulesAndNodes( argumentEditPart, true); } } catch (Exception e) { e.printStackTrace(); MessageWriter.writeMessageToConsole(Messages.ModuleList, MessageTypeImpl.MODULE_INFO_GET_FAILED); return input; } break; } for (Map.Entry<String, String> module : moduleList.entrySet()) { input.add(new ModuleModel(module.getKey(), module.getValue(), ModuleUtil.getReferenceNumber(module.getValue()), ModuleUtil.countNodes(module.getKey()))); } currentFile = file; return input; } private boolean isSameProject(IFile file1, IFile file2) { if (file1 == null || file2 == null) { return false; } return (file1.getProject() == file2.getProject()); } /** * {@inheritDoc} */ @Override public void dispose() { removeObservers(); } /** * Removes file observer and page listener. */ private void removeObservers() { if (fileObserver != null) { FileChangeManager.getInstance().removeFileObserver(fileObserver); fileObserver = null; } if (pageListener != null) { try { IWorkbenchPage page = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); page.removeSelectionListener(pageListener); } catch (NullPointerException e) { // don't care } pageListener = null; } } /** * {@inheritDoc} */ @Override public void setFocus() { viewer.getControl().setFocus(); } /** * Registers the actions. */ private void registerAction() { IActionBars bars = getViewSite().getActionBars(); IAction openAction = new ModuleOpenAction(this); openAction.setText(net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Title0); openAction.setToolTipText(net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Tooltip0); openAction.setImageDescriptor(PlatformUI.getWorkbench() .getSharedImages() .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD)); bars.getToolBarManager().add(openAction); bars.getMenuManager().add(openAction); IAction deleteAction = new ModuleDeleteAction(this); deleteAction.setText(net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Title1); deleteAction.setToolTipText(net.dependableos.dcase.diagram.editor.message.Messages.ModuleView_Tooltip1); deleteAction.setImageDescriptor(PlatformUI.getWorkbench() .getSharedImages() .getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); bars.getToolBarManager().add(deleteAction); bars.getMenuManager().add(deleteAction); } /** * A module model. */ private class ModuleModel { private String name = null; private String node = null; private int links = 0; private int nodes = 0; /** * The constructor. * * @param name * the module name. * @param node * the reference node name. * @param links * the link number. */ public ModuleModel(String name, String node, int links, int nodes) { this.name = name; this.node = node; this.links = links; this.nodes = nodes; } /** * Returns the module name. * * @return the module name. */ public String getName() { return name; } /** * Returns the node reference name. * * @return the node reference name. */ public String getNode() { return node; } /** * Returns the link number. * * @return the link number. */ public String getLinks() { return "" + links; } /** * Returns the node number. * * @return the node number. */ public String getNodes() { return (nodes != 0) ? ("" + nodes) : ""; } } /** * A module label provider. */ private class ModuleLabelProvider extends LabelProvider implements ITableLabelProvider { /** * Returns the properties of module info. */ public String getColumnText(Object obj, int index) { ModuleModel model = (ModuleModel) obj; switch (index) { case 0: return model.getName(); case 1: return model.getNodes(); case 2: return model.getLinks(); case 3: return model.getNode(); } return "[Undefined]"; //$NON-NLS-1$ } /** * Returns the icon image. */ public Image getColumnImage(Object obj, int index) { if (index == 0) { ModuleModel model = (ModuleModel) obj; if (ModuleUtil.isPublicNodeName(model.getName())) { return null; } return PlatformUI.getWorkbench().getSharedImages() .getImage(ISharedImages.IMG_OBJ_ELEMENT); } return null; } } /** * Returns the selected module name. * * @return the selected module name. */ public String getSelectedModuleFile() { IStructuredSelection sel = (IStructuredSelection) viewer.getSelection(); Object obj = sel.getFirstElement(); if (obj instanceof ModuleModel) { return ((ModuleModel) obj).getName(); } return null; } /** * File Observer class for detecting changes. */ private class ModuleFileObserver implements IFileObserver { public ModuleFileObserver() { } public void handleFileRenamed(IFile oldFile, IFile file) { commonFileHandler(oldFile, false); commonFileHandler(file, true); } public void handleFileMoved(IFile oldFile, IFile file) { commonFileHandler(oldFile, false); commonFileHandler(file, true); } public void handleFileDeleted(IFile file) { commonFileHandler(file, false); } public void handleFileChanged(IFile file) { commonFileHandler(file, true); } public void handleMarkerAdded(IMarker marker) { commonMarkerHandler(marker); } public void handleMarkerDeleted(IMarker marker, Map attributes) { commonMarkerHandler(marker); } public void handleMarkerChanged(IMarker marker) { commonMarkerHandler(marker); } private void commonFileHandler(final IFile file, boolean isNormal) { if (ModuleUtil.isModelFile(file)) { if (isNormal) { viewer.setInput(getModuleItems(file, NORMAL)); viewer.refresh(); } else { IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench != null) { IWorkbenchWindow[] windows = workbench .getWorkbenchWindows(); if (windows != null && windows.length > 0) { IWorkbenchPage workbenchPage = windows[0] .getActivePage(); IEditorPart editorPart = workbenchPage .getActiveEditor(); if (editorPart instanceof DcaseDiagramEditor) { Diagram diagram = ((DcaseDiagramEditor) editorPart) .getDiagram(); TransactionalEditingDomain domain = GMFEditingDomainFactory.INSTANCE .getEditingDomain(diagram.eResource() .getResourceSet()); domain.getCommandStack().execute( new RecordingCommand(domain) { public void doExecute() { Display.getDefault().asyncExec( new Runnable() { public void run() { List<ModuleModel> mlist = getModuleItems( file, DELETED); viewer.setInput(mlist); viewer.refresh(); } }); } }); } } } } } } private void commonMarkerHandler(IMarker marker) { // do nothing... } } /** * Page Selection Listener class for detecting current diagram. */ private class ModuleSelectionListener implements ISelectionListener { public void selectionChanged(IWorkbenchPart part, ISelection selection) { if (!(part instanceof DcaseDiagramEditor)) { return; } if (selection == null || selection.isEmpty()) { return; } if (!(selection instanceof IStructuredSelection)) { return; } Object eobj = ((IStructuredSelection) selection).toArray()[0]; if (!(eobj instanceof ArgumentEditPart)) { return; } Object aobj = DcaseEditorUtil.getElement((ArgumentEditPart) eobj); if (aobj instanceof Argument) { if (((Argument) aobj).eResource() == null) { return; } URI uri = ((Argument) aobj).eResource().getURI(); IFile file = ResourcesPlugin.getWorkspace().getRoot() .getFile(new Path(uri.toPlatformString(false))); viewer.setInput(getModuleItems(file, CHANGED)); viewer.refresh(); } } } }