org.eclipse.pde.api.tools.ui.internal.wizards.CompareOperation.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.pde.api.tools.ui.internal.wizards.CompareOperation.java

Source

/*******************************************************************************
 * Copyright (c) 2009, 2014 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.pde.api.tools.ui.internal.wizards;

import java.util.Arrays;
import java.util.Comparator;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.api.tools.internal.ApiBaselineManager;
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
import org.eclipse.pde.api.tools.internal.provisional.Factory;
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
import org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator;
import org.eclipse.pde.api.tools.internal.provisional.comparator.ApiScope;
import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiScope;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot;
import org.eclipse.pde.api.tools.ui.internal.actions.ActionMessages;
import org.eclipse.pde.api.tools.ui.internal.actions.DeltaSession;

/**
 * Default operation for comparing a given selection to the given API baseline
 * 
 * @since 1.0.1
 */
public class CompareOperation extends Job {

    private IApiBaseline baseline = null;
    private IStructuredSelection selection = null;

    /**
     * Constructor
     * 
     * @param baseline
     * @param selection
     */
    public CompareOperation(IApiBaseline baseline, IStructuredSelection selection) {
        super(ActionMessages.CompareWithAction_comparing_apis);
        this.baseline = baseline;
        Assert.isNotNull(this.baseline);
        this.selection = selection;
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.
     * IProgressMonitor)
     */
    @Override
    protected IStatus run(IProgressMonitor monitor) {
        monitor.beginTask(ActionMessages.CompareDialogCollectingElementTaskName, IProgressMonitor.UNKNOWN);
        String baselineName = this.baseline.getName();
        final IApiScope scope = walkStructureSelection(this.selection, monitor);
        try {
            monitor.subTask(ActionMessages.CompareDialogComputeDeltasTaskName);
            try {
                IDelta delta = ApiComparator.compare(scope, baseline, VisibilityModifiers.API, false, monitor);
                if (delta == null) {
                    // we don't want to continue. The .log file should already
                    // contain details about the failure
                    return Status.CANCEL_STATUS;
                }
                int size = this.selection.size();
                String description = NLS.bind(ActionMessages.CompareWithAction_compared_with_against,
                        new Object[] { new Integer(size), baselineName, new Integer(delta.getChildren().length) });
                if (size == 0) {
                    description = ActionMessages.CompareWithAction_compared_against_nothing;
                } else if (size == 1) {
                    Object selectedElement = this.selection.getFirstElement();
                    String elementName = selectedElement instanceof IJavaElement
                            ? ((IJavaElement) selectedElement).getElementName()
                            : selectedElement.toString();
                    description = NLS.bind(ActionMessages.CompareWithAction_compared_project_with,
                            new Object[] { elementName, baselineName, new Integer(delta.getChildren().length) });
                }
                ApiPlugin.getDefault().getSessionManager()
                        .addSession(new DeltaSession(description, delta, baselineName), true);
                return Status.OK_STATUS;
            } catch (CoreException e) {
                ApiPlugin.log(e);
            } catch (OperationCanceledException e) {
                // ignore
            }
        } finally {
            monitor.done();
        }
        return Status.CANCEL_STATUS;
    }

