com.nextep.designer.vcs.ui.services.impl.ComparisonUIManager.java Source code

Java tutorial

Introduction

Here is the source code for com.nextep.designer.vcs.ui.services.impl.ComparisonUIManager.java

Source

/*******************************************************************************
 * Copyright (c) 2011 neXtep Software and contributors.
 * All rights reserved.
 *
 * This file is part of neXtep designer.
 *
 * NeXtep designer is free software: you can redistribute it 
 * and/or modify it under the terms of the GNU General Public 
 * License as published by the Free Software Foundation, either 
 * version 3 of the License, or any later version.
 *
 * NeXtep designer is distributed in the hope that it will be 
 * useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     neXtep Softwares - initial API and implementation
 *******************************************************************************/
package com.nextep.designer.vcs.ui.services.impl;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import com.nextep.datadesigner.Designer;
import com.nextep.datadesigner.exception.ErrorException;
import com.nextep.datadesigner.model.IElementType;
import com.nextep.datadesigner.model.INamedObject;
import com.nextep.datadesigner.model.IReference;
import com.nextep.datadesigner.model.IReferenceable;
import com.nextep.datadesigner.vcs.services.VersionHelper;
import com.nextep.designer.core.helpers.NameHelper;
import com.nextep.designer.vcs.VCSPlugin;
import com.nextep.designer.vcs.model.IComparisonItem;
import com.nextep.designer.vcs.model.IComparisonListener;
import com.nextep.designer.vcs.model.IComparisonManager;
import com.nextep.designer.vcs.model.IMergeStrategy;
import com.nextep.designer.vcs.model.IVersionInfo;
import com.nextep.designer.vcs.ui.VCSUIMessages;
import com.nextep.designer.vcs.ui.compare.IComparisonEditorProvider;
import com.nextep.designer.vcs.ui.services.IComparisonUIManager;

/**
 * The UI comparison manager allows UI based comparisons and UI-synchronized listener calls. It also
 * use asynchronous UI jobs to execute the required tasks and thus may not return the results
 * directly.<br>
 * When using the {@link ComparisonUIManager}, callers should only rely on listeners to get access
 * to resulting information because of the asynchronous processes.<br>
 * Callers willing to have synchronous access to comparison results should access the non-UI
 * comparison manager and implement the UI progress themselves.
 * 
 * @author Christophe Fondacci
 */
public class ComparisonUIManager implements IComparisonUIManager {

    private Map<IComparisonListener, IComparisonListener> listenerUIMap;
    private IComparisonEditorProvider currentProvider;
    private final static String EXTENSION_ID = "com.neXtep.designer.vcs.ui.comparisonEditorProvider"; //$NON-NLS-1$
    private final static Log log = LogFactory.getLog(ComparisonUIManager.class);
    private List<IComparisonEditorProvider> cachedProviders;
    private Map<String, IComparisonEditorProvider> defaultProviderTypeMap;
    private IComparisonManager comparisonManager;

    public ComparisonUIManager() {
        listenerUIMap = new HashMap<IComparisonListener, IComparisonListener>();
        defaultProviderTypeMap = new HashMap<String, IComparisonEditorProvider>();
        initializeComparisonEditorProviders();
    }

    @Override
    public void addComparisonListener(final IComparisonListener listener) {
        // Wrapping into a thread-safe UI listener which will execute all
        // listener call on the UI thread
        final IComparisonListener uiListener = new IComparisonListener() {

            @Override
            public void newComparison(final String description, final IComparisonItem... comparisonItems) {
                Display.getDefault().syncExec(new Runnable() {

                    @Override
                    public void run() {
                        listener.newComparison(description, comparisonItems);
                    }
                });
            }
        };
        listenerUIMap.put(listener, uiListener);
        comparisonManager.addComparisonListener(uiListener);
    }

