// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.mdm.repository.ui.views; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ListenerList; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.util.OpenStrategy; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.IOpenListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IMemento; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.OpenAndLinkWithEditorHelper; import org.eclipse.ui.PartInitException; import org.eclipse.ui.internal.PartSite; import org.eclipse.ui.internal.PopupMenuExtender; import org.eclipse.ui.internal.views.markers.ExtendedMarkersView; import org.eclipse.ui.internal.views.markers.MarkerContentGenerator; import org.eclipse.ui.menus.IMenuService; import org.eclipse.ui.views.markers.MarkerSupportView; import org.eclipse.ui.views.markers.internal.ContentGeneratorDescriptor; import org.eclipse.ui.views.markers.internal.MarkerGroup; import org.talend.commons.exception.PersistenceException; import org.talend.commons.utils.workbench.resources.ResourceUtils; import org.talend.core.model.general.Project; import org.talend.core.model.repository.IRepositoryViewObject; import org.talend.mdm.repository.core.marker.IValidationMarker; import org.talend.mdm.repository.ui.markers.IOpenMarkerHandler; import org.talend.mdm.repository.ui.markers.OpenMarkerHandlerRegister; import org.talend.mdm.repository.ui.markers.datamodel.ModelNameMarkerGroup; import org.talend.mdm.repository.utils.EclipseResourceManager; import org.talend.mdm.repository.utils.RepositoryResourceUtil; import org.talend.mdm.repository.validate.plugin.ValidatePlugin; import org.talend.repository.ProjectManager; /** * created by HHB on 2013-1-5 Detailled comment * */ public class MDMProblemView extends MarkerSupportView implements IValidationMarker { static Logger log = Logger.getLogger(MDMProblemView.class); private static final String GENERATOR_ID = "org.talend.mdm.problemsGenerator"; //$NON-NLS-1$ public static final String VIEW_ID = "org.talend.mdm.repository.ui.views.MDMProblemView"; //$NON-NLS-1$ private ISelectionListener pageSelectionListener; /** * DOC HHB MDMProblemView constructor comment. * * @param contentGeneratorId */ public MDMProblemView() { super(GENERATOR_ID); } private class ViewerPageSelectionListener implements ISelectionListener { private ExtendedMarkersView view; ViewerPageSelectionListener(ExtendedMarkersView view) { this.view = view; } @Override public void selectionChanged(IWorkbenchPart part, ISelection selection) { // Do not respond to our own selections or if we are not // visible if (part == MDMProblemView.this || !(getSite().getPage().isPartVisible(part))) { return; } // get Objects to adapt List objectsToAdapt = new ArrayList(); if (part instanceof IEditorPart) { IEditorPart editor = (IEditorPart) part; objectsToAdapt.add(editor.getEditorInput()); } else { if (selection instanceof IStructuredSelection) { for (Iterator iterator = ((IStructuredSelection) selection).iterator(); iterator.hasNext();) { Object object = iterator.next(); objectsToAdapt.add(object); } } } // try to adapt them in resources and add it to the // selectedElements List selectedElements = new ArrayList(); for (Iterator iterator = objectsToAdapt.iterator(); iterator.hasNext();) { Object object = iterator.next(); if (object instanceof IRepositoryViewObject) { Object[] resElements = RepositoryResourceUtil.adapt2ResourceElement((IRepositoryViewObject) object); if (resElements != null) { for (Object obj : resElements) { selectedElements.add(obj); } } } } MarkerContentGenerator generator = getGenerator(); updateSelectedResource(generator, selectedElements.toArray(), part == null); } } private void addPageAndPartSelectionListener() { // Initialise any selection based filtering pageSelectionListener = new ViewerPageSelectionListener(this); getSite().getPage().addPostSelectionListener(pageSelectionListener); pageSelectionListener.selectionChanged(getSite().getPage().getActivePart(), getSite().getPage().getSelection()); } /* * (non-Javadoc) * * @see org.eclipse.ui.internal.views.markers.ExtendedMarkersView#init(org.eclipse.ui.IViewSite, * org.eclipse.ui.IMemento) */ @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); IMenuService menuService = (IMenuService) site.getService(IMenuService.class); hookModelGroup(); } /** * DOC HHB Comment method "hookModelGroup". */ private void hookModelGroup() { try { Field generatorField = ExtendedMarkersView.class.getDeclaredField("generator"); //$NON-NLS-1$ Field descField = MarkerContentGenerator.class.getDeclaredField("generatorDescriptor"); //$NON-NLS-1$ if (generatorField != null && descField != null) { generatorField.setAccessible(true); descField.setAccessible(true); Object object = generatorField.get(this); if (object != null) { Object descObj = descField.get(object); if (descObj != null) { Collection groups = ((ContentGeneratorDescriptor) descObj).getMarkerGroups(); if (!hasMarkerGroup(groups, ModelNameMarkerGroup.ID)) { groups.add(new ModelNameMarkerGroup()); } } } } } catch (SecurityException e) { log.error(e.getMessage(), e); } catch (IllegalArgumentException e) { log.error(e.getMessage(), e); } catch (NoSuchFieldException e) { log.error(e.getMessage(), e); } catch (IllegalAccessException e) { log.error(e.getMessage(), e); } } private boolean hasMarkerGroup(Collection groups, String id) { for (Object groupObj : groups) { if (((MarkerGroup) groupObj).getId().equals(id)) { return true; } } return false; } private TreeViewer getTreeViewer() { try { Field viewerField = ExtendedMarkersView.class.getDeclaredField("viewer"); //$NON-NLS-1$ if (viewerField != null) { viewerField.setAccessible(true); return (TreeViewer) viewerField.get(this); } } catch (SecurityException e) { log.error(e.getMessage(), e); } catch (IllegalArgumentException e) { log.error(e.getMessage(), e); } catch (NoSuchFieldException e) { log.error(e.getMessage(), e); } catch (IllegalAccessException e) { log.error(e.getMessage(), e); } return null; } private void updateSelectedResource(MarkerContentGenerator generator, Object[] selectedElements, boolean forceUpdate) { try { Method method = MarkerContentGenerator.class.getDeclaredMethod( "updateSelectedResource", Object[].class, boolean.class); //$NON-NLS-1$ if (method != null) { method.setAccessible(true); Object param = selectedElements; method.invoke(generator, param, forceUpdate); } } catch (SecurityException e) { log.error(e.getMessage(), e); } catch (IllegalArgumentException e) { log.error(e.getMessage(), e); } catch (NoSuchMethodException e) { log.error(e.getMessage(), e); } catch (IllegalAccessException e) { log.error(e.getMessage(), e); } catch (InvocationTargetException e) { log.error(e.getMessage(), e); } } private MarkerContentGenerator getGenerator() { try { Field generatorField = ExtendedMarkersView.class.getDeclaredField("generator"); //$NON-NLS-1$ if (generatorField != null) { generatorField.setAccessible(true); return (MarkerContentGenerator) generatorField.get(this); } } catch (SecurityException e) { log.error(e.getMessage(), e); } catch (IllegalArgumentException e) { log.error(e.getMessage(), e); } catch (NoSuchFieldException e) { log.error(e.getMessage(), e); } catch (IllegalAccessException e) { log.error(e.getMessage(), e); } return null; } private void uninstallViewListener(TreeViewer treeViewer) { if (treeViewer != null) { Object listener = findListener(treeViewer); if (listener != null) { treeViewer.removePostSelectionChangedListener((ISelectionChangedListener) listener); treeViewer.removeDoubleClickListener((IDoubleClickListener) listener); treeViewer.removeOpenListener((IOpenListener) listener); } // } } private void removeGotoCmd() { PopupMenuExtender popupMenuExtender = getPopupMenuExtender(); if (popupMenuExtender != null) { final MenuManager manager = popupMenuExtender.getManager(); manager.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { for (IContributionItem item : manager.getItems()) { if (item.getId().equals("org.eclipse.ui.navigate.goToResource")) { //$NON-NLS-1$ manager.remove(item); break; } } } }); } } private PopupMenuExtender getPopupMenuExtender() { try { Field menuListField = PartSite.class.getDeclaredField("menuExtenders"); //$NON-NLS-1$ if (menuListField != null) { menuListField.setAccessible(true); List list = (List) menuListField.get(getSite()); for (Object obj : list) { if (obj instanceof PopupMenuExtender) { return (PopupMenuExtender) obj; } } } } catch (SecurityException e) { log.error(e.getMessage(), e); } catch (IllegalArgumentException e) { log.error(e.getMessage(), e); } catch (NoSuchFieldException e) { log.error(e.getMessage(), e); } catch (IllegalAccessException e) { log.error(e.getMessage(), e); } return null; } private void addLinkWithEditorSupport(TreeViewer viewer) { new OpenAndLinkWithEditorHelper(viewer) { @Override protected void activate(ISelection selection) { final int currentMode = OpenStrategy.getOpenMethod(); try { OpenStrategy.setOpenMethod(OpenStrategy.DOUBLE_CLICK); openSelectedMarkers(null); } finally { OpenStrategy.setOpenMethod(currentMode); } } @Override protected void linkToEditor(ISelection selection) { // Not supported by this part } @Override protected void open(ISelection selection, boolean activate) { openSelectedMarkers(null); } }; } public void openSelectedMarkers(Object param) { IMarker[] markers = getSelectedMarkers(); IWorkbenchPage page = getSite().getPage(); List<IOpenMarkerHandler> handlers = OpenMarkerHandlerRegister.getHandlers(); for (IMarker marker : markers) { boolean canOpen = false; if (handlers != null) { for (IOpenMarkerHandler handler : handlers) { canOpen = handler.canOpen(marker); if (canOpen) { handler.open(page, marker, param); break; } } } if (!canOpen) { openMarkerInEditor(marker, page); } } } private Object findListener(TreeViewer treeViewer) { try { Field doubleListenersField = StructuredViewer.class.getDeclaredField("doubleClickListeners"); //$NON-NLS-1$ if (doubleListenersField != null) { doubleListenersField.setAccessible(true); ListenerList list = (ListenerList) doubleListenersField.get(treeViewer); for (Object listenerObj : list.getListeners()) { if (listenerObj.getClass().getEnclosingClass() == OpenAndLinkWithEditorHelper.class) { return listenerObj; } } } } catch (SecurityException e) { log.error(e.getMessage(), e); } catch (IllegalArgumentException e) { log.error(e.getMessage(), e); } catch (NoSuchFieldException e) { log.error(e.getMessage(), e); } catch (IllegalAccessException e) { log.error(e.getMessage(), e); } return null; } /* * (non-Javadoc) * * @see * org.eclipse.ui.internal.views.markers.ExtendedMarkersView#createPartControl(org.eclipse.swt.widgets.Composite) */ @Override public void createPartControl(Composite parent) { super.createPartControl(parent); TreeViewer treeViewer = getTreeViewer(); uninstallViewListener(treeViewer); removeGotoCmd(); addLinkWithEditorSupport(treeViewer); addPageAndPartSelectionListener(); } private static final Image IMG_PROBLEM = EclipseResourceManager.getImage(ValidatePlugin.PLUGIN_ID, "icons/problems_view.gif"); private static final Image IMG_PROBLEM_ERR = EclipseResourceManager.getImage(ValidatePlugin.PLUGIN_ID, "icons/problems_view_error.gif"); private static final Image IMG_PROBLEM_WARN = EclipseResourceManager.getImage(ValidatePlugin.PLUGIN_ID, "icons/problems_view_warning.gif"); private void updateTitleImage(int severity) { switch (severity) { case IMarker.SEVERITY_ERROR: setTitleImage(IMG_PROBLEM_ERR); break; case IMarker.SEVERITY_WARNING: setTitleImage(IMG_PROBLEM_WARN); break; default: setTitleImage(IMG_PROBLEM); break; } } public void updateViewTitle() { try { Project project = ProjectManager.getInstance().getCurrentProject(); IProject prj = ResourceUtils.getProject(project); int severity = prj.findMaxProblemSeverity(IValidationMarker.MARKER_MDM, true, IResource.DEPTH_INFINITE); updateTitleImage(severity); } catch (PersistenceException e) { log.error(e.getMessage(), e); } catch (CoreException e) { log.error(e.getMessage(), e); } } @Override public void dispose() { getSite().getPage().removePostSelectionListener(pageSelectionListener); super.dispose(); } }