es.cv.gvcase.ide.navigator.search.iu.pages.ElementInDiagramSearchResultPage.java Source code

Java tutorial

Introduction

Here is the source code for es.cv.gvcase.ide.navigator.search.iu.pages.ElementInDiagramSearchResultPage.java

Source

/***************************************************************************
 * Copyright (c) 2008, 2009 Conselleria de Infraestructuras y Transporte,
 * Generalitat de la Comunitat Valenciana . All rights reserved. This program
 * and the accompanying materials are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors: Francisco Javier Cano Muoz (Prodevelop)  initial api implementation
 *
 ******************************************************************************/
package es.cv.gvcase.ide.navigator.search.iu.pages;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.emf.search.core.engine.IModelSearchQuery;
import org.eclipse.emf.search.core.results.AbstractModelSearchResultEntry;
import org.eclipse.emf.search.core.results.IModelResultEntry;
import org.eclipse.emf.search.core.results.IModelSearchResult;
import org.eclipse.emf.search.core.results.ModelSearchResultEvent;
import org.eclipse.emf.search.ui.Activator;
import org.eclipse.emf.search.ui.actions.AbstractModelSearchPageActionGroup;
import org.eclipse.emf.search.ui.actions.OpenInDiagramEditorAction;
import org.eclipse.emf.search.ui.actions.OpenInLegacyEditorAction;
import org.eclipse.emf.search.ui.actions.ToggleOpenButtonAction;
import org.eclipse.emf.search.ui.handlers.IModelElementEditorSelectionHandler;
import org.eclipse.emf.search.ui.pages.ModelEditorOpenEnum;
import org.eclipse.emf.search.ui.providers.DecoratingModelSearchResultLabelProvider;
import org.eclipse.emf.search.ui.services.ActionContributionExtensionManager;
import org.eclipse.emf.search.ui.services.MenuContributionExtensionManager;
import org.eclipse.emf.search.ui.services.ModelSearchParticipantTabExtensionManager;
import org.eclipse.emf.search.ui.services.ParticipantTabDescriptor;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.search.ui.ISearchResult;
import org.eclipse.search.ui.ISearchResultListener;
import org.eclipse.search.ui.ISearchResultPage;
import org.eclipse.search.ui.ISearchResultViewPart;
import org.eclipse.search.ui.SearchResultEvent;
import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
import org.eclipse.search.ui.text.Match;
import org.eclipse.search2.internal.ui.InternalSearchUI;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.progress.UIJob;

import es.cv.gvcase.ide.navigator.search.results.ElementInDiagramSearchResult;
import es.cv.gvcase.ide.navigator.search.ui.utils.ElementInDiagramSearchResultItemProvider;
import es.cv.gvcase.mdt.common.util.MultiDiagramUtil;

/**
 * 
 * @author <a href="mailto:fjcano@prodevelop.es">Francisco Javier Cano Muoz</a>
 * 
 */
