| /******************************************************************************* |
| * 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, false); |
| 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()]); |
| } |
| |
| } |