<commit_before>/*******************************************************************************
 * Copyright (C) 2016 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
 *******************************************************************************/
package org.eclipse.egit.core.synchronize;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.egit.core.internal.util.ProjectUtil;
import org.eclipse.egit.core.internal.util.ResourceUtil;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.variants.IResourceVariant;

/**
 * Extension of {@link GitResourceVariantTreeSubscriber} that is able to lazily
 * load data from resources that were out of the initial scope defined by the
 * provided {@link GitSynchronizeDataSet}. This is supposed to be used by
 * logical model aware {@link RemoteResourceMappingContext}s to allow loading
 * the variants of resources included in logical models.
 */
public class GitLazyResourceVariantTreeSubscriber
		extends GitResourceVariantTreeSubscriber {

	/**
	 * @param gsds
	 */
	public GitLazyResourceVariantTreeSubscriber(GitSynchronizeDataSet gsds) {
		super(gsds);
	}

	@Override
	public boolean isSupervised(IResource res) throws TeamException {
		return true;
	}

	@Override
	protected SyncInfo getSyncInfo(IResource local, IResourceVariant base,
			IResourceVariant remote) throws TeamException {
		if (getDataSet().shouldBeIncluded(local)) {
			return super.getSyncInfo(local, base, remote);
		}
		// Otherwise, the given resource was not in the original scope this
		// subscriber was built. However, we want to access it anyway.

		IProject project = local.getProject();
		Repository repo = ResourceUtil.getRepository(local);
		if (repo == null) {
			return null;
		}
		GitSynchronizeData data = getDataSet().getData(project);
		if (data == null) {
			for (GitSynchronizeData sd : getDataSet()) {
				if (repo.equals(sd.getRepository())) {
					data = sd;
					break;
				}
			}
		}
		if (data == null) {
			return null;
		}
		return getSyncInfo(local, base, remote, data);
	}

	/**
	 * Provide a {@link SyncInfo} for the given resource that is not part of the
	 * resources with which the given {@link GitSynchronizeData} was created
	 * (which implies that the synchronization data for this resource is not yet
	 * cached).
	 *
	 * @param local
	 * @param base
	 * @param remote
	 * @param gsd
	 *            Data that describe the synchronization to perform
	 * @return a new and initialized instance of {@link GitSyncInfo} for the
	 *         given resource that was not part of the resources to synchronize.
	 *         Returns <code>null</code> if anything goes wrong (corrupted repo,
	 *         IO problem, ...)
	 */
	private SyncInfo getSyncInfo(IResource local, IResourceVariant base,
			IResourceVariant remote, @NonNull GitSynchronizeData gsd) {
		GitSyncObjectCache repoCache = getCache().get(gsd.getRepository());
		if (repoCache == null) {
			return null;
		}
		if (GitSyncCache.loadDataFromGit(gsd, null, repoCache)) {
			try {
				return getSyncInfo(local, base, remote, gsd.getRepository());
			} catch (TeamException e) {
				Activator.logError(e.getMessage(), e);
			}
		}
		return null;
	}

	@Override
	public String getName() {
		return CoreText.GitLazyResourceVariantTreeSubscriber_name;
	}

	@Override
	public IResource[] roots() {
		List<IResource> projects = new ArrayList<>();
		try {
			for (GitSynchronizeData data : getDataSet()) {<commit_msg>Avoid multiple tree-walks in model-aware git synchronizations<commit_after>/*******************************************************************************
 * Copyright (C) 2017 Obeo 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
 *******************************************************************************/
package org.eclipse.egit.core.synchronize;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.RemoteResourceMappingContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.egit.core.internal.util.ProjectUtil;
import org.eclipse.egit.core.internal.util.ResourceUtil;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.synchronize.SyncInfo;
import org.eclipse.team.core.variants.IResourceVariant;

/**
 * Extension of {@link GitResourceVariantTreeSubscriber} that is able to lazily
 * load data from resources that were out of the initial scope defined by the
 * provided {@link GitSynchronizeDataSet}. This is supposed to be used by
 * logical model aware {@link RemoteResourceMappingContext}s to allow loading
 * the variants of resources included in logical models.
 */
public class GitLazyResourceVariantTreeSubscriber
		extends GitResourceVariantTreeSubscriber {

	private boolean isLoaded;

	private boolean isValid;

	/**
	 * @param gsds
	 */
	public GitLazyResourceVariantTreeSubscriber(GitSynchronizeDataSet gsds) {
		super(gsds);
	}

	@Override
	public boolean isSupervised(IResource res) throws TeamException {
		return true;
	}

	@Override
	protected SyncInfo getSyncInfo(IResource local, IResourceVariant base,
			IResourceVariant remote) throws TeamException {
		if (getDataSet().shouldBeIncluded(local)) {
			return super.getSyncInfo(local, base, remote);
		}
		// Otherwise, the given resource was not in the original scope this
		// subscriber was built. However, we want to access it anyway.

		IProject project = local.getProject();
		Repository repo = ResourceUtil.getRepository(local);
		if (repo == null) {
			return null;
		}
		GitSynchronizeData data = getDataSet().getData(project);
		if (data == null) {
			for (GitSynchronizeData sd : getDataSet()) {
				if (repo.equals(sd.getRepository())) {
					data = sd;
					break;
				}
			}
		}
		if (data == null) {
			return null;
		}
		return getSyncInfo(local, base, remote, data);
	}

	/**
	 * Provide a {@link SyncInfo} for the given resource that is not part of the
	 * resources with which the given {@link GitSynchronizeData} was created
	 * (which implies that the synchronization data for this resource is not yet
	 * cached).
	 *
	 * @param local
	 * @param base
	 * @param remote
	 * @param gsd
	 *            Data that describe the synchronization to perform
	 * @return a new and initialized instance of {@link GitSyncInfo} for the
	 *         given resource that was not part of the resources to synchronize.
	 *         Returns <code>null</code> if anything goes wrong (corrupted repo,
	 *         IO problem, ...)
	 */
	private SyncInfo getSyncInfo(IResource local, IResourceVariant base,
			IResourceVariant remote, @NonNull GitSynchronizeData gsd) {
		GitSyncObjectCache repoCache = getCache().get(gsd.getRepository());
		if (repoCache == null) {
			return null;
		}
		if (!isLoaded) {
			isLoaded = true;
			isValid = GitSyncCache.loadDataFromGit(gsd, null, repoCache);
		}
		if (isValid) {
			try {
				return getSyncInfo(local, base, remote, gsd.getRepository());
			} catch (TeamException e) {
				Activator.logError(e.getMessage(), e);
			}
		}
		return null;
	}

	@Override
	public String getName() {
		return CoreText.GitLazyResourceVariantTreeSubscriber_name;
	}

	@Override
	public IResource[] roots() {
		List<IResource> projects = new ArrayList<>();
		try {
			for (GitSynchronizeData data : getDataSet()) {
{'fraction_non_alphanumeric': 0.12921412955931424, 'fraction_numerical': 0.0018409849269359108, 'mean_word_length': 4.382043343653251, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1571527', 'n_tokens_mistral': 2683, 'n_tokens_neox': 2456, 'n_words': 728}