    /**
     * @param structuredSelection
     * @param monitor
     * @return the scope
     */
    public static ApiScope walkStructureSelection(IStructuredSelection structuredSelection,
            IProgressMonitor monitor) {
        Object[] selected = structuredSelection.toArray();
        ApiScope scope = new ApiScope();
        IApiBaseline workspaceBaseline = ApiBaselineManager.getManager().getWorkspaceBaseline();
        if (workspaceBaseline == null) {
            return scope;
        }
        Arrays.sort(selected, new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof IJavaElement && o2 instanceof IJavaElement) {
                    IJavaElement element = (IJavaElement) o1;
                    IJavaElement element2 = (IJavaElement) o2;
                    return element.getElementType() - element2.getElementType();
                }
                return 0;
            }
        });
        int length = selected.length;
        for (int i = 0; i < length; i++) {
            Object currentSelection = selected[i];
            if (currentSelection instanceof IJavaElement) {
                IJavaElement element = (IJavaElement) currentSelection;
                IJavaProject javaProject = element.getJavaProject();
                try {
                    switch (element.getElementType()) {
                    case IJavaElement.COMPILATION_UNIT: {
                        ICompilationUnit compilationUnit = (ICompilationUnit) element;
                        IApiComponent apiComponent = workspaceBaseline
                                .getApiComponent(javaProject.getElementName());
                        if (apiComponent != null) {
                            addElementFor(compilationUnit, apiComponent, scope);
                        }
                        break;
                    }
                    case IJavaElement.PACKAGE_FRAGMENT: {
                        IPackageFragment fragment = (IPackageFragment) element;
                        IApiComponent apiComponent = workspaceBaseline
                                .getApiComponent(javaProject.getElementName());
                        IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) fragment
                                .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
                        boolean isArchive = false;
                        if (packageFragmentRoot != null) {
                            isArchive = packageFragmentRoot.isArchive();
                        }
                        if (apiComponent != null) {
                            addElementFor(fragment, isArchive, apiComponent, scope);
                        }
                        break;
                    }
                    case IJavaElement.PACKAGE_FRAGMENT_ROOT: {
                        IPackageFragmentRoot fragmentRoot = (IPackageFragmentRoot) element;
                        IApiComponent apiComponent = workspaceBaseline
                                .getApiComponent(javaProject.getElementName());
                        if (apiComponent != null) {
                            addElementFor(fragmentRoot, apiComponent, scope);
                        }
                        break;
                    }
                    case IJavaElement.JAVA_PROJECT:
                        IApiComponent apiComponent = workspaceBaseline
                                .getApiComponent(javaProject.getElementName());
                        if (apiComponent != null) {
                            scope.addElement(apiComponent);
                        }
                        break;
                    default:
                        break;
                    }
                } catch (JavaModelException e) {
                    ApiPlugin.log(e);
                } catch (CoreException e) {
                    ApiPlugin.log(e);
                }
            }
        }
        return scope;
    }

    private static void addElementFor(IPackageFragmentRoot fragmentRoot, IApiComponent apiComponent, ApiScope scope)
            throws JavaModelException, CoreException {
        boolean isArchive = fragmentRoot.isArchive();
        IJavaElement[] packageFragments = fragmentRoot.getChildren();
        for (int j = 0, max2 = packageFragments.length; j < max2; j++) {
            IPackageFragment packageFragment = (IPackageFragment) packageFragments[j];
            addElementFor(packageFragment, isArchive, apiComponent, scope);
        }
    }

    private static void addElementFor(IPackageFragment packageFragment, boolean isArchive,
            IApiComponent apiComponent, ApiScope scope) throws JavaModelException, CoreException {

        // add package fragment elements only if this is an API package
        IApiDescription apiDescription = apiComponent.getApiDescription();
        IApiAnnotations annotations = apiDescription
                .resolveAnnotations(Factory.packageDescriptor(packageFragment.getElementName()));
        if (annotations == null || !VisibilityModifiers.isAPI(annotations.getVisibility())) {
            return;
        }
        if (isArchive) {
            IClassFile[] classFiles = packageFragment.getClassFiles();
            for (int i = 0, max = classFiles.length; i < max; i++) {
                addElementFor(classFiles[i], apiComponent, scope);
            }
        } else {
            ICompilationUnit[] units = packageFragment.getCompilationUnits();
            for (int i = 0, max = units.length; i < max; i++) {
                addElementFor(units[i], apiComponent, scope);
            }
        }
    }

    private static void addElementFor(IClassFile classFile, IApiComponent apiComponent, ApiScope scope) {
        try {
            IApiTypeRoot typeRoot = apiComponent.findTypeRoot(classFile.getType().getFullyQualifiedName());
            if (typeRoot != null) {
                scope.addElement(typeRoot);
            }
        } catch (CoreException e) {
            ApiPlugin.log(e);
        }
    }

    private static void addElementFor(ICompilationUnit compilationUnit, IApiComponent component, ApiScope scope)
            throws JavaModelException {
        IType[] types = compilationUnit.getTypes();
        for (int i = 0, max = types.length; i < max; i++) {
            try {
                IApiTypeRoot typeRoot = component.findTypeRoot(types[i].getFullyQualifiedName());
                if (typeRoot != null) {
                    scope.addElement(typeRoot);
                }
            } catch (CoreException e) {
                ApiPlugin.log(e);
            }
        }
    }
}