org.eclipse.emf.compare.tests.performance.git.GitUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.compare.tests.performance.git.GitUtil.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Obeo.
 * 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.emf.compare.tests.performance.git;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.IModelProviderDescriptor;
import org.eclipse.core.resources.mapping.ModelProvider;
import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceMappingContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.op.ConnectProviderOperation;
import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
import org.eclipse.egit.core.synchronize.GitSubscriberMergeContext;
import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.team.core.subscribers.Subscriber;
import org.eclipse.team.core.subscribers.SubscriberScopeManager;

import com.google.common.base.Throwables;

/**
 * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
 *
 */
@SuppressWarnings("restriction")
public final class GitUtil {

    /**
     * This will unzip the repository contained in the given zip location in the given destination.
     * 
     * @param zipLocation
     *            the zip (that contains the repository) location.
     * @param destination
     *            the destination
     * @param monitor
     *            {@link IProgressMonitor} that will be used to monitor the operation.
     */
    public static void unzipRepo(URL zipLocation, String destination, IProgressMonitor monitor) {

        try {
            final ZipInputStream zipFileStream = new ZipInputStream(zipLocation.openStream());
            ZipEntry zipEntry = zipFileStream.getNextEntry();

            while (zipEntry != null) {
                // We will construct the new file but we will strip off the project
                // directory from the beginning of the path because we have already
                // created the destination project for this zip.
                final File file = new File(destination, zipEntry.getName());

                if (!zipEntry.isDirectory()) {

                    /*
                     * Copy files (and make sure parent directory exist)
                     */
                    final File parentFile = file.getParentFile();
                    if (null != parentFile && !parentFile.exists()) {
                        parentFile.mkdirs();
                    }

                    OutputStream os = null;

                    try {
                        os = new FileOutputStream(file);

                        final int bufferSize = 102400;
                        final byte[] buffer = new byte[bufferSize];
                        while (true) {
                            final int len = zipFileStream.read(buffer);
                            if (zipFileStream.available() == 0) {
                                break;
                            }
                            os.write(buffer, 0, len);
                        }
                    } finally {
                        if (null != os) {
                            os.close();
                        }
                    }
                }

                zipFileStream.closeEntry();
                zipEntry = zipFileStream.getNextEntry();
            }
        } catch (final IOException e) {
            Throwables.propagate(e);
        }
    }

    /**
     * Delete the repository (and all files contained in).
     * 
     * @param repository
     *             the File representing the repository.
     */
    public static void deleteRepo(File repository) {
        if (repository.exists()) {
            File[] files = repository.listFiles();
            if (null != files) {
                for (int i = 0; i < files.length; i++) {
                    if (files[i].isDirectory()) {
                        deleteRepo(files[i]);
                    } else {
                        files[i].delete();
                    }
                }
            }
            repository.delete();
        }
    }

    /**
     * Import the project from the given repository.
     * 
     * @param repository
     *            the given repository.
     * @param projectFilePath
     *            the path containing the project in the repository.
     * @return the imported project, or null if import step fails.
     */
    public static IProject importProjectFromRepo(File repository, String projectFilePath) {
        try {
            IProjectDescription description = ResourcesPlugin.getWorkspace()
                    .loadProjectDescription(new Path(repository.getPath() + File.separator + projectFilePath));
            IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(description.getName());
            project.create(description, new NullProgressMonitor());
            project.open(new NullProgressMonitor());

            return project;
        } catch (CoreException e) {
            Throwables.propagate(e);
        }
        return null;
    }

    /**
     * Import all projects contain in the given repository.
     * 
     * @param repository
     *            the given repository.
     */
    public static Collection<IProject> importProjectsFromRepo(File repository) {
        Collection<IProject> projects = new ArrayList<IProject>();
        try {
            Collection<File> projectsFromRepo = getProjectsFromRepo(repository);
            for (File file : projectsFromRepo) {
                IProjectDescription description = ResourcesPlugin.getWorkspace()
                        .loadProjectDescription(new Path(file.getPath()));
                IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(description.getName());
                project.create(description, new NullProgressMonitor());
                project.open(new NullProgressMonitor());
                projects.add(project);
            }
        } catch (CoreException e) {
            Throwables.propagate(e);
        }
        return projects;
    }

