org.eclipse.egit.core.internal.job.RuleUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.egit.core.internal.job.RuleUtil.java

Source

/*******************************************************************************
 * Copyright (C) 2011, Jens Baumgart <jens.baumgart@sap.com>
 * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
 *
 * 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
 *******************************************************************************/
package org.eclipse.egit.core.internal.job;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.egit.core.internal.util.ResourceUtil;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.jgit.lib.Repository;

/**
 * Utility class for scheduling rules
 *
 */
public class RuleUtil {

    /**
     * Calculates an {@link ISchedulingRule} for Jobs working on the index of a
     * repository. The rule consists of all projects belonging to the
     * repository. If you schedule two jobs working on different resources of
     * the same repository you have to ensure that these jobs cannot run in
     * parallel because the Git index lock fails if another thread is already
     * owning the lock. Thus it is a good practice to lock all projects
     * belonging to a Git repository when executing a write operation on the
     * index of a repository in a Job.
     *
     * @param repository
     * @return scheduling rule
     */
    public static ISchedulingRule getRule(Repository repository) {
        IProject[] projects = getProjects(repository);
        if (projects.length == 0)
            return null;
        return new MultiRule(projects);
    }

    /**
     * Calculates a {@link ISchedulingRule} for Jobs working on the index of
     * multiple repositories, see {@link #getRule(Repository)}.
     *
     * @param repositories
     * @return scheduling rule
     */
    public static ISchedulingRule getRuleForRepositories(Collection<Repository> repositories) {
        ISchedulingRule result = null;
        for (Repository repository : repositories) {
            ISchedulingRule rule = getRule(repository);
            result = MultiRule.combine(result, rule);
        }
        return result;
    }

    /**
     * Calculates a {@link ISchedulingRule} for all repositories related to the
     * given resources.
     *
     * @see RuleUtil#getRule(Repository)
     * @param resources
     * @return scheduling rule
     */
    public static ISchedulingRule getRuleForRepositories(IResource[] resources) {
        ISchedulingRule result = null;
        Set<Repository> repositories = new HashSet<Repository>();
        for (IResource resource : resources) {
            RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
            if (mapping != null)
                repositories.add(mapping.getRepository());
        }
        for (Repository repository : repositories) {
            ISchedulingRule rule = getRule(repository);
            result = MultiRule.combine(result, rule);
        }
        return result;
    }

    /**
     * Calculates a {@link ISchedulingRule} for all containers of the paths that
     * are in the workspace.
     *
     * @param paths
     * @return scheduling rule
     */
    public static ISchedulingRule getRuleForContainers(Collection<IPath> paths) {
        List<ISchedulingRule> rules = new ArrayList<ISchedulingRule>();
        IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
        for (IPath path : paths) {
            IResource resource = ResourceUtil.getResourceForLocation(path);
            if (resource != null) {
                IContainer container = resource.getParent();
                ISchedulingRule rule = ruleFactory.modifyRule(container);
                if (rule != null)
                    rules.add(rule);
            }
        }
        if (rules.size() == 0)
            return null;
        else
            return new MultiRule(rules.toArray(new ISchedulingRule[rules.size()]));
    }

    private static IProject[] getProjects(Repository repository) {
        final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        List<IProject> result = new ArrayList<IProject>();
        final File parentFile = repository.getWorkTree();
        for (IProject p : projects) {
            IPath projectLocation = p.getLocation();
            if (projectLocation == null)
                continue;
            if (projectLocation.toFile().getAbsolutePath().startsWith(parentFile.getAbsolutePath()))
                result.add(p);
        }
        return result.toArray(new IProject[result.size()]);
    }

}