    @Override
    public void compare(final IReference refElementToCompare, final IVersionInfo sourceVersion,
            final IVersionInfo targetVersion) {
        Job j = new Job(VCSUIMessages.getString("comparison.jobTitle")) { //$NON-NLS-1$

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                String name;
                try {
                    IReferenceable r = VersionHelper.getReferencedItem(refElementToCompare);
                    if (r instanceof INamedObject) {
                        name = ((INamedObject) r).getName();
                    } else {
                        name = NameHelper.getQualifiedName(r);
                    }
                } catch (ErrorException e) {
                    name = "Unknown"; //$NON-NLS-1$
                }
                monitor.beginTask(MessageFormat.format(VCSUIMessages.getString("comparison.jobTask"), name, //$NON-NLS-1$
                        sourceVersion == null ? "-" //$NON-NLS-1$
                                : sourceVersion.getLabel(),
                        targetVersion == null ? "-" : targetVersion.getLabel()), 1); //$NON-NLS-1$
                VCSPlugin.getComparisonManager().compare(refElementToCompare, sourceVersion, targetVersion);
                monitor.done();
                return Status.OK_STATUS;
            }

        };
        j.setUser(true);
        j.schedule();
    }

    @Override
    public <V extends IReferenceable> List<IComparisonItem> compare(final Collection<V> sources,
            final Collection<V> targets, final IMergeStrategy strategy, final boolean noSwap) {
        Job j = new Job(VCSUIMessages.getString("comparison.jobTitle")) { //$NON-NLS-1$

            @Override
            protected IStatus run(IProgressMonitor monitor) {
                monitor.beginTask(VCSUIMessages.getString("comparison.jobTitle"), 1); //$NON-NLS-1$
                VCSPlugin.getComparisonManager().compare(sources, targets, strategy, noSwap);
                monitor.done();
                return Status.OK_STATUS;
            }
        };
        j.setUser(true);
        j.schedule();
        return Collections.emptyList();
    }

    @Override
    public void removeComparisonListener(IComparisonListener listener) {
        VCSPlugin.getComparisonManager().removeComparisonListener(listenerUIMap.get(listener));
        listenerUIMap.remove(listener);
    }

    @Override
    public void setComparisonEditorProvider(IComparisonEditorProvider editorProvider) {
        if (editorProvider != null) {
            this.currentProvider = editorProvider;
        }
    }

    @Override
    public IComparisonEditorProvider getComparisonEditorProvider(IElementType type) {
        final IComparisonEditorProvider specificProvider = type == null ? null
                : defaultProviderTypeMap.get(type.getId());
        return specificProvider != null ? specificProvider : currentProvider;
    }

    @Override
    public List<IComparisonEditorProvider> getAvailableComparisonEditorProviders(IElementType type) {
        final IComparisonEditorProvider specificProvider = type == null ? null
                : defaultProviderTypeMap.get(type.getId());
        List<IComparisonEditorProvider> providers = cachedProviders;
        if (specificProvider != null) {
            providers = new ArrayList<IComparisonEditorProvider>(cachedProviders);
            providers.add(specificProvider);
        }

        return providers;
    }

    private void initializeComparisonEditorProviders() {
        // Retrieving contributions for comparison editor providers
        Collection<IConfigurationElement> elts = Designer.getInstance().getExtensions(EXTENSION_ID, "class", "*"); //$NON-NLS-1$ //$NON-NLS-2$
        cachedProviders = new ArrayList<IComparisonEditorProvider>();
        for (IConfigurationElement elt : elts) {
            try {
                IComparisonEditorProvider provider = (IComparisonEditorProvider) elt
                        .createExecutableExtension("class"); //$NON-NLS-1$
                final Boolean isDefault = Boolean.valueOf(elt.getAttribute("default")); //$NON-NLS-1$
                if (isDefault != null && isDefault.booleanValue()) {
                    currentProvider = provider;
                }
                final String defaultTypeId = elt.getAttribute("typeIdRestriction"); //$NON-NLS-1$
                if (defaultTypeId != null && !"".equals(defaultTypeId.trim())) { //$NON-NLS-1$
                    defaultProviderTypeMap.put(defaultTypeId.trim(), provider);
                } else {
                    cachedProviders.add(provider);
                }
            } catch (CoreException e) {
                log.error("Contribution error: Unable to instantiate a comparison editor provider from " //$NON-NLS-1$
                        + elt.getContributor().getName());
            }
        }
        // Sorting providers by label
        Collections.sort(cachedProviders, new Comparator<IComparisonEditorProvider>() {

            public int compare(IComparisonEditorProvider o1, IComparisonEditorProvider o2) {
                if (o1 != null && o2 != null) {
                    final String l1 = o1.getLabel();
                    final String l2 = o2.getLabel();
                    return (l1 == null ? "" : l1).compareTo(l2 == null ? "" : l2); //$NON-NLS-1$ //$NON-NLS-2$
                } else if (o2 == null) {
                    return o1 == null ? 0 : 1;
                } else {
                    return -1;
                }
            };
        });
    }

    @Override
    public void openComparisonEditor(IComparisonItem compItem, IComparisonEditorProvider provider) {
        try {
            final IEditorInput input = provider.getEditorInput(compItem);
            final String editorId = provider.getEditorId(compItem);
            if (input != null && editorId != null) {
                // Opening our multi editor
                if (PlatformUI.getWorkbench() != null
                        && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null
                        && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
                    PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(input,
                            editorId);
                }
            }
        } catch (PartInitException e) {
            log.error(VCSUIMessages.getString("comparison.openComparisonError") + ": " //$NON-NLS-1$ //$NON-NLS-2$
                    + e.getMessage(), e);
        }
    }

    @Override
    public void showComparison(String description, IComparisonItem... items) {
        notifyNewComparison(description, items);
    }

    @Override
    public void notifyNewComparison(String description, IComparisonItem... comparisonItems) {
        getComparisonManager().notifyNewComparison(description, comparisonItems);
    }

    private IComparisonManager getComparisonManager() {
        return comparisonManager;
    }

    public void setComparisonManager(IComparisonManager comparisonManager) {
        this.comparisonManager = comparisonManager;
    }
}