    /**
     * Get the ".projects" files from the given repository.
     * @param repository
     *            the given repository.
     * @return the ".projects" files from the given repository.
     */
    public static Collection<File> getProjectsFromRepo(File repository) {
        List<File> projects = new ArrayList<File>();
        if (repository.exists()) {
            File[] files = repository.listFiles();
            if (null != files) {
                for (int i = 0; i < files.length; i++) {
                    if (files[i].isDirectory()) {
                        projects.addAll(getProjectsFromRepo(files[i]));
                    } else if (files[i].getName().endsWith(IProjectDescription.DESCRIPTION_FILE_NAME)) {
                        projects.add(files[i]);
                    }
                }
            }
        }
        return projects;
    }

    /**
     * Connect given projects to the given repository.
     * @param repository
     *            the given repository.
     * @param projects
     *            the given projects.
     */
    public static void connectProjectsToRepo(Repository repository, Collection<IProject> projects) {
        for (IProject project : projects) {
            try {
                ConnectProviderOperation op = new ConnectProviderOperation(project, repository.getDirectory());
                op.execute(new NullProgressMonitor());
            } catch (CoreException e) {
                Throwables.propagate(e);
            }
        }
    }

    /**
     * Simulate a comparison between the two given references and returns back the subscriber that can provide
     * all computed synchronization information.
     * 
     * @param sourceRef
     *            Source reference (i.e. "left" side of the comparison).
     * @param targetRef
     *            Target reference (i.e. "right" side of the comparison).
     * @param comparedFile
     *            The file we are comparing (that would be the file right-clicked into the workspace).
     * @return The created subscriber.
     */
    public static Subscriber createSubscriberForComparison(Repository repository, String sourceRef,
            String targetRef, IFile comparedFile, List<Runnable> disposers) throws IOException {
        final GitSynchronizeData data = new GitSynchronizeData(repository, sourceRef, targetRef, false);
        final GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
        final ResourceMapping[] mappings = getResourceMappings(comparedFile);
        final GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(dataSet);
        subscriber.init(new NullProgressMonitor());

        final RemoteResourceMappingContext remoteContext = new GitSubscriberResourceMappingContext(subscriber,
                dataSet);
        final SubscriberScopeManager manager = new SubscriberScopeManager(subscriber.getName(), mappings,
                subscriber, remoteContext, true);
        final GitSubscriberMergeContext context = new GitSubscriberMergeContext(subscriber, manager, dataSet);
        disposers.add(new Runnable() {
            public void run() {
                manager.dispose();
                context.dispose();
                subscriber.dispose();
            }
        });
        return context.getSubscriber();
    }

    /**
     * This will query all model providers for those that are enabled on the given file and list all mappings
     * available for that file.
     * 
     * @param file
     *            The file for which we need the associated resource mappings.
     * @return All mappings available for that file.
     */
    private static ResourceMapping[] getResourceMappings(IFile file) {
        final IModelProviderDescriptor[] modelDescriptors = ModelProvider.getModelProviderDescriptors();

        final Set<ResourceMapping> mappings = new LinkedHashSet<ResourceMapping>();
        for (IModelProviderDescriptor candidate : modelDescriptors) {
            try {
                final IResource[] resources = candidate.getMatchingResources(new IResource[] { file, });
                if (resources.length > 0) {
                    // get mappings from model provider if there are matching resources
                    final ModelProvider model = candidate.getModelProvider();
                    final ResourceMapping[] modelMappings = model.getMappings(file,
                            ResourceMappingContext.LOCAL_CONTEXT, null);
                    for (ResourceMapping mapping : modelMappings) {
                        mappings.add(mapping);
                    }
                }
            } catch (CoreException e) {
                Throwables.propagate(e);
            }
        }
        return mappings.toArray(new ResourceMapping[mappings.size()]);
    }
}