public class ElementInDiagramSearchResultPage extends AbstractTextSearchViewPage
        implements ISearchResultPage, ISearchResultListener {
    private ModelEditorOpenEnum openEditorMode;
    private String fId;
    private AbstractModelSearchPageActionGroup modelSearchActionGroup;

    // Search selection wrappers
    private IModelSearchResult modelSearchResult;

    // Adapter factories based content/label providers
    private ComposedAdapterFactory adapterFactory;
    private ElementInDiagramSearchResultItemProvider searchResultItemProvider;
    private DecoratingModelSearchResultLabelProvider searchResultLabelProvider;
    private List<AdapterFactory> composeableAdapterFactories;
    private List<IModelElementEditorSelectionHandler> modelElementEditorSelectionHandlerList;

    // Menu/Action contribution enabling/visibility support helpers
    private Map<String, String> menuManagerTargetMetaModelIDMap;
    private Map<String, MenuManager> menuManagerMap;
    private Map<String, MenuManager> contributedActionIDToMenuMapping;

    // Model Result Page Actions
    private ToggleOpenButtonAction toggleOpenEditorButtonAction;
    private OpenInDiagramEditorAction openInDiagramEditorAction;
    private OpenInLegacyEditorAction openInLegacyEditorAction;

    private ActionContributionExtensionManager actionContributionExtensionManager;
    private MenuContributionExtensionManager menuContributionExtensionManager;

    // Dialog Settings
    private final static String MODEL_RESULT_PAGE_ID = "modelResultPageID"; //$NON-NLS-1$
    private final static String OPEN_DIAGRAM_TOGGLE_SELECTION_ID = "openDiagramToggleSelectionID"; //$NON-NLS-1$
    private IDialogSettings settings;

    private static final int DEFAULT_ELEMENT_LIMIT = 1000;

    public static Object MODEL_SEARCH_FAMILY = new Object();

    /**
     * Creates a Model Search Page with result tree
     */
    public ElementInDiagramSearchResultPage() {
        super(FLAG_LAYOUT_TREE);

        settings = Activator.getDefault().getDialogSettings();

        ModelSearchParticipantTabExtensionManager modelExtensibleSearchParticipantTabExtensionManager = ModelSearchParticipantTabExtensionManager
                .getInstance();

        ParticipantTabDescriptor[] participantTabDescriptors = modelExtensibleSearchParticipantTabExtensionManager
                .getModelSearchParticipantDescriptors();

        composeableAdapterFactories = new ArrayList<AdapterFactory>();
        modelElementEditorSelectionHandlerList = new ArrayList<IModelElementEditorSelectionHandler>();

        // Add AdapterFactoryLabelAdapters
        for (ParticipantTabDescriptor participantTabDescriptor : participantTabDescriptors) {
            composeableAdapterFactories.add(participantTabDescriptor.getElementComposeableAdapterFactory());
            modelElementEditorSelectionHandlerList
                    .add(participantTabDescriptor.getModelElementEditorSelectionHandler());
        }
        composeableAdapterFactories.add(new ResourceItemProviderAdapterFactory());

        adapterFactory = new ComposedAdapterFactory(composeableAdapterFactories);

        searchResultItemProvider = new ElementInDiagramSearchResultItemProvider();
        searchResultLabelProvider = new DecoratingModelSearchResultLabelProvider(adapterFactory, modelSearchResult);

        actionContributionExtensionManager = ActionContributionExtensionManager.getInstance();
        menuContributionExtensionManager = MenuContributionExtensionManager.getInstance();

        menuManagerTargetMetaModelIDMap = new HashMap<String, String>();
        menuManagerMap = new HashMap<String, MenuManager>();
        contributedActionIDToMenuMapping = new HashMap<String, MenuManager>();

        setElementLimit(new Integer(DEFAULT_ELEMENT_LIMIT));

        initResultPageActions();

        loadDialogSettings();
    }

    public void setViewPart(ISearchResultViewPart part) {
        super.setViewPart(part);
        modelSearchActionGroup = new AbstractModelSearchPageActionGroup(part);
    }

    private void initResultPageActions() {
    }

    private boolean hasAValidTargetMetaModeID(String nsURI) {
        if (modelSearchResult.getQuery() instanceof IModelSearchQuery) {
            return (((IModelSearchQuery) modelSearchResult.getQuery()).isValidTargetMetaModel(nsURI));
        }
        return false;
    }

    private void addResultPageActions(IMenuManager mgr) {
    }

    protected void fillContextMenu(IMenuManager mgr) {
    }

    protected void fillToolbar(IToolBarManager tbm) {
    }

    private void addGroupActions(IToolBarManager mgr) {
    }

    private void updateGroupingActions() {
    }

    public void init(IPageSite site) {
        super.init(site);
    }

    public void dispose() {
        super.dispose();
    }

    public StructuredViewer getViewer() {
        return super.getViewer();
    }

    @Override
    protected void handleOpen(OpenEvent event) {
        ISelection s = event.getSelection();
        if (s instanceof IStructuredSelection) {
            openEditor(((StructuredSelection) s).getFirstElement());
        }
    }

    /**
     * Obtains the workspace file corresponding to the specified resource, if it
     * has a platform-resource URI. Note that the resulting file, if not
     * <code>null</code>, may nonetheless not actually exist (as the file is
     * just a handle).
     * 
     * @param resource
     *            an EMF resource
     * 
     * @return the corresponding workspace file, or <code>null</code> if the
     *         resource's URI is not a platform-resource URI
     */
    public static IFile getFile(Resource resource) {
        if (resource instanceof Resource) {
            ResourceSet rset = resource.getResourceSet();

            return getFile(resource.getURI(), (rset != null) ? rset.getURIConverter() : null);
        }
        return null;
    }

    /**
     * Finds the file corresponding to the specified URI, using a URI converter
     * if necessary (and provided) to normalize it.
     * 
     * @param uri
     *            a URI
     * @param converter
     *            an optional URI converter (may be <code>null</code>)
     * 
     * @return the file, if available in the workspace
     */
    private static IFile getFile(URI uri, URIConverter converter) {
        if ("platform".equals(uri.scheme()) && (uri.segmentCount() > 2)) { //$NON-NLS-1$
            if ("resource".equals(uri.segment(0))) { //$NON-NLS-1$
                IPath path = new Path(URI.decode(uri.path())).removeFirstSegments(1);
                return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
            }
        } else if (uri.isFile() && !uri.isRelative()) {
            return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(uri.toFileString()));
        }
        // normalize, to see whether may we can resolve it this time
        if (converter instanceof URIConverter) {
            URI normalized = converter.normalize(uri);
            if (!uri.equals(normalized)) {
                // recurse on the new URI
                return getFile(normalized, converter);
            }
        }
        return null;
    }

    /**
     * Open editor with given EObject selected if any.
     * 
     * @param eObject
     *            EObject to be selected
     * @return the open editor part, null otherwise
     * @throws PartInitException
     */
    public IEditorPart openEditor(EObject eObject) throws PartInitException {
        if (eObject instanceof Diagram) {
            try {
                return MultiDiagramUtil.openDiagram((Diagram) eObject);
            } catch (ExecutionException ex) {
                return null;
            }
        }
        if (eObject != null) {
            Resource resource = eObject.eResource();
            if (resource != null) {
                URI uri = resource.getURI();
                if (uri != null) {
                    IEditorInput editorInput = null;
                    if (uri.isPlatformResource()) {
                        String path = uri.toPlatformString(true);
                        IResource workspaceResource = ResourcesPlugin.getWorkspace().getRoot()
                                .findMember(new Path(path));
                        if (workspaceResource instanceof IFile) {
                            editorInput = new FileEditorInput((IFile) workspaceResource);
                        }
                    } else {
                        editorInput = new URIEditorInput(uri);
                    }
                    if (editorInput != null) {
                        IWorkbench workbench = PlatformUI.getWorkbench();
                        IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage();
                        IEditorDescriptor desc = workbench.getEditorRegistry().getDefaultEditor(uri.lastSegment());
                        if (desc != null) {
                            IEditorPart editorPart = page.openEditor(editorInput, desc.getId());
                            return editorPart;
                        }
                        return null;
                    }
                }
            }
        }
        return null;
    }

    @Override
    protected void showMatch(Match match, int currentOffset, int currentLength) throws PartInitException {
        showMatch(match, currentOffset, currentLength, true);
    }

    @Override
    protected void showMatch(Match match, int currentOffset, int currentLength, boolean activate)
            throws PartInitException {

        getViewer().setSelection(new StructuredSelection(match));
        getViewer().reveal(match);
        if (activate) {
            if (match instanceof IModelResultEntry)
                openEditor(((IModelResultEntry) match).getSource());
        }
    }

    /**
     * Open editor associated to given target (mostly EMF Resources).
     * 
     * @param destination
     *            an EMF Resource
     */
    public void openEditor(final Object destination) {
        new UIJob("Open EMF Editor") {
            public IStatus runInUIThread(IProgressMonitor monitor) {
                IWorkbenchWindow dw = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
                if (dw != null) {
                    IWorkbenchPage page = dw.getActivePage();
                    if (page != null) {
                        if (destination instanceof AbstractModelSearchResultEntry) {
                            handleEObjectToOpenEditorFrom(
                                    (EObject) ((AbstractModelSearchResultEntry) destination).getSource());
                        } else if (destination instanceof Resource) {
                            if (!((Resource) destination).getContents().isEmpty()) {
                                handleEObjectToOpenEditorFrom(((Resource) destination).getContents().get(0));
                            }
                        }
                    }
                }
                return Status.OK_STATUS;
            }
        }.schedule();
    }

    /**
     * Walk all
     * 
     * @{IModelElementEditorSelectionHandler until finding an EObject selection
     *                                       compatible one.
     * @param eobject
     *            given object which open editor operation has to be handled
     */
    public void handleEObjectToOpenEditorFrom(EObject eobject) {
        try {
            IEditorPart editorPart = openEditor(eobject);
            // check whether the selected EditorPart implements the
            // IEditingDomainProvider interface
            if (editorPart instanceof IEditingDomainProvider) {
                EditingDomain editingDomain = ((IEditingDomainProvider) editorPart).getEditingDomain();
                Object object = editingDomain.getResourceSet().getEObject(EcoreUtil.getURI(eobject), true);
                for (IModelElementEditorSelectionHandler modelElementEditorSelectionHandler : modelElementEditorSelectionHandlerList) {
                    if (modelElementEditorSelectionHandler
                            .isCompatibleModelElementEditorSelectionHandler(editorPart)) {
                        modelElementEditorSelectionHandler.handleModelSearchElementSelection(editorPart, object,
                                getOpenEditorMode());
                    }
                }
            }
        } catch (PartInitException e) {
            Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                    "Editor model element Selection failed !", e));
        }
    }

    /**
     * 
     */
    public void setInput(ISearchResult search, Object viewState) {
        super.setInput(search, viewState);
        if (search instanceof ElementInDiagramSearchResult) {
            search.addListener(this);
            refreshResultPage(modelSearchResult = (ElementInDiagramSearchResult) search);
        }
    }

    public void setID(String id) {
        fId = id;
    }

    public String getID() {
        return fId;
    }

    public String getLabel() {
        return modelSearchResult == null ? "" : modelSearchResult.getLabel(); //$NON-NLS-1$
    }

    public void searchResultChanged(final SearchResultEvent e) {
        if (e instanceof ModelSearchResultEvent) {
            final ModelSearchResultEvent ssre = (ModelSearchResultEvent) e;
            // Update view must be done inside the UI thread.
            refreshResultPage(modelSearchResult = (IModelSearchResult) ssre.getSearchResult());
        }
    }

    private class RefreshResultsUIJob extends UIJob {
        Object input;

        public RefreshResultsUIJob(Object modelSearchResult) {
            super("Refresh Model Search Results");
            setPriority(Job.INTERACTIVE);
            input = modelSearchResult;
        }

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            try {
                Job.getJobManager().sleep(InternalSearchUI.FAMILY_SEARCH);
                getDisplay().asyncExec(new Runnable() {
                    public void run() {
                        if (getViewer().getControl().isDisposed())
                            return;// Status.CANCEL_STATUS;
                        if (getViewer().getContentProvider() == null)
                            return;// Status.CANCEL_STATUS;
                        DecoratingModelSearchResultLabelProvider labelProvider = (DecoratingModelSearchResultLabelProvider) getViewer()
                                .getLabelProvider();
                        labelProvider.setModelSearchResult(modelSearchResult);
                        getViewer().refresh(true);
                    }
                });
                Job.getJobManager().wakeUp(InternalSearchUI.FAMILY_SEARCH);
            } catch (Exception e) {
                return Status.CANCEL_STATUS;
            }

            return Status.OK_STATUS;
        }

        @Override
        public boolean belongsTo(Object family) {
            return MODEL_SEARCH_FAMILY.equals(family);
        }
    }

    private void refreshResultPage(Object modelSearchResult) {
        if (modelSearchResult instanceof ElementInDiagramSearchResult) {
            new RefreshResultsUIJob(modelSearchResult).schedule();
        }
    }

    @Override
    protected void configureTreeViewer(TreeViewer viewer) {
        viewer.setLabelProvider(searchResultLabelProvider);
        viewer.setContentProvider(searchResultItemProvider);
    }

    @Override
    protected void elementsChanged(Object[] objects) {/* nothing change */
    }

    public ModelEditorOpenEnum getOpenEditorMode() {
        return (openEditorMode == null) ? ModelEditorOpenEnum.TREE : openEditorMode;
    }

    public void setOpenEditorMode(ModelEditorOpenEnum openEditorMode) {
        this.openEditorMode = openEditorMode;
        storeDialogSettings();
    }

    private void storeDialogSettings() {
    }

    private void loadDialogSettings() {
    }

    @Override
    protected void clear() {
        getViewer().setInput(null);
    }

    @Override
    protected void configureTableViewer(TableViewer viewer) {
    }

    public ToggleOpenButtonAction getToggleOpenEditorButtonAction() {
        return toggleOpenEditorButtonAction;
    }

    public OpenInDiagramEditorAction getOpenInDiagramEditorAction() {
        return openInDiagramEditorAction;
    }

    public OpenInLegacyEditorAction getOpenInLegacyEditorAction() {
        return openInLegacyEditorAction;
    }
}