diff options
Diffstat (limited to 'bundles/org.eclipse.team.core/src/org/eclipse/team')
96 files changed, 0 insertions, 16214 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/DefaultRepositoryProviderType.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/DefaultRepositoryProviderType.java deleted file mode 100644 index 4fabc2bda..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/DefaultRepositoryProviderType.java +++ /dev/null @@ -1,18 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -/* - */ -public final class DefaultRepositoryProviderType extends RepositoryProviderType { - - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java deleted file mode 100644 index eaab301ba..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IFileTypeInfo.java +++ /dev/null @@ -1,39 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -/** - * A file type info specifies both the file extension and the - * corresponding file type. - * - * @since 2.0 - */ -public interface IFileTypeInfo { - /** - * Returns the string specifying the file extension - * - * @return the file extension - */ - public String getExtension(); - - /** - * Returns the file type for files ending with the corresponding - * extension. - * - * Valid values are: - * Team.UNKNOWN - * Team.TEXT - * Team.BINARY - * - * @return the file type - */ - public int getType(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IIgnoreInfo.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IIgnoreInfo.java deleted file mode 100644 index 86bf1ba9a..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IIgnoreInfo.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -/** - * An ignore info specifies both the pattern and the enabled state - * of a globally ignored pattern. - * - * @since 2.0 - */ -public interface IIgnoreInfo { - /** - * Return the string specifying the pattern of this ignore. The string - * may include the wildcard characters '*' and '?'. If you wish to - * include either of these characters verbatim (i.e. you do not wish - * them to expand to wildcards), you must escape them with a backslash '\'. - * <p> - * If you are using string literals in Java to represent the patterns, don't - * forget escape characters are represented by "\\". - * - * @return the pattern represented by this ignore info - */ - public String getPattern(); - /** - * Return whether or not this ignore info is enabled. A disabled ignore - * info remains in the global ignore list, but no attempt is made to match - * with it to determine resource ignore state. - * - * @return whether the ignore info is enabled - */ - public boolean getEnabled(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java deleted file mode 100644 index 029bfcb45..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/IProjectSetSerializer.java +++ /dev/null @@ -1,69 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * IProjectSetSerializer manages the serializing and deserializing - * of references to projects. Given a project, it can produce a - * UTF-8 encoded String which can be stored in a file. - * Given this String, it can create in the workspace an IProject. - * - * @since 2.0 - * - * @deprecated - * Use {@link org.eclipse.team.core.RepositoryProviderType#getProjectSetCapability()} - * to obtain an instance of {@link org.eclipse.team.core.ProjectSetCapability} instead. - */ - -public interface IProjectSetSerializer { - - /** - * For every IProject in providerProjects, return an opaque - * UTF-8 encoded String to act as a reference to that project. - * The format of the String is specific to the provider. - * The format of the String must be such that - * IProjectSetSerializer.addToWorskpace() will be able to - * consume it and recreate a corresponding project. - * @see IProjectSetSerializer#addToWorkspace(String[] referenceStrings, String filename, Object context, IProgressMonitor monitor) - * - * @param providerProjects an array of projects that the serializer should create - * text references for - * @param context a UI context object. This object will either be a - * com.ibm.swt.widgets.Shell or it will be null. - * @param monitor a progress monitor - * @return String[] an array of serialized reference strings uniquely identifying the projects - * @throws TeamException - */ - public String[] asReference(IProject[] providerProjects, Object context, IProgressMonitor monitor) throws TeamException; - - /** - * For every String in referenceStrings, create in the workspace a - * corresponding IProject. Return an Array of the resulting IProjects. - * Result is unspecified in the case where an IProject of that name - * already exists. In the case of failure, a TeamException must be thrown. - * The opaque strings in referenceStrings are guaranteed to have been previously - * produced by IProjectSetSerializer.asReference(). - * @see IProjectSetSerializer#asReference(IProject[] providerProjects, Object context, IProgressMonitor monitor) - * - * @param referenceStrings an array of referene strings uniquely identifying the projects - * @param filename the name of the file that the references were read from. This is included - * in case the provider needs to deduce relative paths - * @param context a UI context object. This object will either be a - * com.ibm.swt.widgets.Shell or it will be null. - * @param monitor a progress monitor - * @return IProject[] an array of projects that were created - * @throws TeamException - */ - public IProject[] addToWorkspace(String[] referenceStrings, String filename, Object context, IProgressMonitor monitor) throws TeamException; -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ITeamStatus.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ITeamStatus.java deleted file mode 100644 index d0015a365..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ITeamStatus.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; - -/** - * Defines the status codes used in the status of exceptions and errors relating to Team. - * - * @since 3.0 - */ -public interface ITeamStatus extends IStatus { - - /** - * An error occurred trying to obtain the <code>SyncInfo</code> for a single resource. - * The error will be cleared when the set is reset or possibly when a sync info is added to - * the set for the resource for which the error occurred. - */ - public static final int RESOURCE_SYNC_INFO_ERROR = 1; - - /** - * An error occurred that may effect several resources in a <code>SyncInfoSet</code>. - * The error will be cleared when the set is reset. - */ - public static final int SYNC_INFO_SET_ERROR = 2; - - /** - * The collection of sync info for a sync info set has been cancelled so the - * contents fdo not reflect the state of the system. - * The error will be cleared when the set is reset. - */ - public static final int SYNC_INFO_SET_CANCELLATION = 3; - - /** - * Return the resource associated with this status. - * @return Returns the resource. - */ - public IResource getResource(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ProjectSetCapability.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ProjectSetCapability.java deleted file mode 100644 index 2ca19589a..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ProjectSetCapability.java +++ /dev/null @@ -1,268 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - * Dan Rubel - project set serializer API - *******************************************************************************/ -package org.eclipse.team.core; - -import java.io.File; -import java.util.*; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.internal.core.Policy; - -/** - * An object for serializing and deserializing - * references to projects. Given a project, it can produce a - * UTF-8 encoded String which can be stored in a file. - * Given this String, it can load a project into the workspace. - * It also provides a mechanism - * by which repository providers can be notified when a project set is created and exported. - * - * @see RepositoryProviderType - * - * @since 2.1 - */ -public abstract class ProjectSetCapability { - - /** - * Ensure that the provider type is backwards compatible by - * passing the project set serializer to the type if a serializer - * is registered. This is required for repository providers - * who implemented a project set capability in 2.1 (before the - * capability contained the serialization API) and have not - * released a 3.0 plugin yet. This method is - * called before project set export and import and can be used by - * other clients who work with project sets. - * - * @param type the provider type instance - * @param capability the capability that was obtained from the provider type - * - * @since 3.0 - */ - public static void ensureBackwardsCompatible(RepositoryProviderType type, ProjectSetCapability capability) { - if (capability != null) { - IProjectSetSerializer oldSerializer = Team.getProjectSetSerializer(type.getID()); - if (oldSerializer != null) { - capability.setSerializer(oldSerializer); - } - } - } - - /** - * The old serialization interface - */ - private IProjectSetSerializer serializer; - - /** - * Notify the provider that a project set has been created at path. Only - * providers identified as having projects in the project set will be - * notified. The project set may or may not be created in a workspace - * project (thus may not be a resource). - * - * @param file the project set file that was created - * @param context a UI context object. This object will either be a - * com.ibm.swt.widgets.Shell or it will be null. - * @param monitor a progress monitor - * - * @deprecated should use or override - * projectSetCreated(File, ProjectSetSerializationContext, IProgressMonitor) - * instead - */ - public void projectSetCreated(File file, Object context, IProgressMonitor monitor) { - //default is to do nothing - } - - /** - * Notify the provider that a project set has been created at path. Only - * providers identified as having projects in the project set will be - * notified. The project set may or may not be created in a workspace - * project (thus may not be a resource). - * - * @param file the project set file that was created - * @param context - * the context in which the references are created - * (not <code>null</code>) - * @param monitor a progress monitor - * - * @since 3.0 - */ - public void projectSetCreated(File file, ProjectSetSerializationContext context, IProgressMonitor monitor) { - // Invoke old method by default - projectSetCreated(file, context.getShell(), monitor); - } - - /** - * For every project in providerProjects, return an opaque - * UTF-8 encoded String to act as a reference to that project. - * The format of the String is specific to the provider. - * The format of the String must be such that - * {@link #addToWorkspace(String[], ProjectSetSerializationContext, IProgressMonitor)} - * will be able to consume it and load the corresponding project. - * <p> - * This default implementation simply throws an exception - * indicating that no references can be created unless there - * is an IProjectSetSerializer registered for the repository - * provider type in which case the operation is delegated to the - * serializer. - * Subclasses are expected to override. - * - * @since 3.0 - * - * @param providerProjects - * an array of projects for which references are needed - * (not <code>null</code> and contains no <code>null</code>s) - * @param context - * the context in which the references are created - * (not <code>null</code>) - * @param monitor - * a progress monitor or <code>null</code> if none - * @return - * an array containing exactly the same number of elements - * as the providerProjects argument - * where each element is a serialized reference string - * uniquely identifying the corresponding the project in the providerProjects array - * (not <code>null</code> and contains no <code>null</code>s) - * @throws TeamException - * thrown if there is a reference string cannot be created for a project - */ - public String[] asReference( - IProject[] providerProjects, - ProjectSetSerializationContext context, - IProgressMonitor monitor) - throws TeamException { - - if (serializer != null) { - return serializer.asReference(providerProjects, context.getShell(), monitor); - } - throw new TeamException(Policy.bind("ProjectSetCapability.0")); //$NON-NLS-1$ - } - - /** - * For every String in referenceStrings, load the corresponding project into the workspace. - * The opaque strings in referenceStrings are guaranteed to have been previously - * produced by {@link #asReference(IProject[], ProjectSetSerializationContext, IProgressMonitor)}. - * The confirmOverwrite method is called with an array of projects - * for which projects of the same name already exists in the workspace. - * <p> - * Callers from within a UI context should wrapper a call to this method - * inside a WorkspaceModifyOperation so that events generated as a result - * of this operation are deferred until the outermost operation - * has successfully completed. - * <p> - * This default implementation simply throws an exception - * indicating that no projects can be loaded unless there - * is an IProjectSetSerializer registered for the repository - * provider type in which case the operation is delegated to the - * serializer. - * Subclasses are expected to override. - * - * @since 3.0 - * - * @param referenceStrings - * an array of referene strings uniquely identifying the projects - * (not <code>null</code> and contains no <code>null</code>s) - * @param context - * the context in which the projects are loaded - * (not <code>null</code>) - * @param monitor - * a progress monitor or <code>null</code> if none - * @return IProject[] - * an array of projects that were loaded - * excluding those projects already existing and not overwritten - * (not <code>null</code>, contains no <code>null</code>s) - * @throws TeamException - * thrown if there is a problem loading a project into the workspace. - * If an exception is thrown, then the workspace is left in an unspecified state - * where some of the referenced projects may be loaded or partially loaded, and others may not. - */ - public IProject[] addToWorkspace( - String[] referenceStrings, - ProjectSetSerializationContext context, - IProgressMonitor monitor) - throws TeamException { - - if (serializer != null) { - return serializer.addToWorkspace(referenceStrings, context.getFilename(), context.getShell(), monitor); - } - throw new TeamException(Policy.bind("ProjectSetCapability.1")); //$NON-NLS-1$ - } - - //////////////////////////////////////////////////////////////////////////// - // - // Internal utility methods for subclasses - // - //////////////////////////////////////////////////////////////////////////// - - /** - * Determine if any of the projects already exist - * and confirm which of those projects are to be overwritten. - * - * @since 3.0 - * - * @param context - * the context in which the projects are loaded - * (not <code>null</code>) - * @param projects - * an array of proposed projects to be loaded - * (not <code>null</code>, contains no <code>null</code>s) - * @return - * an array of confirmed projects to be loaded - * or <code>null</code> if the operation is to be canceled. - * @throws TeamException - */ - protected IProject[] confirmOverwrite( - ProjectSetSerializationContext context, - IProject[] projects) - throws TeamException { - - // Build a collection of existing projects - - final Collection existingProjects = new ArrayList(); - for (int i = 0; i < projects.length; i++) { - IProject eachProj = projects[i]; - if (eachProj.exists()) - existingProjects.add(eachProj); - } - if (existingProjects.size() == 0) - return projects; - - // Confirm the overwrite - - IProject[] confirmed = - context.confirmOverwrite( - (IProject[]) existingProjects.toArray( - new IProject[existingProjects.size()])); - if (confirmed == null) - return null; - if (existingProjects.size() == confirmed.length) - return projects; - - // Return the amended list of projects to be loaded - - Collection result = new ArrayList(projects.length); - result.addAll(Arrays.asList(projects)); - result.removeAll(existingProjects); - for (int i = 0; i < confirmed.length; i++) { - IProject eachProj = confirmed[i]; - if (existingProjects.contains(eachProj)) - result.add(eachProj); - } - return (IProject[]) result.toArray(new IProject[result.size()]); - } - - /* - * Set the serializer to the one registered. The serializer - * will be used if subclasses do not override asReference - * and addToWorkspace - */ - void setSerializer(IProjectSetSerializer serializer) { - this.serializer = serializer; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ProjectSetSerializationContext.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ProjectSetSerializationContext.java deleted file mode 100644 index aba7d2a2e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/ProjectSetSerializationContext.java +++ /dev/null @@ -1,82 +0,0 @@ -/********************************************************************** - Copyright (c) 2004 Dan Rubel and others. - All rights reserved. This program and the accompanying materials - are made available under the terms of the Common Public License v1.0 - which accompanies this distribution, and is available at - http://www.eclipse.org/legal/cpl-v10.html - - Contributors: - - Dan Rubel - initial API and implementation - - **********************************************************************/ - -package org.eclipse.team.core; - -import org.eclipse.core.resources.IProject; - -/** - * The context in which project serialization occurs. - * The class may be subclassed to represent different serialization contexts. - * - * @since 3.0 - */ -public class ProjectSetSerializationContext { - - private final String filename; - - /** - * Create a serialization context with no filename - */ - public ProjectSetSerializationContext() { - this(null); - } - - /** - * Create a serialization context and set the filename of the file - * that does or is to contain the project set. - * @param filename a filename or <code>null</code> - */ - public ProjectSetSerializationContext(String filename) { - this.filename = filename; - } - - /** - * Given an array of projects that currently exist in the workspace - * determine which of those projects should be overwritten. - * <p> - * This default implementation always returns an empty array - * indicating that no existing projects should be overwritten. - * Subclasses may override this as appropriate. - * - * @param projects - * an array of projects currently existing in the workspace - * that are desired to be overwritten. - * (not <code>null</code>, contains no <code>null</code>s) - * @return - * an array of zero or more projects that should be overwritten - * or <code>null</code> if the operation is to be canceled - */ - public IProject[] confirmOverwrite(IProject[] projects) throws TeamException { - return new IProject[0]; - } - - /** - * Return a org.eclipse.swt.Shell if there is a UI context - * or <code>null</code> if executing headless. - * - * @return the shell or <code>null</code> - */ - public Object getShell() { - return null; - } - - /** - * Return the name of the file to or from which teh project set is being loaded or saved. - * This may be <code>null</code>. - * @return the filename or <code>null</code> - */ - public String getFilename() { - return filename; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/RepositoryProvider.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/RepositoryProvider.java deleted file mode 100644 index 52f22b412..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/RepositoryProvider.java +++ /dev/null @@ -1,666 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -import java.util.*; -import org.eclipse.core.resources.*; -import org.eclipse.core.resources.team.IMoveDeleteHook; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.ILock; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.team.internal.core.*; - -/** - * A concrete subclass of <code>RepositoryProvider</code> is created for each - * project that is associated with a repository provider. The lifecycle of these - * instances is is similar to that of the platform's 'nature' mechanism. - * <p> - * To create a repository provider and have it registered with the platform, a client - * must minimally: - * <ol> - * <li>extend <code>RepositoryProvider</code> - * <li>define a repository extension in <code>plugin.xml</code>. - * Here is an example extension point definition: - * - * <code> - * <br><extension point="org.eclipse.team.core.repository"> - * <br> <repository - * <br> class="org.eclipse.myprovider.MyRepositoryProvider" - * <br> id="org.eclipse.myprovider.myProviderID"> - * <br> </repository> - * <br></extension> - * </code> - * </ol></p> - * <p> - * Once a repository provider is registered with Team, then you - * can associate a repository provider with a project by invoking <code>RepositoryProvider.map()</code>. - * </p> - * @see RepositoryProvider#map(IProject, String) - * - * @since 2.0 - */ -public abstract class RepositoryProvider implements IProjectNature, IAdaptable { - - private final static String TEAM_SETID = "org.eclipse.team.repository-provider"; //$NON-NLS-1$ - - private final static QualifiedName PROVIDER_PROP_KEY = - new QualifiedName("org.eclipse.team.core", "repository"); //$NON-NLS-1$ //$NON-NLS-2$ - - private final static List AllProviderTypeIds = initializeAllProviderTypes(); - - // the project instance that this nature is assigned to - private IProject project; - - // lock to ensure that map/unmap and getProvider support concurrency - private static final ILock mappingLock = Platform.getJobManager().newLock(); - - /** - * Instantiate a new RepositoryProvider with concrete class by given providerID - * and associate it with project. - * - * @param project the project to be mapped - * @param id the ID of the provider to be mapped to the project - * @throws TeamException if - * <ul> - * <li>There is no provider by that ID.</li> - * <li>The project is already associated with a repository provider and that provider - * prevented its unmapping.</li> - * </ul> - * @see RepositoryProvider#unmap(IProject) - */ - public static void map(IProject project, String id) throws TeamException { - ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(project); - try { - // Obtain a scheduling rule on the project before obtaining the - // mappingLock. This is required because a caller of getProvider - // may hold a scheduling rule before getProvider is invoked but - // getProvider itself does not (and can not) obtain a scheduling rule. - // Thus, the locking order is always scheduling rule followed by - // mappingLock. - Platform.getJobManager().beginRule(rule, null); - try { - mappingLock.acquire(); - RepositoryProvider existingProvider = null; - - if(project.getPersistentProperty(PROVIDER_PROP_KEY) != null) - existingProvider = getProvider(project); // get the real one, not the nature one - - //if we already have a provider, and its the same ID, we're ok - //if the ID's differ, unmap the existing. - if(existingProvider != null) { - if(existingProvider.getID().equals(id)) - return; //nothing to do - else - unmap(project); - } - - // Create the provider as a session property before adding the persistant - // property to ensure that the provider can be instantiated - RepositoryProvider provider = mapNewProvider(project, id); - - //mark it with the persistent ID for filtering - try { - project.setPersistentProperty(PROVIDER_PROP_KEY, id); - } catch (CoreException outer) { - // couldn't set the persistant property so clear the session property - try { - project.setSessionProperty(PROVIDER_PROP_KEY, null); - } catch (CoreException inner) { - // something is seriously wrong - TeamPlugin.log(IStatus.ERROR, Policy.bind("RepositoryProvider.couldNotClearAfterError", project.getName(), id), inner);//$NON-NLS-1$ - } - throw outer; - } - - provider.configure(); //xxx not sure if needed since they control with wiz page and can configure all they want - - //adding the nature would've caused project description delta, so trigger one - project.touch(null); - - // Set the rule factory for the provider after the touch - // so the touch does not fail due to incomptible modify rules - TeamHookDispatcher.setProviderRuleFactory(project, provider.getRuleFactory()); - } finally { - mappingLock.release(); - } - } catch (CoreException e) { - throw TeamPlugin.wrapException(e); - } finally { - Platform.getJobManager().endRule(rule); - } - } - - /* - * Instantiate the provider denoted by ID and store it in the session property. - * Return the new provider instance. If a TeamException is thrown, it is - * guaranteed that the session property will not be set. - * - * @param project - * @param id - * @return RepositoryProvider - * @throws TeamException we can't instantiate the provider, or if the set - * session property fails from core - */ - private static RepositoryProvider mapNewProvider(IProject project, String id) throws TeamException { - RepositoryProvider provider = newProvider(id); // instantiate via extension point - - if(provider == null) - throw new TeamException(Policy.bind("RepositoryProvider.couldNotInstantiateProvider", project.getName(), id)); //$NON-NLS-1$ - - // validate that either the provider supports linked resources or the project has no linked resources - if (!provider.canHandleLinkedResources()) { - try { - IResource[] members = project.members(); - for (int i = 0; i < members.length; i++) { - IResource resource = members[i]; - if (resource.isLinked()) { - throw new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, Policy.bind("RepositoryProvider.linkedResourcesExist", project.getName(), id), null)); //$NON-NLS-1$ - } - } - } catch (CoreException e) { - throw TeamPlugin.wrapException(e); - } - } - - //store provider instance as session property - try { - project.setSessionProperty(PROVIDER_PROP_KEY, provider); - provider.setProject(project); - } catch (CoreException e) { - throw TeamPlugin.wrapException(e); - } - return provider; - } - - private static RepositoryProvider mapExistingProvider(IProject project, String id) throws TeamException { - try { - // Obtain the mapping lock before creating the instance so we can make sure - // that a disconnect is not happening at the same time - mappingLock.acquire(); - try { - // Ensure that the persistant property is still set - // (i.e. an unmap may have come in since we checked it last - String currentId = project.getPersistentProperty(PROVIDER_PROP_KEY); - if (currentId == null) { - // The provider has been unmapped - return null; - } - if (!currentId.equals(id)) { - // A provider has been disconnected and another connected - // Since mapping creates the session property, we - // can just return it - return lookupProviderProp(project); - } - } catch (CoreException e) { - throw TeamPlugin.wrapException(e); - } - return mapNewProvider(project, id); - } finally { - mappingLock.release(); - } - } - /** - * Disassoociates project with the repository provider its currently mapped to. - * @param project - * @throws TeamException The project isn't associated with any repository provider. - */ - public static void unmap(IProject project) throws TeamException { - ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule(project); - try{ - // See the map(IProject, String) method for a description of lock ordering - Platform.getJobManager().beginRule(rule, null); - try { - mappingLock.acquire(); - String id = project.getPersistentProperty(PROVIDER_PROP_KEY); - - //If you tried to remove a non-existant nature it would fail, so we need to as well with the persistent prop - if(id == null) { - throw new TeamException(Policy.bind("RepositoryProvider.No_Provider_Registered", project.getName())); //$NON-NLS-1$ - } - - //This will instantiate one if it didn't already exist, - //which is ok since we need to call deconfigure() on it for proper lifecycle - RepositoryProvider provider = getProvider(project); - if (provider == null) { - // There is a persistant property but the provider cannot be obtained. - // The reason could be that the provider's plugin is no longer available. - // Better log it just in case this is unexpected. - TeamPlugin.log(IStatus.ERROR, Policy.bind("RepositoryProvider.couldNotInstantiateProvider", project.getName(), id), null); //$NON-NLS-1$ - } - - if (provider != null) provider.deconfigure(); - - project.setSessionProperty(PROVIDER_PROP_KEY, null); - project.setPersistentProperty(PROVIDER_PROP_KEY, null); - - if (provider != null) provider.deconfigured(); - - //removing the nature would've caused project description delta, so trigger one - project.touch(null); - - // Change the rule factory after the touch in order to - // avoid rule incompatibility - TeamHookDispatcher.setProviderRuleFactory(project, null); - } finally { - mappingLock.release(); - } - } catch (CoreException e) { - throw TeamPlugin.wrapException(e); - } finally { - Platform.getJobManager().endRule(rule); - } - } - - /* - * Return the provider mapped to project, or null if none; - */ - private static RepositoryProvider lookupProviderProp(IProject project) throws CoreException { - return (RepositoryProvider) project.getSessionProperty(PROVIDER_PROP_KEY); - } - - - /** - * Default constructor required for the resources plugin to instantiate this class from - * the nature extension definition. - */ - public RepositoryProvider() { - } - - /** - * Configures the provider for the given project. This method is called after <code>setProject</code>. - * If an exception is generated during configuration - * of the project, the provider will not be assigned to the project. - * - * @throws CoreException if the configuration fails. - */ - abstract public void configureProject() throws CoreException; - - /** - * Configures the nature for the given project. This is called by <code>RepositoryProvider.map()</code> - * the first time a provider is mapped to a project. It is not intended to be called by clients. - * - * @throws CoreException if this method fails. If the configuration fails the provider will not be - * associated with the project. - * - * @see RepositoryProvider#configureProject() - */ - final public void configure() throws CoreException { - try { - configureProject(); - } catch(CoreException e) { - try { - RepositoryProvider.unmap(getProject()); - } catch(TeamException e2) { - throw new CoreException(new Status(IStatus.ERROR, TeamPlugin.ID, 0, Policy.bind("RepositoryProvider_Error_removing_nature_from_project___1") + getID(), e2)); //$NON-NLS-1$ - } - throw e; - } - } - - /** - * Method deconfigured is invoked after a provider has been unmaped. The - * project will no longer have the provider associated with it when this - * method is invoked. It is a last chance for the provider to clean up. - */ - protected void deconfigured() { - } - - /** - * Answer the id of this provider instance. The id should be the repository provider's - * id as defined in the provider plugin's plugin.xml. - * - * @return the nature id of this provider - */ - abstract public String getID(); - - /** - * Returns an <code>IFileModificationValidator</code> for pre-checking operations - * that modify the contents of files. - * Returns <code>null</code> if the provider does not wish to participate in - * file modification validation. - * - * @see org.eclipse.core.resources.IFileModificationValidator - */ - - public IFileModificationValidator getFileModificationValidator() { - return null; - } - - /** - * Returns an <code>IMoveDeleteHook</code> for handling moves and deletes - * that occur withing projects managed by the provider. This allows providers - * to control how moves and deletes occur and includes the ability to prevent them. - * <p> - * Returning <code>null</code> signals that the default move and delete behavior is desired. - * - * @see org.eclipse.core.resources.team.IMoveDeleteHook - */ - public IMoveDeleteHook getMoveDeleteHook() { - return null; - } - - /** - * Returns a brief description of this provider. The exact details of the - * representation are unspecified and subject to change, but the following - * may be regarded as typical: - * - * "SampleProject:org.eclipse.team.cvs.provider" - * - * @return a string description of this provider - */ - public String toString() { - return Policy.bind("RepositoryProvider.toString", getProject().getName(), getID()); //$NON-NLS-1$ - } - - /** - * Returns all known (registered) RepositoryProvider ids. - * - * @return an array of registered repository provider ids. - */ - final public static String[] getAllProviderTypeIds() { - IProjectNatureDescriptor[] desc = ResourcesPlugin.getWorkspace().getNatureDescriptors(); - Set teamSet = new HashSet(); - - teamSet.addAll(AllProviderTypeIds); // add in all the ones we know via extension point - - //fall back to old method of nature ID to find any for backwards compatibility - for (int i = 0; i < desc.length; i++) { - String[] setIds = desc[i].getNatureSetIds(); - for (int j = 0; j < setIds.length; j++) { - if(setIds[j].equals(TEAM_SETID)) { - teamSet.add(desc[i].getNatureId()); - } - } - } - return (String[]) teamSet.toArray(new String[teamSet.size()]); - } - - /** - * Returns the provider for a given IProject or <code>null</code> if a provider is not associated with - * the project or if the project is closed or does not exist. This method should be called if the caller - * is looking for <b>any</b> repository provider. Otherwise call <code>getProvider(project, id)</code> - * to look for a specific repository provider type. - * </p> - * @param project the project to query for a provider - * @return the repository provider associated with the project - */ - final public static RepositoryProvider getProvider(IProject project) { - try { - if(project.isAccessible()) { - - //----------------------------- - //First, look for the session property - RepositoryProvider provider = lookupProviderProp(project); - if(provider != null) - return provider; - - // ----------------------------- - //Next, check if it has the ID as a persistent property, if yes then instantiate provider - String id = project.getPersistentProperty(PROVIDER_PROP_KEY); - if(id != null) - return mapExistingProvider(project, id); - - //Couldn't find using new method, fall back to lookup using natures for backwards compatibility - //----------------------------- - IProjectDescription projectDesc = project.getDescription(); - String[] natureIds = projectDesc.getNatureIds(); - IWorkspace workspace = ResourcesPlugin.getWorkspace(); - // for every nature id on this project, find it's natures sets and check if it is - // in the team set. - for (int i = 0; i < natureIds.length; i++) { - IProjectNatureDescriptor desc = workspace.getNatureDescriptor(natureIds[i]); - // The descriptor can be null if the nature doesn't exist - if (desc != null) { - String[] setIds = desc.getNatureSetIds(); - for (int j = 0; j < setIds.length; j++) { - if(setIds[j].equals(TEAM_SETID)) { - return getProvider(project, natureIds[i]); - } - } - } - } - } - } catch(CoreException e) { - if (!isAcceptableException(e)) { - TeamPlugin.log(e); - } - } - return null; - } - - /* - * Return whether the given exception is acceptable during a getProvider(). - * If the exception is acceptable, it is assumed that there is no provider - * on the project. - */ - private static boolean isAcceptableException(CoreException e) { - return e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND; - } - - /** - * Returns a provider of type with the given id if associated with the given project - * or <code>null</code> if the project is not associated with a provider of that type - * or the nature id is that of a non-team repository provider nature. - * - * @param project the project to query for a provider - * @param id the repository provider id - * @return the repository provider - */ - final public static RepositoryProvider getProvider(IProject project, String id) { - try { - if(project.isAccessible()) { - // Look for an existing provider first to avoid accessing persistant properties - RepositoryProvider provider = lookupProviderProp(project); //throws core, we will reuse the catching already here - if(provider != null) { - if (provider.getID().equals(id)) { - return provider; - } else { - return null; - } - } - // There isn't one so check the persistant property - String existingID = project.getPersistentProperty(PROVIDER_PROP_KEY); - if(id.equals(existingID)) { - // The ids are equal so instantiate and return - RepositoryProvider newProvider = mapExistingProvider(project, id); - if (newProvider!= null && newProvider.getID().equals(id)) { - return newProvider; - } else { - // The id changed before we could create the desired provider - return null; - } - } - - //couldn't find using new method, fall back to lookup using natures for backwards compatibility - //----------------------------- - - // if the nature id given is not in the team set then return - // null. - IProjectNatureDescriptor desc = ResourcesPlugin.getWorkspace().getNatureDescriptor(id); - if(desc == null) //for backwards compat., may not have any nature by that ID - return null; - - String[] setIds = desc.getNatureSetIds(); - for (int i = 0; i < setIds.length; i++) { - if(setIds[i].equals(TEAM_SETID)) { - return (RepositoryProvider)project.getNature(id); - } - } - } - } catch(CoreException e) { - if (!isAcceptableException(e)) { - TeamPlugin.log(e); - } - } - return null; - } - - /** - * Returns whether the given project is shared or not. This is a lightweight - * method in that it will not instantiate a provider instance (as - * <code>getProvider</code> would) if one is not already instantiated. - * - * Note that IProject.touch() generates a project description delta. This, in combination - * with isShared() can be used to be notified of sharing/unsharing of projects. - * - * @param project the project being tested. - * @return boolean - * - * @see #getProvider(IProject) - * - * @since 2.1 - */ - public static boolean isShared(IProject project) { - if (!project.isAccessible()) return false; - try { - if (lookupProviderProp(project) != null) return true; - return project.getPersistentProperty(PROVIDER_PROP_KEY) != null; - } catch (CoreException e) { - TeamPlugin.log(e); - return false; - } - } - - /* - * @see IProjectNature#getProject() - */ - public IProject getProject() { - return project; - } - - /* - * @see IProjectNature#setProject(IProject) - */ - public void setProject(IProject project) { - this.project = project; - } - - private static List initializeAllProviderTypes() { - List allIDs = new ArrayList(); - - TeamPlugin plugin = TeamPlugin.getPlugin(); - if (plugin != null) { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - String extensionId = configElements[j].getAttribute("id"); //$NON-NLS-1$ - allIDs.add(extensionId); - } - } - } - } - return allIDs; - } - - private static RepositoryProvider newProvider(String id) { - TeamPlugin plugin = TeamPlugin.getPlugin(); - if (plugin != null) { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - String extensionId = configElements[j].getAttribute("id"); //$NON-NLS-1$ - if (extensionId != null && extensionId.equals(id)) { - try { - return (RepositoryProvider) configElements[j].createExecutableExtension("class"); //$NON-NLS-1$ - } catch (CoreException e) { - TeamPlugin.log(e); - } catch (ClassCastException e) { - String className = configElements[j].getAttribute("class"); //$NON-NLS-1$ - TeamPlugin.log(IStatus.ERROR, Policy.bind("RepositoryProvider.invalidClass", id, className), e); //$NON-NLS-1$ - } - return null; - } - } - } - } - } - return null; - } - - /** - * Method validateCreateLink is invoked by the Platform Core TeamHook when a - * linked resource is about to be added to the provider's project. It should - * not be called by other clients and it should not need to be overridden by - * subclasses (although it is possible to do so in special cases). - * Subclasses can indicate that they support linked resources by overridding - * the <code>canHandleLinkedResources()</code> method. - * - * @param resource see <code>org.eclipse.core.resources.team.TeamHook</code> - * @param updateFlags see <code>org.eclipse.core.resources.team.TeamHook</code> - * @param location see <code>org.eclipse.core.resources.team.TeamHook</code> - * @return IStatus see <code>org.eclipse.core.resources.team.TeamHook</code> - * - * @see RepositoryProvider#canHandleLinkedResources() - * - * @since 2.1 - */ - public IStatus validateCreateLink(IResource resource, int updateFlags, IPath location) { - if (canHandleLinkedResources()) { - return Team.OK_STATUS; - } else { - return new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.LINKING_NOT_ALLOWED, Policy.bind("RepositoryProvider.linkedResourcesNotSupported", getProject().getName(), getID()), null); //$NON-NLS-1$ - } - } - - /** - * Method canHandleLinkedResources should be overridden by subclasses who - * support linked resources. At a minimum, supporting linked resources - * requires changes to the move/delete hook - * (see org.eclipe.core.resources.team.IMoveDeleteHook). This method is - * called after the RepositoryProvider is instantiated but before - * <code>setProject()</code> is invoked so it will not have access to any - * state determined from the <code>setProject()</code> method. - * @return boolean - * - * @see org.eclipse.core.resources.team.IMoveDeleteHook - * - * @since 2.1 - */ - public boolean canHandleLinkedResources() { - return false; - } - - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class adapter) { - return null; - } - - /** - * Return the resource rule factory for this provider. This factory - * will be used to determine the scheduling rules that are to be obtained - * when performing various resource operations (e.g. move, copy, delete, etc.) - * on the resources in the project the provider is mapped to. - * <p> - * By default, the factory returned by this method is pessimistic and - * obtains the workspace lock for all operations that could result in a - * callback to the provider (either through the <code>IMoveDeleteHook</code> - * or <code>IFileModificationValidator</code>). This is done to ensure that - * older providers are not broken. However, providers should override this - * method and provide a subclass of {@link org.eclipse.core.resources.team.ResourceRuleFactory} - * that provides rules of a more optimistic granularity (e.g. project - * or lower). - * @return the rule factory for this provider - * @since 3.0 - * @see org.eclipse.core.resources.team.ResourceRuleFactory - */ - public IResourceRuleFactory getRuleFactory() { - return new PessimisticResourceRuleFactory(); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/RepositoryProviderType.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/RepositoryProviderType.java deleted file mode 100644 index 2856ca521..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/RepositoryProviderType.java +++ /dev/null @@ -1,174 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IExtension; -import org.eclipse.core.runtime.IExtensionPoint; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.team.internal.core.DefaultProjectSetCapability; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * This class represents provisional API. A provider is not required to implement this API. - * Implementers, and those who reference it, do so with the awareness that this class may be - * removed or substantially changed at future times without warning. - * <p> - * This class represents things you can ask/do with a type of provider. This - * is in the absence of a project, as opposed to RepositoryProvider which - * requires a concrete project in order to be instantiated. - * <p> - * A repository provider type class is asscoaited with it's provider ID along with it's - * corresponding repository provider class. To add a - * repository provider type and have it registered with the platform, a client - * must minimally: - * <ol> - * <li>extend <code>RepositoryProviderType</code> - * <li>add the typeClass field to the repository extension in <code>plugin.xml</code>. - * Here is an example extension point definition: - * - * <code> - * <br><extension point="org.eclipse.team.core.repository"> - * <br> <repository - * <br> class="org.eclipse.myprovider.MyRepositoryProvider" - * <br> typeClass="org.eclipse.myprovider.MyRepositoryProviderType" - * <br> id="org.eclipse.myprovider.myProviderID"> - * <br> </repository> - * <br></extension> - * </code> - * </ol></p> - * - * <p> - * Once a repository provider type is registered with Team, then you - * can access the singleton instance of the class by invoking <code>RepositoryProviderType.getProviderType()</code>. - * </p> - * - * @see RepositoryProviderType#getProviderType(String) - * - * @since 2.1 - */ - -public abstract class RepositoryProviderType { - private static Map allProviderTypes = new HashMap(); - - private String id; - - public RepositoryProviderType() { - } - - /** - * Return the RepositoryProviderType for the given provider ID. - * - * @param id the ID of the provider - * @return RepositoryProviderType - * - * @see #getID() - */ - public static RepositoryProviderType getProviderType(String id) { - RepositoryProviderType type = (RepositoryProviderType) allProviderTypes.get(id); - - if(type != null) - return type; - - //If there isn't one in the table, we'll try to create one from the extension point - //Its possible that newProviderType() will return null, but in that case it will have also logged the error so just return the result - return newProviderType(id); - } - - private void setID(String id) { - this.id = id; - } - - private static RepositoryProviderType newProviderType(String id) { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - String extensionId = configElements[j].getAttribute("id"); //$NON-NLS-1$ - - if (extensionId != null && extensionId.equals(id)) { - try { - RepositoryProviderType providerType; - //Its ok not to have a typeClass extension. In this case, a default instance will be created. - if(configElements[j].getAttribute("typeClass") == null) { //$NON-NLS-1$ - providerType = new DefaultRepositoryProviderType(); - } else { - providerType = (RepositoryProviderType) configElements[j].createExecutableExtension("typeClass"); //$NON-NLS-1$ - } - - providerType.setID(id); - allProviderTypes.put(id, providerType); - return providerType; - } catch (CoreException e) { - TeamPlugin.log(e); - } catch (ClassCastException e) { - String className = configElements[j].getAttribute("typeClass"); //$NON-NLS-1$ - TeamPlugin.log(IStatus.ERROR, Policy.bind("RepositoryProviderType.invalidClass", id, className), e); //$NON-NLS-1$ - } - return null; - } - } - } - } - return null; - } - - /** - * Answer the id of this provider type. The id will be the repository - * provider type's id as defined in the provider plugin's plugin.xml. - * - * @return the id of this provider type - */ - public final String getID() { - return this.id; - } - - /** - * Answers an object for serializing and deserializing - * of references to projects. Given a project, it can produce a - * UTF-8 encoded String which can be stored in a file. - * Given this String, it can load a project into the workspace. - * It also provides a mechanism - * by which repository providers can be notified when a project set is created and exported. - * If the provider doesn't wish to provide this - * feature, return null. - * <p> - * Subclasses should override this method to return the appropriate - * serializer for the associated repository type. - * It is recommended that serializers not have any references to UI classes - * so that they can be used in a headless environment. - * <p> - * At this time, the default implementation wrappers the <code>IProjectSetSerializer</code> - * interface if one exists, providing backward compatibility with existing code. - * At some time in the future, the <code>IProjectSetSerializer</code> interface will be removed - * and the default implementation will revert to having limited functionality. - * - * @return the project set serializer (or <code>null</code>) - */ - public ProjectSetCapability getProjectSetCapability() { - // Provide backward compatibility with the old IProjectSetSerializer interface - IProjectSetSerializer oldSerializer = Team.getProjectSetSerializer(getID()); - if (oldSerializer != null) { - ProjectSetCapability capability = new DefaultProjectSetCapability(); - capability.setSerializer(oldSerializer); - return capability; - } - return null; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java deleted file mode 100644 index 74af21766..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/Team.java +++ /dev/null @@ -1,601 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -import java.io.*; -import java.util.*; - -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; -import org.eclipse.team.internal.core.*; - -/** - * The Team class provides a global point of reference for the global ignore set - * and the text/binary registry. - * - * @since 2.0 - */ -public final class Team { - - private static final String PREF_TEAM_IGNORES = "ignore_files"; //$NON-NLS-1$ - private static final String PREF_TEAM_TYPES = "file_types"; //$NON-NLS-1$ - private static final String PREF_TEAM_SEPARATOR = "\n"; //$NON-NLS-1$ - public static final Status OK_STATUS = new Status(Status.OK, TeamPlugin.ID, Status.OK, Policy.bind("ok"), null); //$NON-NLS-1$ - - // File type constants - public static final int UNKNOWN = 0; - public static final int TEXT = 1; - public static final int BINARY = 2; - - // Keys: file extensions. Values: Integers - private static SortedMap globalTypes, pluginTypes; - - // The ignore list that is read at startup from the persisted file - private static SortedMap globalIgnore, pluginIgnore; - private static StringMatcher[] ignoreMatchers; - - private static class FileTypeInfo implements IFileTypeInfo { - private String extension; - private int type; - - public FileTypeInfo(String extension, int type) { - this.extension = extension; - this.type = type; - } - public String getExtension() { - return extension; - } - public int getType() { - return type; - } - } - - /** - * Return the type of the given IStorage. - * - * Valid return values are: - * Team.TEXT - * Team.BINARY - * Team.UNKNOWN - * - * @param storage the IStorage - * @return whether the given IStorage is TEXT, BINARY, or UNKNOWN - */ - public static int getType(IStorage storage) { - String extension = getFileExtension(storage.getName()); - if (extension == null) return UNKNOWN; - SortedMap table = getFileTypeTable(); - Integer integer = (Integer)table.get(extension); - if (integer == null) return UNKNOWN; - return integer.intValue(); - } - - /** - * Returns whether the given file should be ignored. - * - * This method answers true if the file matches one of the global ignore - * patterns, or if the file is marked as derived. - * - * @param file the file - * @return whether the file should be ignored - */ - public static boolean isIgnoredHint(IResource resource) { - if (resource.isDerived()) return true; - return matchesEnabledIgnore(resource); - } - - /** - * Returns whether the given file should be ignored. - * @deprecated use isIgnoredHint(IResource) instead - */ - public static boolean isIgnoredHint(IFile file) { - if (file.isDerived()) return true; - return matchesEnabledIgnore(file); - } - - private static boolean matchesEnabledIgnore(IResource resource) { - StringMatcher[] matchers = getStringMatchers(); - for (int i = 0; i < matchers.length; i++) { - if (matchers[i].match(resource.getName())) return true; - } - return false; - } - - /** - * Returns whether the given file should be ignored. - * @deprecated use isIgnoredHint instead - */ - public static boolean isIgnored(IFile file) { - return matchesEnabledIgnore(file); - } - - private static IFileTypeInfo[] getFileTypeInfo(SortedMap map) { - List result = new ArrayList(); - Iterator e = map.keySet().iterator(); - while (e.hasNext()) { - String string = (String)e.next(); - int type = ((Integer)map.get(string)).intValue(); - result.add(new FileTypeInfo(string, type)); - } - return (IFileTypeInfo[])result.toArray(new IFileTypeInfo[result.size()]); - } - - /** - * Return all known file types. - * - * @return all known file types - */ - public static IFileTypeInfo[] getAllTypes() { - return getFileTypeInfo(getFileTypeTable()); - } - - /** - * Returns the list of global ignores. - */ - public synchronized static IIgnoreInfo[] getAllIgnores() { - // The ignores are cached and when the preferences change the - // cache is cleared. This makes it faster to lookup without having - // to re-parse the preferences. - if (globalIgnore == null) { - globalIgnore = new TreeMap(); - pluginIgnore = new TreeMap(); - ignoreMatchers = null; - try { - readIgnoreState(); - } catch (TeamException e) { - TeamPlugin.log(IStatus.ERROR, Policy.bind("Team.Error_loading_ignore_state_from_disk_1"), e); //$NON-NLS-1$ - } - initializePluginIgnores(pluginIgnore, globalIgnore); - } - IIgnoreInfo[] result = getIgnoreInfo(globalIgnore); - return result; - } - - private static IIgnoreInfo[] getIgnoreInfo(Map gIgnore) { - IIgnoreInfo[] result = new IIgnoreInfo[gIgnore.size()]; - Iterator e = gIgnore.keySet().iterator(); - int i = 0; - while (e.hasNext() ) { - final String pattern = (String)e.next(); - final boolean enabled = ((Boolean)gIgnore.get(pattern)).booleanValue(); - result[i++] = new IIgnoreInfo() { - private String p = pattern; - private boolean e = enabled; - public String getPattern() { - return p; - } - public boolean getEnabled() { - return e; - } - }; - } - return result; - } - - private synchronized static StringMatcher[] getStringMatchers() { - if (ignoreMatchers==null) { - IIgnoreInfo[] ignorePatterns = getAllIgnores(); - Vector matchers = new Vector(ignorePatterns.length); - for (int i = 0; i < ignorePatterns.length; i++) { - if (ignorePatterns[i].getEnabled()) { - matchers.add(new StringMatcher(ignorePatterns[i].getPattern(), true, false)); - } - } - ignoreMatchers = new StringMatcher[matchers.size()]; - matchers.copyInto(ignoreMatchers); - } - return ignoreMatchers; - } - - private synchronized static SortedMap getFileTypeTable() { - // The types are cached and when the preferences change the - // cache is cleared. This makes it faster to lookup without having - // to re-parse the preferences. - if (globalTypes == null) loadTextState(); - return globalTypes; - } - - /** - * Set the file type for the give extension to the given type. - * - * Valid types are: - * Team.TEXT - * Team.BINARY - * Team.UNKNOWN - * - * @param extension the file extension - * @param type the file type - */ - public static void setAllTypes(String[] extensions, int[] types) { - if (pluginTypes == null) { - loadTextState(); - } - globalTypes = new TreeMap(); - for (int i = 0; i < extensions.length; i++) { - globalTypes.put(extensions[i], new Integer(types[i])); - } - // Now set into preferences - StringBuffer buf = new StringBuffer(); - Iterator e = globalTypes.keySet().iterator(); - while (e.hasNext()) { - String extension = (String)e.next(); - boolean isCustom = (!pluginTypes.containsKey(extension)) || - !((Integer)pluginTypes.get(extension)).equals(globalTypes.get(extension)); - if (isCustom) { - buf.append(extension); - buf.append(PREF_TEAM_SEPARATOR); - Integer type = (Integer)globalTypes.get(extension); - buf.append(type); - buf.append(PREF_TEAM_SEPARATOR); - } - - } - TeamPlugin.getPlugin().getPluginPreferences().setValue(PREF_TEAM_TYPES, buf.toString()); - } - - /** - * Add patterns to the list of global ignores. - */ - public static void setAllIgnores(String[] patterns, boolean[] enabled) { - globalIgnore = new TreeMap(); - ignoreMatchers = null; - for (int i = 0; i < patterns.length; i++) { - globalIgnore.put(patterns[i], new Boolean(enabled[i])); - } - // Now set into preferences - StringBuffer buf = new StringBuffer(); - Iterator e = globalIgnore.keySet().iterator(); - while (e.hasNext()) { - String pattern = (String)e.next(); - boolean isCustom = (!pluginIgnore.containsKey(pattern)) || - !((Boolean)pluginIgnore.get(pattern)).equals(globalIgnore.get(pattern)); - if (isCustom) { - buf.append(pattern); - buf.append(PREF_TEAM_SEPARATOR); - boolean en = ((Boolean)globalIgnore.get(pattern)).booleanValue(); - buf.append(en); - buf.append(PREF_TEAM_SEPARATOR); - } - - } - TeamPlugin.getPlugin().getPluginPreferences().setValue(PREF_TEAM_IGNORES, buf.toString()); - } - - /* - * TEXT - * - * Reads the text patterns currently defined by extensions. - */ - private static void initializePluginPatterns(Map pTypes, Map fTypes) { - TeamPlugin plugin = TeamPlugin.getPlugin(); - if (plugin != null) { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.FILE_TYPES_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - IConfigurationElement[] configElements = extensions[i].getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - String ext = configElements[j].getAttribute("extension"); //$NON-NLS-1$ - if (ext != null) { - String type = configElements[j].getAttribute("type"); //$NON-NLS-1$ - // If the extension doesn't already exist, add it. - if (!fTypes.containsKey(ext)) { - if (type.equals("text")) { //$NON-NLS-1$ - pTypes.put(ext, new Integer(TEXT)); - fTypes.put(ext, new Integer(TEXT)); - } else if (type.equals("binary")) { //$NON-NLS-1$ - fTypes.put(ext, new Integer(BINARY)); - pTypes.put(ext, new Integer(BINARY)); - } - } - } - } - } - } - } - } - - /* - * TEXT - * - * Read the saved file type state from the given input stream. - * - * @param dis the input stream to read the saved state from - * @throws IOException if an I/O problem occurs - */ - private static void readTextState(DataInputStream dis) throws IOException { - int extensionCount = 0; - try { - extensionCount = dis.readInt(); - } catch (EOFException e) { - // Ignore the exception, it will occur if there are no - // patterns stored in the state file. - return; - } - for (int i = 0; i < extensionCount; i++) { - String extension = dis.readUTF(); - int type = dis.readInt(); - globalTypes.put(extension, new Integer(type)); - } - } - - /* - * TEXT - * - * Load the file type registry saved state. This loads the previously saved - * contents, as well as discovering any values contributed by plug-ins. - */ - private static void loadTextState() { - globalTypes = new TreeMap(); - boolean old = loadBackwardCompatibleTextState(); - if (!old) loadTextPreferences(); - pluginTypes = new TreeMap(); - initializePluginPatterns(pluginTypes, globalTypes); - if (old) TeamPlugin.getPlugin().savePluginPreferences(); - } - - private static void loadTextPreferences() { - Preferences pref = TeamPlugin.getPlugin().getPluginPreferences(); - if (!pref.contains(PREF_TEAM_TYPES)) return; - pref.addPropertyChangeListener(new Preferences.IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - // when a property is changed, invalidate our cache so that - // properties will be recalculated. - if(event.getProperty().equals(PREF_TEAM_TYPES)) - globalTypes = null; - } - }); - String prefTypes = pref.getString(PREF_TEAM_TYPES); - StringTokenizer tok = new StringTokenizer(prefTypes, PREF_TEAM_SEPARATOR); - String extension, integer; - try { - while (true) { - extension = tok.nextToken(); - if (extension.length()==0) return; - integer = tok.nextToken(); - globalTypes.put(extension, Integer.valueOf(integer)); - } - } catch (NoSuchElementException e) { - return; - } - - } - /* - * If the workspace is an old 2.0 one, read the old file and delete it - */ - private static boolean loadBackwardCompatibleTextState() { - // File name of the persisted file type information - String STATE_FILE = ".fileTypes"; //$NON-NLS-1$ - IPath pluginStateLocation = TeamPlugin.getPlugin().getStateLocation().append(STATE_FILE); - File f = pluginStateLocation.toFile(); - if (!f.exists()) return false; - try { - DataInputStream dis = new DataInputStream(new FileInputStream(f)); - try { - readTextState(dis); - } finally { - dis.close(); - } - } catch (IOException ex) { - TeamPlugin.log(Status.ERROR, ex.getMessage(), ex); - return false; - } - f.delete(); - return true; - } - - /* - * IGNORE - * - * Reads the ignores currently defined by extensions. - */ - private static void initializePluginIgnores(SortedMap pIgnore, SortedMap gIgnore) { - TeamPlugin plugin = TeamPlugin.getPlugin(); - if (plugin != null) { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.IGNORE_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - String pattern = configElements[j].getAttribute("pattern"); //$NON-NLS-1$ - if (pattern != null) { - String selected = configElements[j].getAttribute("enabled"); //$NON-NLS-1$ - if (selected == null) { - // Check for selected because this used to be the field name - selected = configElements[j].getAttribute("selected"); //$NON-NLS-1$ - } - boolean enabled = selected != null && selected.equalsIgnoreCase("true"); //$NON-NLS-1$ - // if this ignore doesn't already exist, add it to the global list - pIgnore.put(pattern, new Boolean(enabled)); - if (!gIgnore.containsKey(pattern)) { - gIgnore.put(pattern, new Boolean(enabled)); - } - } - } - } - } - } - } - - /* - * IGNORE - * - * Reads global ignore preferences and populates globalIgnore - */ - private static void readIgnoreState() throws TeamException { - if (readBackwardCompatibleIgnoreState()) return; - Preferences pref = TeamPlugin.getPlugin().getPluginPreferences(); - if (!pref.contains(PREF_TEAM_IGNORES)) return; - pref.addPropertyChangeListener(new Preferences.IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - // when a property is changed, invalidate our cache so that - // properties will be recalculated. - if(event.getProperty().equals(PREF_TEAM_IGNORES)) - globalIgnore = null; - } - }); - String prefIgnores = pref.getString(PREF_TEAM_IGNORES); - StringTokenizer tok = new StringTokenizer(prefIgnores, PREF_TEAM_SEPARATOR); - String pattern, enabled; - try { - while (true) { - pattern = tok.nextToken(); - if (pattern.length()==0) return; - enabled = tok.nextToken(); - globalIgnore.put(pattern, new Boolean(enabled)); - } - } catch (NoSuchElementException e) { - return; - } - } - - /* - * For backward compatibility, we still look at if we have .globalIgnores - */ - private static boolean readBackwardCompatibleIgnoreState() throws TeamException { - String GLOBALIGNORE_FILE = ".globalIgnores"; //$NON-NLS-1$ - IPath pluginStateLocation = TeamPlugin.getPlugin().getStateLocation().append(GLOBALIGNORE_FILE); - File f = pluginStateLocation.toFile(); - if (!f.exists()) return false; - try { - DataInputStream dis = new DataInputStream(new FileInputStream(f)); - try { - int ignoreCount = 0; - try { - ignoreCount = dis.readInt(); - } catch (EOFException e) { - // Ignore the exception, it will occur if there are no ignore - // patterns stored in the provider state file. - return false; - } - for (int i = 0; i < ignoreCount; i++) { - String pattern = dis.readUTF(); - boolean enabled = dis.readBoolean(); - globalIgnore.put(pattern, new Boolean(enabled)); - } - } finally { - dis.close(); - } - f.delete(); - } catch (FileNotFoundException e) { - // not a fatal error, there just happens not to be any state to read - } catch (IOException ex) { - throw new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, 0, Policy.bind("Team.readError"), ex)); //$NON-NLS-1$ - } - return true; - } - /** - * Initialize the registry, restoring its state. - * - * This method is called by the plug-in upon startup, clients should not call this method - */ - public static void startup() { - // Register a delta listener that will tell the provider about a project move - ResourcesPlugin.getWorkspace().addResourceChangeListener(new IResourceChangeListener() { - public void resourceChanged(IResourceChangeEvent event) { - IResourceDelta[] projectDeltas = event.getDelta().getAffectedChildren(); - for (int i = 0; i < projectDeltas.length; i++) { - IResourceDelta delta = projectDeltas[i]; - IResource resource = delta.getResource(); - // Only consider project additions that are moves - if (delta.getKind() != IResourceDelta.ADDED) continue; - if ((delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) continue; - // Only consider projects that have a provider - if (!RepositoryProvider.isShared(resource.getProject())) continue; - RepositoryProvider provider = RepositoryProvider.getProvider(resource.getProject()); - if (provider == null) continue; - // Only consider providers whose project is not mapped properly already - if (provider.getProject().equals(resource.getProject())) continue; - // Tell the provider about it's new project - provider.setProject(resource.getProject()); - } - } - }, IResourceChangeEvent.POST_CHANGE); - } - - /** - * Shut down the registry, persisting its state. - * - * This method is called by the plug-in upon shutdown, clients should not call this method - */ - public static void shutdown() { - TeamPlugin.getPlugin().savePluginPreferences(); - } - /** - * @deprecated - * Use {@link org.eclipse.team.core.RepositoryProviderType#getProjectSetCapability()} - * to obtain an instance of {@link ProjectSetCapability} instead. - */ - public static IProjectSetSerializer getProjectSetSerializer(String id) { - TeamPlugin plugin = TeamPlugin.getPlugin(); - if (plugin != null) { - IExtensionPoint extension = plugin.getDescriptor().getExtensionPoint(TeamPlugin.PROJECT_SET_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - String extensionId = configElements[j].getAttribute("id"); //$NON-NLS-1$ - if (extensionId != null && extensionId.equals(id)) { - try { - return (IProjectSetSerializer)configElements[j].createExecutableExtension("class"); //$NON-NLS-1$ - } catch (CoreException e) { - TeamPlugin.log(e); - return null; - } - } - } - } - } - } - return null; - } - - private static String getFileExtension(String name) { - if (name == null) return null; - int index = name.lastIndexOf('.'); - if (index == -1) - return null; - if (index == (name.length() - 1)) - return ""; //$NON-NLS-1$ - return name.substring(index + 1); - } - - /** - * Return the default ignore infos - * (i.e. those that are specified in - * plugin manifests). - * @return the default ignore infos. - * @since 3.0 - */ - public static IIgnoreInfo[] getDefaultIgnores() { - SortedMap gIgnore = new TreeMap(); - SortedMap pIgnore = new TreeMap(); - initializePluginIgnores(pIgnore, gIgnore); - return getIgnoreInfo(gIgnore); - } - - /** - * Return the default file type bindings - * (i.e. those that are specified in - * plugin manifests). - * @return the default file type bindings - * @since 3.0 - */ - public static IFileTypeInfo[] getDefaultTypes() { - SortedMap gTypes = new TreeMap(); - SortedMap pTypes = new TreeMap(); - initializePluginPatterns(pTypes, gTypes); - return getFileTypeInfo(gTypes); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/TeamException.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/TeamException.java deleted file mode 100644 index 60f40b197..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/TeamException.java +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * This exception is thrown by the team provider API. It represents a failure in an API call. - * Since some API calls take multiple arguments, the exception is capable of returning multiple - * statuses. The API definition determinies if the exception represents a single or multiple status - * response; this can also be tested on the exception instance itself. - * <p> - * To determine the exact cause of the failure the caller should look at each status in detail. - * </p> - * @since 2.0 - */ -public class TeamException extends CoreException { - - // Field required to avoid compiler warning - private static final long serialVersionUID = 1L; - - // The operation completed successfully. - public static final int OK = 0; - - // The operation failed because the resource is not checked-in. - public static final int NOT_CHECKED_IN = -1; - - // The operation failed because the resource is not checked-out. - public static final int NOT_CHECKED_OUT = -2; - - // The corresponding remote resource no longer exists or was never created. - public static final int NO_REMOTE_RESOURCE = -3; - - // The provider suffered an IO failure, the operation may be retried. - public static final int IO_FAILED = -4; - - // The user is not authorized to execute the attempted operation. - public static final int NOT_AUTHORIZED = -5; - - // The provider was unable to complete the operation for an unspecified reason. - public static final int UNABLE = -6; - - // The operation cannot be performed due to a conflict with other work. - public static final int CONFLICT = -7; - - /** - * Create a <code>TeamException</code> which contains the given status object. - * @param status the status for this exception - */ - public TeamException(IStatus status) { - super(status); - } - - /** - * Create a <code>TeamException</code> with an - * error status that contains the given message and - * throwable. - * @param message the message for the exception - * @param e an associated exception - * @since 3.0 - */ - public TeamException(String message, Throwable e) { - super(new Status(IStatus.ERROR, TeamPlugin.ID, 0, message, e)); - } - - /** - * Create a <code>TeamException</code> with an - * error status that contains the given message. - * @param message the message for the exception - */ - public TeamException(String message) { - this(message, null); - } - - /** - * Create a <code>TeamException</code> that wraps the given <code>CoreException</code> - * @param e a <code>CoreException</code> - * @since 3.0 - */ - protected TeamException(CoreException e) { - super(asStatus(e)); - } - - private static Status asStatus(CoreException e) { - IStatus status = e.getStatus(); - return new Status(status.getSeverity(), status.getPlugin(), status.getCode(), status.getMessage(), e); - } - - /** - * Return a <code>TeamException</code> for the given exception. - * @param e an exception - * @return a <code>TeamException</code> for the given exception - * @since 3.0 - */ - public static TeamException asTeamException(CoreException e) { - if (e instanceof TeamException) { - return (TeamException)e; - } - return new TeamException(e); - } - - /** - * Return a <code>TeamException</code> for the given exception. - * @param e an exception - * @return a <code>TeamException</code> for the given exception - * @since 3.0 - */ - public static TeamException asTeamException(InvocationTargetException e) { - Throwable target = e.getTargetException(); - if (target instanceof TeamException) { - return (TeamException) target; - } - return new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, UNABLE, target.getMessage() != null ? target.getMessage() : "", target)); //$NON-NLS-1$ - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/TeamStatus.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/TeamStatus.java deleted file mode 100644 index fe03d189b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/TeamStatus.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.Status; - -/** - * Status that is returned from some Team operations or is the payload of - * some TeamExceptions. - * - * @since 3.0 - */ -public class TeamStatus extends Status implements ITeamStatus { - - private IResource resource; - - /** - * Create a new status object. - * @param severity the severity; one of <code>OK</code>, - * <code>ERROR</code>, <code>INFO</code>, or <code>WARNING</code> - * @param pluginId the unique identifier of the relevant plug-in - * @param code the plug-in-specific status code, or <code>OK</code> - * @param message a human-readable message, localized to the - * current locale - * @param exception a low-level exception, or <code>null</code> if not - * applicable - * @param resource the resource asociated with the exception - */ - public TeamStatus(int severity, String pluginId, int code, String message, Throwable exception, IResource resource) { - super(severity, pluginId, code, message, exception); - if (resource == null) { - this.resource = ResourcesPlugin.getWorkspace().getRoot(); - } else { - this.resource = resource; - } - } - - /** - * Return the resource associated with this status. - * @return Returns the resource. - */ - public IResource getResource() { - return resource; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/package.html b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/package.html deleted file mode 100644 index 998490f0d..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/package.html +++ /dev/null @@ -1,20 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="Author" content="IBM"> - <title>Package-level Javadoc</title> -</head> -<body> -Application programming interfaces for defining and working with repository providers. -<h2> -Package Specification</h2> -This package specifies the API for defining repository providers. A repository -provider supports the sharing of projects in the local Eclipse workspace -with remote locations managed by a particular type of repository system. -Additional facilites included in this API exist for the mapping and unmapping of a -repository provider to a project, the deifnition of a project set serializer for -sharing workspace setup, and the management of global ignore patterns and content type -determination for files. -</body> -</html>
\ No newline at end of file diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ActiveChangeSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ActiveChangeSet.java deleted file mode 100644 index 6c44c292f..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ActiveChangeSet.java +++ /dev/null @@ -1,213 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import java.util.*; - -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.Path; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.core.synchronize.SyncInfoTree; -import org.eclipse.team.internal.core.TeamPlugin; -import org.osgi.service.prefs.Preferences; - -/** - * An active change set represents a set of local resource changes - * that are grouped together as a single logical change. - * @since 3.1 - */ -public class ActiveChangeSet extends ChangeSet { - - private static final String CTX_TITLE = "title"; //$NON-NLS-1$ - private static final String CTX_COMMENT = "comment"; //$NON-NLS-1$ - private static final String CTX_RESOURCES = "resources"; //$NON-NLS-1$ - - private String comment; - private final SubscriberChangeSetCollector manager; - - /** - * Create a change set with the given title - * @param manager the manager that owns this set - * @param title the title of the set - */ - public ActiveChangeSet(SubscriberChangeSetCollector manager, String title) { - super(title); - this.manager = manager; - } - - /** - * Get the title of the change set. The title is used - * as the comment when the set is checking in if no comment - * has been explicitly set using <code>setComment</code>. - * @return the title of the set - */ - public String getTitle() { - return getName(); - } - - /** - * Set the title of the set. The title is used - * as the comment when the set is committed if no comment - * has been explicitly set using <code>setComment</code>. - * @param title the title of the set - */ - public void setTitle(String title) { - setName(title); - getManager().fireNameChangedEvent(this); - } - - /** - * Get the comment of this change set. If the comment - * as never been set, the title is returned as the comment - * @return the comment to be used when the set is committed - */ - public String getComment() { - if (comment == null) { - return getTitle(); - } - return comment; - } - - /** - * Set the comment to be used when the change set is committed. - * If <code>null</code> is passed, the title of the set - * will be used as the comment. - * @param comment the comment for the set or <code>null</code> - * if the title should be the comment - */ - public void setComment(String comment) { - if (comment != null && comment.equals(getTitle())) { - this.comment = null; - } else { - this.comment = comment; - } - } - - /* - * Override inherited method to only include outgoing changes - */ - protected boolean isValidChange(SyncInfo info) { - return getManager().isModified(info); - } - - private void addResource(IResource resource) throws TeamException { - Subscriber subscriber = getManager().getSubscriber(); - SyncInfo info = subscriber.getSyncInfo(resource); - if (info != null) { - add(info); - } - } - - private SubscriberChangeSetCollector getManager() { - return manager; - } - - /** - * Return whether the set has a comment that differs from the title. - * @return whether the set has a comment that differs from the title - */ - public boolean hasComment() { - return comment != null; - } - - public void save(Preferences prefs) { - prefs.put(CTX_TITLE, getTitle()); - if (comment != null) { - prefs.put(CTX_COMMENT, comment); - } - if (!isEmpty()) { - StringBuffer buffer = new StringBuffer(); - IResource[] resources = getResources(); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - buffer.append(resource.getFullPath().toString()); - buffer.append('\n'); - } - prefs.put(CTX_RESOURCES, buffer.toString()); - } - } - - public void init(Preferences prefs) { - setName(prefs.get(CTX_TITLE, "")); //$NON-NLS-1$ - comment = prefs.get(CTX_COMMENT, null); - String resourcePaths = prefs.get(CTX_RESOURCES, null); - if (resourcePaths != null) { - SyncInfoTree syncInfoSet = getSyncInfoSet(); - try { - syncInfoSet.beginInput(); - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - StringTokenizer tokenizer = new StringTokenizer(resourcePaths, "\n"); //$NON-NLS-1$ - while (tokenizer.hasMoreTokens()) { - String next = tokenizer.nextToken(); - if (next.trim().length() > 0) { - IResource resource = getResource(root, next); - try { - // Only include the resource if it is out-of-sync - if (resource != null && manager.getSubscriber().getSyncInfo(resource) != null) { - try { - addResource(resource); - } catch (TeamException e) { - TeamPlugin.log(e); - } - } - } catch (TeamException e) { - // Log and continue - TeamPlugin.log(e); - } - } - } - } finally { - syncInfoSet.endInput(null); - } - } - } - - private IResource getResource(IWorkspaceRoot root, String next) { - IResource resource = root.findMember(next); - if (resource == null) { - // May be an outgoing deletion - Path path = new Path(null, next); - if (next.charAt(next.length()-1) == Path.SEPARATOR) { - if (path.segmentCount() == 1) { - // resource is a project - resource = root.getProject(path.lastSegment()); - } else { - // resource is a folder - resource = root.getFolder(path); - } - } else { - // resource is a file - resource = root.getFile(path); - } - } - return resource; - } - - /** - * Add the resources to the change set if they are outgoing changes. - * @param resources the resouces to add. - * @throws TeamException - */ - public void add(IResource[] resources) throws TeamException { - List toAdd = new ArrayList(); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - SyncInfo info = manager.getSyncInfo(resource); - if (info != null) { - toAdd.add(info); - } - } - if (!toAdd.isEmpty()) { - add((SyncInfo[]) toAdd.toArray(new SyncInfo[toAdd.size()])); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSet.java deleted file mode 100644 index a5dbb4ebf..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSet.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.core.synchronize.SyncInfoTree; - -/** - * A change set represents a set of changes that are logically - * grouped together as a single change. The changes are - * represented usign a set of <code>SyncInfo</code>. - * - * @since 3.1 - */ -public abstract class ChangeSet { - - private String name; - - private final SyncInfoTree set = new SyncInfoTree(); - - /** - * Create a change set with no name. Subclasses - * that create a change set in this manner should - * provide a name before the set is used by other clients. - */ - protected ChangeSet() { - super(); - } - - /** - * Create a change set with the given name. - */ - public ChangeSet(String name) { - this.name = name; - } - - /** - * Return the SyncInfoSet that contains the resources that belong to this change set. - * @return the SyncInfoSet that contains the resources that belong to this change set - */ - public SyncInfoTree getSyncInfoSet() { - return set; - } - - /** - * Return the resources that are contained in this set. - * @return the resources that are contained in this set - */ - public IResource[] getResources() { - return set.getResources(); - } - - /** - * Return whether the set contains any files. - * @return whether the set contains any files - */ - public boolean isEmpty() { - return set.isEmpty(); - } - - /** - * Return true if the given file is included in this set. - * @param local a ocal file - * @return true if the given file is included in this set - */ - public boolean contains(IResource local) { - return set.getSyncInfo(local) != null; - } - - /** - * Add the resource to this set if it is modified - * w.r.t. the subscriber. - * @param resource - * @throws TeamException - */ - public void add(SyncInfo info) { - if (isValidChange(info)) { - set.add(info); - } - } - - /** - * Return whether the given sync info is a valid change - * and can be included in this set. This method is used - * by the <code>add</code> method to filter set additions. - * @param info a sync info - * @return whether the sync info is a valid member of this set - */ - protected boolean isValidChange(SyncInfo info) { - return (info != null); - } - - /** - * Add the resources to this set if they are modified - * w.r.t. the subscriber. - * @param resources the resources to be added. - * @throws TeamException - */ - public void add(SyncInfo[] infos) { - try { - set.beginInput(); - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - add(info); - } - } finally { - set.endInput(null); - } - } - - /** - * Remove the resource from the set. - * @param resource the resource to be removed - */ - public void remove(IResource resource) { - if (contains(resource)) { - set.remove(resource); - } - } - - /** - * Remove the resources from the set. - * @param resources the resources to be removed - */ - public void remove(IResource[] resources) { - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - remove(resource); - } - } - - /** - * Remove the resource and it's descendants to the given depth. - * @param resource the resource to be removed - * @param depth the depth of the removal (one of - * <code>IResource.DEPTH_ZERO, IResource.DEPTH_ONE, IResource.DEPTH_INFINITE)</code> - */ - public void rootRemoved(IResource resource, int depth) { - SyncInfo[] infos = set.getSyncInfos(resource, depth); - if (infos.length > 0) { - IResource[] resources = new IResource[infos.length]; - for (int i = 0; i < resources.length; i++) { - resources[i] = infos[i].getLocal(); - } - set.removeAll(resources); - } - } - - /** - * Return a comment describing the change. - * @return a comment describing the change - */ - public abstract String getComment(); - - /** - * Return the name assigned to this set. The name should be - * unique. - * @return the name assigned to this set - */ - public String getName() { - return name; - } - - /** - * Set the name of the change set. The name of a change - * set can be changed but it is up to subclass to notify - * any interested partied of the name change. - * @param name the new name for the set - */ - protected void setName(String name) { - this.name = name; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSetCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSetCollector.java deleted file mode 100644 index aeeaef4d8..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSetCollector.java +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import java.util.*; - -import org.eclipse.core.internal.runtime.ListenerList; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.Platform; -import org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener; -import org.eclipse.team.core.synchronize.SyncInfoSet; - -/** - * This class defines the common aspects of collecting a set of change - * sets, including event notification. - * - * @since 3.1 - */ -public abstract class ChangeSetCollector { - - private ListenerList listeners = new ListenerList(); - private Set sets = new HashSet(); - - private Object[] getListeners() { - return listeners.getListeners(); - } - - /** - * Method that can be invoked by subclasses when the name of - * a managed change set changes. - * @param set the set whose title has changed - */ - protected void fireNameChangedEvent(final ChangeSet set) { - if (contains(set)) { - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.nameChanged(set); - } - }); - } - } - } - - /** - * Method which allows subclasses to notify listeners that the default - * set has changed. - * @param oldSet the previous default - * @param defaultSet the new default - */ - protected void fireDefaultChangedEvent(final ChangeSet oldSet, final ChangeSet defaultSet) { - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.defaultSetChanged(oldSet, defaultSet); - } - }); - } - } - - /** - * Add the set to the list of active sets. - * @param set the set to be added - */ - public void add(final ChangeSet set) { - if (!contains(set)) { - sets.add(set); - set.getSyncInfoSet().addSyncSetChangedListener(getChangeSetChangeListener()); - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.setAdded(set); - } - }); - } - } - } - - /** - * Remove the set from the list of active sets. - * @param set the set to be removed - */ - public void remove(final ChangeSet set) { - if (contains(set)) { - set.getSyncInfoSet().removeSyncSetChangedListener(getChangeSetChangeListener()); - sets.remove(set); - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.setRemoved(set); - } - }); - } - } - } - - /** - * Return the change listener that will be registered with each - * <code>SyncInfoSet</code> associated with the <code>ChangeSets</code> - * added to this collector. - * @return the change listener that will be registered with each - * <code>SyncInfoSet</code> associated with the <code>ChangeSets</code> - * added to this collector - */ - protected abstract ISyncInfoSetChangeListener getChangeSetChangeListener(); - - /** - * Return whether the manager contains the given commit set - * @param set the commit set being tested - * @return whether the set is contained in the manager's list of active sets - */ - public boolean contains(ChangeSet set) { - return sets.contains(set); - } - - /** - * Add the listener to the set of registered listeners. - * @param listener the listener to be added - */ - public void addListener(IChangeSetChangeListener listener) { - listeners.add(listener); - } - - /** - * Remove the listener from the set of registered listeners. - * @param listener the listener to remove - */ - public void removeListener(IChangeSetChangeListener listener) { - listeners.remove(listener); - } - - /** - * Return the list of active commit sets. - * @return the list of active commit sets - */ - public ChangeSet[] getSets() { - return (ChangeSet[]) sets.toArray(new ChangeSet[sets.size()]); - } - - /** - * Dispose of any resources maintained by the manager - */ - public void dispose() { - // Nothing to do - } - - /** - * @param changeSet - * @param allAffectedResources - */ - protected void fireResourcesChangedEvent(final ChangeSet changeSet, final IResource[] allAffectedResources) { - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.resourcesChanged(changeSet, allAffectedResources); - } - }); - } - } - - /** - * Return the Change Set whose sync info set is the - * one given. - * @param set a sync info set - * @return the change set for the given sync info set - */ - protected ChangeSet getChangeSet(SyncInfoSet set) { - for (Iterator iter = sets.iterator(); iter.hasNext();) { - ChangeSet changeSet = (ChangeSet) iter.next(); - if (changeSet.getSyncInfoSet() == set) { - return changeSet; - } - } - return null; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/CheckedInChangeSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/CheckedInChangeSet.java deleted file mode 100644 index dc59a4f03..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/CheckedInChangeSet.java +++ /dev/null @@ -1,32 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import java.util.Date; - -/** - * A checked-in change set represents a group of resource - * changes that were previously checked into a repository - * as a single logical change. - * <p> - * A previously checked-in set of changes may not apply directly - * to the local versions of the resources involved. However, - * a <code>SyncInfo</code> is still used to reprsent each change. - * The base and remote slots of the <code>SyncInfo</code> identify - * the state before and after the resources were checked-in. - * @since 3.1 - */ -public abstract class CheckedInChangeSet extends ChangeSet { - - public abstract String getAuthor(); - - public abstract Date getDate(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/IChangeSetChangeListener.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/IChangeSetChangeListener.java deleted file mode 100644 index 090fc84ea..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/IChangeSetChangeListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import org.eclipse.core.resources.IResource; - - -/** - * Interface for registering change set change listeners with - * the change set manager. - */ -public interface IChangeSetChangeListener { - - /** - * The given set has been added to the set manager. - * @param set the added set - */ - void setAdded(ChangeSet set); - - /** - * The default change set has change to be the given set. - * All new modifications will be placed in the default - * set. - * @param set the default set - */ - void defaultSetChanged(ChangeSet previousDefault, ChangeSet set); - - /** - * The given set has been removed from the set manager. - * @param set the removed set - */ - void setRemoved(ChangeSet set); - - /** - * The title of the given set has changed. - * @param set the set whose title changed - */ - void nameChanged(ChangeSet set); - - /** - * The state of the given resources have change with respect to the - * given set. This means that the resource have either been added - * or removed from the set. Callers can use the resources contained - * in the set to determine if each resource is an addition or removal. - * @param set the set that has changed - * @param resources the resources whose containment state has changed w.r.t the set - */ - void resourcesChanged(ChangeSet set, IResource[] resources); - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ISubscriberChangeEvent.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ISubscriberChangeEvent.java deleted file mode 100644 index 1961991c7..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ISubscriberChangeEvent.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; -import org.eclipse.core.resources.IResource; - -/** - * A change event that describes a change in a resource - * that is or was supervised by a subscriber. - * <p> - * Clients are not intented to implement. Instead subclass {@link SubscriberChangeEvent}. - * </p> - * @see ISubscriberChangeListener - * @since 3.0 - */ -public interface ISubscriberChangeEvent { - /*==================================================================== - * Constants defining the kinds of team changes to resources: - *====================================================================*/ - /** - * Delta kind constant indicating that the resource has not been changed in any way - * @see IResourceDelta#getKind - */ - public static final int NO_CHANGE = 0; - /** - * Delta kind constant (bit mask) indicating that the synchronization state of a resource has changed. - * @see #getFlags - */ - public static final int SYNC_CHANGED = 0x1; - /** - * Delta kind constant (bit mask) indicating that a team provider has been configured on the resource. - * @see #getFlags - */ - public static final int ROOT_ADDED = 0x2; - /** - * Delta kind constant (bit mask) indicating that a team provider has been de-configured on the resource. - * @see #getFlags - */ - public static final int ROOT_REMOVED = 0x4; - - /** - * Return the flags that describe the type of change. - * The returned value should be ANDed with the change type - * flags to determine whether the change event is of - * a particular type. For exampe, - * <pre> - * if (event.getFlags() & ISubscriberChangeEvent.SYNC_CHANGED) { - * // the sync info for the resource has changed - * } - * </pre> - * @return the flags that describe the type of change - */ - public abstract int getFlags(); - - /** - * Return the resource whose state with - * respect to the subscriber has changed. - * @return the resource whose state with - * respect to the subscriber has changed - */ - public abstract IResource getResource(); - - /** - * Return the subscriber to which this change event applies. - * @return the subscriber to which this change event applies - */ - public abstract Subscriber getSubscriber(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ISubscriberChangeListener.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ISubscriberChangeListener.java deleted file mode 100644 index ca73c6914..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ISubscriberChangeListener.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import java.util.EventListener; - -/** - * A subscriber change listener is notified of changes to resources - * regarding their subscriber synchronization state. - * <p> - * Clients may implement this interface. - * </p> - * @see Subscriber#addListener(ISubscriberChangeListener) - * @since 3.0 - */ -public interface ISubscriberChangeListener extends EventListener{ - - /** - * Notifies this listener that some resources' subscriber properties have - * changed. The changes have already happened. For example, a resource's - * base revision may have changed. The resource tree may or may not be open for modification - * when this method is invoked. - * - * @param deltas detailing the kinds of changes - */ - public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas); -} - diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/Subscriber.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/Subscriber.java deleted file mode 100644 index ba54254b2..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/Subscriber.java +++ /dev/null @@ -1,334 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.team.core.ITeamStatus; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.TeamStatus; -import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.core.synchronize.SyncInfoSet; -import org.eclipse.team.core.variants.IResourceVariantComparator; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * A Subscriber provides synchronization between local resources and a - * remote location that is used to share those resources. - * <p> - * When queried for the <code>SyncInfo</code> corresponding to a local resource using - * <code>getSyncInfo(IResource)</code>, the subscriber should not contact the server. - * Server round trips should only occur within the <code>refresh<code> - * method of the subscriber. Consequently, - * the implementation of a subscriber must cache enough state information for a remote resource to calculate the - * synchronization state without contacting the server. During a refresh, the latest remote resource state - * information should be fetched and cached. For - * a subscriber that supports three-way compare, the refresh should also fetch the latest base state unless this is - * available by some other means (e.g. for some repository tools, the base state is persisted on disk with the - * local resources). - * </p> - * <p> - * After a refresh, the subscriber must notify any listeners of local resources whose corresponding remote resource - * or base resource changed. The subscriber does not need to notify listeners when the state changes due to a local - * modification since local changes are available through the <code>IResource</code> delta mechanism. However, - * the subscriber must - * cache enough information (e.g. the local timestamp of when the file was in-sync with its corresponding remote - * resource) - * to determine if the file represents an outgoing change so that <code>SyncInfo</code> obtained - * after a delta will indicate that the file has an outgoing change. The subscriber must also notify listeners - * when roots and added - * or removed. For example, a subscriber for a repository provider would fire a root added event when a project - * was shared - * with a repository. No event is required when a root is deleted as this is available through the - * <code>IResource</code> delta mechanism. It is up to clients to requery the subscriber - * when the state of a resource changes locally by listening to IResource deltas. - * </p><p> - * The remote and base states can also include the state for resources that do not exist locally (i.e outgoing deletions - * or incoming additions). When queried for the members of a local resource, the subscriber should include any children - * for which a remote exists even if the local does not. - * </p> - * @since 3.0 - */ -abstract public class Subscriber { - - private List listeners = new ArrayList(1); - - /** - * Return the name of this subscription, in a format that is - * suitable for display to an end user. - * - * @return String representing the name of this subscription. - */ - abstract public String getName(); - - /** - * Returns <code>true</code> if this resource is supervised by this - * subscriber. A supervised resource is one for which this subscriber - * maintains the synchronization state. Supervised resources are the only - * resources returned when <code>members(IResource)</code> was invoked with the parent - * of the resource. Returns <code>false</code> in all - * other cases. - * - * @return <code>true</code> if this resource is supervised, and <code>false</code> - * otherwise - */ - abstract public boolean isSupervised(IResource resource) throws TeamException; - - /** - * Returns all non-transient member resources of the given resource. The - * result will include entries for resources that exist either in the - * workspace or are implicated in an incoming change. Returns an empty list - * if the given resource exists neither in the workspace nor in the - * corresponding subscriber location, or if the given resource is transient. - * <p> - * This is a fast operation; the repository is not contacted. - * </p> - * @param resource the resource - * @return a list of member resources - */ - abstract public IResource[] members(IResource resource) throws TeamException; - - /** - * Returns the list of root resources this subscriber considers for - * synchronization. A client should call this method first then can safely - * call <code>members</code> to navigate the resources managed by this - * subscriber. - * - * @return a list of resources - */ - abstract public IResource[] roots(); - - /** - * Returns synchronization info for the given resource, or <code>null</code> - * if there is no synchronization info because the subscriber does not apply - * to this resource. - * <p> - * Note that sync info may be returned for non-existing or for resources - * which have no corresponding remote resource. - * </p><p> - * This method will be quick. If synchronization calculation requires content from - * the server it must be cached when the subscriber is refreshed. A client should - * call refresh before calling this method to ensure that the latest information - * is available for computing the sync state. - * </p> - * @param resource the resource of interest - * @return sync info - */ - abstract public SyncInfo getSyncInfo(IResource resource) throws TeamException; - - /** - * Returns the comparison criteria that will be used by the sync info - * created by this subscriber. - * - * @return the comparator to use when computing sync states for this - * subscriber. - */ - abstract public IResourceVariantComparator getResourceComparator(); - - /** - * Refreshes the resource hierarchy from the given resources and their - * children (to the specified depth) from the corresponding resources in the - * remote location. Resources are ignored in the following cases: - * <ul> - * <li>if they do not exist either in the workspace or in the corresponding - * remote location</li> - * <li>if the given resource is not supervised by this subscriber</li> - * <li>if the given resource is a closed project (they are ineligible for - * synchronization)</li> - * <p> - * Typical synchronization operations use the statuses computed by this - * method as the basis for determining what to do. It is possible for the - * actual sync status of the resource to have changed since the current - * local sync status was refreshed. Operations typically skip resources with - * stale sync information. The chances of stale information being used can - * be reduced by running this method (where feasible) before doing other - * operations. Note that this will of course affect performance. - * </p> - * <p> - * The depth parameter controls whether refreshing is performed on just the - * given resource (depth= <code>DEPTH_ZERO</code>), the resource and its - * children (depth= <code>DEPTH_ONE</code>), or recursively to the - * resource and all its descendents (depth= <code>DEPTH_INFINITE</code>). - * Use depth <code>DEPTH_ONE</code>, rather than depth - * <code>DEPTH_ZERO</code>, to ensure that new members of a project or - * folder are detected. - * </p> - * <p> - * This method might change resources; any changes will be reported in a - * subsequent subscriber resource change event indicating changes to server - * sync status. - * </p> - * <p> - * This method contacts the server and is therefore long-running; progress - * and cancellation are provided by the given progress monitor. - * </p> - * @param resources the resources - * @param depth valid values are <code>DEPTH_ZERO</code>, - * <code>DEPTH_ONE</code>, or <code>DEPTH_INFINITE</code> - * @param monitor progress monitor, or <code>null</code> if progress - * reporting and cancellation are not desired - * @return status with code <code>OK</code> if there were no problems; - * otherwise a description (possibly a multi-status) consisting of - * low-severity warnings or informational messages. - * @exception TeamException if this method fails. Reasons include: - * <ul> - * <li>The server could not be contacted.</li> - * </ul> - */ - abstract public void refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException; - - /** - * Adds a listener to this team subscriber. Has no effect if an identical - * listener is already registered. - * <p> - * Team resource change listeners are informed about state changes that - * affect the resources supervised by this subscriber. - * </p> - * @param listener a team resource change listener - */ - public void addListener(ISubscriberChangeListener listener) { - synchronized (listeners) { - if (!listeners.contains(listener)) { - listeners.add(listener); - } - } - } - - /** - * Removes a listener previously registered with this team subscriber. Has - * no affect if an identical listener is not registered. - * - * @param listener a team resource change listener - */ - public void removeListener(ISubscriberChangeListener listener) { - synchronized (listeners) { - listeners.remove(listener); - } - } - - /** - * Adds all out-of-sync resources (getKind() != IN_SYNC) that occur - * under the given resources to the specified depth. The purpose of this - * method is to provide subscribers a means of optimizing the determination - * of all out-of-sync out-of-sync descendants of a set of resources. - * <p> - * If any of the directly provided resources are not supervised by the subscriber, then - * they should be removed from the set. - * If errors occur while determining the sync info for the resources, they should - * be added to the set using <code>addError</code>. - * </p> - * @param resources the root of the resource subtrees from which out-of-sync sync info should be collected - * @param depth the depth to which sync info should be collected - * (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @param set the sync info set to which out-of-sync resources should be added (or removed). Any errors - * should be added to the set as well. - * @param monitor a progress monitor - */ - public void collectOutOfSync(IResource[] resources, int depth, SyncInfoSet set, IProgressMonitor monitor) { - try { - monitor.beginTask(null, 100 * resources.length); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - IProgressMonitor subMonitor = Policy.subMonitorFor(monitor, 100); - subMonitor.beginTask(null, IProgressMonitor.UNKNOWN); - collect(resource, depth, set, subMonitor); - subMonitor.done(); - } - } finally { - monitor.done(); - } - } - - /** - * Fires a team resource change event to all registered listeners Only - * listeners registered at the time this method is called are notified. - * Listener notification makes use of an ISafeRunnable to ensure that - * client exceptions do not effect the notification to other clients. - */ - protected void fireTeamResourceChange(final ISubscriberChangeEvent[] deltas) { - ISubscriberChangeListener[] allListeners; - // Copy the listener list so we're not calling client code while synchronized - synchronized (listeners) { - allListeners = (ISubscriberChangeListener[]) listeners.toArray(new ISubscriberChangeListener[listeners.size()]); - } - // Notify the listeners safely so all will receive notification - for (int i = 0; i < allListeners.length; i++) { - final ISubscriberChangeListener listener = allListeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // don't log the exception....it is already being logged in - // Platform#run - } - public void run() throws Exception { - listener.subscriberResourceChanged(deltas); - } - }); - } - } - - /* - * Collect the calculated synchronization information for the given resource at the given depth. The - * results are added to the provided list. - */ - private void collect( - IResource resource, - int depth, - SyncInfoSet set, - IProgressMonitor monitor) { - - Policy.checkCanceled(monitor); - - if (resource.getType() != IResource.FILE - && depth != IResource.DEPTH_ZERO) { - try { - IResource[] members = members(resource); - for (int i = 0; i < members.length; i++) { - collect( - members[i], - depth == IResource.DEPTH_INFINITE - ? IResource.DEPTH_INFINITE - : IResource.DEPTH_ZERO, - set, - monitor); - } - } catch (TeamException e) { - set.addError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, ITeamStatus.SYNC_INFO_SET_ERROR, Policy.bind("SubscriberEventHandler.8", resource.getFullPath().toString(), e.getMessage()), e, resource)); //$NON-NLS-1$ - } - } - - monitor.subTask(Policy.bind("SubscriberEventHandler.2", resource.getFullPath().toString())); //$NON-NLS-1$ - try { - SyncInfo info = getSyncInfo(resource); - if (info == null || info.getKind() == SyncInfo.IN_SYNC) { - // Resource is no longer under the subscriber control. - // This can occur for the resources past as arguments to collectOutOfSync - set.remove(resource); - } else { - set.add(info); - } - } catch (TeamException e) { - set.addError(new TeamStatus( - IStatus.ERROR, TeamPlugin.ID, ITeamStatus.RESOURCE_SYNC_INFO_ERROR, - Policy.bind("SubscriberEventHandler.9", resource.getFullPath().toString(), e.getMessage()), //$NON-NLS-1$ - e, resource)); - } - // Tick the monitor to give the owner a chance to do something - monitor.worked(1); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeEvent.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeEvent.java deleted file mode 100644 index 2152f7192..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeEvent.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import org.eclipse.core.resources.IResource; - -/** - * A concrete implementation of <code>ISubscriberChangeEvent</code> that can - * be used by clients. - * - * @see ISubscriberChangeEvent - * @see Subscriber - * - * @since 3.0 - */ -public class SubscriberChangeEvent implements ISubscriberChangeEvent { - - private Subscriber subscriber; - private int flags; - private IResource resource; - - /** - * Create a cahnge event with the given flags for the given subscriber and resource. - * @param subscriber the subscriber to which the state change applies - * @param flags the flags that describe the change - * @param resource the resource whose state has change - */ - public SubscriberChangeEvent(Subscriber subscriber, int flags, IResource resource) { - this.subscriber = subscriber; - this.flags = flags; - this.resource = resource; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.ISubscriberChangeEvent#getFlags() - */ - public int getFlags() { - return flags; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.ISubscriberChangeEvent#getResource() - */ - public IResource getResource() { - return resource; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.ISubscriberChangeEvent#getSubscriber() - */ - public Subscriber getSubscriber() { - return subscriber; - } - - /** - * Returns an array of deltas for the resources with <code>ISubscriberChangeEvent.SYNC_CHANGED</code> - * as the flag. - * @param resources the resources whose sync info has changed - * @return an array of change events - */ - public static SubscriberChangeEvent[] asSyncChangedDeltas(Subscriber subscriber, IResource[] resources) { - SubscriberChangeEvent[] deltas = new SubscriberChangeEvent[resources.length]; - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - deltas[i] = new SubscriberChangeEvent(subscriber, ISubscriberChangeEvent.SYNC_CHANGED, resource); - } - return deltas; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetCollector.java deleted file mode 100644 index 8d065bb8c..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetCollector.java +++ /dev/null @@ -1,566 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import java.util.*; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.core.runtime.preferences.*; -import org.eclipse.team.core.ITeamStatus; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.synchronize.*; -import org.eclipse.team.internal.core.*; -import org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector; -import org.osgi.service.prefs.BackingStoreException; -import org.osgi.service.prefs.Preferences; - -/** - * This class manages the active change sets associated with a subscriber. - */ -public class SubscriberChangeSetCollector extends ChangeSetCollector implements ISyncInfoSetChangeListener { - - private static final String PREF_CHANGE_SETS = "changeSets"; //$NON-NLS-1$ - private static final String CTX_DEFAULT_SET = "defaultSet"; //$NON-NLS-1$ - - private static final int RESOURCE_REMOVAL = 1; - private static final int RESOURCE_CHANGE = 2; - - private ActiveChangeSet defaultSet; - private EventHandler handler; - private ResourceCollector collector; - - /* - * Background event handler for serializing and batching change set changes - */ - private class EventHandler extends BackgroundEventHandler { - - private List dispatchEvents = new ArrayList(); - - protected EventHandler(String jobName, String errorTitle) { - super(jobName, errorTitle); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.BackgroundEventHandler#processEvent(org.eclipse.team.internal.core.BackgroundEventHandler.Event, org.eclipse.core.runtime.IProgressMonitor) - */ - protected void processEvent(Event event, IProgressMonitor monitor) throws CoreException { - // Handle everything in the dispatch - dispatchEvents.add(event); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.BackgroundEventHandler#doDispatchEvents(org.eclipse.core.runtime.IProgressMonitor) - */ - protected boolean doDispatchEvents(IProgressMonitor monitor) throws TeamException { - if (dispatchEvents.isEmpty()) { - return false; - } - SyncInfoTree[] locked = null; - try { - locked = beginDispath(); - for (Iterator iter = dispatchEvents.iterator(); iter.hasNext();) { - Event event = (Event) iter.next(); - switch (event.getType()) { - case RESOURCE_REMOVAL: - handleRemove(event.getResource()); - break; - case RESOURCE_CHANGE: - handleChange(event.getResource(), ((ResourceEvent)event).getDepth()); - break; - default: - break; - } - } - } finally { - try { - endDispatch(locked, monitor); - } finally { - dispatchEvents.clear(); - } - } - return true; - } - - /* - * Begin input on all the sets and return the sync sets that were - * locked. If this method throws an exception then the client - * can assume that no sets were locked - */ - private SyncInfoTree[] beginDispath() { - ChangeSet[] sets = getSets(); - List lockedSets = new ArrayList(); - try { - for (int i = 0; i < sets.length; i++) { - ChangeSet set = sets[i]; - SyncInfoTree syncInfoSet = set.getSyncInfoSet(); - lockedSets.add(syncInfoSet); - syncInfoSet.beginInput(); - } - return (SyncInfoTree[]) lockedSets.toArray(new SyncInfoTree[lockedSets.size()]); - } catch (RuntimeException e) { - try { - for (Iterator iter = lockedSets.iterator(); iter.hasNext();) { - SyncInfoTree tree = (SyncInfoTree) iter.next(); - try { - tree.endInput(null); - } catch (Throwable e1) { - // Ignore so that original exception is not masked - } - } - } catch (Throwable e1) { - // Ignore so that original exception is not masked - } - throw e; - } - } - - private void endDispatch(SyncInfoTree[] locked, IProgressMonitor monitor) { - if (locked == null) { - // The begin failed so there's nothing to unlock - return; - } - monitor.beginTask(null, 100 * locked.length); - for (int i = 0; i < locked.length; i++) { - SyncInfoTree tree = locked[i]; - try { - tree.endInput(Policy.subMonitorFor(monitor, 100)); - } catch (RuntimeException e) { - // Don't worry about ending every set if an error occurs. - // Instead, log the error and suggest a restart. - TeamPlugin.log(IStatus.ERROR, Policy.bind("SubscriberChangeSetCollector.0"), e); //$NON-NLS-1$ - throw e; - } - } - monitor.done(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.BackgroundEventHandler#queueEvent(org.eclipse.team.internal.core.BackgroundEventHandler.Event, boolean) - */ - protected synchronized void queueEvent(Event event, boolean front) { - // Override to allow access from enclosing class - super.queueEvent(event, front); - } - - /* - * Handle the removal - */ - private void handleRemove(IResource resource) { - ChangeSet[] sets = getSets(); - for (int i = 0; i < sets.length; i++) { - ChangeSet set = sets[i]; - // This will remove any descendants from the set and callback to - // resourcesChanged which will batch changes - if (!set.isEmpty()) { - set.rootRemoved(resource, IResource.DEPTH_INFINITE); - if (set.isEmpty()) { - remove(set); - } - } - } - } - - /* - * Handle the change - */ - private void handleChange(IResource resource, int depth) throws TeamException { - SyncInfo syncInfo = getSyncInfo(resource); - if (isModified(syncInfo)) { - ActiveChangeSet[] containingSets = getContainingSets(resource); - if (containingSets.length == 0) { - // Consider for inclusion in the default set - // if the resource is not already a memebr of another set - if (defaultSet != null) { - defaultSet.add(syncInfo); - } - } else { - for (int i = 0; i < containingSets.length; i++) { - ActiveChangeSet set = containingSets[i]; - // Update the sync info in the set - set.getSyncInfoSet().add(syncInfo); - } - } - } else { - removeFromAllSets(resource); - } - if (depth != IResource.DEPTH_ZERO) { - IResource[] members = getSubscriber().members(resource); - for (int i = 0; i < members.length; i++) { - IResource member = members[i]; - handleChange(member, depth == IResource.DEPTH_ONE ? IResource.DEPTH_ZERO : IResource.DEPTH_INFINITE); - } - } - } - - private void removeFromAllSets(IResource resource) { - List toRemove = new ArrayList(); - ChangeSet[] sets = getSets(); - for (int i = 0; i < sets.length; i++) { - ChangeSet set = sets[i]; - if (set.contains(resource)) { - set.remove(resource); - if (set.isEmpty()) { - toRemove.add(set); - } - } - } - for (Iterator iter = toRemove.iterator(); iter.hasNext();) { - ActiveChangeSet set = (ActiveChangeSet) iter.next(); - remove(set); - } - } - - private ActiveChangeSet[] getContainingSets(IResource resource) { - Set result = new HashSet(); - ChangeSet[] sets = getSets(); - for (int i = 0; i < sets.length; i++) { - ChangeSet set = sets[i]; - if (set.contains(resource)) { - result.add(set); - } - } - return (ActiveChangeSet[]) result.toArray(new ActiveChangeSet[result.size()]); - } - } - - private class ResourceCollector extends SubscriberResourceCollector { - - public ResourceCollector(Subscriber subscriber) { - super(subscriber); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#remove(org.eclipse.core.resources.IResource) - */ - protected void remove(IResource resource) { - handler.queueEvent(new BackgroundEventHandler.ResourceEvent(resource, RESOURCE_REMOVAL, IResource.DEPTH_INFINITE), false); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#change(org.eclipse.core.resources.IResource, int) - */ - protected void change(IResource resource, int depth) { - handler.queueEvent(new BackgroundEventHandler.ResourceEvent(resource, RESOURCE_CHANGE, depth), false); - } - - } - - public SubscriberChangeSetCollector(Subscriber subscriber) { - collector = new ResourceCollector(subscriber); - load(); - handler = new EventHandler(Policy.bind("SubscriberChangeSetCollector.1", subscriber.getName()), Policy.bind("SubscriberChangeSetCollector.2", subscriber.getName())); //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Add the active change set to this collector. - * @param set the active change set being added - */ - public void add(ChangeSet set) { - Assert.isTrue(set instanceof ActiveChangeSet); - if (!contains(set)) { - super.add(set); - handleAddedResources(set, set.getSyncInfoSet().getSyncInfos()); - } - } - - /** - * Return whether the manager allows a resource to - * be in mulitple sets. By default, a resource - * may only be in one set. - * @return whether the manager allows a resource to - * be in mulitple sets. - */ - protected boolean isSingleSetPerResource() { - return true; - } - - /** - * Create a commit set with the given title and files. The created - * set is not added to the control of the commit set manager - * so no events are fired. The set can be added using the - * <code>add</code> method. - * @param title the title of the commit set - * @param files the files contained in the set - * @return the created set - * @throws CVSException - */ - public ActiveChangeSet createSet(String title, SyncInfo[] infos) { - ActiveChangeSet commitSet = new ActiveChangeSet(this, title); - if (infos != null && infos.length > 0) { - commitSet.add(infos); - } - return commitSet; - } - - /** - * Create a change set containing the given files if - * they have been modified locally. - * @param title the title of the commit set - * @param files the files contained in the set - * @return the created set - * @throws TeamException - */ - public ActiveChangeSet createSet(String title, IFile[] files) throws TeamException { - List infos = new ArrayList(); - for (int i = 0; i < files.length; i++) { - IFile file = files[i]; - SyncInfo info = getSyncInfo(file); - if (info != null) { - infos.add(info); - } - } - return createSet(title, (SyncInfo[]) infos.toArray(new SyncInfo[infos.size()])); - } - - /** - * Make the given set the default set into which all new modifications - * that ae not already in another set go. - * @param set the set which is to become the default set - */ - public void makeDefault(ActiveChangeSet set) { - // The default set must be an active set - if (!contains(set)) { - add(set); - } - ActiveChangeSet oldSet = defaultSet; - defaultSet = set; - fireDefaultChangedEvent(oldSet, defaultSet); - } - - /** - * Retrn the set which is currently the default or - * <code>null</code> if there is no default set. - * @return - */ - public ActiveChangeSet getDefaultSet() { - return defaultSet; - } - /** - * Return whether the given set is the default set into which all - * new modifications will be placed. - * @param set the set to test - * @return whether the set is the default set - */ - public boolean isDefault(ActiveChangeSet set) { - return set == defaultSet; - } - - /** - * Return the sync info for the given resource obtained - * from the subscriber. - * @param resource the resource - * @return the sync info for the resource - * @throws TeamException - */ - protected SyncInfo getSyncInfo(IResource resource) throws TeamException { - Subscriber subscriber = getSubscriber(); - SyncInfo info = subscriber.getSyncInfo(resource); - return info; - } - - /** - * Return the subscriber associated with this collector. - * @return the subscriber associated with this collector - */ - public Subscriber getSubscriber() { - return collector.getSubscriber(); - } - - protected boolean isModified(SyncInfo info) { - if (info != null) { - if (info.getComparator().isThreeWay()) { - int dir = (info.getKind() & SyncInfo.DIRECTION_MASK); - return dir == SyncInfo.OUTGOING || dir == SyncInfo.CONFLICTING; - } else { - return (info.getKind() & SyncInfo.CHANGE_MASK) == SyncInfo.CHANGE; - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#dispose() - */ - public void dispose() { - handler.shutdown(); - collector.dispose(); - super.dispose(); - save(); - } - - private void save() { - Preferences prefs = getPreferences(); - ChangeSet[] sets = getSets(); - for (int i = 0; i < sets.length; i++) { - ChangeSet set = sets[i]; - if (set instanceof ActiveChangeSet && !set.isEmpty()) { - Preferences child = prefs.node(((ActiveChangeSet)set).getTitle()); - ((ActiveChangeSet)set).save(child); - } - } - if (defaultSet != null) { - prefs.put(CTX_DEFAULT_SET, defaultSet.getTitle()); - } - try { - prefs.flush(); - } catch (BackingStoreException e) { - TeamPlugin.log(IStatus.ERROR, Policy.bind("SubscriberChangeSetCollector.3", getSubscriber().getName()), e); //$NON-NLS-1$ - } - } - - private void load() { - Preferences prefs = getPreferences(); - String defaultSetTitle = prefs.get(CTX_DEFAULT_SET, null); - try { - String[] childNames = prefs.childrenNames(); - for (int i = 0; i < childNames.length; i++) { - String string = childNames[i]; - Preferences childPrefs = prefs.node(string); - ActiveChangeSet set = createSet(string, childPrefs); - if (!set.isEmpty()) { - if (defaultSet == null && defaultSetTitle != null && set.getTitle().equals(defaultSetTitle)) { - defaultSet = set; - } - add(set); - } - } - } catch (BackingStoreException e) { - TeamPlugin.log(IStatus.ERROR, Policy.bind("SubscriberChangeSetCollector.4", getSubscriber().getName()), e); //$NON-NLS-1$ - } - } - - /** - * Create a change set from the given preferences that were - * previously saved. - * @param childPrefs the previously saved preferences - * @return the created change set - */ - protected ActiveChangeSet createSet(String title, Preferences childPrefs) { - ActiveChangeSet changeSet = new ActiveChangeSet(this, title); - changeSet.init(childPrefs); - return changeSet; - } - - private Preferences getPreferences() { - return getParentPreferences().node(getSubscriberIdentifier()); - } - - private static Preferences getParentPreferences() { - return getTeamPreferences().node(PREF_CHANGE_SETS); - } - - private static Preferences getTeamPreferences() { - IPreferencesService service = Platform.getPreferencesService(); - IEclipsePreferences root = service.getRootNode(); - return root.node(InstanceScope.SCOPE).node(TeamPlugin.getPlugin().getBundle().getSymbolicName()); - } - - /** - * Return the id that will uniquely identify the subscriber accross - * restarts. - * @return - */ - protected String getSubscriberIdentifier() { - return getSubscriber().getName(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { - handleSyncSetChange(set, set.getSyncInfos(), set.getResources()); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoChanged(org.eclipse.team.core.synchronize.ISyncInfoSetChangeEvent, org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { - SyncInfoSet set = event.getSet(); - handleSyncSetChange(set, event.getAddedResources(), getAllResources(event)); - } - - private IResource[] getAllResources(ISyncInfoSetChangeEvent event) { - Set allResources = new HashSet(); - SyncInfo[] addedResources = event.getAddedResources(); - for (int i = 0; i < addedResources.length; i++) { - SyncInfo info = addedResources[i]; - allResources.add(info.getLocal()); - } - SyncInfo[] changedResources = event.getChangedResources(); - for (int i = 0; i < changedResources.length; i++) { - SyncInfo info = changedResources[i]; - allResources.add(info.getLocal()); - } - allResources.addAll(Arrays.asList(event.getRemovedResources())); - return (IResource[]) allResources.toArray(new IResource[allResources.size()]); - } - - private void handleAddedResources(ChangeSet set, SyncInfo[] infos) { - if (isSingleSetPerResource()) { - IResource[] resources = new IResource[infos.length]; - for (int i = 0; i < infos.length; i++) { - resources[i] = infos[i].getLocal(); - } - // Remove the added files from any other set that contains them - ChangeSet[] sets = getSets(); - for (int i = 0; i < sets.length; i++) { - ChangeSet otherSet = sets[i]; - if (otherSet != set) { - otherSet.remove(resources); - } - } - } - } - - private void handleSyncSetChange(SyncInfoSet set, SyncInfo[] addedInfos, IResource[] allAffectedResources) { - ChangeSet changeSet = getChangeSet(set); - if (set.isEmpty() && changeSet != null) { - remove(changeSet); - } - fireResourcesChangedEvent(changeSet, allAffectedResources); - handleAddedResources(changeSet, addedInfos); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetErrors(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { - // Nothing to do - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.ChangeSetCollector#getChangeSetSyncSetChangeListener() - */ - protected ISyncInfoSetChangeListener getChangeSetChangeListener() { - return this; - } - - /** - * Wait until the collector is done processing any events. - * This method is for testing purposes only. - */ - public void waitUntilDone(IProgressMonitor monitor) { - monitor.worked(1); - // wait for the event handler to process changes. - while(handler.getEventHandlerJob().getState() != Job.NONE) { - monitor.worked(1); - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - Policy.checkCanceled(monitor); - } - monitor.worked(1); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/package.html b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/package.html deleted file mode 100644 index 9066327bb..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/package.html +++ /dev/null @@ -1,50 +0,0 @@ -<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta content="text/html; charset=iso-8859-1" - http-equiv="Content-Type"> - <meta content="IBM" name="Author"> - <title>Package-level Javadoc</title> -</head> -<body> -Application programming interfaces for generating and refreshing -synchronization state. -<h2>Package Specification</h2> -<p>This package specifies the API for Team subscribers. A Subscriber -provides access to the synchronization state between the local -workspace resources and a set of variants of those resources, whether -it be a code repository or some other type of server (e.g. FTP). A -subscriber is typically associated with only a subset of the resources -in the local workspace, referred to as the set of resources the -subscriber supervises. The supervised local resources have a -corresponding variant state which describes the state of the remote -resources that correspond to the local resources.</p> -<p>A Subscriber provides:</p> -<ul> - <li>a set of root resources that define the subset of resources in -the workspace that the subscriber supervises (some children of the -roots may not be supervised, as indicated by the isSupervised method).</li> - <li>access to the synchronization state (using SyncInfo) between the -resources it supervises and their corresponding variant resources.</li> - <li> the ability to refresh the the remote state</li> - <li>change notification to registered listeners (of type -ISubscriberChangeListener) when the variant state changes or when roots -are added or removed.</li> -</ul> -<h3>Implementing a Subscriber </h3> -<p>An implementation of a subscriber must provide: -</p> -<ul> - <li>a subclass of Subcriber which maintains the synchronization state -between its local resources and their corresponding variants.</li> - <li>an implemenation of org.eclipse.team.core.variants.IResourceVariant which provides access to the -contents and other state of a variant resource that corresponds to a -local resource</li> - <li>an implementation of org.eclipse.team.core.variants.IResourceVariantComparator which is used by -org.eclipse.team.core.synchronize.SyncInfo to determine the synchronization state of a resource.</li> -</ul> -Optionally, a subscriber may provide a subclass of org.eclipse.team.core.synchronize.SyncInfo in order to -customize the algorithm used to -determine the synchronization state of a resource. -</body> -</html> diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/FastSyncInfoFilter.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/FastSyncInfoFilter.java deleted file mode 100644 index 51663c96a..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/FastSyncInfoFilter.java +++ /dev/null @@ -1,225 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * A specialized <code>SyncInfoFilter</code> that does not require a progress monitor. - * This enables these filters to be used when determining menu enablement or other - * operations that must be short running. - * - * @see SyncInfo - * @see SyncInfoSet - * @see SyncInfoFilter - * @since 3.0 - */ -public class FastSyncInfoFilter extends SyncInfoFilter { - - /** - * Selects <code>SyncInfo</code> that match the given change type and direction. - * - * @param direction the change direction (<code>SyncInfo.OUTGOING</code>, - * <code>SyncInfo.INCOMING</code> and <code>SyncInfo.CONFLICTING</code>) that this filter matches - * @param change the change type (<code>SyncInfo.ADDITION</code>, - * <code>SyncInfo.DELETION</code> and <code>SyncInfo.CHANGE</code>) that this filter matches - * @return a <code>FastSyncInfoFilter</code> that selects <code>SyncInfo</code> that match the given - * change type and direction. - */ - public static FastSyncInfoFilter getDirectionAndChangeFilter(int direction, int change) { - return new AndSyncInfoFilter(new FastSyncInfoFilter[]{new SyncInfoDirectionFilter(direction), new SyncInfoChangeTypeFilter(change)}); - } - - /** - * An abstract class which contains a set of <code>FastSyncInfoFilter</code> instances. - * Subclasses must provide the <code>select(SyncInfo)</code> method for determining - * matches. - */ - public static abstract class CompoundSyncInfoFilter extends FastSyncInfoFilter { - /** - * Instance variable which contains all the child filters for ths compound filter. - */ - protected FastSyncInfoFilter[] filters; - /** - * Create a compund filter that contains the provided filters. - * @param filters the child filters - */ - protected CompoundSyncInfoFilter(FastSyncInfoFilter[] filters) { - this.filters = filters; - } - } - - /** - * Selects <code>SyncInfo</code> which match all child filters. - */ - public static class AndSyncInfoFilter extends CompoundSyncInfoFilter { - /** - * Create an AND filter from the given filters - * @param filters the filters to be ANDed - */ - public AndSyncInfoFilter(FastSyncInfoFilter[] filters) { - super(filters); - } - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.FastSyncInfoFilter#select(org.eclipse.team.core.synchronize.SyncInfo) - */ - public boolean select(SyncInfo info) { - for (int i = 0; i < filters.length; i++) { - FastSyncInfoFilter filter = filters[i]; - if (!filter.select(info)) { - return false; - } - } - return true; - } - } - - /** - * Selects <code>SyncInfo</code> instances that are auto-mergable. - */ - public static class AutomergableFilter extends FastSyncInfoFilter { - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.FastSyncInfoFilter#select(org.eclipse.team.core.synchronize.SyncInfo) - */ - public boolean select(SyncInfo info) { - return (info.getKind() & SyncInfo.AUTOMERGE_CONFLICT) != 0; - } - } - - /** - * Selects <code>SyncInfo</code> instances that are pseudo-conflicts. - */ - public static class PseudoConflictFilter extends FastSyncInfoFilter { - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.FastSyncInfoFilter#select(org.eclipse.team.core.synchronize.SyncInfo) - */ - public boolean select(SyncInfo info) { - return info.getKind() != 0 && (info.getKind() & SyncInfo.PSEUDO_CONFLICT) == 0; - } - } - - /** - * Selects <code>SyncInfo</code> that match any of the child filters. - */ - public static class OrSyncInfoFilter extends CompoundSyncInfoFilter { - /** - * Create an OR filter from the given filters - * @param filters the filters to be ORed - */ - public OrSyncInfoFilter(FastSyncInfoFilter[] filters) { - super(filters); - } - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.FastSyncInfoFilter#select(org.eclipse.team.core.synchronize.SyncInfo) - */ - public boolean select(SyncInfo info) { - for (int i = 0; i < filters.length; i++) { - FastSyncInfoFilter filter = filters[i]; - if (filter.select(info)) { - return true; - } - } - return false; - } - } - - /** - * Selects <code>SyncInfo</code> whose change type match those of the filter. - */ - public static class SyncInfoChangeTypeFilter extends FastSyncInfoFilter { - private int[] changeFilters = new int[]{SyncInfo.ADDITION, SyncInfo.DELETION, SyncInfo.CHANGE}; - /** - * Create a filter that will match <code>SyncInfo</code> whose change type - * match those passed as arguments to this constructor. - * @param changeFilters the array of change types (<code>SyncInfo.ADDITION</code>, - * <code>SyncInfo.DELETION</code> and <code>SyncInfo.CHANGE</code>) that this filter match - */ - public SyncInfoChangeTypeFilter(int[] changeFilters) { - this.changeFilters = changeFilters; - } - /** - * Create a filter that will match <code>SyncInfo</code> whose change type - * match that passed as an argument to this constructor. - * @param change the change type (<code>SyncInfo.ADDITION</code>, - * <code>SyncInfo.DELETION</code> and <code>SyncInfo.CHANGE</code>) that this filter matches - */ - public SyncInfoChangeTypeFilter(int change) { - this(new int[]{change}); - } - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.FastSyncInfoFilter#select(org.eclipse.team.core.synchronize.SyncInfo) - */ - public boolean select(SyncInfo info) { - int syncKind = info.getKind(); - for (int i = 0; i < changeFilters.length; i++) { - int filter = changeFilters[i]; - if ((syncKind & SyncInfo.CHANGE_MASK) == filter) - return true; - } - return false; - } - } - - /** - * Selects <code>SyncInfo</code> whose change direction match those of the filter. - */ - public static class SyncInfoDirectionFilter extends FastSyncInfoFilter { - int[] directionFilters = new int[] {SyncInfo.OUTGOING, SyncInfo.INCOMING, SyncInfo.CONFLICTING}; - /** - * Create a filter that will match <code>SyncInfo</code> whose change direction - * match those passed as arguments to this constructor. - * @param directionFilters the array of change directions (<code>SyncInfo.OUTGOING</code>, - * <code>SyncInfo.INCOMING</code> and <code>SyncInfo.CONFLICTING</code>) that this filter match - */ - public SyncInfoDirectionFilter(int[] directionFilters) { - this.directionFilters = directionFilters; - } - /** - * Create a filter that will match <code>SyncInfo</code> whose change direction - * match that passed as arguments to this constructor. - * @param direction the change direction (<code>SyncInfo.OUTGOING</code>, - * <code>SyncInfo.INCOMING</code> and <code>SyncInfo.CONFLICTING</code>) that this filter matches - */ - public SyncInfoDirectionFilter(int direction) { - this(new int[] { direction }); - } - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.FastSyncInfoFilter#select(org.eclipse.team.core.synchronize.SyncInfo) - */ - public boolean select(SyncInfo info) { - int syncKind = info.getKind(); - for (int i = 0; i < directionFilters.length; i++) { - int filter = directionFilters[i]; - if ((syncKind & SyncInfo.DIRECTION_MASK) == filter) - return true; - } - return false; - } - } - - /** - * Return whether the provided <code>SyncInfo</code> matches the filter. The default - * behavior it to include resources whose syncKind is non-zero. - * - * @param info the <code>SyncInfo</code> being tested - * @return <code>true</code> if the <code>SyncInfo</code> matches the filter - */ - public boolean select(SyncInfo info) { - return info.getKind() != 0; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.SyncInfoFilter#select(org.eclipse.team.core.subscribers.SyncInfo, org.eclipse.core.runtime.IProgressMonitor) - */ - public final boolean select(SyncInfo info, IProgressMonitor monitor) { - return select(info); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoSetChangeEvent.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoSetChangeEvent.java deleted file mode 100644 index 7e8ac987f..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoSetChangeEvent.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import org.eclipse.core.resources.IResource; - -/** - * An event generated when a {@link SyncInfoSet} collection is changed. The event contains - * a description of the changes which include added, changed and removed resources. - * In some cases, (e.g. when the change is too complicated to be efficiently described - * using the mechanisms provided by this interface) the event will be a reset. In these - * cases, the client should ignore any other contents of the event and reclaculate - * from scratch any state that is derived from the <code>SyncInfoSet</code> from - * which the event originated. - * <p> - * The mix of return types, <code>SyncInfo</code> and <code>IResource</code>is required as a result of an optimization - * included in {@link SyncInfoSet} collections that doesn't maintain <code>SyncInfo</code> objects - * for in-sync resources. - * </p> - * @see SyncInfoSet#addSyncSetChangedListener(ISyncInfoSetChangeListener) - * @see ISyncInfoSetChangeListener - * @since 3.0 - */ -public interface ISyncInfoSetChangeEvent { - - /** - * Returns newly added out-of-sync <code>SyncInfo</code> elements. - * - * @return newly added <code>SyncInfo</code> elements or an empty list if this event - * doesn't contain added resources. - */ - public SyncInfo[] getAddedResources(); - - /** - * Returns changed <code>SyncInfo</code> elements. The returned elements - * are still out-of-sync. - * - * @return changed <code>SyncInfo</code> elements or an empty list if this event - * doesn't contain changes resources. - */ - public SyncInfo[] getChangedResources(); - - /** - * Returns the removed <code>IResource</code> elements for which the set no longer - * contains on out-of-sync <code>SyncInfo</code>. The returned elements - * are all in-sync resources. - * - * @return removed <code>SyncInfo</code> elements or an empty list if this event - * doesn't contain removed resources. - */ - public IResource[] getRemovedResources(); - - /** - * Returns the {@link SyncInfoSet} that generated these events. - * - * @return the {@link SyncInfoSet} that generated these events. - */ - public SyncInfoSet getSet(); - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoSetChangeListener.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoSetChangeListener.java deleted file mode 100644 index 3da2277a1..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoSetChangeListener.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.ITeamStatus; - -/** - * Classes which implement this interface provide methods that deal with the - * change events that are generated by a {@link SyncInfoSet}. - * <p> - * Implementors of this interface it can - * be added to a sync info set using the <code>addSyncSetChangedListener</code> - * method and removed using the <code>removeSyncSetChangedListener</code> - * method. - * </p><p> - * The originating sync set holds modification locks on the sync info set to ensure - * that no more changes occur until after the current change event is processed. - * The implementors of this interface must not modify the set within the scope of - * the listener's methods. If modiciations are attempted a runtime exception will occur. - * </p> - * @see ISyncInfoSetChangeEvent - * @since 3.0 - */ -public interface ISyncInfoSetChangeListener { - - /** - * Sent when the contents of a {@link SyncInfoSet} have been reset or the - * listener has been connected to the set for the first time using - * <code>SyncInfoSet#connect(ISyncInfoSetChangeListener, IProgressMonitor)</code>. Listeners - * should discard any state they have accumulated from the originating sync info set - * and re-obtain their state from the set. The originating sync set will be - * locked for modification when this method is called. - * <p> - * Clients should not modify the set within this method and other threads that try to - * modify the set will be blocked until the reset is processed. - * </p> - * @param set the originating {@link SyncInfoSet} - */ - public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor); - - /** - * Sent when a {@link SyncInfoSet} changes. For example, when a resource's - * synchronization state changes. The originating sync set will be - * locked for modification when this method is called. - * Clients should not modify the set within this method and other threads that try to - * modify the set will be blocked until the change is processed. - * <p> - * If the originating set is an instance of <code>SyncInfoTree</code> then - * the event will be an instance of <code>ISyncInfoTreeChangeEvent</code>. - * Clients can determine this using an <code>instancof</code> check. - * </p> - * @param event an event containing information about the change. - */ - public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor); - - /** - * This method is called when errors have occurred calculating the <code>SyncInfo</code> - * for a resource. The resource associated with the error is available from the - * <code>ITeamStatus</code>. This event only provides the latest errors that occurred. - * An array of all errors can be retrieved directly from the set. - * - * @param set the originating {@link SyncInfoSet} - * @param errors the errors that occurred during the latest set modifications - * @param monitor a progress monitor - */ - public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor); - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoTreeChangeEvent.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoTreeChangeEvent.java deleted file mode 100644 index 3c24fa48c..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/ISyncInfoTreeChangeEvent.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import org.eclipse.core.resources.IResource; - -/** - * This is a change event that provides access to changes in subtrees - * that contain the out-of-sync resources. It is the event type - * provided by {@link SyncInfoTree} when it notifies listeners - * of changes. - * @since 3.0 - */ -public interface ISyncInfoTreeChangeEvent extends ISyncInfoSetChangeEvent { - - /** - * Returns the highest parent resources of all newly added elements available in this event - * by calling <code>getAddedResources()</code>. In other words, it returns the set of all - * parent containers that did not previously have descendants in the sync set but are direct - * children of containers that did previously have descescendants in the set. - * <p> - * These roots are provided in order - * to allow listeners to optimize the reconciliation of hierachical views of - * the <code>SyncInfoSet</code> contents. - * - * @return parents of all newly added elements or an empty list if this event - * doesn't contain added resources. - */ - public IResource[] getAddedSubtreeRoots(); - - /** - * Returns the highest parent resources of all newly removed elements available in this event - * by calling <code>getRemovedResources()</code>. In other words, it returns the set of all - * parent containers that previously had descendants in the sync set but are direct - * children of containers that still have descescendants in the set. - * <p> - * These roots are provided in order - * to allow listeners to optimize the reconciliation of hierachical views of - * the <code>SyncInfoSet</code> contents. - * - * @return parents of all newly removed elements. or an empty list if this event - * doesn't contain added resources. - */ - public IResource[] getRemovedSubtreeRoots(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfo.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfo.java deleted file mode 100644 index 7d4dc7b64..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfo.java +++ /dev/null @@ -1,474 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.variants.*; -import org.eclipse.team.internal.core.Assert; -import org.eclipse.team.internal.core.Policy; - -/** - * Describes the synchronization of a <b>local</b> resource - * relative to a <b>remote</b> resource variant. There are two - * types of comparison: two-way and three-way. - * The {@link IResourceVariantComparator} is used to decide which - * comparison type to use. - * </p> - * <p> - * For two-way comparisons, a <code>SyncInfo</code> node has a change - * type. This will be one of IN-SYNC, ADDITION, DELETION or CHANGE determined - * in the following manner. - * <ul> - * <li>A resource is considered an ADDITION if it exists locally and there is no remote. - * <li>A resource is considered an DELETION if it does not exists locally and there is remote. - * <li>A resource is considered a CHANGE if both the local and remote exist but the - * comparator indicates that they differ. The comparator may be comparing contents or - * timestamps or some other resource state. - * <li>A resource is considered IN_SYNC in all other cases. - * </ul> - * </p><p> - * For three-way comparisons, the sync info node has a direction as well as a change - * type. The direction is one of INCOMING, OUTGOING or CONFLICTING. The comparison - * of the local and remote resources with a <b>base</b> resource is used to determine - * the direction of the change. - * <ul> - * <li>Differences between the base and local resources - * are classified as <b>outgoing changes</b>; if there is - * a difference, the local resource is considered the - * <b>outgoing resource</b>. - * <li>Differences between the base and remote resources - * are classified as <b>incoming changes</b>; if there is - * a difference, the remote resource is considered the - * <b>incoming resource</b>. - * <li>If there are both incoming and outgoing changes, the resource - * is considered a <b>conflicting change</b>. - * Again, the comparison of resources is done using the variant comparator provided - * when the sync info was created. - * </p> - * @since 3.0 - */ -public class SyncInfo implements IAdaptable { - - /*==================================================================== - * Constants defining synchronization types: - *====================================================================*/ - - /** - * Sync constant (value 0) indicating element is in sync. - */ - public static final int IN_SYNC = 0; - - /** - * Sync constant (value 1) indicating that one side was added. - */ - public static final int ADDITION = 1; - - /** - * Sync constant (value 2) indicating that one side was deleted. - */ - public static final int DELETION = 2; - - /** - * Sync constant (value 3) indicating that one side was changed. - */ - public static final int CHANGE = 3; - - /** - * Bit mask for extracting the change type. - */ - public static final int CHANGE_MASK = CHANGE; - - /*==================================================================== - * Constants defining synchronization direction: - *====================================================================*/ - - /** - * Sync constant (value 4) indicating a change to the local resource. - */ - public static final int OUTGOING = 4; - - /** - * Sync constant (value 8) indicating a change to the remote resource. - */ - public static final int INCOMING = 8; - - /** - * Sync constant (value 12) indicating a change to both the remote and local resources. - */ - public static final int CONFLICTING = 12; - - /** - * Bit mask for extracting the synchronization direction. - */ - public static final int DIRECTION_MASK = CONFLICTING; - - /*==================================================================== - * Constants defining synchronization conflict types: - *====================================================================*/ - - /** - * Sync constant (value 16) indication that both the local and remote resources have changed - * relative to the base but their contents are the same. - */ - public static final int PSEUDO_CONFLICT = 16; - - /** - * Sync constant (value 32) indicating that both the local and remote resources have changed - * relative to the base but their content changes do not conflict (e.g. source file changes on different - * lines). These conflicts could be merged automatically. - */ - public static final int AUTOMERGE_CONFLICT = 32; - - /** - * Sync constant (value 64) indicating that both the local and remote resources have changed relative - * to the base and their content changes conflict (e.g. local and remote resource have changes on - * same lines). These conflicts can only be correctly resolved by the user. - */ - public static final int MANUAL_CONFLICT = 64; - - /*==================================================================== - * Members: - *====================================================================*/ - private IResource local; - private IResourceVariant base; - private IResourceVariant remote; - private IResourceVariantComparator comparator; - - private int syncKind; - - /** - * Construct a sync info object. - * @param local the local resource. Must be non-null but may not exist. - * @param base the base resource variant or <code>null</code> - * @param remote the remote resource variant or <code>null</code> - * @param comparator the comparator used to determine if resources differ - */ - public SyncInfo(IResource local, IResourceVariant base, IResourceVariant remote, IResourceVariantComparator comparator) { - Assert.isNotNull(local); - Assert.isNotNull(comparator); - this.local = local; - this.base = base; - this.remote = remote; - this.comparator = comparator; - } - - /** - * Returns the state of the local resource. Note that the - * resource may or may not exist. - * - * @return a resource - */ - public IResource getLocal() { - return local; - } - - /** - * Returns the content identifier for the local resource or <code>null</code> if - * it doesn't have one. For example, in CVS this would be the revision number. - * - * @return String that could be displayed to the user to identify this resource. - */ - public String getLocalContentIdentifier() { - return null; - } - - /** - * Returns the remote resource handle for the base resource, - * or <code>null</code> if the base resource does not exist. - * <p> - * [Note: The type of the common resource may be different from the types - * of the local and remote resources. - * ] - * </p> - * @return a remote resource handle, or <code>null</code> - */ - public IResourceVariant getBase() { - return base; - } - - /** - * Returns the handle for the remote resource, - * or <code>null</code> if the remote resource does not exist. - * <p> - * [Note: The type of the remote resource may be different from the types - * of the local and common resources. - * ] - * </p> - * @return a remote resource handle, or <code>null</code> - */ - public IResourceVariant getRemote() { - return remote; - } - - /** - * Returns the comparator that is used to determine the - * kind of this sync node. - * - * @return the comparator that is used to determine the - * kind of this sync node. - */ - public IResourceVariantComparator getComparator() { - return comparator; - } - - /** - * Returns the kind of synchronization for this node. - * - * @return the kind of synchronization for this node. - */ - public int getKind() { - return syncKind; - } - - /** - * Helper method that returns whether the given kind represents - * an in-sync resource. - * - * @param kind the kind of a <code>SyncInfo</code> - * @return whether the kind is <code>IN_SYNC</code>. - */ - static public boolean isInSync(int kind) { - return kind == IN_SYNC; - } - - /** - * Helper method to return the direction portion - * of the given kind. The resulting value - * can be compared directly with the direction constants. - * - * @param kind the kind of a <code>SyncInfo</code> - * @return the direction portion of the kind - */ - static public int getDirection(int kind) { - return kind & DIRECTION_MASK; - } - - /** - * Helper method to return the change portion - * of the given kind. The resulting value - * can be compared directly with the change - * type constants. - * - * @param kind the kind of a <code>SyncInfo</code> - * @return the change portion of the kind - */ - static public int getChange(int kind) { - return kind & CHANGE_MASK; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object other) { - if(other == this) return true; - if(other instanceof SyncInfo) { - return equalNodes(this, (SyncInfo)other); - } - return false; - } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return getLocal().hashCode(); - } - - private boolean equalNodes(SyncInfo node1, SyncInfo node2) { - if(node1 == null || node2 == null) { - return false; - } - - // First, ensure the local resources are equals - IResource local1 = null; - if (node1.getLocal() != null) - local1 = node1.getLocal(); - IResource local2 = null; - if (node2.getLocal() != null) - local2 = node2.getLocal(); - if (!equalObjects(local1, local2)) return false; - - // Next, ensure the base resources are equal - IResourceVariant base1 = null; - if (node1.getBase() != null) - base1 = node1.getBase(); - IResourceVariant base2 = null; - if (node2.getBase() != null) - base2 = node2.getBase(); - if (!equalObjects(base1, base2)) return false; - - // Finally, ensure the remote resources are equal - IResourceVariant remote1 = null; - if (node1.getRemote() != null) - remote1 = node1.getRemote(); - IResourceVariant remote2 = null; - if (node2.getRemote() != null) - remote2 = node2.getRemote(); - if (!equalObjects(remote1, remote2)) return false; - - return true; - } - - private boolean equalObjects(Object o1, Object o2) { - if (o1 == null && o2 == null) return true; - if (o1 == null || o2 == null) return false; - return o1.equals(o2); - } - - /* (non-Javadoc) - * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) - */ - public Object getAdapter(Class adapter) { - if (adapter == IResource.class) { - return getLocal(); - } - return null; - } - - /* (non-Javadoc) - * @see java.lang.Object#toString() - */ - public String toString() { - return getLocal().getName() + " " + kindToString(getKind()); //$NON-NLS-1$ - } - - /** - * A helper method that returns a displayable (i.e. externalized) - * string describing the provided sync kind. - * - * @param kind the sync kind obtained from a <code>SyncInfo</code> - * @return a displayable string that descibes the kind - */ - public static String kindToString(int kind) { - String label = ""; //$NON-NLS-1$ - if(kind==IN_SYNC) { - label = Policy.bind("RemoteSyncElement.insync"); //$NON-NLS-1$ - } else { - switch(kind & DIRECTION_MASK) { - case CONFLICTING: label = Policy.bind("RemoteSyncElement.conflicting"); break; //$NON-NLS-1$ - case OUTGOING: label = Policy.bind("RemoteSyncElement.outgoing"); break; //$NON-NLS-1$ - case INCOMING: label = Policy.bind("RemoteSyncElement.incoming"); break; //$NON-NLS-1$ - } - switch(kind & CHANGE_MASK) { - case CHANGE: label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.change")); break; //$NON-NLS-1$ //$NON-NLS-2$ - case ADDITION: label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.addition")); break; //$NON-NLS-1$ //$NON-NLS-2$ - case DELETION: label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.deletion")); break; //$NON-NLS-1$ //$NON-NLS-2$ - } - if((kind & MANUAL_CONFLICT) != 0) { - label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.manual")); //$NON-NLS-1$ //$NON-NLS-2$ - } - if((kind & AUTOMERGE_CONFLICT) != 0) { - label = Policy.bind("concatStrings", label, Policy.bind("RemoteSyncElement.auto")); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - return Policy.bind("RemoteSyncElement.delimit", label); //$NON-NLS-1$ - } - - /** - * Method that is invoked after instance creation to initialize the sync kind. - * This method should only be invoked by the creator of the <code>SyncInfo</code> - * instance. It is not done from the constructor in order to allow subclasses - * to calculate the sync kind from any additional state variables they may have. - * - * @throws TeamException if there were problems calculating the sync state. - */ - public final void init() throws TeamException { - syncKind = calculateKind(); - } - - /** - * Method that is invoked from the <code>init()</code> method to calculate - * the sync kind for this instance of <code>SyncInfo</code>. The result is - * assigned to an instance variable and is available using <code>getKind()</code>. - * Subclasses should not invoke this method but may override it in order to customize - * the sync kind calculation algorithm. - * - * @return the sync kind of this <code>SyncInfo</code> - * @throws TeamException if there were problems calculating the sync state. - */ - protected int calculateKind() throws TeamException { - int description = IN_SYNC; - - boolean localExists = local.exists(); - - if (comparator.isThreeWay()) { - if (base == null) { - if (remote == null) { - if (!localExists) { - description = IN_SYNC; - } else { - description = OUTGOING | ADDITION; - } - } else { - if (!localExists) { - description = INCOMING | ADDITION; - } else { - description = CONFLICTING | ADDITION; - if (comparator.compare(local, remote)) { - description |= PSEUDO_CONFLICT; - } - } - } - } else { - if (!localExists) { - if (remote == null) { - description = CONFLICTING | DELETION | PSEUDO_CONFLICT; - } else { - if (comparator.compare(base, remote)) - description = OUTGOING | DELETION; - else - description = CONFLICTING | CHANGE; - } - } else { - if (remote == null) { - if (comparator.compare(local, base)) - description = INCOMING | DELETION; - else - description = CONFLICTING | CHANGE; - } else { - boolean ay = comparator.compare(local, base); - boolean am = comparator.compare(base, remote); - if (ay && am) { - // in-sync - } else if (ay && !am) { - description = INCOMING | CHANGE; - } else if (!ay && am) { - description = OUTGOING | CHANGE; - } else { - if(! comparator.compare(local, remote)) { - description = CONFLICTING | CHANGE; - } - } - } - } - } - } else { // two compare without access to base contents - if (remote == null) { - if (!localExists) { - Assert.isTrue(false); - // shouldn't happen - } else { - description= DELETION; - } - } else { - if (!localExists) { - description= ADDITION; - } else { - if (! comparator.compare(local, remote)) - description= CHANGE; - } - } - } - return description; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoFilter.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoFilter.java deleted file mode 100644 index 1d2b15095..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoFilter.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.variants.IResourceVariant; -import org.eclipse.team.internal.core.Assert; -import org.eclipse.team.internal.core.subscribers.ContentComparator; - -/** - * A <code>SyncInfoFilter</code> tests a <code>SyncInfo</code> for inclusion, - * typically in a <code>SyncInfoSet</code>. - * - * @see SyncInfo - * @see SyncInfoSet - * - * @since 3.0 - */ -public abstract class SyncInfoFilter { - - /** - * Selects <code>SyncInfo</code> whose local and remote contents match. - * This filter makes use of the <code>IStorage</code> provided by - * an <code>IResourceVariant</code> to obtain the remote contents. - * This means that the comparison may contact the server unless the contents - * were cached locally by a previous operation. The caching of remote - * contents is subscriber specific. - * <p> - * For folders, the comparison always returns <code>true</code>. - */ - public static class ContentComparisonSyncInfoFilter extends SyncInfoFilter { - ContentComparator criteria = new ContentComparator(false); - /** - * Create a filter that does not ignore whitespace. - */ - public ContentComparisonSyncInfoFilter() { - this(false); - } - /** - * Create a filter and configure how whitspace is handled. - * @param ignoreWhitespace whether whitespace should be ignored - */ - public ContentComparisonSyncInfoFilter(boolean ignoreWhitespace) { - criteria = new ContentComparator(ignoreWhitespace); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.SyncInfoFilter#select(org.eclipse.team.core.synchronize.SyncInfo, org.eclipse.core.runtime.IProgressMonitor) - */ - public boolean select(SyncInfo info, IProgressMonitor monitor) { - IResourceVariant remote = info.getRemote(); - IResource local = info.getLocal(); - if (local.getType() != IResource.FILE) return true; - if (remote == null) return !local.exists(); - if (!local.exists()) return false; - return compareContents((IFile)local, remote, monitor); - } - - /** - * Compare the contents of the local file and its variant. - * This is used by the <code>select</code> method to compare the - * contents of two non-null files. - * @param local a local file - * @param remote a resource variant of the file - * @param monitor a progress monitor - * @return whether the contents of the two files are equal - */ - public boolean compareContents(IFile local, IResourceVariant remote, IProgressMonitor monitor) { - Assert.isNotNull(local); - Assert.isNotNull(remote); - return criteria.compare(local, remote, monitor); - } - } - - /** - * Return <code>true</code> if the provided <code>SyncInfo</code> matches the filter. - * - * @param info the <code>SyncInfo</code> to be tested - * @param monitor a progress monitor - * @return <code>true</code> if the <code>SyncInfo</code> matches the filter - */ - public abstract boolean select(SyncInfo info, IProgressMonitor monitor); - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoSet.java deleted file mode 100644 index 6658ee042..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoSet.java +++ /dev/null @@ -1,650 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import java.util.*; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.ILock; -import org.eclipse.team.core.ITeamStatus; -import org.eclipse.team.core.TeamStatus; -import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; -import org.eclipse.team.internal.core.*; -import org.eclipse.team.internal.core.subscribers.SyncInfoStatistics; -import org.eclipse.team.internal.core.subscribers.SyncSetChangedEvent; - -/** - * A dynamic collection of {@link SyncInfo} objects that provides - * change notification to registered listeners. Batching of change notifications - * can be accomplished using the <code>beginInput/endInput</code> methods. - * - * @see SyncInfoTree - * @see SyncInfo - * @see ISyncInfoSetChangeListener - * @since 3.0 - */ -public class SyncInfoSet { - // fields used to hold resources of interest - // {IPath -> SyncInfo} - private Map resources = Collections.synchronizedMap(new HashMap()); - - // keep track of number of sync kinds in the set - private SyncInfoStatistics statistics = new SyncInfoStatistics(); - - // keep track of errors that occurred while trying to populate the set - private Map errors = new HashMap(); - - private boolean lockedForModification; - - /** - * Create an empty set. - */ - public SyncInfoSet() { - } - - /** - * Create a <code>SyncInfoSet</code> containing the given <code>SyncInfo</code> - * instances. - * - * @param infos the <code>SyncInfo</code> instances to be contained by this set - */ - public SyncInfoSet(SyncInfo[] infos) { - this(); - // use the internal add since we can't have listeners at this point anyway - for (int i = 0; i < infos.length; i++) { - internalAdd(infos[i]); - } - } - - /** - * Return an array of <code>SyncInfo</code> for all out-of-sync resources that are contained by the set. - * - * @return an array of <code>SyncInfo</code> - */ - public synchronized SyncInfo[] getSyncInfos() { - return (SyncInfo[]) resources.values().toArray(new SyncInfo[resources.size()]); - } - - /** - * Return all out-of-sync resources contained in this set. The default implementation - * uses <code>getSyncInfos()</code> to determine the resources contained in the set. - * Subclasses may override to optimize. - * - * @return all out-of-sync resources contained in the set - */ - public IResource[] getResources() { - SyncInfo[] infos = getSyncInfos(); - List resources = new ArrayList(); - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - resources.add(info.getLocal()); - } - return (IResource[]) resources.toArray(new IResource[resources.size()]); - } - - /** - * Return the <code>SyncInfo</code> for the given resource or <code>null</code> - * if the resource is not contained in the set. - * - * @param resource the resource - * @return the <code>SyncInfo</code> for the resource or <code>null</code> if - * the resource is in-sync or doesn't have synchronization information in this set. - */ - public synchronized SyncInfo getSyncInfo(IResource resource) { - return (SyncInfo)resources.get(resource.getFullPath()); - } - - /** - * Return the number of out-of-sync resources contained in this set. - * - * @return the size of the set. - * @see #countFor(int, int) - */ - public synchronized int size() { - return resources.size(); - } - - /** - * Return the number of out-of-sync resources in the given set whose sync kind - * matches the given kind and mask (e.g. <code>(SyncInfo#getKind() & mask) == kind</code>). - * <p> - * For example, this will return the number of outgoing changes in the set: - * <pre> - * long outgoing = countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK); - * </pre> - * </p> - * @param kind the sync kind - * @param mask the sync kind mask - * @return the number of matching resources in the set. - */ - public long countFor(int kind, int mask) { - return statistics.countFor(kind, mask); - } - - /** - * Returns <code>true</code> if there are any conflicting nodes in the set, and - * <code>false</code> otherwise. - * - * @return <code>true</code> if there are any conflicting nodes in the set, and - * <code>false</code> otherwise. - */ - public boolean hasConflicts() { - return countFor(SyncInfo.CONFLICTING, SyncInfo.DIRECTION_MASK) > 0; - } - - /** - * Return whether the set is empty. - * - * @return <code>true</code> if the set is empty - */ - public synchronized boolean isEmpty() { - return resources.isEmpty(); - } - - /** - * Add the <code>SyncInfo</code> to the set, replacing any previously existing one. - * - * @param info the new <code>SyncInfo</code> - */ - protected synchronized void internalAdd(SyncInfo info) { - Assert.isTrue(!lockedForModification); - IResource local = info.getLocal(); - IPath path = local.getFullPath(); - SyncInfo oldSyncInfo = (SyncInfo)resources.put(path, info); - if(oldSyncInfo == null) { - statistics.add(info); - } else { - statistics.remove(oldSyncInfo); - statistics.add(info); - } - } - - /** - * Remove the resource from the set, updating all internal data structures. - * - * @param resource the resource to be removed - * @return the <code>SyncInfo</code> that was just removed - */ - protected synchronized SyncInfo internalRemove(IResource resource) { - Assert.isTrue(!lockedForModification); - IPath path = resource.getFullPath(); - SyncInfo info = (SyncInfo)resources.remove(path); - if (info != null) { - statistics.remove(info); - } - return info; - } - - /** - * Registers the given listener for sync info set notifications. Has - * no effect if an identical listener is already registered. - * - * @param listener listener to register - */ - public void addSyncSetChangedListener(ISyncInfoSetChangeListener listener) { - synchronized(listeners) { - listeners.add(listener); - } - } - - /** - * Deregisters the given listener for participant notifications. Has - * no effect if listener is not already registered. - * - * @param listener listener to deregister - */ - public void removeSyncSetChangedListener(ISyncInfoSetChangeListener listener) { - synchronized(listeners) { - listeners.remove(listener); - } - } - - /** - * Reset the sync set so it is empty. Listeners are notified of the change. - */ - public void clear() { - try { - beginInput(); - errors.clear(); - resources.clear(); - statistics.clear(); - getChangeEvent().reset(); - } finally { - endInput(null); - } - } - - /* - * Run the given runnable. This operation - * will block other threads from modifying the - * set and postpone any change notifications until after the runnable - * has been executed. Mutable subclasses must override. - * <p> - * The given runnable may be run in the same thread as the caller or - * more be run asynchronously in another thread at the discretion of the - * subclass implementation. However, it is gaurenteed that two invocations - * of <code>run</code> performed in the same thread will be executed in the - * same order even if run in different threads. - * </p> - * @param runnable a runnable - * @param progress a progress monitor or <code>null</code> - */ - private void run(IWorkspaceRunnable runnable, IProgressMonitor monitor) { - monitor = Policy.monitorFor(monitor); - monitor.beginTask(null, 100); - try { - beginInput(); - runnable.run(Policy.subMonitorFor(monitor, 80)); - } catch (CoreException e) { - addError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, ITeamStatus.SYNC_INFO_SET_ERROR, e.getMessage(), e, null)); - } finally { - endInput(Policy.subMonitorFor(monitor, 20)); - } - } - - /** - * Connect the listener to the sync set in such a fashion that the listener will - * be connected the the sync set using <code>addChangeListener</code> - * and issued a reset event. This is done to provide a means of connecting to the - * sync set and initializing a model based on the sync set without worrying about - * missing events. - * <p> - * The reset event may be done in the context of this method invocation or may be - * done in another thread at the discretion of the <code>SyncInfoSet</code> - * implementation. - * </p><p> - * Disconnecting is done by calling <code>removeChangeListener</code>. Once disconnected, - * a listener can reconnect to be reinitialized. - * </p> - * @param listener the listener that should be connected to this set - * @param monitor a progress monitor - */ - public void connect(final ISyncInfoSetChangeListener listener, IProgressMonitor monitor) { - run(new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) { - try { - monitor.beginTask(null, 100); - addSyncSetChangedListener(listener); - listener.syncInfoSetReset(SyncInfoSet.this, Policy.subMonitorFor(monitor, 95)); - } finally { - monitor.done(); - } - } - }, monitor); - } - - private ILock lock = Platform.getJobManager().newLock(); - - private Set listeners = Collections.synchronizedSet(new HashSet()); - - private SyncSetChangedEvent changes = createEmptyChangeEvent(); - - /** - * Add the given <code>SyncInfo</code> to the set. A change event will - * be generated unless the call to this method is nested in between calls - * to <code>beginInput()</code> and <code>endInput(IProgressMonitor)</code> - * in which case the event for this addition and any other sync set - * change will be fired in a batched event when <code>endInput</code> - * is invoked. - * <p> - * Invoking this method outside of the above mentioned block will result - * in the <code>endInput(IProgressMonitor)</code> being invoked with a null - * progress monitor. If responsiveness is required, the client should always - * nest sync set modifications within <code>beginInput/endInput</code>. - * </p> - * @param info the sync info to be added to this set. - */ - public void add(SyncInfo info) { - try { - beginInput(); - boolean alreadyExists = getSyncInfo(info.getLocal()) != null; - internalAdd(info); - if (alreadyExists) { - getChangeEvent().changed(info); - } else { - getChangeEvent().added(info); - } - } finally { - endInput(null); - } - } - - /** - * Add all the syncinfo from the given set to this set. - * - * @param set the set whose sync info should be added to this set - */ - public void addAll(SyncInfoSet set) { - try { - beginInput(); - SyncInfo[] infos = set.getSyncInfos(); - for (int i = 0; i < infos.length; i++) { - add(infos[i]); - } - } finally { - endInput(null); - } - } - - /** - * Remove the given local resource from the set. - * - * @param resource the local resource to remove - */ - public synchronized void remove(IResource resource) { - try { - beginInput(); - SyncInfo info = internalRemove(resource); - getChangeEvent().removed(resource, info); - } finally { - endInput(null); - } - } - - /** - * Remove all the given resources from the set. - * - * @param resources the resources to be removed - */ - public void removeAll(IResource[] resources) { - try { - beginInput(); - for (int i = 0; i < resources.length; i++) { - remove(resources[i]); - } - } finally { - endInput(null); - } - } - - /** - * Removes all conflicting nodes from this set. - */ - public void removeConflictingNodes() { - rejectNodes(new SyncInfoDirectionFilter(SyncInfo.CONFLICTING)); - } - - /** - * Removes all outgoing nodes from this set. - */ - public void removeOutgoingNodes() { - rejectNodes(new SyncInfoDirectionFilter(SyncInfo.OUTGOING)); - } - - /** - * Removes all incoming nodes from this set. - */ - public void removeIncomingNodes() { - rejectNodes(new SyncInfoDirectionFilter(SyncInfo.INCOMING)); - } - - /** - * Indicate whether the set has nodes matching the given filter. - * - * @param filter a sync info filter - */ - public boolean hasNodes(FastSyncInfoFilter filter) { - SyncInfo[] infos = getSyncInfos(); - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - if (info != null && filter.select(info)) { - return true; - } - } - return false; - } - - /** - * Removes all nodes from this set that do not match the given filter - * leaving only those that do match the filter. - * - * @param filter a sync info filter - */ - public void selectNodes(FastSyncInfoFilter filter) { - try { - beginInput(); - SyncInfo[] infos = getSyncInfos(); - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - if (info == null || !filter.select(info)) { - remove(info.getLocal()); - } - } - } finally { - endInput(null); - } - } - - /** - * Removes all nodes from this set that match the given filter - * leaving those that do not match the filter. - * - * @param filter a sync info filter - */ - public void rejectNodes(FastSyncInfoFilter filter) { - try { - beginInput(); - SyncInfo[] infos = getSyncInfos(); - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - if (info != null && filter.select(info)) { - remove(info.getLocal()); - } - } - } finally { - endInput(null); - } - } - - /** - * Return all nodes in this set that match the given filter. - * - * @param filter a sync info filter - */ - public SyncInfo[] getNodes(FastSyncInfoFilter filter) { - List result = new ArrayList(); - SyncInfo[] infos = getSyncInfos(); - for (int i = 0; i < infos.length; i++) { - SyncInfo info = infos[i]; - if (info != null && filter.select(info)) { - result.add(info); - } - } - return (SyncInfo[]) result.toArray(new SyncInfo[result.size()]); - } - - /** - * Returns <code>true</code> if this sync set has incoming changes. - * Note that conflicts are not considered to be incoming changes. - * - * @return <code>true</code> if this sync set has incoming changes. - */ - public boolean hasIncomingChanges() { - return countFor(SyncInfo.INCOMING, SyncInfo.DIRECTION_MASK) > 0; - } - - /** - * Returns <code>true</code> if this sync set has outgoing changes. - * Note that conflicts are not considered to be outgoing changes. - * - * @return <code>true</code> if this sync set has outgoing changes. - */ - public boolean hasOutgoingChanges() { - return countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK) > 0; - } - - /** - * This method is used to obtain a lock on the set which ensures thread safety - * and batches change notification. If the set is locked by another thread, - * the calling thread will block until the lock - * becomes available. This method uses an <code>org.eclipse.core.runtime.jobs.ILock</code>. - * <p> - * It is important that the lock is released after it is obtained. Calls to <code>endInput</code> - * should be done in a finally block as illustrated in the following code snippet. - * <pre> - * try { - * set.beginInput(); - * // do stuff - * } finally { - * set.endInput(progress); - * } - * </pre> - * </p><p> - * Calls to <code>beginInput</code> and <code>endInput</code> can be nested and must be matched. - * </p> - */ - public void beginInput() { - lock.acquire(); - } - - /** - * This method is used to release the lock on this set. The prgress monitor is needed to allow - * listeners to perform long-running operations is reponse to the set change. The lock is held - * while the listeners are notified so listeners must be cautious in order to avoid deadlock. - */ - public void endInput(IProgressMonitor monitor) { - try { - if (lock.getDepth() == 1) { - // Remain locked while firing the events so the handlers - // can expect the set to remain constant while they process the events - fireChanges(Policy.monitorFor(monitor)); - } - } finally { - lock.release(); - } - } - - /** - * Reset the changes accumulated so far by this set. This method is not - * intended to be invoked or implemented by clients. - */ - protected void resetChanges() { - changes = createEmptyChangeEvent(); - } - - /** - * Create an empty change event. Subclass may override to provided specialized event types - * - * @return an empty change event - */ - protected SyncSetChangedEvent createEmptyChangeEvent() { - return new SyncSetChangedEvent(this); - } - - private void fireChanges(final IProgressMonitor monitor) { - // Use a synchronized block to ensure that the event we send is static - final SyncSetChangedEvent event; - synchronized(this) { - event = getChangeEvent(); - resetChanges(); - } - // Ensure that the list of listeners is not changed while events are fired. - // Copy the listeners so that addition/removal is not blocked by event listeners - if(event.isEmpty() && ! event.isReset()) return; - ISyncInfoSetChangeListener[] allListeners = getListeners(); - // Fire the events using an ISafeRunnable - final ITeamStatus[] newErrors = event.getErrors(); - monitor.beginTask(null, 100 + (newErrors.length > 0 ? 50 : 0) * allListeners.length); - for (int i = 0; i < allListeners.length; i++) { - final ISyncInfoSetChangeListener listener = allListeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // don't log the exception....it is already being logged in Platform#run - } - public void run() throws Exception { - try { - lockedForModification = true; - if (event.isReset()) { - listener.syncInfoSetReset(SyncInfoSet.this, Policy.subMonitorFor(monitor, 100)); - } else { - listener.syncInfoChanged(event, Policy.subMonitorFor(monitor, 100)); - } - if (newErrors.length > 0) { - listener.syncInfoSetErrors(SyncInfoSet.this, newErrors, Policy.subMonitorFor(monitor, 50)); - } - } finally { - lockedForModification = false; - } - } - }); - } - monitor.done(); - } - - /** - * Return a copy of all the listeners registered with this set - * @return the listeners - */ - protected ISyncInfoSetChangeListener[] getListeners() { - ISyncInfoSetChangeListener[] allListeners; - synchronized(listeners) { - allListeners = (ISyncInfoSetChangeListener[]) listeners.toArray(new ISyncInfoSetChangeListener[listeners.size()]); - } - return allListeners; - } - - /** - * Return the change event that is accumulating the changes to the set. - * This can be called by sublasses to access the event. - * @return Returns the changes. - */ - protected SyncSetChangedEvent getChangeEvent() { - return changes; - } - - /** - * Add the error to the set. Errors should be added to the set when the client - * populating the set cannot determine the <code>SyncInfo</code> for one - * or more resources due to an exception or some other problem. Listeners - * will be notified that an error occurred and can react accordingly. - * <p> - * Only one error can be associated with a resource (which is obtained from - * the <code>ITeamStatus</code>). It is up to the - * client populating the set to ensure that the error associated with a - * resource contains all relevent information. - * The error will remain in the set until the set is reset. - * </p> - * @param resource the resource associated with the error or the workspace root - * @param status the status that describes the error that occurred. - */ - public void addError(ITeamStatus status) { - try { - beginInput(); - errors.put(status.getResource(), status); - getChangeEvent().errorOccurred(status); - } finally { - endInput(null); - } - } - - /** - * Return an array of the errors the occurred while populating this set. - * The errors will remain with the set until it is reset. - * - * @return the errors - */ - public ITeamStatus[] getErrors() { - return (ITeamStatus[]) errors.values().toArray(new ITeamStatus[errors.size()]); - } - - /** - * Return an interator over all <code>SyncInfo</code> - * contained in this set. - * @return an interator over all <code>SyncInfo</code> - * contained in this set. - * @since 3.1 - */ - public Iterator iterator() { - return resources.values().iterator(); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoTree.java deleted file mode 100644 index 94005804c..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/SyncInfoTree.java +++ /dev/null @@ -1,353 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.synchronize; - -import java.util.*; - -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; -import org.eclipse.team.internal.core.TeamPlugin; -import org.eclipse.team.internal.core.subscribers.SyncInfoTreeChangeEvent; -import org.eclipse.team.internal.core.subscribers.SyncSetChangedEvent; -import org.eclipse.team.internal.core.Policy; - -/** - * Provides addition API for accessing the <code>SyncInfo</code> in the set through - * their resource's hierarchical relationships. - * <p> - * Events fired from a <code>SyncInfoTree</code> will be instances of <code>ISyncInfoTreeChangeEvent</code>. - * </p> - * @see SyncInfoSet - * @since 3.0 - */ -public class SyncInfoTree extends SyncInfoSet { - - protected Map parents = Collections.synchronizedMap(new HashMap()); - - /** - * Create an empty sync info tree. - */ - public SyncInfoTree() { - super(); - } - - /** - * Create a sync info tree containing the given sync info elements. - * - * @param infos the sync info elements - */ - public SyncInfoTree(SyncInfo[] infos) { - super(infos); - } - - /** - * Return wether the given resource has any children in the sync set. The children - * could be either out-of-sync resources that are contained by the set or containers - * that are ancestors of out-of-sync resources contained by the set. - * - * @param resource the resource to check for children. - * @return <code>true</code> if the resource has children in the set. - */ - public synchronized boolean hasMembers(IResource resource) { - if (resource.getType() == IResource.FILE) return false; - IContainer parent = (IContainer)resource; - if (parent.getType() == IResource.ROOT) return !isEmpty(); - IPath path = parent.getFullPath(); - Set allDescendants = (Set)parents.get(path); - return (allDescendants != null && !allDescendants.isEmpty()); - } - - /** - * Return the <code>SyncInfo</code> for each out-of-sync resource in the subtree rooted at the given resource - * to the depth specified. The depth is one of: - * <ul> - * <li><code>IResource.DEPTH_ZERO</code>: the resource only, - * <li><code>IResource.DEPTH_ONE</code>: the resource or its direct children, - * <li><code>IResource.DEPTH_INFINITE</code>: the resource and all of it's descendants. - * <ul> - * If the given resource is out of sync, it will be included in the result. - * <p> - * The default implementation makes use of <code>getSyncInfo(IResource)</code>, - * <code>members(IResource)</code> and <code>getSyncInfos()</code> - * to provide the varying depths. Subclasses may override to optimize. - * </p> - * @param resource the root of the resource subtree - * @param depth the depth of the subtree - * @return the <code>SyncInfo</code> for any out-of-sync resources - */ - public synchronized SyncInfo[] getSyncInfos(IResource resource, int depth) { - if (depth == IResource.DEPTH_ZERO || resource.getType() == IResource.FILE) { - SyncInfo info = getSyncInfo(resource); - if (info == null) { - return new SyncInfo[0]; - } else { - return new SyncInfo[] { info }; - } - } - if (depth == IResource.DEPTH_ONE) { - List result = new ArrayList(); - SyncInfo info = getSyncInfo(resource); - if (info != null) { - result.add(info); - } - IResource[] members = members(resource); - for (int i = 0; i < members.length; i++) { - IResource member = members[i]; - info = getSyncInfo(member); - if (info != null) { - result.add(info); - } - } - return (SyncInfo[]) result.toArray(new SyncInfo[result.size()]); - } - // if it's the root then return all out of sync resources. - if(resource.getType() == IResource.ROOT) { - return getSyncInfos(); - } - // for folders return all children deep. - return internalGetDeepSyncInfo((IContainer)resource); - } - - /* - * Return the <code>SyncInfo</code> for all out-of-sync resources in the - * set that are at or below the given resource in the resource hierarchy. - * @param resource the root resource - * @return the <code>SyncInfo</code> for all out-of-sync resources at or below the given resource - */ - private synchronized SyncInfo[] internalGetDeepSyncInfo(IContainer resource) { - List infos = new ArrayList(); - IResource[] children = internalGetOutOfSyncDescendants(resource); - for (int i = 0; i < children.length; i++) { - IResource child = children[i]; - SyncInfo info = getSyncInfo(child); - if(info != null) { - infos.add(info); - } else { - TeamPlugin.log(IStatus.INFO, Policy.bind("SyncInfoTree.0") + child.getFullPath(), null); //$NON-NLS-1$ - } - } - return (SyncInfo[]) infos.toArray(new SyncInfo[infos.size()]); - } - - /** - * Overrides inherited method to provide an instance of - * <code>ISyncInfoTreeChangeEvent</code>. - */ - protected SyncSetChangedEvent createEmptyChangeEvent() { - return new SyncInfoTreeChangeEvent(this); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.SyncInfoSet#add(org.eclipse.team.core.synchronize.SyncInfo) - */ - public void add(SyncInfo info) { - try { - beginInput(); - boolean alreadyExists = getSyncInfo(info.getLocal()) != null; - super.add(info); - if(! alreadyExists) { - IResource local = info.getLocal(); - addToParents(local, local); - } - } finally { - endInput(null); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.SyncInfoSet#remove(org.eclipse.core.resources.IResource) - */ - public void remove(IResource resource) { - try { - beginInput(); - super.remove(resource); - removeFromParents(resource, resource); - } finally { - endInput(null); - } - - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.SyncInfoSet#clear() - */ - public void clear() { - try { - beginInput(); - super.clear(); - synchronized(this) { - parents.clear(); - } - } finally { - endInput(null); - } - } - - private synchronized boolean addToParents(IResource resource, IResource parent) { - if (parent.getType() == IResource.ROOT) { - return false; - } - // this flag is used to indicate if the parent was previosuly in the set - boolean addedParent = false; - if (parent.getType() == IResource.FILE) { - // the file is new - addedParent = true; - } else { - Set children = (Set)parents.get(parent.getFullPath()); - if (children == null) { - children = new HashSet(); - parents.put(parent.getFullPath(), children); - // this is a new folder in the sync set - addedParent = true; - } - children.add(resource); - } - // if the parent already existed and the resource is new, record it - if (!addToParents(resource, parent.getParent()) && addedParent) { - internalAddedSubtreeRoot(parent); - } - return addedParent; - } - - private synchronized boolean removeFromParents(IResource resource, IResource parent) { - if (parent.getType() == IResource.ROOT) { - return false; - } - // this flag is used to indicate if the parent was removed from the set - boolean removedParent = false; - if (parent.getType() == IResource.FILE) { - // the file will be removed - removedParent = true; - } else { - Set children = (Set)parents.get(parent.getFullPath()); - if (children != null) { - children.remove(resource); - if (children.isEmpty()) { - parents.remove(parent.getFullPath()); - removedParent = true; - } - } - } - // if the parent wasn't removed and the resource was, record it - if (!removeFromParents(resource, parent.getParent()) && removedParent) { - internalRemovedSubtreeRoot(parent); - } - return removedParent; - } - - private void internalAddedSubtreeRoot(IResource parent) { - ((SyncInfoTreeChangeEvent)getChangeEvent()).addedSubtreeRoot(parent); - } - - private void internalRemovedSubtreeRoot(IResource parent) { - ((SyncInfoTreeChangeEvent)getChangeEvent()).removedSubtreeRoot(parent); - } - - /** - * Remove from this set the <code>SyncInfo</code> for the given resource and any of its descendants - * within the specified depth. The depth is one of: - * <ul> - * <li><code>IResource.DEPTH_ZERO</code>: the resource only, - * <li><code>IResource.DEPTH_ONE</code>: the resource or its direct children, - * <li><code>IResource.DEPTH_INFINITE</code>: the resource and all of it's descendants. - * <ul> - * @param resource the root of the resource subtree - * @param depth the depth of the subtree - */ - public void remove(IResource resource, int depth) { - try { - beginInput(); - if (getSyncInfo(resource) != null) { - remove(resource); - } - if (depth == IResource.DEPTH_ZERO || resource.getType() == IResource.FILE) return; - if (depth == IResource.DEPTH_ONE) { - IResource[] members = members(resource); - for (int i = 0; i < members.length; i++) { - IResource member = members[i]; - if (getSyncInfo(member) != null) { - remove(member); - } - } - } else if (depth == IResource.DEPTH_INFINITE) { - IResource [] toRemove = internalGetOutOfSyncDescendants((IContainer)resource); - for (int i = 0; i < toRemove.length; i++) { - remove(toRemove[i]); - } - } - } finally { - endInput(null); - } - } - - /** - * This is an internal method and is not intended to be invoked or - * overriden by clients. - */ - protected synchronized IResource[] internalGetOutOfSyncDescendants(IContainer resource) { - // The parent map contains a set of all out-of-sync children - Set allChildren = (Set)parents.get(resource.getFullPath()); - if (allChildren == null) return new IResource[0]; - return (IResource[]) allChildren.toArray(new IResource[allChildren.size()]); - } - - private synchronized IResource[] internalMembers(IWorkspaceRoot root) { - Set possibleChildren = parents.keySet(); - Set children = new HashSet(); - for (Iterator it = possibleChildren.iterator(); it.hasNext();) { - Object next = it.next(); - IResource element = root.findMember((IPath)next); - if (element != null) { - children.add(element.getProject()); - } - } - return (IResource[]) children.toArray(new IResource[children.size()]); - } - - /** - * Return the immediate children of the given resource who are either out-of-sync - * or contain out-of-sync resources. - * - * @param resource the parent resource - * @return the children of the resource that are either out-of-sync or are ancestors of - * out-of-sync resources contained in the set - */ - public synchronized IResource[] members(IResource resource) { - if (resource.getType() == IResource.FILE) return new IResource[0]; - IContainer parent = (IContainer)resource; - if (parent.getType() == IResource.ROOT) return internalMembers((IWorkspaceRoot)parent); - // OPTIMIZE: could be optimized so that we don't traverse all the deep - // children to find the immediate ones. - Set children = new HashSet(); - IPath path = parent.getFullPath(); - Set possibleChildren = (Set)parents.get(path); - if(possibleChildren != null) { - for (Iterator it = possibleChildren.iterator(); it.hasNext();) { - Object next = it.next(); - IResource element = (IResource)next; - IPath childPath = element.getFullPath(); - IResource modelObject = null; - if(childPath.segmentCount() == (path.segmentCount() + 1)) { - modelObject = element; - - } else if (childPath.segmentCount() > path.segmentCount()) { - IContainer childFolder = parent.getFolder(new Path(null, childPath.segment(path.segmentCount()))); - modelObject = childFolder; - } - if (modelObject != null) { - children.add(modelObject); - } - } - } - return (IResource[]) children.toArray(new IResource[children.size()]); - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/package.html b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/package.html deleted file mode 100644 index 25d39ad6b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/synchronize/package.html +++ /dev/null @@ -1,61 +0,0 @@ -<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta content="text/html; charset=iso-8859-1" - http-equiv="Content-Type"> - <meta content="IBM" name="Author"> - <title>Package-level Javadoc</title> -</head> -<body> -Application programming interfaces for managing synchronization state. -<h2>Package Specification</h2> -<p>This package specifies the API for managing the synchronization state between - the local workspace resources and a corresponding variants of those resources. - The classes in this package can be used by Subscribers (see the org.eclipse.team.core.subscribers - package) or others. The classes are roughly divided into three categories: </p> -<ul> - <li>describing the synchronization state of a one or more resources,</li> - <li>notifying interested parties of changes in the synchronization state.</li> - <li>filtering a set of resource based on a sync state criteria</li> -</ul> -<h3>Describing the synchronization state of resources</h3> -<p>The following classes are provided to accumulate (and possibly filter) the - synchronization state of one or more resources.</p> -<ul> - <li>SyncInfo: node which maps a local resource to a corresponding variant resource - (and a base resource for three-way compare) and descibes the synchronization - state of those resources (e.g. in-sync or incoming-change).</li> - <li>SyncInfoSet: a set which contains the out-of-sync SyncInfo for multiple - local resources.</li> - <li>SyncInfoTree: a specialized set optimized for hierarchical resource based - access (e.g. to obtain all out-of-sync children of a particular local resource).</li> -</ul> -<h3>Notifying interested parties of sync info set changes</h3> -<p>Interested parties can register with a SyncInfoSet in order to -receive notification when a set changes.</p> -<ul> - <li>ISyncInfoSetChangeListener: implementors of this interface can be -registered with a SyncInfoSet in order to recieve notification when the -contents of the set change.</li> - <li>ISyncInfoSetChangeEvent: the type of the events generated by a -SyncInfoSet</li> - <li>ISyncInfoTreeChangeEvent: specialized ISyncInfoSetChangeEvent -generated by SyncInfoTree which includes notification of resource -subtree aditions and removals.</li> -</ul> -<h3>Sync info filtering</h3> -<p>There are also some additional classes provided to help manage -SyncInfoSets</p> -<ul> - <li>SyncInfoFilter: a filter that can be used to test SyncInfo. Long -running tests are supported via an IProgressMonitor. SyncInfoSet has -API for selecting and rejecting SyncInfo based on a provided filter.</li> - <li>FastSyncInfoFilter: a specialized filter that does not support -the ue of a progress monitor</li> -</ul> -<p>Several common filters are provided as inner classes of the two -filter classes for doing synchronization state tests and filter -compounding (and, or, not).</p> -<p> </p> -</body> -</html> diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/AbstractResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/AbstractResourceVariantTree.java deleted file mode 100644 index 3bda82ad3..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/AbstractResourceVariantTree.java +++ /dev/null @@ -1,272 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Path; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Assert; -import org.eclipse.team.internal.core.Policy; - -/** - * An implemenation of <code>IResourceVariantTree</code> that provides the logic for - * refreshing the tree and collecting the results so they can be cached locally. - * This class does not perform the caching but relies on subclasses to do that by - * overriding the <code>setVariant</code> method. The subclass - * {@link ResourceVariantTree} does provide caching. - * - * @see IResourceVariantTree - * @see ResourceVariantTree - * - * @since 3.0 - */ -public abstract class AbstractResourceVariantTree implements IResourceVariantTree { - - /** - * Refreshes the resource variant tree for the specified resources and possibly their descendants, - * depending on the depth. The default implementation of this method invokes - * <code>refresh(IResource, int, IProgressMonitor)</code> for each resource. - * Subclasses may override but should either invoke the above mentioned refresh or - * <code>collectChanges</code> in order to reconcile the resource variant tree. - * @param resources the resources whose variants should be refreshed - * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @param monitor a progress monitor - * @return the array of resources whose corresponding varianst have changed - * @throws TeamException - */ - public IResource[] refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { - List changedResources = new ArrayList(); - monitor.beginTask(null, 100 * resources.length); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - IResource[] changed = refresh(resource, depth, Policy.subMonitorFor(monitor, 100)); - changedResources.addAll(Arrays.asList(changed)); - } - monitor.done(); - if (changedResources == null) return new IResource[0]; - return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]); - } - - /** - * Helper method invoked from <code>refresh(IResource[], int, IProgressMonitor monitor)</code> - * for each resource. The default implementation performs the following steps: - * <ol> - * <li>get the resource variant handle corresponding to the local resource by calling - * <code>getRemoteTree</code>. - * <li>pass the local resource and the resource variant handle to <code>collectChanges</code> - * </ol> - * Subclasses may override but should perform roughly the same steps. - * @param resource the resoure being refreshed - * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @param monitor a progress monitor - * @return the resource's whose variants have changed - * @throws TeamException - */ - protected IResource[] refresh(IResource resource, int depth, IProgressMonitor monitor) throws TeamException { - IResource[] changedResources = null; - monitor.beginTask(null, 100); - try { - monitor.setTaskName(Policy.bind("SynchronizationCacheRefreshOperation.0", resource.getFullPath().makeRelative().toString())); //$NON-NLS-1$ - - // build the remote tree only if an initial tree hasn't been provided - IResourceVariant tree = fetchVariant(resource, depth, Policy.subMonitorFor(monitor, 70)); - - // update the known remote handles - IProgressMonitor sub = Policy.infiniteSubMonitorFor(monitor, 30); - try { - sub.beginTask(null, 64); - changedResources = collectChanges(resource, tree, depth, Policy.subMonitorFor(sub, 64)); - } finally { - sub.done(); - } - } finally { - monitor.done(); - } - if (changedResources == null) return new IResource[0]; - return changedResources; - } - - /** - * Collect the changes in the remote tree to the specified depth. - * @param local the local resource being refreshed - * @param remote the corresponding resource variant - * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @param monitor a progress monitor - * @return the resource's whose variants have changed - * @throws TeamException - */ - protected IResource[] collectChanges(IResource local, IResourceVariant remote, int depth, IProgressMonitor monitor) throws TeamException { - List changedResources = new ArrayList(); - collectChanges(local, remote, changedResources, depth, monitor); - return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]); - } - - /** - * Fetch the members of the given resource variant handle. This method may - * return members that were fetched when <code>fetchVariant</code> was called or - * may fetch the children directly (i.e. this method may contact the server). - * @param variant the resource variant - * @param progress a progress monitor - * @return the members of the resource variant. - */ - protected abstract IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException; - - /** - * Fetch the resource variant corresponding to the given resource. The depth - * parameter indicates the depth of the refresh operation and also indicates the - * depth to which the resource variant's desendants will be traversed. - * This method may prefetch the descendants to the provided depth - * or may just return the variant handle corresponding to the given - * local resource, in which case - * the descendant variants will be fetched by <code>fetchMembers(IResourceVariant, IProgressMonitor)</code>. - * @param resource the local resource - * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @param monitor a progress monitor - * @return the resource variant corresponding to the given local resource - */ - protected abstract IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException; - - /** - * Method that is invoked during collection to let subclasses know which members - * were collected for the given resource. Implementors should purge any cached - * state for children of the local resource that are no longer members. Any such resources - * should be returned to allow clients to clear any state they maintain for those resources. - * @param local the local resource - * @param members the collected members - * @return any resources that were previously collected whose state has been flushed - */ - protected IResource[] collectedMembers(IResource local, IResource[] members) throws TeamException { - return new IResource[0]; - } - - /** - * Set the variant associated with the local resource to the newly fetched resource - * variant. This method is invoked during change collection and should return whether - * the variant associated with the local resource has changed - * @param local the local resource - * @param remote the newly fetched resoure variant - * @return <code>true</code> if the resource variant changed - * @throws TeamException - */ - protected abstract boolean setVariant(IResource local, IResourceVariant remote) throws TeamException; - - private void collectChanges(IResource local, IResourceVariant remote, Collection changedResources, int depth, IProgressMonitor monitor) throws TeamException { - boolean changed = setVariant(local, remote); - if (changed) { - changedResources.add(local); - } - if (depth == IResource.DEPTH_ZERO) return; - Map children = mergedMembers(local, remote, monitor); - for (Iterator it = children.keySet().iterator(); it.hasNext();) { - IResource localChild = (IResource) it.next(); - IResourceVariant remoteChild = (IResourceVariant)children.get(localChild); - collectChanges(localChild, remoteChild, changedResources, - depth == IResource.DEPTH_INFINITE ? IResource.DEPTH_INFINITE : IResource.DEPTH_ZERO, - monitor); - } - - IResource[] cleared = collectedMembers(local, (IResource[]) children.keySet().toArray(new IResource[children.keySet().size()])); - changedResources.addAll(Arrays.asList(cleared)); - monitor.worked(1); - } - - private Map mergedMembers(IResource local, IResourceVariant remote, IProgressMonitor progress) throws TeamException { - - // {IResource -> IResourceVariant} - Map mergedResources = new HashMap(); - - IResourceVariant[] remoteChildren; - if (remote == null) { - remoteChildren = new IResourceVariant[0]; - } else { - remoteChildren = fetchMembers(remote, progress); - } - - - IResource[] localChildren = members(local); - - if (remoteChildren.length > 0 || localChildren.length > 0) { - Set allSet = new HashSet(20); - Map localSet = null; - Map remoteSet = null; - - if (localChildren.length > 0) { - localSet = new HashMap(10); - for (int i = 0; i < localChildren.length; i++) { - IResource localChild = localChildren[i]; - String name = localChild.getName(); - localSet.put(name, localChild); - allSet.add(name); - } - } - - if (remoteChildren.length > 0) { - remoteSet = new HashMap(10); - for (int i = 0; i < remoteChildren.length; i++) { - IResourceVariant remoteChild = remoteChildren[i]; - String name = remoteChild.getName(); - remoteSet.put(name, remoteChild); - allSet.add(name); - } - } - - Iterator e = allSet.iterator(); - while (e.hasNext()) { - String keyChildName = (String) e.next(); - - Policy.checkCanceled(progress); - - IResource localChild = - localSet != null ? (IResource) localSet.get(keyChildName) : null; - - IResourceVariant remoteChild = - remoteSet != null ? (IResourceVariant) remoteSet.get(keyChildName) : null; - - if (localChild == null) { - // there has to be a remote resource available if we got this far - Assert.isTrue(remoteChild != null); - boolean isContainer = remoteChild.isContainer(); - localChild = getResourceChild(local /* parent */, keyChildName, isContainer); - } - mergedResources.put(localChild, remoteChild); - } - } - return mergedResources; - } - - private IResource getResourceChild(IResource parent, String childName, boolean isContainer) { - if (parent.getType() == IResource.FILE) { - return null; - } - if (isContainer) { - return ((IContainer) parent).getFolder(new Path(null, childName)); - } else { - return ((IContainer) parent).getFile(new Path(null, childName)); - } - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/CachedResourceVariant.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/CachedResourceVariant.java deleted file mode 100644 index 86c3583f6..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/CachedResourceVariant.java +++ /dev/null @@ -1,282 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.*; - -/** - * A resource variant is a partial implementation of a remote resource - * whose contents and handle are cached locally. It is assumed that a - * resource variant is an immutable version or revision of a resource. - * Therefore, once the contents are cached they cannot be replaced. - * However, the cached handle can be replaced to allow clients to - * cache addition state or properties for a resource variant. - * <p> - * Overriding subclasses need to provide a cache Id for all their resource variants - * and a cache path for each resource variant that uniquely identifies it. In addition, - * they must implement <code>fetchContents</code> to retrieve the contents of the - * resource variant and then call <code>setContents</code> to place these contents in the cache. - * Subclasses may also call <code>cacheHandle</code> in order to place the handle in the - * cache so that it can be retrieved later by calling <code>getCachedHandle</code> on any - * resource variant whose cache path is the same as the cached handle. This allows subclasses to - * cache additional resource variant properties such as author, comment, etc. - * </p> - * <p> - * The <code>IStorage</code> instance returned by this class will be - * an {@link org.eclipse.core.resources.IEncodedStorage}. - * <p> - * The cache in which the resource variants reside will occasionally clear - * cached entries if they have not been accessed for a certain amount of time. - * </p> - * - * @since 3.0 - */ -public abstract class CachedResourceVariant extends PlatformObject implements IResourceVariant { - - // holds the storage instance for this resource variant - private IStorage storage; - - /* - * Internal class which provides access to the cached contents - * of this resource variant - */ - class ResourceVariantStorage implements IEncodedStorage { - public InputStream getContents() throws CoreException { - if (!isContentsCached()) { - // The cache may have been cleared if someone held - // on to the storage too long - throw new TeamException(Policy.bind("CachedResourceVariant.0", getCachePath())); //$NON-NLS-1$ - } - return getCachedContents(); - } - public IPath getFullPath() { - return getDisplayPath(); - } - public String getName() { - return CachedResourceVariant.this.getName(); - } - public boolean isReadOnly() { - return true; - } - public Object getAdapter(Class adapter) { - return CachedResourceVariant.this.getAdapter(adapter); - } - public String getCharset() throws CoreException { - InputStream contents = getContents(); - try { - String charSet = TeamPlugin.getCharset(getName(), contents); - return charSet; - } catch (IOException e) { - throw new TeamException(new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.FAILED_DESCRIBING_CONTENTS, Policy.bind("CachedResourceVariant.1", getFullPath().toString()), e)); //$NON-NLS-1$ - } finally { - try { - contents.close(); - } catch (IOException e1) { - // Ignore - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.IResourceVariant#getStorage(org.eclipse.core.runtime.IProgressMonitor) - */ - public IStorage getStorage(IProgressMonitor monitor) throws TeamException { - if (isContainer()) return null; - ensureContentsCached(monitor); - if (storage == null) { - storage = new ResourceVariantStorage(); - } - return storage; - } - - private void ensureContentsCached(IProgressMonitor monitor) throws TeamException { - // Ensure that the contents are cached from the server - if (!isContentsCached()) { - fetchContents(monitor); - } - } - - /** - * Method that is invoked when the contents of the resource variant need to - * be fetched. This method will only be invoked for files (i.e. - * <code>isContainer()</code> returns <code>false</code>. - * Subclasses should override this method and invoke <code>setContents</code> - * with a stream containing the fetched contents. - * @param monitor a progress monitor - */ - protected abstract void fetchContents(IProgressMonitor monitor) throws TeamException; - - /** - * This method should be invoked by subclasses from within their <code>fetchContents</code> - * method in order to cache the contents for this resource variant. - * <p> - * This method is not intended to be overridden by clients. - * @param stream the stream containing the contents of the resource variant - * @param monitor a progress monitor - * @throws TeamException - */ - protected void setContents(InputStream stream, IProgressMonitor monitor) throws TeamException { - // Ensure that there is a cache entry to receive the contents - Assert.isTrue(!isContainer()); - if (!isHandleCached()) cacheHandle(); - getCacheEntry().setContents(stream, monitor); - } - - private ResourceVariantCacheEntry getCacheEntry() { - return getCache().getCacheEntry(this.getCachePath()); - } - - /** - * Return whether there are already contents cached for this resource variant. - * This method will return <code>false</code> even if the contents are currently - * being cached by another thread. The consequence of this is that the contents - * may be fetched twice in the rare case where two threads request the same contents - * concurrently. For containers, this method will always return <code>false</code>. - * <p> - * This method is not intended to be overridden by clients. - */ - protected boolean isContentsCached() { - if (isContainer() || !isHandleCached()) { - return false; - } - ResourceVariantCacheEntry entry = getCache().getCacheEntry(getCachePath()); - return entry.getState() == ResourceVariantCacheEntry.READY; - } - - /** - * Return the cached contents for this resource variant or <code>null</code> - * if the contents have not been cached. - * For containers, this method will always return <code>null</code>. - * <p> - * This method is not intended to be overridden by clients. - * @return the cached contents or <code>null</code> - * @throws TeamException - */ - protected InputStream getCachedContents() throws TeamException { - if (isContainer() || !isContentsCached()) return null; - return getCache().getCacheEntry(getCachePath()).getContents(); - } - - /** - * Return <code>true</code> if the cache contains an entry for this resource - * variant. It is possible that another instance of this variant is cached. - * To get the cached instance, call <code>getCachedHandle()</code>. Note that - * cached contents can be retrieved from any handle to a resource variant whose - * cache path (as returned by <code>getCachePath()</code>) match but other - * state information may only be accessible from the cached copy. - * <p> - * This method is not intended to be overridden by clients. - * @return whether the variant is cached - */ - protected boolean isHandleCached() { - return (getCache().hasEntry(getCachePath())); - } - - /** - * Get the path that uniquely identifies the remote resource - * variant. This path descibes the remote location where - * the remote resource is stored and also uniquely identifies - * each resource variant. It is used to uniquely identify this - * resource variant when it is stored in the resource variant cache. - * This path is also returned as the full path of the <code>IStorage</code> - * returned from this variant so the path could be converted to an - * <code>IPath</code> and displayed to the user. - * @return the full path of the remote resource variant - */ - protected abstract String getCachePath(); - - /** - * Return the size (in bytes) of the contents of this resource variant. - * The method will return 0 if the contents have not yet been cached - * locally. - * For containers, this method will always return 0. - */ - public long getSize() { - if (isContainer() || !isContentsCached()) return 0; - ResourceVariantCacheEntry entry = getCacheEntry(); - if (entry == null || entry.getState() != ResourceVariantCacheEntry.READY) { - return 0; - } - return entry.getSize(); - } - - /* - * Return the cache that is used to cache this resource variant and its contents. - * @return Returns the cache. - */ - private ResourceVariantCache getCache() { - ResourceVariantCache.enableCaching(getCacheId()); - return ResourceVariantCache.getCache(getCacheId()); - } - - /** - * Return the ID that uniquely identifies the cache in which this resource variant - * is to be cache. The ID of the plugin that provides the resource variant subclass - * is a good candidate for this ID. The creation, management and disposal of the cache - * is managed by Team. - * @return the cache ID - */ - protected abstract String getCacheId(); - - /** - * Return the cached handle for this resource variant if there is - * one. If there isn't one, then <code>null</code> is returned. - * If there is no cached handle and one is desired, then <code>cacheHandle()</code> - * should be called. - * <p> - * This method is not intended to be overridden by clients. - * @return a cached copy of this resource variant or <code>null</code> - */ - protected CachedResourceVariant getCachedHandle() { - ResourceVariantCacheEntry entry = getCacheEntry(); - if (entry == null) return null; - return entry.getResourceVariant(); - } - - /** - * Cache this handle in the cache, replacing any previously cached handle. - * Note that caching this handle will replace any state associated with a - * previously cached handle, if there is one, but the contents will remain. - * The reason for this is the assumption that the cache path for a resource - * variant (as returned by <code>getCachePath()</code> identifies an immutable - * resource version (or revision). The ability to replace the handle itself - * is provided so that additional state may be cached before or after the contents - * are fetched. - * <p> - * This method is not intended to be overridden by clients. - */ - protected void cacheHandle() { - getCache().add(getCachePath(), this); - } - - /** - * Return the full path of this resource that should be displayed to the - * user. This path is used by the instabce of <code>IStorage</code> that - * is returned by this instance. By default, the path return by <code>getCachePath()</code> - * is used to create a <code>Path</code> object which is returned by this method. - * Subclasses may override. - * @return the full path of this resource that should be displayed to the - * user - * - * @since 3.1 - */ - public IPath getDisplayPath() { - return new Path(null, getCachePath()); - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariant.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariant.java deleted file mode 100644 index d2ac3043c..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariant.java +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IStorage; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/** - * This interface is used by <code>SyncInfo</code> instances - * to provide access to the base and remote resources that correspond to - * a local resource. - * - * @see org.eclipse.team.core.synchronize.SyncInfo - * @since 3.0 - */ -public interface IResourceVariant { - - /** - * Answers the name of the remote resource. The name may be - * displayed to the user. - * - * @return name of the resource variant. - */ - public String getName(); - - /** - * Answers if the remote resource may have children. - * - * @return <code>true</code> if the remote resource may have children and - * <code>false</code> otherwise. - */ - public boolean isContainer(); - - /** - * Return an instance of IStorage or <code>null</code> if the remote resource - * does not have contents (i.e. is a folder). Since the <code>ISorage#getContents()</code> - * method does not accept an <code>IProgressMonitor</code>, this method must ensure that the contents - * access by the resulting <code>IStorage</code> is cached locally (hence the <code>IProgressMonitor</code> - * argument to this method). Implementations of this method should - * ensure that the resulting <code>IStorage</code> is accessing locally cached contents and is not - * contacting the server. - * <p> - * The returned storage object may be an instance of (@link org.eclipse.core.resources.IEncodedStorage} - * in which case clients can determine the character encoding of the contents. - * - * @return an <code>IStorage</code> that provides access to the contents of - * the remote resource or <code>null</code> if the remote resource is a container. - */ - public IStorage getStorage(IProgressMonitor monitor) throws TeamException; - - /** - * Return a content identifier that is used to differentiate versions - * or revisions of the same resource. - * - * @return a String that identifies the version of the subscriber resource - * @throws TeamException - */ - public String getContentIdentifier(); - - /** - * Return an array of bytes that can be used to uniquely identify this - * resource variant when compared to other resource variants and could - * also potentially be used to recreate a resource variant handle. - * @return the bytes that uniquely identify this resource variant - */ - public byte[] asBytes(); - - /** - * Returns whether the remote resource is equal to the provided object. - * @param object the object to be compared - * @return whether the object is equal to the remote resource - */ - public boolean equals(Object object); - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariantComparator.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariantComparator.java deleted file mode 100644 index c39483995..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariantComparator.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IResource; - -/** - * An <code>IResourceVariantComparator</code> is provided by a <code>Subscriber</code> - * and used by a <code>SyncInfo</code> to calculate the sync - * state of the workspace resources. Subscribers should provide a criteria - * best suited for their environment. For example, an FTP subscriber could choose to use file - * size or file timestamps as comparison criterias whereas a CVS workspace subscriber would - * use file revision numbers. - * - * @see org.eclipse.team.core.synchronize.SyncInfo - * @see org.eclipse.team.core.subscribers.Subscriber - * @since 3.0 - */ -public interface IResourceVariantComparator { - - /** - * Returns <code>true</code> if the local resource - * matches the remote resource based on this criteria and <code>false</code> - * otherwise. Comparing should be fast and based on cached information. - * - * @param resource the local resource to be compared - * @param remote the remote resources to be compared - * @return <code>true</code> if local and remote are equal based on this criteria and <code>false</code> - * otherwise. - */ - public boolean compare(IResource local, IResourceVariant remote); - - /** - * Returns <code>true</code> if the base resource - * matches the remote resource based on this criteria and <code>false</code> - * otherwise. Comparing should be fast and based on cached information. - * - * @param base the base resource to be compared - * @param remote the remote resources to be compared - * @return <code>true</code> if base and remote are equal based on this criteria and <code>false</code> - * otherwise. - */ - public boolean compare(IResourceVariant base, IResourceVariant remote); - - /** - * Answers <code>true</code> if the base tree is maintained by this comparator's - * subscriber. If the base tree is not considered than the subscriber can - * be considered as not supported three-way comparisons. Instead - * comparisons are made between the local and remote only without - * consideration for the base. - */ - public boolean isThreeWay(); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariantTree.java deleted file mode 100644 index f74886e36..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/IResourceVariantTree.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/** - * A handle that provides access to locally cached resource variants that - * represent a resource line-up such as a project version or branch. - * <p> - * This interface is not intended to be implemented by clients. However, - * clients may subclass {@link AbstractResourceVariantTree} or {@link ResourceVariantTree}. - * </p> - * - * @see AbstractResourceVariantTree - * @see ResourceVariantTree - * @since 3.0 - */ -public interface IResourceVariantTree { - - /** - * Returns the list of root resources for which this tree may have resource - * variants. - * @return the list of root resources. - */ - public abstract IResource[] roots(); - - /** - * Returns the members of the local resource that have resource variants in this tree. - * The members may or may not exist locally. The resource variants corresponding to the - * members can be retrieved using <code>getResourceVariant(IResource)</code>. - * @param resource the local resource - * @return the members of the local resource for which this tree contains resource variants - * @throws TeamException - */ - public abstract IResource[] members(IResource resource) throws TeamException; - - /** - * Return the resource variant corresponding to the local resource. Return - * <code>null</code> if there is no variant for the resource. - * @param resource the local resource - * @return the resource's variant in this tree - * @throws TeamException - */ - public abstract IResourceVariant getResourceVariant(IResource resource) throws TeamException; - - /** - * Return whether the local resource has a variant in this tree. - * @param resource the local resource - * @return <code>true</code> if the tree contains a variant for the resource - * @throws TeamException - */ - public boolean hasResourceVariant(IResource resource) throws TeamException; - - /** - * Refreshes the resource variant tree for the specified resources and possibly - * their descendants, depending on the depth. - * @param resources the resources whose variants should be refreshed - * @param depth the depth of the refresh (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @param monitor a progress monitor - * @return the array of resources whose corresponding variants have changed - * as a result of the refresh - * @throws TeamException - */ - public IResource[] refresh( - IResource[] resources, - int depth, - IProgressMonitor monitor) throws TeamException; - - /** - * Flush any variants in the tree for the given resource to the depth - * specified. - * @param resource the resource - * @param depth the flush depth (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - */ - public void flushVariants(IResource resource, int depth) throws TeamException; -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ISynchronizerChangeListener.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ISynchronizerChangeListener.java deleted file mode 100644 index ed29b0825..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ISynchronizerChangeListener.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IResource; - -/** - * Listener that can receive notification from a <code>ThreeWaySynchronizer</code> - * when the synchronization state of one or more resources has changed. - * @see ThreeWaySynchronizer - * @since 3.0 - */ -public interface ISynchronizerChangeListener { - - /** - * Notification of synchronization state changes for the given resources. - * Clients must query the <code>ThreeWaySynchronizer</code> that generated - * this event to determine the new synchronization state. - * @param resources the resources whose synchronization state has changed - */ - public void syncStateChanged(IResource[] resources); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/PersistantResourceVariantByteStore.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/PersistantResourceVariantByteStore.java deleted file mode 100644 index 681e419c0..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/PersistantResourceVariantByteStore.java +++ /dev/null @@ -1,179 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Assert; - -/** - * A <code>ResourceVariantByteStore</code> that caches the variant bytes using - * the <code>org.eclipse.core.resources.ISynchronizer</code> so that - * the tree is cached accross workbench invocations. - * <p> - * This class is not intended to be subclassed by clients. - * - * @since 3.0 - */ -public class PersistantResourceVariantByteStore extends ResourceVariantByteStore { - - private static final byte[] NO_REMOTE = new byte[0]; - - private QualifiedName syncName; - - /** - * Create a persistant tree that uses the given qualified name - * as the key in the <code>org.eclipse.core.resources.ISynchronizer</code>. - * It must be unique and should use the plugin as the local name - * and a unique id within the plugin as the qualifier name. - * @param name the key used in the Core synchronizer - */ - public PersistantResourceVariantByteStore(QualifiedName name) { - syncName = name; - getSynchronizer().add(syncName); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#dispose() - */ - public void dispose() { - getSynchronizer().remove(getSyncName()); - } - - /** - * Return the qualified name that uniquely identifies this tree. - * @return the qwualified name that uniquely identifies this tree. - */ - public QualifiedName getSyncName() { - return syncName; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#getBytes(org.eclipse.core.resources.IResource) - */ - public byte[] getBytes(IResource resource) throws TeamException { - byte[] syncBytes = internalGetSyncBytes(resource); - if (syncBytes != null && equals(syncBytes, NO_REMOTE)) { - // If it is known that there is no remote, return null - return null; - } - return syncBytes; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#setBytes(org.eclipse.core.resources.IResource, byte[]) - */ - public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { - Assert.isNotNull(bytes); - byte[] oldBytes = internalGetSyncBytes(resource); - if (oldBytes != null && equals(oldBytes, bytes)) return false; - try { - getSynchronizer().setSyncInfo(getSyncName(), resource, bytes); - return true; - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#flushBytes(org.eclipse.core.resources.IResource, int) - */ - public boolean flushBytes(IResource resource, int depth) throws TeamException { - if (resource.exists() || resource.isPhantom()) { - try { - if (depth != IResource.DEPTH_ZERO || internalGetSyncBytes(resource) != null) { - getSynchronizer().flushSyncInfo(getSyncName(), resource, depth); - return true; - } - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } - return false; - } - - /** - * Return whether the resource variant state for this resource is known. - * This is used to differentiate the case where a resource variant has never been fetched - * from the case where the resource variant is known to not exist. In the later - * case, this method returns <code>true</code> while <code>getBytes</code> returns <code>null</code> - * @param resource the local resource - * @return whether the resource variant state for this resource is known - * @throws TeamException - */ - public boolean isVariantKnown(IResource resource) throws TeamException { - return internalGetSyncBytes(resource) != null; - } - - /** - * This method should be invoked by a client to indicate that it is known that - * there is no remote resource associated with the local resource. After this method - * is invoked, <code>isVariantKnown(resource)</code> will return <code>true</code> and - * <code>getBytes(resource)</code> will return <code>null</code>. - * @return <code>true</code> if this changes the remote sync bytes - */ - public boolean deleteBytes(IResource resource) throws TeamException { - return setBytes(resource, NO_REMOTE); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#members(org.eclipse.core.resources.IResource) - */ - public IResource[] members(IResource resource) throws TeamException { - if(resource.getType() == IResource.FILE) { - return new IResource[0]; - } - try { - // Filter and return only resources that have sync bytes in the cache. - IResource[] members = ((IContainer)resource).members(true /* include phantoms */); - List filteredMembers = new ArrayList(members.length); - for (int i = 0; i < members.length; i++) { - IResource member = members[i]; - if(getBytes(member) != null) { - filteredMembers.add(member); - } - } - return (IResource[]) filteredMembers.toArray(new IResource[filteredMembers.size()]); - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } - - private ISynchronizer getSynchronizer() { - return ResourcesPlugin.getWorkspace().getSynchronizer(); - } - - private byte[] internalGetSyncBytes(IResource resource) throws TeamException { - try { - return getSynchronizer().getSyncInfo(getSyncName(), resource); - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#run(org.eclipse.core.resources.IWorkspaceRunnable, org.eclipse.core.runtime.IProgressMonitor) - */ - public void run(IResource root, IWorkspaceRunnable runnable, IProgressMonitor monitor) - throws TeamException { - try { - ResourcesPlugin.getWorkspace().run(runnable, root, 0, monitor); - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantByteStore.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantByteStore.java deleted file mode 100644 index 82ebe51e5..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantByteStore.java +++ /dev/null @@ -1,135 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.team.core.TeamException; - -/** - * The purpose of a <code>ResourceVariantByteStore</code> is to support the caching of - * the synchronization bytes for the resource variants that represent - * a resource line-up of interest such as a version, baseline or branch. The - * cache stores bytes in order to minimize the memory footprint of the tree. It is the - * reponsibility of the client of this API to cache enough bytes to meaningfully identify - * a resource variant (and possibly create an {@link IResourceVariant} handle from them). - * <p> - * The bytes for a resource variant are accessed using the local <code>IResource</code> handle - * that corresponds to the resource variant (using the <code>getBytes</code> method). - * The potential children of a resource variant are also accessed - * by using the local handle that corresponds to the resource variant - * (using the <code>members</code> method). - * - * @since 3.0 - */ -public abstract class ResourceVariantByteStore { - - /** - * Dispose of any cached sync bytes when this cache is no longer needed. - */ - public abstract void dispose(); - - /** - * Return the bytes for the variant corresponding the given local resource. - * A return value of <code>null</code> means that no bytes have been stored - * for the resource variant. It is up to the client to determine whether - * this means that the resource variant does not exist or that it has not been - * fetched or otherwise determined yet. - * @param resource the local resource - * @return the bytes that represent the resource's variant - * @throws TeamException - */ - public abstract byte[] getBytes(IResource resource) throws TeamException; - - /** - * Set the bytes for the variant corresponding the given local resource. - * The bytes should never be <code>null</code>. If it is known that the remote - * does not exist, <code>deleteBytes(IResource)</code> should be used instead. - * If the sync bytes for the remote are stale and should be removed, - * <code>flushBytes(IResouce, int)</code> should be called. - * @param resource the local resource - * @param bytes the bytes that represent the resource's variant - * @return <code>true</code> if the bytes changed - * @throws TeamException - */ - public abstract boolean setBytes(IResource resource, byte[] bytes) throws TeamException; - - /** - * Remove the bytes from the tree for the resource variants corresponding to the - * given local resource and its descendants to the given depth. - * After the bytes are removed, <code>getBytes(resource)</code> will - * return <code>null</code> for the affected resources. - * @param resource the local resource - * @param depth the depth of the operation (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @return <code>true</code> if there were bytes present which were removed - * @throws TeamException - */ - public abstract boolean flushBytes(IResource resource, int depth) throws TeamException; - - /** - * Method called to indicate that it is known that there is no variant associated - * with the local resource. Subclasses may handle this information in different ways. - * The <code>flush(IResource, int)</code> method should be used in the cases - * where a client wishes to remove bytes for other reason. - * @param resource the local resource - * @return <code>true</code> if this changes the bytes for the variant - */ - public abstract boolean deleteBytes(IResource resource) throws TeamException; - - /** - * Return the children of the given resource that have resource variants in this tree. - * @param resource the parent resource - * @return the members who have resource variants in this tree. - */ - public abstract IResource[] members(IResource resource) throws TeamException; - - /** - * Helper method to compare two byte arrays for equality - * @param syncBytes1 the first byte array or <code>null</code> - * @param syncBytes2 the second byte array or <code>null</code> - * @return whetehr the two arrays are equal (i.e. same content) - */ - protected boolean equals(byte[] syncBytes1, byte[] syncBytes2) { - if (syncBytes1 == null) { - return syncBytes2 == null; - } else if (syncBytes2 == null) { - return false; - } - if (syncBytes1.length != syncBytes2.length) return false; - for (int i = 0; i < syncBytes1.length; i++) { - if (syncBytes1[i] != syncBytes2[i]) return false; - } - return true; - } - - /** - * Run the given action which may contain multiple modfications - * to the byte store. By default, the action is run. Subclasses - * may override to obtain scheduling rules or batch deltas (if - * the byte store modifies workspace resources). - * @param root the root resource for all modifications - * @param action the action to perform - * @param monitor a progress monitor. - * @exception CoreException if the operation failed. - * @exception OperationCanceledException if the operation is canceled. - */ - public void run(IResource root, IWorkspaceRunnable runnable, IProgressMonitor monitor) throws TeamException { - try { - runnable.run(monitor); - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantTree.java deleted file mode 100644 index afde6ead2..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantTree.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/** - * Provides caching for a {@link AbstractResourceVariantTree} using a - * {@link ResourceVariantByteStore}. - * - * @see IResourceVariantTree - * @see AbstractResourceVariantTree - * @see ResourceVariantByteStore - * @since 3.0 - */ -public abstract class ResourceVariantTree extends AbstractResourceVariantTree { - - private ResourceVariantByteStore store; - - /** - * Create a resource variant tree that uses the provided byte store to - * cache the resource variant bytes. - * @param store the resource variant byte store used to cahe resource variants - */ - protected ResourceVariantTree(ResourceVariantByteStore store) { - this.store = store; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.IResourceVariantTree#members(org.eclipse.core.resources.IResource) - */ - public IResource[] members(IResource resource) throws TeamException { - return getByteStore().members(resource); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.IResourceVariantTree#hasResourceVariant(org.eclipse.core.resources.IResource) - */ - public boolean hasResourceVariant(IResource resource) throws TeamException { - return getByteStore().getBytes(resource) != null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.IResourceVariantTree#flushVariants(org.eclipse.core.resources.IResource, int) - */ - public void flushVariants(IResource resource, int depth) throws TeamException { - getByteStore().flushBytes(resource, depth); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.AbstractResourceVariantTree#setVariant(org.eclipse.core.resources.IResource, org.eclipse.team.core.variants.IResourceVariant) - */ - protected boolean setVariant(IResource local, IResourceVariant remote) throws TeamException { - ResourceVariantByteStore cache = getByteStore(); - byte[] newRemoteBytes = getBytes(local, remote); - boolean changed; - if (newRemoteBytes == null) { - changed = cache.deleteBytes(local); - } else { - changed = cache.setBytes(local, newRemoteBytes); - } - return changed; - } - - /** - * Get the byte store that is used to cache the serialization bytes - * for the resource variants of this tree. A byte store is used - * to reduce the memory footprint of the tree. - * <p> - * This method is not intended to be overriden by subclasses. - * - * @return the resource variant tree that is being refreshed. - */ - protected ResourceVariantByteStore getByteStore() { - return store; - } - - /** - * Get the bytes to be stored in the <code>ResourceVariantByteStore</code> - * from the given resource variant. By default, the <code>IResourceVariant#asBytes()</code> - * method is used to get the bytes. - * @param local the local resource - * @param remote the corresponding resource variant handle - * @return the bytes for the resource variant. - */ - protected byte[] getBytes(IResource local, IResourceVariant remote) throws TeamException { - if (remote == null) return null; - return remote.asBytes(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.AbstractResourceVariantTree#collectChanges(org.eclipse.core.resources.IResource, org.eclipse.team.core.variants.IResourceVariant, int, org.eclipse.core.runtime.IProgressMonitor) - */ - protected IResource[] collectChanges(final IResource local, - final IResourceVariant remote, final int depth, IProgressMonitor monitor) - throws TeamException { - final IResource[][] resources = new IResource[][] { null }; - getByteStore().run(local, new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - resources[0] = ResourceVariantTree.super.collectChanges(local, remote, depth, monitor); - } - }, monitor); - return resources[0]; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantTreeSubscriber.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantTreeSubscriber.java deleted file mode 100644 index 9fc328115..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ResourceVariantTreeSubscriber.java +++ /dev/null @@ -1,185 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceStatus; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.TeamStatus; -import org.eclipse.team.core.subscribers.Subscriber; -import org.eclipse.team.core.subscribers.SubscriberChangeEvent; -import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * A specialization of Subscriber that uses <code>IResourceVariantTree</code> objects - * to manage the base (for three-way) and remote trees. Refreshing and obtaining the subscriber - * members and resource variants is delegated to the resource variant trees. - * - * @since 3.0 - */ -public abstract class ResourceVariantTreeSubscriber extends Subscriber { - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.Subscriber#getSyncInfo(org.eclipse.core.resources.IResource) - */ - public SyncInfo getSyncInfo(IResource resource) throws TeamException { - if (!isSupervised(resource)) return null; - IResourceVariant remoteResource = getRemoteTree().getResourceVariant(resource); - IResourceVariant baseResource; - if (getResourceComparator().isThreeWay()) { - baseResource= getBaseTree().getResourceVariant(resource); - } else { - baseResource = null; - } - return getSyncInfo(resource, baseResource, remoteResource); - } - - /** - * Method that creates an instance of SyncInfo for the provided local, base and remote - * resource variants. - * Can be overiden by subclasses. - * @param local the local resource - * @param base the base resource variant or <code>null</code> - * @param remote the remote resource variant or <code>null</code> - * @return the <code>SyncInfo</code> containing the provided resources - */ - protected SyncInfo getSyncInfo(IResource local, IResourceVariant base, IResourceVariant remote) throws TeamException { - SyncInfo info = new SyncInfo(local, base, remote, this.getResourceComparator()); - info.init(); - return info; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.Subscriber#members(org.eclipse.core.resources.IResource) - */ - public IResource[] members(IResource resource) throws TeamException { - if(resource.getType() == IResource.FILE) { - return new IResource[0]; - } - try { - Set allMembers = new HashSet(); - try { - allMembers.addAll(Arrays.asList(((IContainer)resource).members())); - } catch (CoreException e) { - if (e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND) { - // The resource is no longer exists so ignore the exception - } else { - throw e; - } - } - allMembers.addAll(Arrays.asList(internalMembers(getRemoteTree(), resource))); - if (getResourceComparator().isThreeWay()) { - allMembers.addAll(Arrays.asList(internalMembers(getBaseTree(), resource))); - } - for (Iterator iterator = allMembers.iterator(); iterator.hasNext();) { - IResource member = (IResource) iterator.next(); - if(!member.exists() && !getRemoteTree().hasResourceVariant(member)) { - // Remove deletion conflicts - iterator.remove(); - } else if (!isSupervised(resource)) { - // Remove unsupervised resources - iterator.remove(); - } - } - return (IResource[]) allMembers.toArray(new IResource[allMembers.size()]); - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.Subscriber#refresh(org.eclipse.core.resources.IResource[], int, org.eclipse.core.runtime.IProgressMonitor) - */ - public void refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { - monitor = Policy.monitorFor(monitor); - List errors = new ArrayList(); - try { - monitor.beginTask(null, 1000 * resources.length); - for (int i = 0; i < resources.length; i++) { - IResource resource = resources[i]; - IStatus status = refresh(resource, depth, Policy.subMonitorFor(monitor, 1000)); - if (!status.isOK()) { - errors.add(status); - } - } - } finally { - monitor.done(); - } - if (!errors.isEmpty()) { - int numSuccess = resources.length - errors.size(); - throw new TeamException(new MultiStatus(TeamPlugin.ID, 0, - (IStatus[]) errors.toArray(new IStatus[errors.size()]), - Policy.bind("ResourceVariantTreeSubscriber.1", new Object[] {getName(), Integer.toString(numSuccess), Integer.toString(resources.length)}), null)); //$NON-NLS-1$ - } - } - - /** - * Return the base resource variant tree. - */ - protected abstract IResourceVariantTree getBaseTree(); - - /** - * Return the remote resource variant tree. - */ - protected abstract IResourceVariantTree getRemoteTree(); - - private IStatus refresh(IResource resource, int depth, IProgressMonitor monitor) { - monitor = Policy.monitorFor(monitor); - try { - monitor.beginTask(null, 100); - Set allChanges = new HashSet(); - if (getResourceComparator().isThreeWay()) { - IResource[] baseChanges = getBaseTree().refresh(new IResource[] {resource}, depth, Policy.subMonitorFor(monitor, 25)); - allChanges.addAll(Arrays.asList(baseChanges)); - } - IResource[] remoteChanges = getRemoteTree().refresh(new IResource[] {resource}, depth, Policy.subMonitorFor(monitor, 75)); - allChanges.addAll(Arrays.asList(remoteChanges)); - IResource[] changedResources = (IResource[]) allChanges.toArray(new IResource[allChanges.size()]); - fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, changedResources)); - return Status.OK_STATUS; - } catch (TeamException e) { - return new TeamStatus(IStatus.ERROR, TeamPlugin.ID, 0, Policy.bind("ResourceVariantTreeSubscriber.2", resource.getFullPath().toString(), e.getMessage()), e, resource); //$NON-NLS-1$ - } finally { - monitor.done(); - } - } - - private IResource[] internalMembers(IResourceVariantTree tree, IResource resource) throws TeamException, CoreException { - // Filter and return only phantoms associated with the remote synchronizer. - IResource[] members; - try { - members = tree.members(resource); - } catch (CoreException e) { - if (!isSupervised(resource) || e.getStatus().getCode() == IResourceStatus.RESOURCE_NOT_FOUND) { - // The resource is no longer supervised or doesn't exist in any form - // so ignore the exception and return that there are no members - return new IResource[0]; - } - throw e; - } - return members; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/SessionResourceVariantByteStore.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/SessionResourceVariantByteStore.java deleted file mode 100644 index dfffe949c..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/SessionResourceVariantByteStore.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import java.util.*; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Assert; - -/** - * A <code>ResourceVariantByteStore</code> that caches the variant bytes in memory - * and does not persist them over workbench invocations. - * <p> - * This class is not intended to be subclassed by clients. - * - * @since 3.0 - */ -public class SessionResourceVariantByteStore extends ResourceVariantByteStore { - - private static final byte[] NO_REMOTE = new byte[0]; - private Map membersCache = new HashMap(); - - private Map syncBytesCache = new HashMap(); - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#deleteBytes(org.eclipse.core.resources.IResource) - */ - public boolean deleteBytes(IResource resource) throws TeamException { - return flushBytes(resource, IResource.DEPTH_ZERO); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#dispose() - */ - public void dispose() { - syncBytesCache.clear(); - membersCache.clear(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#flushBytes(org.eclipse.core.resources.IResource, int) - */ - public boolean flushBytes(IResource resource, int depth) throws TeamException { - if (getSyncBytesCache().containsKey(resource)) { - if (depth != IResource.DEPTH_ZERO) { - IResource[] members = members(resource); - for (int i = 0; i < members.length; i++) { - IResource child = members[i]; - flushBytes(child, (depth == IResource.DEPTH_INFINITE) ? IResource.DEPTH_INFINITE: IResource.DEPTH_ZERO); - } - } - getSyncBytesCache().remove(resource); - internalRemoveFromParent(resource); - return true; - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#getBytes(org.eclipse.core.resources.IResource) - */ - public byte[] getBytes(IResource resource) throws TeamException { - byte[] syncBytes = internalGetSyncBytes(resource); - if (syncBytes != null && equals(syncBytes, NO_REMOTE)) { - // If it is known that there is no remote, return null - return null; - } - return syncBytes; - } - - /** - * Return <code>true</code> if no bytes are contained in this tree. - * @return <code>true</code> if no bytes are contained in this tree. - */ - public boolean isEmpty() { - return syncBytesCache.isEmpty(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#members(org.eclipse.core.resources.IResource) - */ - public IResource[] members(IResource resource) { - List members = (List)membersCache.get(resource); - if (members == null) { - return new IResource[0]; - } - return (IResource[]) members.toArray(new IResource[members.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#setBytes(org.eclipse.core.resources.IResource, byte[]) - */ - public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { - Assert.isNotNull(bytes); - byte[] oldBytes = internalGetSyncBytes(resource); - if (oldBytes != null && equals(oldBytes, bytes)) return false; - internalSetSyncInfo(resource, bytes); - return true; - } - - private Map getSyncBytesCache() { - return syncBytesCache; - } - - private void internalAddToParent(IResource resource) { - IContainer parent = resource.getParent(); - if (parent == null) return; - List members = (List)membersCache.get(parent); - if (members == null) { - members = new ArrayList(); - membersCache.put(parent, members); - } - members.add(resource); - } - - private byte[] internalGetSyncBytes(IResource resource) { - return (byte[])getSyncBytesCache().get(resource); - } - - private void internalRemoveFromParent(IResource resource) { - IContainer parent = resource.getParent(); - List members = (List)membersCache.get(parent); - if (members != null) { - members.remove(resource); - if (members.isEmpty()) { - membersCache.remove(parent); - } - } - } - - private void internalSetSyncInfo(IResource resource, byte[] bytes) { - getSyncBytesCache().put(resource, bytes); - internalAddToParent(resource); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWayRemoteTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWayRemoteTree.java deleted file mode 100644 index bd84b1903..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWayRemoteTree.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/** - * A resource variant tree that caches and obtains its bytes from the remote slot - * in a three-way synchronizer. Clients must subclass to provide remote resource - * variant refresh functionality. - * - * @see ThreeWaySubscriber - * - * @since 3.0 - */ -public abstract class ThreeWayRemoteTree extends ResourceVariantTree { - - private ThreeWaySubscriber subscriber; - - /* - * A resource variant byte store that accesses the remote bytes - * from a three-way synchronizer. Both access and modification - * are supported. - */ - static class RemoteResourceVariantByteStore extends ResourceVariantByteStore { - private ThreeWaySynchronizer synchronizer; - public RemoteResourceVariantByteStore(ThreeWaySynchronizer synchronizer) { - this.synchronizer = synchronizer; - } - public void dispose() { - // Nothing to do as contents are owned by the TargetSynchronizer - } - public byte[] getBytes(IResource resource) throws TeamException { - return getSynchronizer().getRemoteBytes(resource); - } - public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { - return getSynchronizer().setRemoteBytes(resource, bytes); - } - public boolean flushBytes(IResource resource, int depth) throws TeamException { - // This method is invoked when the remote bytes are stale and should be removed - // This is handled by the ThreeWaySynchronizer so nothing needs to be done here. - return false; - } - public boolean isVariantKnown(IResource resource) throws TeamException { - return getSynchronizer().hasSyncBytes(resource); - } - public boolean deleteBytes(IResource resource) throws TeamException { - return getSynchronizer().removeRemoteBytes(resource); - } - public IResource[] members(IResource resource) throws TeamException { - return synchronizer.members(resource); - } - private ThreeWaySynchronizer getSynchronizer() { - return synchronizer; - } - } - - /** - * Create a remote resource variant tree that stores and obtains - * it's bytes from the remote slot of the synchronizer of the - * given subscriber - * @param subscriber a three-way subscriber - */ - public ThreeWayRemoteTree(ThreeWaySubscriber subscriber) { - super(new RemoteResourceVariantByteStore(subscriber.getSynchronizer())); - this.subscriber = subscriber; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#roots() - */ - public IResource[] roots() { - return getSubscriber().roots(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getResourceVariant(org.eclipse.core.resources.IResource) - */ - public IResourceVariant getResourceVariant(IResource resource) throws TeamException { - return getSubscriber().getResourceVariant(resource, getByteStore().getBytes(resource)); - } - - /** - * Return the subscriber associated with this resource variant tree. - * @return the subscriber associated with this resource variant tree - */ - protected ThreeWaySubscriber getSubscriber() { - return subscriber; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.AbstractResourceVariantTree#collectChanges(org.eclipse.core.resources.IResource, org.eclipse.team.core.variants.IResourceVariant, int, org.eclipse.core.runtime.IProgressMonitor) - */ - protected IResource[] collectChanges(final IResource local, - final IResourceVariant remote, final int depth, IProgressMonitor monitor) - throws TeamException { - final IResource[][] resources = new IResource[][] { null }; - getSubscriber().getSynchronizer().run(local, new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - resources[0] = ThreeWayRemoteTree.super.collectChanges(local, remote, depth, monitor); - } - }, monitor); - return resources[0]; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWayResourceComparator.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWayResourceComparator.java deleted file mode 100644 index bc8955118..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWayResourceComparator.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * A resource comparator that uses the <code>ThreeWaySynchronizer</code> - * to compare local resources to their resource variants. The local state - * is determined using the local modification state and the remote state - * is determined by comparing the base bytes to the remote bytes obtained - * from the synchronizer. - * - * @since 3.0 - */ -public class ThreeWayResourceComparator implements IResourceVariantComparator { - - private ThreeWaySynchronizer synchronizer; - - /** - * Create a three-way resource comparator that uses the <code>ThreeWaySynchronizer</code> - * to compare a local resource to a resource variant. - * @param synchronizer - */ - public ThreeWayResourceComparator(ThreeWaySynchronizer synchronizer) { - this.synchronizer = synchronizer; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.IResourceVariantComparator#compare(org.eclipse.core.resources.IResource, org.eclipse.team.core.variants.IResourceVariant) - */ - public boolean compare(IResource local, IResourceVariant remote) { - // First, ensure the resources are the same gender - if ((local.getType() == IResource.FILE) == remote.isContainer()) { - return false; - } - try { - // If the file is locally modified, it cannot be in sync - if (local.getType() == IResource.FILE && getSynchronizer().isLocallyModified(local)) { - return false; - } - // If there is no base, the local cannopt match the remote - if (getSynchronizer().getBaseBytes(local) == null) return false; - // Otherwise, assume they are the same if the remote equals the base - return equals(getSynchronizer().getBaseBytes(local), getBytes(remote)); - } catch (TeamException e) { - TeamPlugin.log(e); - return false; - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.IResourceVariantComparator#compare(org.eclipse.team.core.variants.IResourceVariant, org.eclipse.team.core.variants.IResourceVariant) - */ - public boolean compare(IResourceVariant base, IResourceVariant remote) { - byte[] bytes1 = getBytes(base); - byte[] bytes2 = getBytes(remote); - return equals(bytes1, bytes2); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.IResourceVariantComparator#isThreeWay() - */ - public boolean isThreeWay() { - return true; - } - - private ThreeWaySynchronizer getSynchronizer() { - return synchronizer; - } - - private byte[] getBytes(IResourceVariant remote) { - return remote.asBytes(); - } - - private boolean equals(byte[] syncBytes, byte[] oldBytes) { - if (syncBytes.length != oldBytes.length) return false; - for (int i = 0; i < oldBytes.length; i++) { - if (oldBytes[i] != syncBytes[i]) return false; - } - return true; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWaySubscriber.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWaySubscriber.java deleted file mode 100644 index 7e026a342..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWaySubscriber.java +++ /dev/null @@ -1,174 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.team.core.Team; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ISubscriberChangeEvent; -import org.eclipse.team.core.subscribers.SubscriberChangeEvent; -import org.eclipse.team.internal.core.TeamPlugin; -import org.eclipse.team.internal.core.subscribers.ThreeWayBaseTree; - -/** - * A resource variant tree subscriber whose trees use an underlying - * <code>ThreeWaySycnrhonizer</code> to store and manage the - * synchronization state for the local workspace. Subclasses need to - * provide a subclass of <code>ThreeWayRemoteTree</code> and a method - * to create resource variant handles from the bytes cached in the - * <code>ThreeWaySynchronizer</code>. - * - * @see ThreeWaySynchronizer - * @see ThreeWayRemoteTree - * @see CachedResourceVariant - * - * @since 3.0 - */ -public abstract class ThreeWaySubscriber extends ResourceVariantTreeSubscriber implements ISynchronizerChangeListener { - - private ThreeWayResourceComparator comparator; - private ThreeWayBaseTree baseTree; - private ThreeWayRemoteTree remoteTree; - private ThreeWaySynchronizer synchronizer; - - /** - * Create a three-way subscriber that uses the given synchronizer - * to manage the synchronization state of local resoures - * and their variants - * @param synchronizer the three-way synchronizer for this subscriber - */ - protected ThreeWaySubscriber(ThreeWaySynchronizer synchronizer) { - this.synchronizer = synchronizer; - baseTree = new ThreeWayBaseTree(this); - getSynchronizer().addListener(this); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantTreeSubscriber#getBaseTree() - */ - protected final IResourceVariantTree getBaseTree() { - return baseTree; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantTreeSubscriber#getRemoteTree() - */ - protected final IResourceVariantTree getRemoteTree() { - if (remoteTree == null) { - remoteTree = createRemoteTree(); - } - return remoteTree; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.Subscriber#getResourceComparator() - */ - public final IResourceVariantComparator getResourceComparator() { - if (comparator == null) { - comparator = new ThreeWayResourceComparator(this.getSynchronizer()); - } - return comparator; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ISynchronizerChangeListener#syncStateChanged(org.eclipse.core.resources.IResource[]) - */ - public void syncStateChanged(IResource[] resources) { - fireTeamResourceChange(SubscriberChangeEvent.asSyncChangedDeltas(this, resources)); - } - - /** - * Returns <code>false</code> for resources that are not children - * of a subscriber root, are ignored by the subscriber's synchronizer - * or are ignored by the <code>Team.ignoreHist(IResource)</code>. Returns - * <code>true</code> otherwise. - * @see org.eclipse.team.core.subscribers.Subscriber#isSupervised(IResource) - */ - public boolean isSupervised(IResource resource) throws TeamException { - if (!isChildOfRoot(resource)) return false; - if (getSynchronizer().isIgnored(resource)) return false; - if (Team.isIgnoredHint(resource)) return false; - return true; - } - - /** - * Return the three-way sychronizer of this subscriber. - * @return the three-way sychronizer of this subscriber. - */ - public ThreeWaySynchronizer getSynchronizer() { - return synchronizer; - } - - /** - * Create the resource variant for the given local resource from the - * given bytes. The bytes are those that were previously returned - * from a call to <code>IResourceVariant#asBytes()</code>. - * @param resource the local resource - * @param bytes the bytes that identify a variant of the resource - * @return the resouce variant handle recreated from the bytes - * @throws TeamException - */ - public abstract IResourceVariant getResourceVariant(IResource resource, byte[] bytes) throws TeamException; - - /** - * Create the three-way remote tree which provides access to the - * remote bytes in the three-way synchronizer. This method is invoked - * once when the remote tree is first accessed. The returned object is - * cached and reused on subsequent accesses. - * @return the remote tree - */ - protected abstract ThreeWayRemoteTree createRemoteTree(); - - /** - * Convenience method that can be used by subclasses to notify listeners - * when a root is added or removed from the subscriber. The added - * parameter should be <code>true</code> if the root was added and <code>false</code> - * if it was removed. - * @param resource the added or removed root - * @param added <code>true</code> if the root was added and <code>false</code> - * if it was removed. - */ - protected void handleRootChanged(IResource resource, boolean added) { - if (added) { - rootAdded(resource); - } else { - rootRemoved(resource); - } - } - - private void rootAdded(IResource resource) { - SubscriberChangeEvent delta = new SubscriberChangeEvent(this, ISubscriberChangeEvent.ROOT_ADDED, resource); - fireTeamResourceChange(new SubscriberChangeEvent[] { delta }); - } - - private void rootRemoved(IResource resource) { - try { - getSynchronizer().flush(resource, IResource.DEPTH_INFINITE); - } catch (TeamException e) { - TeamPlugin.log(e); - } - SubscriberChangeEvent delta = new SubscriberChangeEvent(this, ISubscriberChangeEvent.ROOT_REMOVED, resource); - fireTeamResourceChange(new SubscriberChangeEvent[] { delta }); - } - - private boolean isChildOfRoot(IResource resource) { - IResource[] roots = roots(); - IPath fullPath = resource.getFullPath(); - for (int i = 0; i < roots.length; i++) { - IResource root = roots[i]; - if (root.getFullPath().isPrefixOf(fullPath)) { - return true; - } - } - return false; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWaySynchronizer.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWaySynchronizer.java deleted file mode 100644 index 0e05c9019..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/ThreeWaySynchronizer.java +++ /dev/null @@ -1,519 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.variants; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.eclipse.core.resources.IContainer; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.QualifiedName; -import org.eclipse.core.runtime.jobs.ILock; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Assert; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.subscribers.BatchingLock; -import org.eclipse.team.internal.core.subscribers.SyncByteConverter; -import org.eclipse.team.internal.core.subscribers.BatchingLock.IFlushOperation; -import org.eclipse.team.internal.core.subscribers.BatchingLock.ThreadInfo; - -/** - * This class manages the synchronization between local resources and their - * corresponding resource variants. It provides the following: - * <ul> - * <li>Three way synchronization (set base, set remote, ignored) - * <li>Resource traversal (members) - * <li>Change events and event batching (run) - * <li>Thread-safety - * </ul> - * - * @since 3.0 - */ -public class ThreeWaySynchronizer implements IFlushOperation { - - private static final byte[] IGNORED_BYTES = "i".getBytes(); //$NON-NLS-1$ - - private ILock lock = Platform.getJobManager().newLock(); - private BatchingLock batchingLock = new BatchingLock(); - private ResourceVariantByteStore cache; - private Set listeners = new HashSet(); - - /** - * Create a three-way synchronizer that uses a persistant - * byte store with the given qualified name as its unique - * identifier. - * @param name the unique identifier for the persistant store - */ - public ThreeWaySynchronizer(QualifiedName name) { - this(new PersistantResourceVariantByteStore(name)); - } - - /** - * Create a three-way synchronizer that uses the given byte store - * as its underlying byte cache. - * @param store the byte store this synchronizer uses to cache its bytes - */ - public ThreeWaySynchronizer(ResourceVariantByteStore store) { - cache = store; - } - - /** - * Adds a listener to this synchronizer. Listeners will be notified - * when the synchronization state of a resource changes. Listeners - * are not notified when files are modified locally. Clients can - * make use of the <code>IResource</code> delta mechanism if they - * need to know about local modifications. - * Has no effect if an identical listener is already registered. - * <p> - * Team resource change listeners are informed about state changes - * that affect the resources supervised by this subscriber.</p> - * - * @param listener a synchronizer change listener - */ - public void addListener(ISynchronizerChangeListener listener) { - synchronized (listeners) { - listeners.add(listener); - } - } - - /** - * Removes a listener previously registered with this synchronizer. - * Has no affect if an identical listener is not registered. - * - * @param listener a synchronizer change listener - */ - public void removeListener(ISynchronizerChangeListener listener) { - synchronized (listeners) { - listeners.remove(listener); - } - } - - /** - * Return the base bytes that are cached for the given resource - * or <code>null</code> if no base is cached. The returned bytes - * should uniquely identify the resource variant that is the base - * for the given local resource. - * - * @param resource the resource - * @return the base bytes cached with the resource or <code>null</code> - * @throws TeamException - */ - public byte[] getBaseBytes(IResource resource) throws TeamException { - try { - beginOperation(); - byte[] syncBytes = internalGetSyncBytes(resource); - if (syncBytes == null) return null; - byte[] baseBytes = getSlot(syncBytes, 1); - if (baseBytes == null || baseBytes.length == 0) return null; - return baseBytes; - } finally { - endOperation(); - } - } - - /** - * Set the base bytes for the given resource. The provided bytes - * should encode enough information to uniquely identify - * (and possibly recreate) the resource variant that is the base - * for the given local resource. In essence, setting the base - * bytes is equivalent to marking the file as in-sync. As such, - * setting the base bytes will also set the remote bytes and mark - * the file as clean (i.e. having no outgoing changes). - * - * @param resource the resource - * @param baseBytes the base bytes that identify the base resource variant - * @throws TeamException - */ - public void setBaseBytes(IResource resource, byte[] baseBytes) throws TeamException { - Assert.isNotNull(baseBytes); - ISchedulingRule rule = null; - try { - rule = beginBatching(resource, null); - try { - beginOperation(); - String base = new String(baseBytes); - String[] slots = new String[] { - new Long(resource.getModificationStamp()).toString(), - base, - base - }; - byte[] syncBytes = toBytes(slots); - internalSetSyncBytes(resource, syncBytes); - batchingLock.resourceChanged(resource); - } finally { - endOperation(); - } - } finally { - if (rule != null) endBatching(rule, null); - } - } - - /** - * Return whether the local resource has been modified since the last time - * the base bytes were set. This method will return <code>false</code> - * for ignored resources and <code>true</code> for non-existant resources - * that have base bytes cached. - * @param resource the resource - * @return <code>true</code> if the resource has been modified since the - * last time the base bytes were set. - * @throws TeamException - */ - public boolean isLocallyModified(IResource resource) throws TeamException { - return ((internalGetSyncBytes(resource) == null && ! isIgnored(resource)) || - (getLocalTimestamp(resource) != resource.getModificationStamp()) || - (getBaseBytes(resource) != null && !resource.exists())); - } - - /** - * Return the remote bytes that are cached for the given resource - * or <code>null</code> if no remote is cached. The returned bytes - * should uniquely identify the resource variant that is the remote - * for the given local resource. - * - * @param resource the resource - * @return the remote bytes cached with the resource or <code>null</code> - * @throws TeamException - */ - public byte[] getRemoteBytes(IResource resource) throws TeamException { - try { - beginOperation(); - byte[] syncBytes = internalGetSyncBytes(resource); - if (syncBytes == null) return null; - byte[] remoteBytes = getSlot(syncBytes, 2); - if (remoteBytes == null || remoteBytes.length == 0) return null; - return remoteBytes; - } finally { - endOperation(); - } - } - - /** - * Set the remote bytes for the given resource. The provided bytes - * should encode enough information to uniquely identify - * (and possibly recreate) the resource variant that is the remote - * for the given local resource. If the remote for a resource - * no longer exists, <code>removeRemoteBytes(IResource)</code> - * should be called. - * - * @param resource the resource - * @param remoteBytes the base bytes that identify the remote resource variant - * @return <code>true</code> if the remote bytes changed as a result of the set - * @throws TeamException - */ - public boolean setRemoteBytes(IResource resource, byte[] remoteBytes) throws TeamException { - Assert.isNotNull(remoteBytes); - ISchedulingRule rule = null; - try { - rule = beginBatching(resource, null); - try { - beginOperation(); - byte[] syncBytes = internalGetSyncBytes(resource); - if (syncBytes == null) { - String[] slots = new String[] { - "", //$NON-NLS-1$ - "", //$NON-NLS-1$ - new String(remoteBytes) - }; - syncBytes = toBytes(slots); - } else { - byte[] currentRemote = getSlot(syncBytes, 2); - if (equals(remoteBytes, currentRemote)) return false; - syncBytes = setSlot(syncBytes, 2, remoteBytes); - } - internalSetSyncBytes(resource, syncBytes); - batchingLock.resourceChanged(resource); - return true; - } finally { - endOperation(); - } - } finally { - if (rule != null) endBatching(rule, null); - } - } - - /** - * Remove the remote bytes associated with the resource. This is typically - * done when the corresponding remote resource variant no longer exists. - * @param resource the resource - * @return <code>true</code> if the remote bytes changed as a result of the removal - * @throws TeamException - */ - public boolean removeRemoteBytes(IResource resource) throws TeamException { - ISchedulingRule rule = null; - try { - rule = beginBatching(resource, null); - try { - beginOperation(); - byte[] syncBytes = internalGetSyncBytes(resource); - if (syncBytes != null) { - String currentRemote = new String(getSlot(syncBytes, 2)); - if (currentRemote.length() == 0) return false; - syncBytes = setSlot(syncBytes, 2, new byte[0]); - internalSetSyncBytes(resource, syncBytes); - batchingLock.resourceChanged(resource); - return true; - } - return false; - } finally { - endOperation(); - } - } finally { - if (rule != null) endBatching(rule, null); - } - } - - /** - * Return whether the given resource has sync bytes in the synchronizer. - * @param resource the local resource - * @return whether there are sync bytes cached for the local resources. - */ - public boolean hasSyncBytes(IResource resource) throws TeamException { - return internalGetSyncBytes(resource) != null; - } - - /** - * Returns whether the resource has been marked as ignored - * using <code>setIgnored(IResource)</code>. - * @param resource the resource - * @return <code>true</code> if the resource is ignored. - * @throws TeamException - */ - public boolean isIgnored(IResource resource) throws TeamException { - byte[] bytes = cache.getBytes(resource); - return (bytes != null && equals(bytes, IGNORED_BYTES)); - } - - /** - * Mark the resource as being ignored. Ignored resources - * are not returned by the <code>members</code> method, - * are never dirty (see <code>isLocallyModified</code>) and - * do not have base or remote bytes cahced for them. - * @param resource the resource to be ignored - * @throws TeamException - */ - public void setIgnored(IResource resource) throws TeamException { - internalSetSyncBytes(resource, IGNORED_BYTES); - } - - /** - * Return the members of the local resource that either have sync bytes - * or exist locally and are not ignored. - * @param resource the local resource - * @return the children of the local resource that have cached sync bytes - * or are not ignored - * @throws TeamException - */ - public IResource[] members(IResource resource) throws TeamException { - if (resource.getType() == IResource.FILE) { - return new IResource[0]; - } - try { - Set potentialChildren = new HashSet(); - IContainer container = (IContainer)resource; - if (container.exists()) { - potentialChildren.addAll(Arrays.asList(container.members())); - } - potentialChildren.addAll(Arrays.asList(cache.members(resource))); - List result = new ArrayList(); - for (Iterator iter = potentialChildren.iterator(); iter.hasNext();) { - IResource child = (IResource) iter.next(); - if (child.exists() || hasSyncBytes(child)) { - result.add(child); - } - } - return (IResource[]) result.toArray(new IResource[result.size()]); - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } - - /** - * Flush any cached bytes for the given resource to the depth specified. - * @param resource the resource - * @param depth the depth of the flush (one of <code>IResource.DEPTH_ZERO</code>, - * <code>IResource.DEPTH_ONE</code>, or <code>IResource.DEPTH_INFINITE</code>) - * @throws TeamException - */ - public void flush(IResource resource, int depth) throws TeamException { - ISchedulingRule rule = null; - try { - rule = beginBatching(resource, null); - try { - beginOperation(); - if (cache.flushBytes(resource, depth)) { - batchingLock.resourceChanged(resource); - } - } finally { - endOperation(); - } - } finally { - if (rule != null) endBatching(rule, null); - } - } - - /** - * Perform multiple sync state modifications and fire only a single change notification - * at the end. - * @param resourceRule the scheduling rule that encompasses all modifications - * @param runnable the runnable that performs the sync state modifications - * @param monitor a progress monitor - * @throws TeamException - */ - public void run(IResource resourceRule, IWorkspaceRunnable runnable, IProgressMonitor monitor) throws TeamException { - monitor = Policy.monitorFor(monitor); - monitor.beginTask(null, 100); - ISchedulingRule rule = beginBatching(resourceRule, Policy.subMonitorFor(monitor, 10)); - try { - cache.run(resourceRule, runnable, Policy.subMonitorFor(monitor, 80)); - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } finally { - if (rule != null) endBatching(rule, Policy.subMonitorFor(monitor, 10)); - monitor.done(); - } - } - - /* (non-Javadoc) - * - * Callback which is invoked when the batching resource lock is released - * or when a flush is requested (see beginBatching(IResource)). - * - * @see org.eclipse.team.internal.ftp.deployment.BatchingLock.IFlushOperation#flush(org.eclipse.team.internal.ftp.deployment.BatchingLock.ThreadInfo, org.eclipse.core.runtime.IProgressMonitor) - */ - public void flush(ThreadInfo info, IProgressMonitor monitor) throws TeamException { - if (info != null && !info.isEmpty()) { - broadcastSyncChanges(info.getChangedResources()); - } - } - - private void broadcastSyncChanges(final IResource[] resources) { - ISynchronizerChangeListener[] allListeners; - // Copy the listener list so we're not calling client code while synchronized - synchronized(listeners) { - allListeners = (ISynchronizerChangeListener[]) listeners.toArray(new ISynchronizerChangeListener[listeners.size()]); - } - // Notify the listeners safely so all will receive notification - for (int i = 0; i < allListeners.length; i++) { - final ISynchronizerChangeListener listener = allListeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // don't log the exception....it is already being logged in Platform#run - } - public void run() throws Exception { - listener.syncStateChanged(resources); - - } - }); - } - } - - /* - * Return the cached sync bytes for the given resource. - * The value <code>null</code> is returned if there is no - * cached bytes or if the resource is ignored. - */ - private byte[] internalGetSyncBytes(IResource resource) throws TeamException { - byte[] bytes = cache.getBytes(resource); - if (bytes != null && equals(bytes, IGNORED_BYTES)) return null; - return bytes; - } - - /* - * Set the cached sync bytes - */ - private boolean internalSetSyncBytes(IResource resource, byte[] syncBytes) throws TeamException { - return cache.setBytes(resource, syncBytes); - } - - private byte[] getSlot(byte[] syncBytes, int i) { - return SyncByteConverter.getSlot(syncBytes, i, false); - } - - private byte[] setSlot(byte[] syncBytes, int i, byte[] insertBytes) throws TeamException { - return SyncByteConverter.setSlot(syncBytes, i, insertBytes); - } - - private byte[] toBytes(String[] slots) { - return SyncByteConverter.toBytes(slots); - } - - private long getLocalTimestamp(IResource resource) throws TeamException { - try { - beginOperation(); - byte[] syncBytes = internalGetSyncBytes(resource); - if (syncBytes == null) return 0; - byte[] bytes = getSlot(syncBytes, 0); - if (bytes == null || bytes.length == 0) return 0; - return Long.parseLong(new String(bytes)); - } finally { - endOperation(); - } - } - - private boolean equals(byte[] syncBytes, byte[] oldBytes) { - if (syncBytes.length != oldBytes.length) return false; - for (int i = 0; i < oldBytes.length; i++) { - if (oldBytes[i] != syncBytes[i]) return false; - } - return true; - } - - /* - * Begin an access to the internal data structures of the synchronizer - */ - private void beginOperation() { - // Do not try to acquire the lock if the resources tree is locked - // The reason for this is that during the resource delta phase (i.e. when the tree is locked) - // the workspace lock is held. If we obtain our lock, there is - // a chance of dealock. It is OK if we don't as we are still protected - // by scheduling rules and the workspace lock. - if (ResourcesPlugin.getWorkspace().isTreeLocked()) return; - lock.acquire(); - } - - /* - * End an access to the internal data structures of the synchronizer - */ - private void endOperation() { - // See beginOperation() for a description of why the lock is not obtained when the tree is locked - if (ResourcesPlugin.getWorkspace().isTreeLocked()) return; - lock.release(); - } - - /* - * Begins a batch of operations in order to batch event changes. - * The provided scheduling rule indicates the resources - * that the resources affected by the operation while the returned scheduling rule - * is the rule obtained by the lock. It may differ from the provided rule. - */ - private ISchedulingRule beginBatching(ISchedulingRule resourceRule, IProgressMonitor monitor) { - return batchingLock.acquire(resourceRule, this /* IFlushOperation */, monitor); - } - - /* - * Ends a batch of operations. The provided rule must be the one that was returned - * by the corresponding call to beginBatching. - */ - private void endBatching(ISchedulingRule rule, IProgressMonitor monitor) throws TeamException { - batchingLock.release(rule, monitor); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/package.html b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/package.html deleted file mode 100644 index 0b1e91c13..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/variants/package.html +++ /dev/null @@ -1,80 +0,0 @@ -<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta content="text/html; charset=iso-8859-1" - http-equiv="Content-Type"> - <meta content="IBM" name="Author"> - <title>Package-level Javadoc</title> -</head> -<body> -Application programming interfaces for accessing and managing resource variants. -<h2>Package Specification</h2> -<p>This package specifies the API for accessing and managing variants for local - workspace resources. The classes in this package can be used by Subscribers - (see the org.eclipse.team.core.subscribers package) or others. The classes are - roughly divided into three categories: <br> -</p> -<h3>Access to Resource Variants</h3> -<p>The following interfaces define the API required for subscribers to access - and manage variants of local resources.</p> -<ul> - <li>IResourceVariant: provides access to information about a variant resource, - such as it's name, its type (file or container) and its contents.</li> - <li>IResourceVariantComparator: supports the comparison of a local resource - with a variant or the comparison of two variants (if three-way comparison - is supported).</li> - <li>IResourceVariantTree: provides access to a tree of locally cached resource - variants along with API to refresh the cached variants.</li> -</ul> -<h3>Implementing Resource Variants</h3> -<p>Several classes are available that provide partial, extandable implementations - of the above mentioned interfaces.</p> -<ul> - <li>CachedResourceVariant: an IResourceVariant implementation that supports - the caching of the contents of the variant. Subclasses must override to provide - fecthing of contents.</li> - <li>AbstractResourceVariantTree: an IResourceVariantTree that contains logic - for performing a refresh of the cached resource variants. The caching mechanism - is delegated to subclasses as is the fetching of the resource variants. - <ul> - <li>ResourceVariantTree: An AbstractResourceVariantTree that uses a ResourceVariantByteStore - to cache the resource variants. Subclasses must still provide the fecthing - of the remote state.</li> - </ul> - </li> - <li>ResourceVariantByteStore: An abstract class that defines the API required - for caching resource variants as byte arrays. - <ul> - <li>PersistantResourceVariantByteStore: a ResourceVariantByteStore that - persists the bytes accross workbench invocations.</li> - <li>SessionResourceVariantByteStore: a ResourceVariantByteStore that caches - the bytes in a session store and does not persist them.</li> - </ul> - </li> -</ul> -<h3>Implementing Subscribers</h3> -<p>This package also contains two partial subscriber implementations.</p> -<ul> - <li>ResourceVariantTreeSubscriber: a subscriber that makes use of IResourceVariantTree - objects to provide the traversal and refresh of the base and remote trees.</li> - <li>ThreeWaySubscriber: a ResourceVariantTreeSubscriber that is build on top - of the following classes. - <ul> - <li>ThreeWaySynchronizer: a byte store that maintains the complete synchronization - state (local, base and remote) required by a subscriber. It provides API - to access and set the base and remote bytes corresponding to resource - variants as well as change notification to registered ISynchronizerChangeListener - instances. </li> - <li>ThreeWayRemoteTree: A remote tree that uses the ThreeWaySynchronizer - remote slot as its byte store. Subclasses of ResourceVariantTreeSubscriber - must also subclass ThreeWayRemoteTree in order to provide the tree refresh - behavior.</li> - <li>ThreeWayResourceComparator: a IResourceVariantComparator that uses the - state from a ThreeWaySynchronizer to compare local resources to their - variants.</li> - </ul> - </li> -</ul> -<p> </p> -</body> -</html> diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Assert.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Assert.java deleted file mode 100644 index 50dbb156e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Assert.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - - - -public final class Assert { - public static class AssertionFailedException extends RuntimeException { - // Field required to avoid compiler warning - private static final long serialVersionUID = -3361573629971779153L; - public AssertionFailedException() { - } - public AssertionFailedException(String detail) { - super(Policy.bind("Assert.assertionFailed", detail)); //$NON-NLS-1$ - } - } -/* This class is not intended to be instantiated. */ -private Assert() { -} -/** Asserts that an argument is legal. If the given boolean is - * not <code>true</code>, an <code>IllegalArgumentException</code> - * is thrown. - * - * @param expression the outcode of the check - * @return <code>true</code> if the check passes (does not return - * if the check fails) - * @exception IllegalArgumentException if the legality test failed - */ -public static boolean isLegal(boolean expression) { - return isLegal(expression, ""); //$NON-NLS-1$ -} -/** Asserts that an argument is legal. If the given boolean is - * not <code>true</code>, an <code>IllegalArgumentException</code> - * is thrown. - * The given message is included in that exception, to aid debugging. - * - * @param expression the outcode of the check - * @param message the message to include in the exception - * @return <code>true</code> if the check passes (does not return - * if the check fails) - * @exception IllegalArgumentException if the legality test failed - */ -public static boolean isLegal(boolean expression, String message) { - if (!expression) - throw new IllegalArgumentException(message); - return expression; -} -/** Asserts that the given object is not <code>null</code>. If this - * is not the case, some kind of unchecked exception is thrown. - * - * @param object the value to test - * @exception IllegalArgumentException if the object is <code>null</code> - */ -public static void isNotNull(Object object) { - if (object == null) - throw new AssertionFailedException("null argument"); //$NON-NLS-1$ -} -/** Asserts that the given object is not <code>null</code>. If this - * is not the case, some kind of unchecked exception is thrown. - * The given message is included in that exception, to aid debugging. - * - * @param object the value to test - * @param message the message to include in the exception - * @exception IllegalArgumentException if the object is <code>null</code> - */ -public static void isNotNull(Object object, String message) { - if (object == null) - throw new AssertionFailedException("null argument:" /*non NLS*/ + message); //$NON-NLS-1$ -} -/** Asserts that the given boolean is <code>true</code>. If this - * is not the case, some kind of unchecked exception is thrown. - * - * @param expression the outcode of the check - * @return <code>true</code> if the check passes (does not return - * if the check fails) - */ -public static boolean isTrue(boolean expression) { - return isTrue(expression, ""/*nonNLS*/); //$NON-NLS-1$ -} -/** Asserts that the given boolean is <code>true</code>. If this - * is not the case, some kind of unchecked exception is thrown. - * The given message is included in that exception, to aid debugging. - * - * @param expression the outcode of the check - * @param message the message to include in the exception - * @return <code>true</code> if the check passes (does not return - * if the check fails) - */ -public static boolean isTrue(boolean expression, String message) { - if (!expression) - throw new AssertionFailedException("assert failed:" /*non NLS*/ + message); //$NON-NLS-1$ - return expression; -} -/** - * Indicates that the caller has not implemented the method. - * Usually this is a temporary condition. - */ -public static void notYetImplemented() { -} -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/BackgroundEventHandler.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/BackgroundEventHandler.java deleted file mode 100644 index 628fc8bbd..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/BackgroundEventHandler.java +++ /dev/null @@ -1,429 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.*; -import org.eclipse.team.core.TeamException; - -/** - * This class provides the infrastucture for processing/dispatching of events using a - * background job. This is useful in the following situations. - * <ul> - * <li>an operation is potentially long running but a resposive UI is desired - * while the operation is being performed.</li> - * <li>a change is a POST_CHANGE delta requires further modifications to the workspace - * which cannot be performed in the delta handler because the workspace is locked.</li> - * <li>a data structure is not thread safe and requires serialized operations.<li> - * </ul> - * </p> - * @since 3.0 - */ -public abstract class BackgroundEventHandler { - - // Events that need to be processed - private List awaitingProcessing = new ArrayList(); - - // The job that runs when events need to be processed - private Job eventHandlerJob; - - // Indicate if the event handler has been shutdown - private boolean shutdown; - - // Accumulate exceptions that occur - private ExceptionCollector errors; - - // time the last dispath occured - private long timeOfLastDispatch = 0L; - - // the number of dispatches that have occurred since the job started - private int dispatchCount; - - // time between event dispatches - private static final long DISPATCH_DELAY = 1500; - - // time between dispatches if the dispatch threshoild has been exceeded - private static final long LONG_DISPATCH_DELAY = 10000; - - // the numbver of dispatches that can occur before using the long delay - private static final int DISPATCH_THRESHOLD = 3; - - // time to wait for messages to be queued - private static final long WAIT_DELAY = 1000; - - private String jobName; - - /** - * General event class. The type is specific to subclasses. - */ - public static class Event { - private int type; - public Event(int type) { - this.type = type; - } - public int getType() { - return type; - } - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("Background Event: "); //$NON-NLS-1$ - buffer.append(getTypeString()); - return buffer.toString(); - } - public IResource getResource() { - return null; - } - protected String getTypeString() { - return String.valueOf(type); - } - } - - /** - * Resource event class. The type is specific to subclasses. - */ - public static class ResourceEvent extends Event { - private IResource resource; - private int depth; - public ResourceEvent(IResource resource, int type, int depth) { - super(type); - this.resource = resource; - this.depth = depth; - } - public int getDepth() { - return depth; - } - public IResource getResource() { - return resource; - } - public String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.append("resource: "); //$NON-NLS-1$ - buffer.append(resource.getFullPath()); - buffer.append(" type: "); //$NON-NLS-1$ - buffer.append(getTypeString()); - buffer.append(" depth: "); //$NON-NLS-1$ - buffer.append(getDepthString()); - return buffer.toString(); - } - protected String getDepthString() { - switch (depth) { - case IResource.DEPTH_ZERO : - return "DEPTH_ZERO"; //$NON-NLS-1$ - case IResource.DEPTH_ONE : - return "DEPTH_ONE"; //$NON-NLS-1$ - case IResource.DEPTH_INFINITE : - return "DEPTH_INFINITE"; //$NON-NLS-1$ - default : - return "INVALID"; //$NON-NLS-1$ - } - } - } - - protected BackgroundEventHandler(String jobName, String errorTitle) { - this.jobName = jobName; - errors = - new ExceptionCollector( - errorTitle, - TeamPlugin.ID, - IStatus.ERROR, - null /* don't log */ - ); - createEventHandlingJob(); - schedule(); - } - - /** - * Create the job used for processing the events in the queue. The job stops working when - * the queue is empty. - */ - protected void createEventHandlingJob() { - eventHandlerJob = new Job(getName()) { - public IStatus run(IProgressMonitor monitor) { - return processEvents(monitor); - } - public boolean shouldRun() { - return ! isQueueEmpty(); - } - public boolean shouldSchedule() { - return ! isQueueEmpty(); - } - public boolean belongsTo(Object family) { - return family == getJobFamiliy(); - } - }; - eventHandlerJob.addJobChangeListener(new JobChangeAdapter() { - public void done(IJobChangeEvent event) { - jobDone(event); - } - }); - eventHandlerJob.setSystem(true); - eventHandlerJob.setPriority(Job.SHORT); - } - - /** - * Return the family that the background job for this - * event handler belongs to. - * @return the family that the background job for this - * event handler belongs to - */ - protected Object getJobFamiliy() { - return null; - } - - /** - * This method is invoked when the processing job completes. The - * default behavior of the handler is to restart the job if the queue - * is no longer empty and to clear the queue if the handler was shut down. - */ - protected void jobDone(IJobChangeEvent event) { - if (isShutdown()) { - // The handler has been shutdown. Clean up the queue. - synchronized(this) { - awaitingProcessing.clear(); - } - } else if (! isQueueEmpty()) { - // An event squeaked in as the job was finishing. Reschedule the job. - schedule(); - } - } - - /** - * Schedule the job to process the events now. - */ - protected void schedule() { - eventHandlerJob.schedule(); - } - - /** - * Shutdown the event handler. Any events on the queue will be removed from the queue - * and will not be processed. - */ - public void shutdown() { - shutdown = true; - eventHandlerJob.cancel(); - } - - /** - * Returns whether the handle has been shutdown. - * @return Returns whether the handle has been shutdown. - */ - public boolean isShutdown() { - return shutdown; - } - - /** - * Queue the event and start the job if it's not already doing work. If the job is - * already running then notify in case it was waiting. - * @param event the event to be queued - */ - protected synchronized void queueEvent(Event event, boolean front) { - if (Policy.DEBUG_BACKGROUND_EVENTS) { - System.out.println("Event queued on " + getName() + ":" + event.toString()); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (front) { - awaitingProcessing.add(0, event); - } else { - awaitingProcessing.add(event); - } - if (!isShutdown() && eventHandlerJob != null) { - if(eventHandlerJob.getState() == Job.NONE) { - schedule(); - } else { - notify(); - } - } - } - - /** - * Return the name that is to be associated with the background job. - * @return the job name - */ - protected String getName() { - return jobName; - } - - /* - * Return the next event that has been queued, removing it from the queue. - * @return the next event in the queue - */ - protected synchronized Event nextElement() { - if (isShutdown() || isQueueEmpty()) { - return null; - } - return (Event) awaitingProcessing.remove(0); - } - - protected synchronized Event peek() { - if (isShutdown() || isQueueEmpty()) { - return null; - } - return (Event) awaitingProcessing.get(0); - } - - /** - * Return whether there are unprocessed events on the event queue. - * @return whether there are unprocessed events on the queue - */ - protected synchronized boolean isQueueEmpty() { - return awaitingProcessing.isEmpty(); - } - - /** - * Process events from the events queue and dispatch results. This method does not - * directly check for or handle cancelation of the provided monitor. However, - * it does invoke <code>processEvent(Event)</code> which may check for and handle - * cancelation by shuting down the receiver. - * <p> - * The <code>isReadyForDispatch()</code> method is used in conjuntion - * with the <code>dispatchEvents(IProgressMonitor)</code> to allow - * the output of the event handler to be batched in order to avoid - * fine grained UI updating. - * @param monitor a progress monitor - */ - protected IStatus processEvents(IProgressMonitor monitor) { - errors.clear(); - try { - // It's hard to know how much work is going to happen - // since the queue can grow. Use the current queue size as a hint to - // an infinite progress monitor - monitor.beginTask(null, IProgressMonitor.UNKNOWN); - IProgressMonitor subMonitor = Policy.infiniteSubMonitorFor(monitor, 90); - subMonitor.beginTask(null, 1024); - - Event event; - timeOfLastDispatch = System.currentTimeMillis(); - dispatchCount = 1; - while ((event = nextElement()) != null && ! isShutdown()) { - try { - processEvent(event, subMonitor); - if (Policy.DEBUG_BACKGROUND_EVENTS) { - System.out.println("Event processed on " + getName() + ":" + event.toString()); //$NON-NLS-1$ //$NON-NLS-2$ - } - if(isReadyForDispatch(true /*wait if queue is empty*/)) { - dispatchEvents(Policy.subMonitorFor(subMonitor, 1)); - } - } catch (CoreException e) { - // handle exception but keep going - handleException(e); - } - } - } finally { - monitor.done(); - } - return errors.getStatus(); - } - - /** - * Dispatch any accumulated events by invoking <code>doDispatchEvents</code> - * and then rest the dispatch counters. - * @param monitor a progress monitor - * @throws TeamException - */ - protected final void dispatchEvents(IProgressMonitor monitor) throws TeamException { - if (doDispatchEvents(monitor)) { - // something was dispatched so adjust dispatch count. - dispatchCount++; - } - timeOfLastDispatch = System.currentTimeMillis(); - } - - /** - * Notify clients of processed events. - * @param monitor a progress monitor - */ - protected abstract boolean doDispatchEvents(IProgressMonitor monitor) throws TeamException; - - /** - * Returns <code>true</code> if processed events should be dispatched and - * <code>false</code> otherwise. Events are dispatched at regular intervals - * to avoid fine grain events causing the UI to be too jumpy. Also, if the - * events queue is empty we will wait a small amount of time to allow - * pending events to be queued. The queueEvent notifies when events are - * queued. - * @return <code>true</code> if processed events should be dispatched and - * <code>false</code> otherwise - */ - protected boolean isReadyForDispatch(boolean wait) { - long duration = System.currentTimeMillis() - timeOfLastDispatch; - if((dispatchCount < DISPATCH_THRESHOLD && duration >= getShortDispatchDelay()) || - duration >= getLongDispatchDelay()) { - return true; - } - synchronized(this) { - if(! isQueueEmpty() || ! wait) { - return false; - } - try { - wait(WAIT_DELAY); - } catch (InterruptedException e) { - // just continue - } - } - return isQueueEmpty(); - } - - /** - * Return the value that is used to determine how often - * the events are dispatched (i.e. how often the UI is - * updated) for the first 3 cycles. The default value is 1.5 seconds. - * After the first 3 cycles, a longer delay is used - * @return the dispatch delay used for the first 3 cycles. - */ - protected long getShortDispatchDelay() { - return DISPATCH_DELAY; - } - - /** - * Return the value that is used to determine how often - * the events are dispatched (i.e. how often the UI is - * updated) after the first 3 cycles. The default value is 10 seconds. - * @return the dispatch delay used after the first 3 cycles. - */ - protected long getLongDispatchDelay() { - return LONG_DISPATCH_DELAY; - } - - /** - * Handle the exception by recording it in the errors list. - * @param e - */ - protected void handleException(CoreException e) { - errors.handleException(e); - } - - /** - * Process the event in the context of a running background job. Subclasses may - * (but are not required to) check the provided monitor for cancelation and shut down the - * receiver by invoking the <code>shutdown()</code> method. - * <p> - * In many cases, a background event handler will translate incoming events into outgoing - * events. If this is the case, the handler should accumulate these events in the - * <code>proceessEvent</code> method and propogate them from the <code>dispatchEvent</code> - * method which is invoked periodically in order to batch outgoing events and avoid - * the UI becoming too jumpy. - * - * @param event the <code>Event</code> to be processed - * @param monitor a progress monitor - */ - protected abstract void processEvent(Event event, IProgressMonitor monitor) throws CoreException; - - /** - * Return the job from which the <code>processedEvent</code> method is invoked. - * @return Returns the background event handlig job. - */ - public Job getEventHandlerJob() { - return eventHandlerJob; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultFileModificationValidator.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultFileModificationValidator.java deleted file mode 100644 index 7979cb149..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultFileModificationValidator.java +++ /dev/null @@ -1,114 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; - -public class DefaultFileModificationValidator implements IFileModificationValidator { - - /* - * A validator plugged in the the Team UI that will prompt - * the user to make read-only files writtable. In the absense of - * this validator, edit/save fail on read-only files. - */ - private IFileModificationValidator uiValidator; - - private IStatus getDefaultStatus(IFile file) { - return - file.isReadOnly() - ? new Status(IStatus.ERROR, TeamPlugin.ID, IResourceStatus.READ_ONLY_LOCAL, Policy.bind("FileModificationValidator.fileIsReadOnly", file.getFullPath().toString()), null) //$NON-NLS-1$ - : Status.OK_STATUS; - } - - /** - * @see IFileModificationValidator#validateEdit(IFile[], Object) - */ - public IStatus validateEdit(IFile[] files, Object context) { - IFile[] readOnlyFiles = getReadOnly(files); - if (readOnlyFiles.length == 0) - return Status.OK_STATUS; - synchronized (this) { - if (uiValidator == null) - uiValidator = loadUIValidator(); - } - if (uiValidator != null) { - return uiValidator.validateEdit(files, context); - } - // There was no plugged in validator so fail gracefully - return getStatus(files); - } - - protected IStatus getStatus(IFile[] files) { - if (files.length == 1) { - return getDefaultStatus(files[0]); - } - - IStatus[] stati = new Status[files.length]; - boolean allOK = true; - - for (int i = 0; i < files.length; i++) { - stati[i] = getDefaultStatus(files[i]); - if(! stati[i].isOK()) - allOK = false; - } - - return new MultiStatus(TeamPlugin.ID, - 0, stati, - Policy.bind( - allOK - ? "FileModificationValidator.ok" //$NON-NLS-1$ - : "FileModificationValidator.someReadOnly" ), //$NON-NLS-1$ - null); - } - - private IFile[] getReadOnly(IFile[] files) { - List result = new ArrayList(files.length); - for (int i = 0; i < files.length; i++) { - IFile file = files[i]; - if (file.isReadOnly()) { - result.add(file); - } - } - return (IFile[]) result.toArray(new IFile[result.size()]); - } - - /** - * @see IFileModificationValidator#validateSave(IFile) - */ - public IStatus validateSave(IFile file) { - return getDefaultStatus(file); - } - - private IFileModificationValidator loadUIValidator() { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.DEFAULT_FILE_MODIFICATION_VALIDATOR_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - if (extensions.length > 0) { - IConfigurationElement[] configElements = extensions[0].getConfigurationElements(); - if (configElements.length > 0) { - try { - Object o = configElements[0].createExecutableExtension("class"); //$NON-NLS-1$ - if (o instanceof IFileModificationValidator) { - return (IFileModificationValidator)o; - } - } catch (CoreException e) { - TeamPlugin.log(e); - } - } - } - } - return null; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultMoveDeleteHook.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultMoveDeleteHook.java deleted file mode 100644 index 18dc39d63..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultMoveDeleteHook.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.team.IMoveDeleteHook; -import org.eclipse.core.resources.team.IResourceTree; -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * A class which provides the default behavior for resource deletions and moves. - * This class can be overridden by providers to change some or all of the behavior - * related to resources deletions or moves. - * - * @see org.eclipse.team.core.ResourceProvider#getMoveDeleteHook() - */ - -public class DefaultMoveDeleteHook implements IMoveDeleteHook { - - /** - * @see IMoveDeleteHook#deleteFile(IResourceTree, IFile, int, IProgressMonitor) - */ - public boolean deleteFile( - IResourceTree tree, - IFile file, - int updateFlags, - IProgressMonitor monitor) { - return false; - } - - /** - * @see IMoveDeleteHook#deleteFolder(IResourceTree, IFolder, int, IProgressMonitor) - */ - public boolean deleteFolder( - IResourceTree tree, - IFolder folder, - int updateFlags, - IProgressMonitor monitor) { - return false; - } - - /** - * @see IMoveDeleteHook#deleteProject(IResourceTree, IProject, int, IProgressMonitor) - */ - public boolean deleteProject( - IResourceTree tree, - IProject project, - int updateFlags, - IProgressMonitor monitor) { - return false; - } - - /** - * @see IMoveDeleteHook#moveFile(IResourceTree, IFile, IFile, int, IProgressMonitor) - */ - public boolean moveFile( - IResourceTree tree, - IFile source, - IFile destination, - int updateFlags, - IProgressMonitor monitor) { - return false; - } - - /** - * @see IMoveDeleteHook#moveFolder(IResourceTree, IFolder, IFolder, int, IProgressMonitor) - */ - public boolean moveFolder( - IResourceTree tree, - IFolder source, - IFolder destination, - int updateFlags, - IProgressMonitor monitor) { - return false; - } - - /** - * @see IMoveDeleteHook#moveProject(IResourceTree, IProject, IProjectDescription, int, IProgressMonitor) - */ - public boolean moveProject( - IResourceTree tree, - IProject source, - IProjectDescription description, - int updateFlags, - IProgressMonitor monitor) { - return false; - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultProjectSetCapability.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultProjectSetCapability.java deleted file mode 100644 index c29f6590f..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/DefaultProjectSetCapability.java +++ /dev/null @@ -1,26 +0,0 @@ -/********************************************************************** - Copyright (c) 2004 Dan Rubel and others. - All rights reserved. This program and the accompanying materials - are made available under the terms of the Common Public License v1.0 - which accompanies this distribution, and is available at - http://www.eclipse.org/legal/cpl-v10.html - - Contributors: - - Dan Rubel - initial API and implementation - - **********************************************************************/ - -package org.eclipse.team.internal.core; - -import org.eclipse.team.core.ProjectSetCapability; - -/** - * An internal class for backward compatibility with the - * {@link org.eclipse.team.core.IProjectSetSerializer} interface. - * - * @since 3.0 - */ -public class DefaultProjectSetCapability extends ProjectSetCapability { - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ExceptionCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ExceptionCollector.java deleted file mode 100644 index 8fb182356..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ExceptionCollector.java +++ /dev/null @@ -1,157 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.ILog; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.core.runtime.Status; - -/** - * Collects exceptions and can be configured to ignore duplicates exceptions. Exceptions can be logged - * and a MultiStatus containing all collected exceptions can be returned. - * - * @see org.eclipse.core.runtime.MultiStatus - * @see org.eclipse.core.runtime.IStatus - * - * @since 3.0 - */ -public class ExceptionCollector { - - private Map exceptionBucket = new HashMap(); - private List statuses = new ArrayList(); - private String message; - private String pluginId; - private int severity; - private ILog log; - private boolean ignoreDuplicates = false; - - /** - * Creates a collector and initializes the parameters for the top-level exception - * that would be returned from <code>getStatus</code> is exceptions are collected. - * - * @param message a human-readable message, localized to the current locale - * @param pluginId the unique identifier of the relevant plug-in - * @param severity the severity; one of <code>OK</code>, - * <code>ERROR</code>, <code>INFO</code>, or <code>WARNING</code> - * @param code the plug-in-specific status code, or <code>OK</code> - * @param log the log to output the exceptions to, or <code>null</code> if - * exceptions should not be logged. - */ - public ExceptionCollector(String message, String pluginId, int severity, ILog log) { - this.message = message; - this.pluginId = pluginId; - this.severity = severity; - this.log = log; - } - - /** - * Clears the exceptions collected. - */ - public void clear() { - statuses.clear(); - exceptionBucket.clear(); - } - - /** - * Returns a status that represents the exceptions collected. If the collector - * is empty <code>IStatus.OK</code> is returned. Otherwise a MultiStatus containing - * all collected exceptions is returned. - * @return a multistatus containing the exceptions collected or IStatus.OK if - * the collector is empty. - */ - public IStatus getStatus() { - if(statuses.isEmpty()) { - return Status.OK_STATUS; - } else { - MultiStatus multiStatus = new MultiStatus(pluginId, severity, message, null); - Iterator it = statuses.iterator(); - while (it.hasNext()) { - IStatus status = (IStatus) it.next(); - multiStatus.merge(status); - } - return multiStatus; - } - } - - /** - * Returns whether duplicate exceptions are being ignored. - * @return <code>true</code> if this collector is ignoring duplicate exceptions, and - * <code>false</code> otherwise. - */ - public boolean isIgnoreDuplicates() { - return ignoreDuplicates; - } - - /** - * Sets whether duplicate exceptions are being ignored. - * @param ignoreDuplicates <code>true</code> if this collector should ignore duplicate - * exceptions, and <code>false</code> otherwise. - */ - public void setIgnoreDuplicates(boolean ignoreDuplicates) { - this.ignoreDuplicates = ignoreDuplicates; - } - - /** - * Add this exception to the collector. If a log was specified in the constructor - * then the exception will be output to the log. You can retreive exceptions - * using <code>getStatus</code>. - * - * @param exception the exception to collect - */ - public void handleException(Exception e) { - IStatus status = null; - if(e instanceof CoreException) { - status = ((CoreException)e).getStatus(); - } - if(status != null) { - logStatus(status); - IStatus[] children = status.getChildren(); - for (int i = 0; i < children.length; i++) { - IStatus status2 = children[i]; - logStatus(status2); - } - } - } - - /** - * Log and accumulate exceptions once for each {plugid,code} combination. - */ - private void logStatus(IStatus status) { - String pluginId = status.getPlugin(); - List codes = (List)exceptionBucket.get(pluginId); - Integer code = new Integer(status.getCode()); - if(codes != null) { - if(codes.contains(code) && isIgnoreDuplicates()) { - return; - } - } - // collect the status - statuses.add(status); - - // update counts for this exception - codes = new ArrayList(1); - codes.add(code); - exceptionBucket.put(pluginId, codes); - - // log if necessary - if(log != null) { - log.log(new Status(status.getSeverity(), pluginId, status.getCode(), message, status.getException())); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/FileModificationValidatorManager.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/FileModificationValidatorManager.java deleted file mode 100644 index 1db832230..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/FileModificationValidatorManager.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - - -import java.util.*; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFileModificationValidator; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.team.core.RepositoryProvider; - -public class FileModificationValidatorManager implements IFileModificationValidator { - private IFileModificationValidator defaultValidator; - - /* - * @see IFileModificationValidator#validateEdit(IFile[], Object) - * For all files, determine which provider. - * Ask each provider once for its files. - * Collect the resulting status' and return a MultiStatus. - */ - public IStatus validateEdit(IFile[] files, Object context) { - ArrayList returnStati = new ArrayList(); - - //map provider to the files under that provider's control - Map providersToFiles = new HashMap(files.length); - - //for each file, determine which provider, map providers to files - for (int i = 0; i < files.length; i++) { - IFile file = files[i]; - RepositoryProvider provider = RepositoryProvider.getProvider(file.getProject()); - - if (!providersToFiles.containsKey(provider)) { - providersToFiles.put(provider, new ArrayList()); - } - - ((ArrayList)providersToFiles.get(provider)).add(file); - } - - Iterator providersIterator = providersToFiles.keySet().iterator(); - - boolean allOK = true; - - //for each provider, validate its files - while(providersIterator.hasNext()) { - RepositoryProvider provider = (RepositoryProvider)providersIterator.next(); - ArrayList filesList = (ArrayList)providersToFiles.get(provider); - IFile[] filesArray = (IFile[])filesList.toArray(new IFile[filesList.size()]); - IFileModificationValidator validator = getDefaultValidator(); - - //if no provider or no validator use the default validator - if (provider != null) { - IFileModificationValidator v = provider.getFileModificationValidator(); - if (v != null) validator = v; - } - - IStatus status = validator.validateEdit(filesArray, context); - if(!status.isOK()) - allOK = false; - - returnStati.add(status); - } - - if (returnStati.size() == 1) { - return (IStatus)returnStati.get(0); - } - - return new MultiStatus(TeamPlugin.ID, - 0, - (IStatus[])returnStati.toArray(new IStatus[returnStati.size()]), - Policy.bind( - allOK - ? "FileModificationValidator.ok" //$NON-NLS-1$ - : "FileModificationValidator.editFailed"), //$NON-NLS-1$ - null); //$NON-NLS-1$ - } - - /* - * @see IFileModificationValidator#validateSave(IFile) - */ - public IStatus validateSave(IFile file) { - RepositoryProvider provider = RepositoryProvider.getProvider(file.getProject()); - IFileModificationValidator validator = getDefaultValidator(); - - //if no provider or no validator use the default validator - if (provider != null) { - IFileModificationValidator v = provider.getFileModificationValidator(); - if (v != null) validator = v; - } - - return validator.validateSave(file); - } - - private synchronized IFileModificationValidator getDefaultValidator() { - if (defaultValidator == null) { - defaultValidator = new DefaultFileModificationValidator(); - } - return defaultValidator; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/IJobListener.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/IJobListener.java deleted file mode 100644 index b747d5be2..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/IJobListener.java +++ /dev/null @@ -1,26 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import org.eclipse.core.runtime.QualifiedName; - -/** - * This interface allows interested parties to receive notification - * when work has started or stopped for a given job type. The <code>started</code> - * method is invoked when the first job is started for the given <code>jobType</code>. - * The <code>finish</code> method is called when the last job of a given type stops. - * Several jobs for the job type may start and stop in the interum without causing - * notification to the listener. - */ -public interface IJobListener { - public void started(QualifiedName jobType); - public void finished(QualifiedName jobType); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/InfiniteSubProgressMonitor.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/InfiniteSubProgressMonitor.java deleted file mode 100644 index 2f6baacdc..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/InfiniteSubProgressMonitor.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; - -/** - * Provides an infinite progress monitor by subdividing by half repeatedly. - * - * The ticks parameter represents the number of ticks shown in the progress dialog - * (or propogated up to a parent IProgressMonitor). The totalWork parameter provided - * in actually a hint used to determine how work is translated into ticks. - * The number of totalWork that can actually be worked is n*totalWork/2 where - * 2^n = totalWork. What this means is that if you provide a totalWork of 32 (2^5) than - * the maximum number of ticks is 5*32/2 = 80. - * - */ -public class InfiniteSubProgressMonitor extends SubProgressMonitor { - - int totalWork; - int halfWay; - int currentIncrement; - int nextProgress; - int worked; - - /** - * Constructor for InfiniteSubProgressMonitor. - * @param monitor - * @param ticks - */ - public InfiniteSubProgressMonitor(IProgressMonitor monitor, int ticks) { - this(monitor, ticks, 0); - } - - /** - * Constructor for InfiniteSubProgressMonitor. - * @param monitor - * @param ticks - * @param style - */ - public InfiniteSubProgressMonitor(IProgressMonitor monitor, int ticks, int style) { - super(monitor, ticks, style); - } - - public void beginTask(String name, int totalWork) { - super.beginTask(name, totalWork); - this.totalWork = totalWork; - this.halfWay = totalWork / 2; - this.currentIncrement = 1; - this.nextProgress = currentIncrement; - this.worked = 0; - } - - public void worked(int work) { - if (worked >= totalWork) return; - if (--nextProgress <= 0) { - super.worked(1); - worked++; - if (worked >= halfWay) { - // we have passed the current halfway point, so double the - // increment and reset the halfway point. - currentIncrement *= 2; - halfWay += (totalWork - halfWay) / 2; - } - // reset the progress counter to another full increment - nextProgress = currentIncrement; - } - } - - /** - * Don't allow clearing of the subtask. This will stop the flickering - * of the subtask in the progress dialogs. - * - * @see IProgressMonitor#subTask(String) - */ - public void subTask(String name) { - if(name != null && ! name.equals("")) { //$NON-NLS-1$ - super.subTask(name); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/MoveDeleteManager.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/MoveDeleteManager.java deleted file mode 100644 index 694418e6b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/MoveDeleteManager.java +++ /dev/null @@ -1,116 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.team.IMoveDeleteHook; -import org.eclipse.core.resources.team.IResourceTree; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.RepositoryProvider; - -public class MoveDeleteManager implements IMoveDeleteHook { - - private static final IMoveDeleteHook DEFAULT_HOOK = new DefaultMoveDeleteHook(); - - private IMoveDeleteHook getHookFor(IResource resource) { - IProject project = resource.getProject(); - RepositoryProvider provider = RepositoryProvider.getProvider(project); - if(provider==null) { - return DEFAULT_HOOK; - } - IMoveDeleteHook hook = provider.getMoveDeleteHook(); - if (hook == null) { - return DEFAULT_HOOK; - } - return hook; - } - - /* - * @see IMoveDeleteHook#deleteFile(IResourceTree, IFile, int, IProgressMonitor) - */ - public boolean deleteFile( - IResourceTree tree, - IFile file, - int updateFlags, - IProgressMonitor monitor) { - - return getHookFor(file).deleteFile(tree, file, updateFlags, monitor); - } - - /* - * @see IMoveDeleteHook#deleteFolder(IResourceTree, IFolder, int, IProgressMonitor) - */ - public boolean deleteFolder( - IResourceTree tree, - IFolder folder, - int updateFlags, - IProgressMonitor monitor) { - - return getHookFor(folder).deleteFolder(tree, folder, updateFlags, monitor); - } - - /* - * @see IMoveDeleteHook#deleteProject(IResourceTree, IProject, int, IProgressMonitor) - */ - public boolean deleteProject( - IResourceTree tree, - IProject project, - int updateFlags, - IProgressMonitor monitor) { - - return getHookFor(project).deleteProject(tree, project, updateFlags, monitor); - } - - /* - * @see IMoveDeleteHook#moveFile(IResourceTree, IFile, IFile, int, IProgressMonitor) - */ - public boolean moveFile( - IResourceTree tree, - IFile source, - IFile destination, - int updateFlags, - IProgressMonitor monitor) { - - return getHookFor(source).moveFile(tree, source, destination, updateFlags, monitor); - } - - /* - * @see IMoveDeleteHook#moveFolder(IResourceTree, IFolder, IFolder, int, IProgressMonitor) - */ - public boolean moveFolder( - IResourceTree tree, - IFolder source, - IFolder destination, - int updateFlags, - IProgressMonitor monitor) { - - return getHookFor(source).moveFolder(tree, source, destination, updateFlags, monitor); - } - - /* - * @see IMoveDeleteHook#moveProject(IResourceTree, IProject, IProjectDescription, int, IProgressMonitor) - */ - public boolean moveProject( - IResourceTree tree, - IProject source, - IProjectDescription description, - int updateFlags, - IProgressMonitor monitor) { - - return getHookFor(source).moveProject(tree, source, description, updateFlags, monitor); - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/NullSubProgressMonitor.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/NullSubProgressMonitor.java deleted file mode 100644 index 50edd1a6a..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/NullSubProgressMonitor.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; - -/** - * This sub-progress monitor can be used to ignore progress indication for - * methods but allow cancellation. - * <p> - * This implementation supports cancelation. The default implementations of the - * other methods do nothing. - * </p> - * @see NullProgressMonitor - * @see SubProgressMonitor - */ -public class NullSubProgressMonitor extends SubProgressMonitor { - /** - * Constructor for InfiniteSubProgressMonitor. - * @param monitor - * @param ticks - */ - public NullSubProgressMonitor(IProgressMonitor monitor) { - super(monitor, 0, 0); - } - - /** - * @see IProgressMonitor#beginTask(String, int) - */ - public void beginTask(String name, int totalWork) { - } - - /** - * @see IProgressMonitor#done() - */ - public void done() { - } - - /** - * @see IProgressMonitor#internalWorked(double) - */ - public void internalWorked(double work) { - } - - /** - * @see IProgressMonitor#subTask(String) - */ - public void subTask(String name) { - } - - /** - * @see IProgressMonitor#worked(int) - */ - public void worked(int work) { - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/PessimisticResourceRuleFactory.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/PessimisticResourceRuleFactory.java deleted file mode 100644 index 67e4e4671..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/PessimisticResourceRuleFactory.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import org.eclipse.core.resources.*; -import org.eclipse.core.resources.team.ResourceRuleFactory; -import org.eclipse.core.runtime.jobs.ISchedulingRule; - -/** - * A pessimistic rule factory used to ensure older repository providers - * are not broken by new scheduling rule locking. The workspace root - * is returned for all rules. - */ -public class PessimisticResourceRuleFactory extends ResourceRuleFactory { - - IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); - - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceRuleFactory#copyRule(org.eclipse.core.resources.IResource, org.eclipse.core.resources.IResource) - */ - public ISchedulingRule copyRule(IResource source, IResource destination) { - return root; - } - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceRuleFactory#createRule(org.eclipse.core.resources.IResource) - */ - public ISchedulingRule createRule(IResource resource) { - return root; - } - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceRuleFactory#deleteRule(org.eclipse.core.resources.IResource) - */ - public ISchedulingRule deleteRule(IResource resource) { - return root; - } - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceRuleFactory#modifyRule(org.eclipse.core.resources.IResource) - */ - public ISchedulingRule modifyRule(IResource resource) { - return root; - } - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceRuleFactory#moveRule(org.eclipse.core.resources.IResource, org.eclipse.core.resources.IResource) - */ - public ISchedulingRule moveRule(IResource source, IResource destination) { - return root; - } - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceRuleFactory#refreshRule(org.eclipse.core.resources.IResource) - */ - public ISchedulingRule refreshRule(IResource resource) { - return root; - } - /* (non-Javadoc) - * @see org.eclipse.core.resources.IResourceRuleFactory#validateEditRule(org.eclipse.core.resources.IResource[]) - */ - public ISchedulingRule validateEditRule(IResource[] resources) { - return root; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Policy.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Policy.java deleted file mode 100644 index b52f9a262..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Policy.java +++ /dev/null @@ -1,117 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import java.text.MessageFormat; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -import org.eclipse.core.runtime.*; - -public class Policy { - protected static ResourceBundle bundle = null; - - //debug constants - public static boolean DEBUG_STREAMS = false; - public static boolean DEBUG_REFRESH_JOB = true; - public static boolean DEBUG_BACKGROUND_EVENTS = false; - public static boolean DEBUG_THREADING = false; - - static { - //init debug options - if (TeamPlugin.getPlugin().isDebugging()) { - DEBUG_STREAMS = "true".equalsIgnoreCase(Platform.getDebugOption(TeamPlugin.ID + "/streams"));//$NON-NLS-1$ //$NON-NLS-2$ - DEBUG_REFRESH_JOB = "true".equalsIgnoreCase(Platform.getDebugOption(TeamPlugin.ID + "/refreshjob"));//$NON-NLS-1$ //$NON-NLS-2$ - DEBUG_BACKGROUND_EVENTS = "true".equalsIgnoreCase(Platform.getDebugOption(TeamPlugin.ID + "/backgroundevents"));//$NON-NLS-1$ //$NON-NLS-2$ - DEBUG_THREADING = "true".equalsIgnoreCase(Platform.getDebugOption(TeamPlugin.ID + "/threading"));//$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /** - * Creates a NLS catalog for the given locale. - */ - public static void localize(String bundleName) { - bundle = ResourceBundle.getBundle(bundleName); - } - - /** - * Lookup the message with the given ID in this catalog and bind its - * substitution locations with the given string. - */ - public static String bind(String id, String binding) { - return bind(id, new String[] { binding }); - } - - /** - * Lookup the message with the given ID in this catalog and bind its - * substitution locations with the given strings. - */ - public static String bind(String id, String binding1, String binding2) { - return bind(id, new String[] { binding1, binding2 }); - } - - /** - * Gets a string from the resource bundle. We don't want to crash because of a missing String. - * Returns the key if not found. - */ - public static String bind(String key) { - try { - return bundle.getString(key); - } catch (MissingResourceException e) { - return key; - } catch (NullPointerException e) { - return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /** - * Gets a string from the resource bundle and binds it with the given arguments. If the key is - * not found, return the key. - */ - public static String bind(String key, Object[] args) { - try { - return MessageFormat.format(bind(key), args); - } catch (MissingResourceException e) { - return key; - } catch (NullPointerException e) { - return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /** - * Progress monitor helpers - */ - public static void checkCanceled(IProgressMonitor monitor) { - if (monitor != null && monitor.isCanceled()) - throw new OperationCanceledException(); - } - public static IProgressMonitor monitorFor(IProgressMonitor monitor) { - if (monitor == null) - return new NullProgressMonitor(); - return monitor; - } - - public static IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks) { - if (monitor == null) - return new NullProgressMonitor(); - if (monitor instanceof NullProgressMonitor) - return monitor; - return new SubProgressMonitor(monitor, ticks); - } - - public static IProgressMonitor infiniteSubMonitorFor(IProgressMonitor monitor, int ticks) { - if (monitor == null) - return new NullProgressMonitor(); - if (monitor instanceof NullProgressMonitor) - return monitor; - return new InfiniteSubProgressMonitor(monitor, ticks); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ResourceVariantCache.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ResourceVariantCache.java deleted file mode 100644 index 87d8a22e1..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ResourceVariantCache.java +++ /dev/null @@ -1,247 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.jobs.ILock; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.variants.CachedResourceVariant; - -/** - * This class implements a caching facility that can be used by TeamProviders to cache contents - */ -public class ResourceVariantCache { - - // Directory to cache file contents - private static final String CACHE_DIRECTORY = ".cache"; //$NON-NLS-1$ - // Maximum lifespan of local cache file, in milliseconds - private static final long CACHE_FILE_LIFESPAN = 60*60*1000; // 1hr - - // Map of registered cahces indexed by local name of a QualifiedName - private static Map caches = new HashMap(); // String (local name) > RemoteContentsCache - - private String name; - private Map cacheEntries; - private long lastCacheCleanup; - private int cacheDirSize; - - // Lock used to serialize the writting of cache contents - private ILock lock = Platform.getJobManager().newLock(); - - /** - * Enables the use of remote contents caching for the given cacheId. The cache ID must be unique. - * A good candidate for this ID is the plugin ID of the plugin peforming the caching. - * - * @param cacheId the unique Id of the cache being enabled - * @throws TeamException if the cache area on disk could not be properly initialized - */ - public static synchronized void enableCaching(String cacheId) { - if (isCachingEnabled(cacheId)) return; - ResourceVariantCache cache = new ResourceVariantCache(cacheId); - cache.createCacheDirectory(); - caches.put(cacheId, cache); - } - - /** - * Returns whether caching has been enabled for the given Id. A cache should only be enabled once. - * It is conceivable that a cache be persisted over workbench invocations thus leading to a cahce that - * is enabled on startup without intervention by the owning plugin. - * - * @param cacheId the unique Id of the cache - * @return true if caching for the given Id is enabled - */ - public static boolean isCachingEnabled(String cacheId) { - return getCache(cacheId) != null; - } - - /** - * Disable the cache, dispoing of any file contents in the cache. - * - * @param cacheId the unique Id of the cache - * @throws TeamException if the cached contents could not be deleted from disk - */ - public static void disableCache(String cacheId) { - ResourceVariantCache cache = getCache(cacheId); - if (cache == null) { - // There is no cache to dispose of - return; - } - caches.remove(cacheId); - cache.deleteCacheDirectory(); - } - - /** - * Return the cache for the given id or null if caching is not enabled for the given id. - * @param cacheId - * @return - */ - public static synchronized ResourceVariantCache getCache(String cacheId) { - return (ResourceVariantCache)caches.get(cacheId); - } - - public static synchronized void shutdown() { - for (Iterator iter = caches.keySet().iterator(); iter.hasNext();) { - String id = (String) iter.next(); - disableCache(id); - } - } - - private ResourceVariantCache(String name) { - this.name = name; - } - - /** - * Return whether the cache contains an entry for the given id. Register a hit if it does. - * @param id the id of the cache entry - * @return true if there are contents cached for the id - */ - public boolean hasEntry(String id) { - return internalGetCacheEntry(id) != null; - } - - protected IPath getCachePath() { - return getStateLocation().append(CACHE_DIRECTORY).append(name); - } - - private IPath getStateLocation() { - return TeamPlugin.getPlugin().getStateLocation(); - } - - private synchronized void clearOldCacheEntries() { - long current = new Date().getTime(); - if ((lastCacheCleanup!=-1) && (current - lastCacheCleanup < CACHE_FILE_LIFESPAN)) return; - List stale = new ArrayList(); - for (Iterator iter = cacheEntries.values().iterator(); iter.hasNext();) { - ResourceVariantCacheEntry entry = (ResourceVariantCacheEntry) iter.next(); - long lastHit = entry.getLastAccessTimeStamp(); - if ((current - lastHit) > CACHE_FILE_LIFESPAN){ - stale.add(entry); - } - } - for (Iterator iter = stale.iterator(); iter.hasNext();) { - ResourceVariantCacheEntry entry = (ResourceVariantCacheEntry) iter.next(); - entry.dispose(); - } - } - - private synchronized void purgeFromCache(String id) { - ResourceVariantCacheEntry entry = (ResourceVariantCacheEntry)cacheEntries.get(id); - File f = entry.getFile(); - try { - deleteFile(f); - } catch (TeamException e) { - // Ignore the deletion failure. - // A failure only really matters when purging the directory on startup - } - cacheEntries.remove(id); - } - - private synchronized void createCacheDirectory() { - IPath cacheLocation = getCachePath(); - File file = cacheLocation.toFile(); - if (file.exists()) { - try { - deleteFile(file); - } catch (TeamException e) { - // Check to see if were in an acceptable state - if (file.exists() && (!file.isDirectory() || file.listFiles().length != 0)) { - TeamPlugin.log(e); - } - } - } - if (! file.exists() && ! file.mkdirs()) { - TeamPlugin.log(new TeamException(Policy.bind("RemoteContentsCache.fileError", file.getAbsolutePath()))); //$NON-NLS-1$ - } - cacheEntries = new HashMap(); - lastCacheCleanup = -1; - cacheDirSize = 0; - } - - private synchronized void deleteCacheDirectory() { - cacheEntries = null; - lastCacheCleanup = -1; - cacheDirSize = 0; - IPath cacheLocation = getCachePath(); - File file = cacheLocation.toFile(); - if (file.exists()) { - try { - deleteFile(file); - } catch (TeamException e) { - // Don't worry about problems deleting. - // The only case that matters is when the cache directory is created - } - } - } - - private void deleteFile(File file) throws TeamException { - if (file.isDirectory()) { - File[] children = file.listFiles(); - for (int i = 0; i < children.length; i++) { - deleteFile(children[i]); - } - } - if (! file.delete()) { - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", file.getAbsolutePath())); //$NON-NLS-1$ - } - } - - /** - * Purge the given cache entry from the cache. This method should only be invoked from - * an instance of ResourceVariantCacheEntry after it has set it's state to DISPOSED. - * @param entry - */ - protected void purgeFromCache(ResourceVariantCacheEntry entry) { - purgeFromCache(entry.getId()); - } - - private synchronized ResourceVariantCacheEntry internalGetCacheEntry(String id) { - if (cacheEntries == null) { - // This probably means that the cache has been disposed - throw new IllegalStateException(Policy.bind("RemoteContentsCache.cacheDisposed", name)); //$NON-NLS-1$ - } - ResourceVariantCacheEntry entry = (ResourceVariantCacheEntry)cacheEntries.get(id); - if (entry != null) { - entry.registerHit(); - } - return entry; - } - - /** - * @param id the id that uniquely identifes the remote resource that is cached. - * @return - */ - public ResourceVariantCacheEntry getCacheEntry(String id) { - return internalGetCacheEntry(id); - } - - public synchronized ResourceVariantCacheEntry add(String id, CachedResourceVariant resource) { - clearOldCacheEntries(); - String filePath = String.valueOf(cacheDirSize++); - ResourceVariantCacheEntry entry = new ResourceVariantCacheEntry(this, lock, id, filePath); - entry.setResourceVariant(resource); - cacheEntries.put(id, entry); - return entry; - } - - public String getName() { - return name; - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ResourceVariantCacheEntry.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ResourceVariantCacheEntry.java deleted file mode 100644 index 1b94be663..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/ResourceVariantCacheEntry.java +++ /dev/null @@ -1,216 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import java.io.*; -import java.util.Date; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.jobs.ILock; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.variants.CachedResourceVariant; - -/** - * This class provides the implementation for the ICacheEntry - */ -public class ResourceVariantCacheEntry { - - public static final int UNINITIALIZED = 0; - public static final int READY = 1; - public static final int DISPOSED = 2; - - private String id; - private String filePath; - private ResourceVariantCache cache; - private int state = UNINITIALIZED; - private long lastAccess; - private CachedResourceVariant resourceVariant; - private ILock lock; - - public ResourceVariantCacheEntry(ResourceVariantCache cache, ILock lock, String id, String filePath) { - this.lock = lock; - state = UNINITIALIZED; - this.cache = cache; - this.id = id; - this.filePath = filePath; - registerHit(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getContents() - */ - public InputStream getContents() throws TeamException { - if (state != READY) return null; - registerHit(); - File ioFile = getFile(); - try { - try { - if (ioFile.exists()) { - return new FileInputStream(ioFile); - } - } catch (IOException e) { - // Try to purge the cache and continue - cache.purgeFromCache(this); - throw e; - } - } catch (IOException e) { - // We will end up here if we couldn't read or delete the cache file - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", ioFile.getAbsolutePath()), e); //$NON-NLS-1$ - } - // This can occur when there is no remote contents - return new ByteArrayInputStream(new byte[0]); - } - - protected File getFile() { - return new File(cache.getCachePath().toFile(), filePath); - } - - /** - * Set the contents of for this cache entry. This method supports concurrency by only allowing - * one cache entry to be written at a time. In the case of two concurrent writes to the same cache entry, - * the contents from the first write is used and the content from subsequent writes is ignored. - * @param stream an InputStream that provides the contents to be cached - * @param monitor a progress monitor - * @throws TeamException if the entry is DISPOSED or an I/O error occurres - */ - public void setContents(InputStream stream, IProgressMonitor monitor) throws TeamException { - // Use a lock to only allow one write at a time - beginOperation(); - try { - internalSetContents(stream, monitor); - } finally { - endOperation(); - } - } - - private void endOperation() { - lock.release(); - } - - private void beginOperation() { - lock.acquire(); - } - - private void internalSetContents(InputStream stream, IProgressMonitor monitor) throws TeamException { - // if the state is DISPOSED then there is a problem - if (state == DISPOSED) { - throw new TeamException(Policy.bind("RemoteContentsCacheEntry.3", cache.getName(), id)); //$NON-NLS-1$ - } - // Otherwise, the state is UNINITIALIZED or READY so we can proceed - registerHit(); - File ioFile = getFile(); - try { - - // Open the cache file for writing - OutputStream out; - try { - if (state == UNINITIALIZED) { - out = new BufferedOutputStream(new FileOutputStream(ioFile)); - } else { - // If the entry is READY, the contents must have been read in another thread. - // We still need to red the contents but they can be ignored since presumably they are the same - out = new ByteArrayOutputStream(); - } - } catch (FileNotFoundException e) { - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", ioFile.getAbsolutePath()), e); //$NON-NLS-1$ - } - - // Transfer the contents - try { - try { - byte[] buffer = new byte[1024]; - int read; - while ((read = stream.read(buffer)) >= 0) { - Policy.checkCanceled(monitor); - out.write(buffer, 0, read); - } - } finally { - out.close(); - } - } catch (IOException e) { - // Make sure we don't leave the cache file around as it may not have the right contents - cache.purgeFromCache(this); - throw e; - } - - // Mark the cache entry as ready - state = READY; - } catch (IOException e) { - throw new TeamException(Policy.bind("RemoteContentsCache.fileError", ioFile.getAbsolutePath()), e); //$NON-NLS-1$ - } finally { - try { - stream.close(); - } catch (IOException e1) { - // Ignore close errors - } - } - - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getState() - */ - public int getState() { - return state; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getSize() - */ - public long getSize() { - if (state != READY) return 0; - File ioFile = getFile(); - if (ioFile.exists()) { - return ioFile.length(); - } - return 0; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ICacheEntry#getLastAccessTimeStamp() - */ - public long getLastAccessTimeStamp() { - return lastAccess; - } - - /** - * Registers a hit on this cache entry. This updates the last access timestamp. - * Thsi method is intended to only be invokded from inside this class or the cahce itself. - * Other clients should not use it. - */ - protected void registerHit() { - lastAccess = new Date().getTime(); - } - - public void dispose() { - // Use a lock to avoid changing state while another thread may be writting - beginOperation(); - try { - state = DISPOSED; - cache.purgeFromCache(this); - } finally { - endOperation(); - } - } - - - public String getId() { - return id; - } - - public CachedResourceVariant getResourceVariant() { - return resourceVariant; - } - - public void setResourceVariant(CachedResourceVariant resourceVariant) { - this.resourceVariant = resourceVariant; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Sorter.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Sorter.java deleted file mode 100644 index c1689dd8b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/Sorter.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -/** - * The SortOperation takes a collection of objects and returns - * a sorted collection of these objects. Concrete instances of this - * class provide the criteria for the sorting of the objects based on - * the type of the objects. - */ -public abstract class Sorter { - /** - * Returns true is elementTwo is 'greater than' elementOne - * This is the 'ordering' method of the sort operation. - * Each subclass overides this method with the particular - * implementation of the 'greater than' concept for the - * objects being sorted. - */ - public abstract boolean compare(Object elementOne, Object elementTwo); - /** - * Sort the objects in sorted collection and return that collection. - */ - private Object[] quickSort(Object[] sortedCollection, int left, int right) { - int originalLeft = left; - int originalRight = right; - Object mid = sortedCollection[ (left + right) / 2]; - do { - while (compare(sortedCollection[left], mid)) - left++; - while (compare(mid, sortedCollection[right])) - right--; - if (left <= right) { - Object tmp = sortedCollection[left]; - sortedCollection[left] = sortedCollection[right]; - sortedCollection[right] = tmp; - left++; - right--; - } - } while (left <= right); - if (originalLeft < right) - sortedCollection = quickSort(sortedCollection, originalLeft, right); - if (left < originalRight) - sortedCollection = quickSort(sortedCollection, left, originalRight); - return sortedCollection; - } - /** - * Return a new sorted collection from this unsorted collection. - * Sort using quick sort. - */ - public Object[] sort(Object[] unSortedCollection) { - int size = unSortedCollection.length; - Object[] sortedCollection = new Object[size]; - //copy the array so can return a new sorted collection - System.arraycopy(unSortedCollection, 0, sortedCollection, 0, size); - if (size > 1) - quickSort(sortedCollection, 0, size - 1); - return sortedCollection; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/StringMatcher.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/StringMatcher.java deleted file mode 100644 index 5262fedaf..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/StringMatcher.java +++ /dev/null @@ -1,398 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - - -import java.util.*; - -/** - * A string pattern matcher, suppporting * and ? wildcards. - * Note: code copied from org.eclipse.jdt.internal.core.util.StringMatcher on April 3, 2001 - * (version 0.1 - 010901H18 [rename jbl]). - */ -public class StringMatcher { - protected String fPattern; - protected int fLength; // pattern length - protected boolean fIgnoreWildCards; - protected boolean fIgnoreCase; - protected boolean fHasLeadingStar; - protected boolean fHasTrailingStar; - protected String fSegments[]; //the given pattern is split into * separated segments - - /* boundary value beyond which we don't need to search in the text */ - protected int fBound = 0; - - - protected static final char fSingleWildCard = '\u0000'; - - public static class Position { - int start; //inclusive - int end; //exclusive - public Position(int start, int end) { - this.start = start; - this.end = end; - } - public int getStart() { - return start; - } - public int getEnd() { - return end; - } - } - /** - * Find the first occurrence of the pattern between <code>start</code)(inclusive) - * and <code>end</code>(exclusive). - * @param <code>text</code>, the String object to search in - * @param <code>start</code>, the starting index of the search range, inclusive - * @param <code>end</code>, the ending index of the search range, exclusive - * @return an <code>StringMatcher.Position</code> object that keeps the starting - * (inclusive) and ending positions (exclusive) of the first occurrence of the - * pattern in the specified range of the text; return null if not found or subtext - * is empty (start==end). A pair of zeros is returned if pattern is empty string - * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc" - * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned - */ - - public StringMatcher.Position find(String text, int start, int end) { - if (fPattern == null|| text == null) - throw new IllegalArgumentException(); - - int tlen = text.length(); - if (start < 0) - start = 0; - if (end > tlen) - end = tlen; - if (end < 0 ||start >= end ) - return null; - if (fLength == 0) - return new Position(start, start); - if (fIgnoreWildCards) { - int x = posIn(text, start, end); - if (x < 0) - return null; - return new Position(x, x+fLength); - } - - int segCount = fSegments.length; - if (segCount == 0)//pattern contains only '*'(s) - return new Position (start, end); - - int curPos = start; - int matchStart = -1; - int i; - for (i = 0; i < segCount && curPos < end; ++i) { - String current = fSegments[i]; - int nextMatch = regExpPosIn(text, curPos, end, current); - if (nextMatch < 0 ) - return null; - if(i == 0) - matchStart = nextMatch; - curPos = nextMatch + current.length(); - } - if (i < segCount) - return null; - return new Position(matchStart, curPos); - } - /** - * StringMatcher constructor takes in a String object that is a simple - * pattern which may contain '*' for 0 and many characters and - * '?' for exactly one character. - * - * Literal '*' and '?' characters must be escaped in the pattern - * e.g., "\*" means literal "*", etc. - * - * Escaping any other character (including the escape character itself), - * just results in that character in the pattern. - * e.g., "\a" means "a" and "\\" means "\" - * - * If invoking the StringMatcher with string literals in Java, don't forget - * escape characters are represented by "\\". - * - * @param aPattern the pattern to match text with - * @param ignoreCase if true, case is ignored - * @param ignoreWildCards if true, wild cards and their escape sequences are ignored - * (everything is taken literally). - */ - public StringMatcher(String aPattern, boolean ignoreCase, boolean ignoreWildCards) { - fIgnoreCase = ignoreCase; - fIgnoreWildCards = ignoreWildCards; - fLength = aPattern.length(); - - /* convert case */ - if (fIgnoreCase) { - fPattern = aPattern.toUpperCase(); - } else { - fPattern = aPattern; - } - - if (fIgnoreWildCards) { - parseNoWildCards(); - } else { - parseWildCards(); - } - } - /** - * Given the starting (inclusive) and the ending (exclusive) poisitions in the - * <code>text</code>, determine if the given substring matches with aPattern - * @return true if the specified portion of the text matches the pattern - * @param String <code>text</code>, a String object that contains the substring to match - * @param int <code>start<code> marks the starting position (inclusive) of the substring - * @param int <code>end<code> marks the ending index (exclusive) of the substring - */ - public boolean match(String text, int start, int end) { - if (null == text) - throw new IllegalArgumentException(); - - if (start > end) - return false; - - if (fIgnoreWildCards) - return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength); - int segCount= fSegments.length; - if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s) - return true; - if (start == end) - return fLength == 0; - if (fLength == 0) - return start == end; - - int tlen= text.length(); - if (start < 0) - start= 0; - if (end > tlen) - end= tlen; - - int tCurPos= start; - int bound= end - fBound; - if ( bound < 0) - return false; - int i=0; - String current= fSegments[i]; - int segLength= current.length(); - - /* process first segment */ - if (!fHasLeadingStar){ - if(!regExpRegionMatches(text, start, current, 0, segLength)) { - return false; - } else { - ++i; - tCurPos= tCurPos + segLength; - } - } - if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) { - // only one segment to match, no wildcards specified - return tCurPos == end; - } - /* process middle segments */ - while (i < segCount) { - current= fSegments[i]; - int currentMatch; - int k= current.indexOf(fSingleWildCard); - if (k < 0) { - currentMatch= textPosIn(text, tCurPos, end, current); - if (currentMatch < 0) - return false; - } else { - currentMatch= regExpPosIn(text, tCurPos, end, current); - if (currentMatch < 0) - return false; - } - tCurPos= currentMatch + current.length(); - i++; - } - - /* process final segment */ - if (!fHasTrailingStar && tCurPos != end) { - int clen= current.length(); - return regExpRegionMatches(text, end - clen, current, 0, clen); - } - return i == segCount ; - } - /** - * match the given <code>text</code> with the pattern - * @return true if matched eitherwise false - * @param <code>text</code>, a String object - */ - public boolean match(String text) { - return match(text, 0, text.length()); - } - /** - * This method parses the given pattern into segments seperated by wildcard '*' characters. - * Since wildcards are not being used in this case, the pattern consists of a single segment. - */ - private void parseNoWildCards() { - fSegments = new String[1]; - fSegments[0] = fPattern; - fBound = fLength; - } - /** - * This method parses the given pattern into segments seperated by wildcard '*' characters. - * @param p, a String object that is a simple regular expression with '*' and/or '?' - */ - private void parseWildCards() { - if(fPattern.startsWith("*"))//$NON-NLS-1$ - fHasLeadingStar = true; - if(fPattern.endsWith("*")) {//$NON-NLS-1$ - /* make sure it's not an escaped wildcard */ - if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') { - fHasTrailingStar = true; - } - } - - Vector temp = new Vector(); - - int pos = 0; - StringBuffer buf = new StringBuffer(); - while (pos < fLength) { - char c = fPattern.charAt(pos++); - switch (c) { - case '\\': - if (pos >= fLength) { - buf.append(c); - } else { - char next = fPattern.charAt(pos++); - /* if it's an escape sequence */ - if (next == '*' || next == '?' || next == '\\') { - buf.append(next); - } else { - /* not an escape sequence, just insert literally */ - buf.append(c); - buf.append(next); - } - } - break; - case '*': - if (buf.length() > 0) { - /* new segment */ - temp.addElement(buf.toString()); - fBound += buf.length(); - buf.setLength(0); - } - break; - case '?': - /* append special character representing single match wildcard */ - buf.append(fSingleWildCard); - break; - default: - buf.append(c); - } - } - - /* add last buffer to segment list */ - if (buf.length() > 0) { - temp.addElement(buf.toString()); - fBound += buf.length(); - } - - fSegments = new String[temp.size()]; - temp.copyInto(fSegments); - } - /** - * @param <code>text</code>, a string which contains no wildcard - * @param <code>start</code>, the starting index in the text for search, inclusive - * @param <code>end</code>, the stopping point of search, exclusive - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int posIn(String text, int start, int end) {//no wild card in pattern - int max = end - fLength; - - if (!fIgnoreCase) { - int i = text.indexOf(fPattern, start); - if (i == -1 || i > max) - return -1; - return i; - } - - for (int i = start; i <= max; ++i) { - if (text.regionMatches(true, i, fPattern, 0, fLength)) - return i; - } - - return -1; - } - /** - * @param <code>text</code>, a simple regular expression that may only contain '?'(s) - * @param <code>start</code>, the starting index in the text for search, inclusive - * @param <code>end</code>, the stopping point of search, exclusive - * @param <code>p</code>, a simple regular expression that may contains '?' - * @param <code>caseIgnored</code>, wether the pattern is not casesensitive - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int regExpPosIn(String text, int start, int end, String p) { - int plen = p.length(); - - int max = end - plen; - for (int i = start; i <= max; ++i) { - if (regExpRegionMatches(text, i, p, 0, plen)) - return i; - } - return -1; - } - /** - * - * @return boolean - * @param <code>text</code>, a String to match - * @param <code>start</code>, int that indicates the starting index of match, inclusive - * @param <code>end</code> int that indicates the ending index of match, exclusive - * @param <code>p</code>, String, String, a simple regular expression that may contain '?' - * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive - */ - protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) { - while (plen-- > 0) { - char tchar = text.charAt(tStart++); - char pchar = p.charAt(pStart++); - - /* process wild cards */ - if (!fIgnoreWildCards) { - /* skip single wild cards */ - if (pchar == fSingleWildCard) { - continue; - } - } - if (pchar == tchar) - continue; - if (fIgnoreCase) { - char tc = Character.toUpperCase(tchar); - if (tc == pchar) - continue; - } - return false; - } - return true; - } - /** - * @param <code>text</code>, the string to match - * @param <code>start</code>, the starting index in the text for search, inclusive - * @param <code>end</code>, the stopping point of search, exclusive - * @param code>p</code>, a string that has no wildcard - * @param <code>ignoreCase</code>, boolean indicating wether code>p</code> is case sensitive - * @return the starting index in the text of the pattern , or -1 if not found - */ - protected int textPosIn(String text, int start, int end, String p) { - - int plen = p.length(); - int max = end - plen; - - if (!fIgnoreCase) { - int i = text.indexOf(p, start); - if (i == -1 || i > max) - return -1; - return i; - } - - for (int i = start; i <= max; ++i) { - if (text.regionMatches(true, i, p, 0, plen)) - return i; - } - - return -1; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/TeamHookDispatcher.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/TeamHookDispatcher.java deleted file mode 100644 index 843ef4ac2..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/TeamHookDispatcher.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import org.eclipse.core.resources.*; -import org.eclipse.core.resources.team.ResourceRuleFactory; -import org.eclipse.core.resources.team.TeamHook; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.team.core.RepositoryProvider; - -/** - * This class forwards TeamHook callbacks to the proper RepositoryProvider - */ -public class TeamHookDispatcher extends TeamHook { - - private static final ResourceRuleFactory defaultFactory = new ResourceRuleFactory() {}; - private static TeamHookDispatcher instance; - - public static void setProviderRuleFactory(IProject project, IResourceRuleFactory factory) { - if (instance != null) { - if (factory == null) { - factory = defaultFactory; - } - instance.setRuleFactory(project, factory); - } - } - - public TeamHookDispatcher() { - instance = this; - } - - /** - * @see org.eclipse.core.resources.team.TeamHook#validateCreateLink(org.eclipse.core.resources.IFile, int, org.eclipse.core.runtime.IPath) - */ - public IStatus validateCreateLink(IFile file, int updateFlags, IPath location) { - RepositoryProvider provider = getProvider(file); - if (provider == null) { - return super.validateCreateLink(file, updateFlags, location); - } else { - return provider.validateCreateLink(file, updateFlags, location); - } - } - - /** - * @see org.eclipse.core.resources.team.TeamHook#validateCreateLink(org.eclipse.core.resources.IFolder, int, org.eclipse.core.runtime.IPath) - */ - public IStatus validateCreateLink(IFolder folder, int updateFlags, IPath location) { - RepositoryProvider provider = getProvider(folder); - if (provider == null) { - return super.validateCreateLink(folder, updateFlags, location); - } else { - return provider.validateCreateLink(folder, updateFlags, location); - } - } - - /** - * Method getProvider. - * @param folder - * @return RepositoryProvider - */ - private RepositoryProvider getProvider(IResource resource) { - return RepositoryProvider.getProvider(resource.getProject()); - } - - /* (non-Javadoc) - * @see org.eclipse.core.resources.team.TeamHook#getRuleFactory(org.eclipse.core.resources.IProject) - */ - public IResourceRuleFactory getRuleFactory(IProject project) { - if (RepositoryProvider.isShared(project)) { - RepositoryProvider provider = getProvider(project); - // Provider can be null if the provider plugin is not available - if (provider != null) { - return provider.getRuleFactory(); - } - } - // Use the default provided by the superclass - return super.getRuleFactory(project); - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/TeamPlugin.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/TeamPlugin.java deleted file mode 100644 index a5fa77c7b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/TeamPlugin.java +++ /dev/null @@ -1,161 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core; - -import java.io.IOException; -import java.io.InputStream; - -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.content.IContentDescription; -import org.eclipse.core.runtime.content.IContentTypeManager; -import org.eclipse.team.core.*; -import org.osgi.framework.BundleContext; - -/** - * <code>TeamPlugin</code> is the plug-in runtime class for the Team - * resource management plugin. - * <p> - * - * @see Team - * @see RepositoryProvider - * - * @since 2.0 - */ -final public class TeamPlugin extends Plugin { - - // The id of the core team plug-in - public static final String ID = "org.eclipse.team.core"; //$NON-NLS-1$ - - // The id of the providers extension point - public static final String PROVIDER_EXTENSION = "repository-provider-type"; //$NON-NLS-1$ - - // The id of the file types extension point - public static final String FILE_TYPES_EXTENSION = "fileTypes"; //$NON-NLS-1$ - - // The id of the global ignore extension point - public static final String IGNORE_EXTENSION = "ignore"; //$NON-NLS-1$ - // The id of the project set extension point - public static final String PROJECT_SET_EXTENSION = "projectSets"; //$NON-NLS-1$ - // The id of the repository extension point - public static final String REPOSITORY_EXTENSION = "repository"; //$NON-NLS-1$ - // The id of the default file modification vaidator extension point - public static final String DEFAULT_FILE_MODIFICATION_VALIDATOR_EXTENSION = "defaultFileModificationValidator"; //$NON-NLS-1$ - - - // The one and only plug-in instance - private static TeamPlugin plugin; - - /** - * Constructs a plug-in runtime class. - */ - public TeamPlugin() { - super(); - plugin = this; - } - - /** - * @see Plugin#start(BundleContext) - */ - public void start(BundleContext context) throws Exception { - super.start(context); - Policy.localize("org.eclipse.team.internal.core.messages"); //$NON-NLS-1$ - Team.startup(); - } - - /** - * @see Plugin#stop(BundleContext) - */ - public void stop(BundleContext context) throws Exception { - try { - Team.shutdown(); - ResourceVariantCache.shutdown(); - } finally { - super.stop(context); - } - } - - /** - * Returns the Team plug-in. - * - * @return the single instance of this plug-in runtime class - */ - public static TeamPlugin getPlugin() { - return plugin; - } - - /** - * Log the given exception alloing with the provided message and severity indicator - */ - public static void log(int severity, String message, Throwable e) { - plugin.getLog().log(new Status(severity, ID, 0, message, e)); - } - - /** - * Log the given CoreException in a manner that will include the stacktrace of - * the exception in the log. - */ - public static void log(CoreException e) { - log(e.getStatus().getSeverity(), e.getMessage(), e); - } - - /* - * Static helper methods for creating exceptions - */ - public static TeamException wrapException(Exception e) { - return new TeamException(new Status(IStatus.ERROR, ID, 0, e.getMessage() != null ? e.getMessage() : "", e)); //$NON-NLS-1$ - } - - public static TeamException wrapException(CoreException e) { - IStatus status = e.getStatus(); - return new TeamException(new Status(status.getSeverity(), ID, status.getCode(), status.getMessage(), e)); - } - - public static String getCharset(String name, InputStream stream) throws IOException { - IContentDescription description = getContentDescription(name, stream); - return description == null ? null : description.getCharset(); - - } - public static IContentDescription getContentDescription(String name, InputStream stream) throws IOException { - // tries to obtain a description for this file contents - IContentTypeManager contentTypeManager = Platform.getContentTypeManager(); - try { - return contentTypeManager.getDescriptionFor(stream, name, IContentDescription.ALL); - } finally { - if (stream != null) - try { - stream.close(); - } catch (IOException e) { - // Ignore exceptions on close - } - } - } - - public static RepositoryProviderType getAliasType(String id) { - IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(TeamPlugin.ID, TeamPlugin.REPOSITORY_EXTENSION); - if (extension != null) { - IExtension[] extensions = extension.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - IConfigurationElement [] configElements = extensions[i].getConfigurationElements(); - for (int j = 0; j < configElements.length; j++) { - String aliasId = configElements[j].getAttribute("canImportId"); //$NON-NLS-1$ - if (aliasId != null && aliasId.equals(id)) { - String extensionId = configElements[j].getAttribute("id"); //$NON-NLS-1$ - if (extensionId != null) { - return RepositoryProviderType.getProviderType(extensionId); - } - } - } - } - } - return null; - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/messages.properties b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/messages.properties deleted file mode 100644 index 22dfa1eb2..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/messages.properties +++ /dev/null @@ -1,126 +0,0 @@ -############################################################################### -# Copyright (c) 2000, 2004 IBM Corporation and others. -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Common Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/cpl-v10.html -# -# Contributors: -# IBM Corporation - initial API and implementation -############################################################################### -ok=OK -concatStrings={0} {1} - -Assert.assertionFailed=Assertion failed: {0} - -manager.providerAlreadyMapped=Error associating {0} with provider named {1}. The project is already associated with a provider. -manager.errorFlushSync=Error flushing provider mapping information for {0}. -manager.errorDeconfigure=Error deconfiguring provider named {0} from project {1}. -manager.providerTypeInvalid=The provider type is not registered: {0}. -manager.providerExtensionNotFound=TeamPlugin provider extension not found. -manager.providerNoConfigElems=No configuration elements found for extension: {0}. -manager.cannotInstantiateExt=Cannot instantiate extension: {0}. -manager.errorSerialize=Error serializing provider mappings for {0}. -manager.errorUnserializeProvider=Cannot unserialize association of {0} with provider of type: {1}. It is no longer a registered provider type. -manager.errorUnserialize=Error un-serializing provider mappings {0}. -manager.notTeamNature=Error setting nature: {0} is not a registered team nature. -manager.errorSettingNature=Error setting nature {1} on project {0}. -manager.errorRemovingNature=Error removing nature {1} on project {0}. - -manager.badClassType=Error creating validator decorator: bad class type -manager.coreException=Error creating validator decorator: core exception - -FileModificationValidator.someReadOnly=Some files are read-only. -FileModificationValidator.fileIsReadOnly=File {0} is read-only. -FileModificationValidator.editFailed=Files are read-only. - -RepositoryProvider_Error_removing_nature_from_project___1=Error removing nature from project: -RepositoryProvider_Too_many_providers_associated_with_project___2=Too many providers associated with project: -RepositoryProviderTypeduplicate_provider_found_in_plugin.xml___1=duplicate provider found in plugin.xml: -RepositoryProviderTypeRepositoryProvider_assigned_to_the_project_must_be_a_subclass_of_RepositoryProvider___2=RepositoryProvider assigned to the project must be a subclass of RepositoryProvider: -RepositoryProviderTypeRepositoryProvider_not_registered_as_a_nature_id___3=RepositoryProvider not registered as a nature id: {0}. -RepositoryProvider_providerTypeIdNotRegistered=Error configuring the RepositoryProvider the nature id is not registered as a valid RepositoryProviderType id. -RepositoryProvider.couldNotInstantiateProvider=Could not instantiate provider {1} for project {0}. -RepositoryProvider.No_Provider_Registered=No provider registered for {0}. -RepositoryProvider.propertyMismatch=Inconsistent session/persistent property state looking up provider {1}. -RepositoryProvider.linkedResourcesExist=Project ''{0}'' contains linked resources but the''{1}'' repository provider does not supported them. -RepositoryProvider.linkedResourcesNotSupported=Project ''{0}'' is mapped to repository type ''{1}'' which does not support linked resources. -RepositoryProvider.couldNotClearAfterError=A serious error has occurred trying to map project ''{0}'' to provider ''{1}''. Please restart Eclipse. -RepositoryProvider.invalidClass=Class ''{1}'' registered for id ''{0}'' is not a subclass of RepositoryProvider. - -TeamPlugin_setting_global_ignore_7=setting global ignore - -Team.couldNotDelete=Could not delete previous state file ''{0}''. -Team.couldNotRename=Could not rename new state file from ''{0}'' to ''{1}''. -Team.writeError=An error occurred writing the state file ''{0}''. -Team.readError=An error occurred reading the state file ''{0}'' -Team.Could_not_delete_state_file_1=Could not delete state file -Team.Could_not_rename_state_file_2=Could not rename state file - -PollingInputStream.readTimeout=Timeout while reading from input stream -PollingInputStream.closeTimeout=Timeout while closing input stream -PollingOutputStream.writeTimeout=Timeout while writing to output stream -PollingOutputStream.closeTimeout=Timeout while closing output stream -TimeoutOutputStream.cannotWriteToStream=Cannot write to output stream - -Config.error=Error configuring the provider - -teamStatus.notCheckedOut=Not checked out. -teamStatus.notCheckedIn=Not checked in. -teamStatus.unmanagedResource=Unmanaged resource. -teamStatus.noRemoteResource=Remote resource does not exist. -teamStatus.ioFailed=An IO error occurred. -teamStatus.conflict=A conflict occurred. - -multiStatus.errorsOccurred=Errors occurred. -provider.configuration.missing=Required configuration value missing. -provider.configuration.invalid=Configuration value is invalid. -filetransfer.monitor={0} ({1}K of {2}K bytes) - -SynchronizedTargetProvider.invalidURLCombination=Could not form a valid URL from {0} and {1} - -RemoteSyncElement.delimit=[{0}] -RemoteSyncElement.insync=in-sync -RemoteSyncElement.conflicting=conflicting -RemoteSyncElement.outgoing=outgoing -RemoteSyncElement.incoming=incoming -RemoteSyncElement.change=change -RemoteSyncElement.addition=addition -RemoteSyncElement.deletion=deletion -RemoteSyncElement.manual={manual} -RemoteSyncElement.auto={auto} - -Team.Error_loading_ignore_state_from_disk_1=Error loading ignore state from disk - -RemoteContentsCache.cacheNotEnabled=The cache for {0} is not enabled. -RemoteContentsCache.cacheDisposed=The cache for {0} is disposed. -RemoteContentsCache.fileError=An I/O error performing an operation on {0}. -TeamProvider.10=Error restoring subscribers. Cannot find factory with id: {0} -TeamProvider.11=Error saving subscribers. Cannot find factory with id: {0} -ContentComparisonCriteria.2=Comparing content {0} -ContentComparisonCriteria.3=\ ignoring whitespace - -SubscriberEventHandler.2=Updating {0}. -SubscriberEventHandler.jobName=Updating {0}. -SubscriberChangeSetCollector.0=An error occurred while reconciling change sets. Restarting the application is recommended. -SubscriberChangeSetCollector.1=Updating Change Sets for {0} -SubscriberChangeSetCollector.2=Errors occurred while updating the change sets for {0} -SubscriberChangeSetCollector.3=An error occurred saving the change set state for {0} -SubscriberChangeSetCollector.4=An error occurred restoring the change set state for {0} -SubscriberEventHandler.errors=Errors have occured while calculating the synchronization state for {0}. -RemoteContentsCacheEntry.3=Cache entry in {0} for {1} has been disposed -SynchronizationCacheRefreshOperation.0=Processing {0} -SubscriberEventHandler.8=The members of folder {0} could not be retrieved: {1} -SubscriberEventHandler.9=The synchronization state for resource {0} could not be determined: {1} -SubscriberEventHandler.10=An internal error occurred processing subscriber events. -SubscriberEventHandler.11=An internal error occurred processing resource {0}: {1} -CachedResourceVariant.0=There is no cached contents for resource {0}. -CachedResourceVariant.1=As error occurred computing the content type of resource variant {0} -SyncInfoTree.0=Sync info is missing for resource {0}. -ResourceVariantTreeSubscriber.1=Problems reported while synchronizing {0}. {1} of {2} resources were synchronized. -ResourceVariantTreeSubscriber.2=An error occurred synchronizing {0}: {1} -SyncByteConverter.1=Malformed sync byte format detected in {0} -BatchingLock.11=An error occurred while flushing batched changes -SubscriberEventHandler.12=Synchronization state collection cancelled by a user action. -ProjectSetCapability.0=Failed to create project references -ProjectSetCapability.1=Failed to load projects diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/simpleAccess/SimpleAccessOperations.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/simpleAccess/SimpleAccessOperations.java deleted file mode 100644 index db7d7fc06..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/simpleAccess/SimpleAccessOperations.java +++ /dev/null @@ -1,267 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.simpleAccess; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; - -/* - * This class represents provisional API. Its here to allow experimentation with 3rd party tools - * calling providers in a repository neutral manner. - * - * A provider is not required to implement this API. - * Implementers, and those who reference it, do so with the awareness that this class may be - * removed or substantially changed at future times without warning. - * - * The <code>SimpleAccessOperations</code> class exposes a basic repository model that - * providers may implement to allow third-party plugins to perform repository operations - * programmatically. For example, a code generation tool may want to get source - * files before generating the code, and check-in the results. If a provider plugin does - * not adhere to the <i>semantics</i> of the <code>SimpleAccessOperations</code> class - * as described, they are free to opt out of implementing it. - * - * @since 2.0 - */ -public interface SimpleAccessOperations { - /* - * Updates the local resource to have the same content as the corresponding remote - * resource. Where the local resource does not exist, this method will create it. - * <p> - * If the remote resource is a container (e.g. folder or project) this operation is equivalent - * to getting each non-container member of the remote resource, thereby updating the - * content of existing local members, creating local members to receive new remote resources, - * and deleting local members that no longer have a corresponding remote resource.</p> - * <p> - * The method is applied to all resources satisfying the depth parameter, described above.</p> - * <p> - * Interrupting the method (via the progress monitor) may lead to partial, but consistent, results.</p> - * - * @param resources an array of local resources to update from the corresponding remote - * resources. - * @param depth the depth to traverse the given resources, taken from <code>IResource</code> - * static constants. - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * @throws TeamException if there is a problem getting one or more of the resources. The - * exception will contain multiple statuses, one for each resource in the <code>resources</code> - * array. Possible status codes include: - * <ul> - * <li>NO_REMOTE_RESOURCE</li> - * <li>IO_FAILED</li> - * <li>NOT_AUTHORIZED</li> - * <li>UNABLE</li> - * </ul> - */ - public void get(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; - - /* - * Changes the state of the local resource from checked-in to checked-out and transfers the content - * of the remote resource to the local resource. - * <p> - * Where no corresponding local resource exists in the workspace, one is created (including any - * intermediate parent containers) to receive the contents of the remote resource.</p> - * <p> - * Implementations may optimistically only flag the state change locally and rely on resolving conflicts - * during check-in, or they may pessimistically also checkout or lock the remote resource during a - * local resource checkout to avoid conflicts. The provider API does not subscribe to either model - * and supports each equally.</p> - * <p> - * Where checkout is applied to a resource that is already checked-out the method has no - * effect.</p> - * - * @param resources the array of local resources to be checked-out. - * @param depth the depth to traverse the given resources, taken from <code>IResource</code> - * constants. - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * @throws TeamProviderException if there is a problem checking-out one or more of the resources. - * The exception will contain multiple statuses, one for each resource in the <code>resources</code> - * array. Possible status codes include: - * <ul> - * <li>NOT_CHECKED_IN</li> - * <li>NO_REMOTE_RESOURCE</li> - * <li>IO_FAILED</li> - * <li>NOT_AUTHORIZED</li> - * <li>UNABLE</li> - * </ul> - * @see checkin(IResource[], int, IProgressMonitor) - */ - public void checkout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; - - /* - * Transfers the content of the local resource to the corresponding remote resource, and changes the - * state of the local resource from checked-out to checked-in. - * <p> - * If a remote resource does not exist this method creates a new remote resource with the same content - * as the given local resource. The local resource is said to <i>correspond</i> to the new remote resource.</p> - * <p> - * Where providers deal with stores that check-out or lock resources this method is an opportunity - * to transfer the content and make the corresponding remote check-in or unlock. It is envisaged that - * where the server maintains resource versions, checkin creates a new version of the remote resource.</p> - * <p> - * Note that some providers may <em>require</em> that a resource is checked-out before it can be - * checked-in. However, all providers must support the explicit checking out a resource before checking - * it in (e.g., even if the check out is a no-op).</p> - * - * @param resources an array of local resources to be checked-in. - * @param the depth to traverse the given resources, taken from <code>IResource</code> - * constants. - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * @throws TeamException if there is a problem checking-in one or more of the resources. - * The exception will contain multiple statuses, one for each resource in the <code>resources</code> - * array. Possible status codes include: - * <ul> - * <li>NOT_CHECKED_OUT</li> - * <li>IO_FAILED</li> - * <li>NOT_AUTHORIZED</li> - * <li>UNABLE</li> - * </ul> - * @see checkout(IResource[], int, IProgressMonitor) - */ - public void checkin(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; - - /* - * Changes the state of the local resource from checked-out to checked-in without updating the contents - * of the remote resource. - * <p> - * Note that where the provider is a versioning provider, it is envisaged (though not required) that the - * uncheckout operation does not create a new version.</p> - * <p> - * Note also that <code>uncheckout()</code> does not affect the content of the local resource. The - * caller is required to perform a <code>get()</code> to revert the local resource if that is required - * (otherwise the local resource will be left with the changes that were made while the remote resource - * was checked-out. Furthermore, it is valid to call <code>uncheckout()</code> with an - * <code>IResource</code> that does not exist locally.</p> - * - * @param resources an array of the local resources that are to be unchecked-out. - * @param depth the depth to traverse the given resources, taken from <code>IResource</code> - * constants. - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * @throws TeamProviderException if there is a problem undoing the check-out of one or more of - * the resources. The exception will contain multiple statuses, one for each resource in the - * <code>resources</code> array. Possible status codes include: - * <ul> - * <li>NOT_CHECKED_OUT</li> - * <li>IO_FAILED</li> - * <li>NOT_AUTHORIZED</li> - * <li>UNABLE</li> - * </ul> - * @see checkin(IResource) - * @see uncheckout(IResource) - */ - public void uncheckout(IResource[] resources, int depth, IProgressMonitor progress) throws TeamException; - - /* - * Deletes the remote resource corresponding to the given local resource. - * <p> - * The notion of delete is simply to make the remote resource unavailable. Where the provider - * supports versioning it is not specified whether the delete operation makes the version - * temporarily or forever unavailable, or indeed whether the entire history is made unavailable.</p> - * <p> - * Note that the <code>IResource</code>'s passed as arguments may be non-existant in the - * workbench, the typical case is when such a resource has been received in a core callback.</p> - * <p> - * The resource may be checked-in or checked-out prior to deletion. The local resource is not - * deleted by this method.</p> - * <p> - * Resource deletions are inherently deep.</p> - * - * @param resources the array of resources whose corresponding remote resources are to be deleted. - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * @throws TeamProviderException if there is a problem deleting one or more of - * the resources. The exception will contain multiple statuses, one for each resource in the - * <code>resources</code> array. Possible status codes include: - * <ul> - * <li>NO_REMOTE_RESOURCE</li> - * <li>IO_FAILED</li> - * <li>NOT_AUTHORIZED</li> - * <li>UNABLE</li> - * </ul> - */ - public void delete(IResource[] resources, IProgressMonitor progress) throws TeamException; - - /* - * Informs the provider that a local resource's name or path has changed. - * <p> - * Some providers, such as versioning providers, may require this information to track the resource - * across name changes.</p> - * <p> - * Note that this method is always called <em>after</em> the local resource has been moved.</p> - * - * @param source the full name of the resource before it was moved. - * @param target the resource that was moved. - * @param progress a progress monitor to indicate the duration of the operation, or - * <code>null</code> if progress reporting is not required. - * @throws TeamProviderException if there is a problem recording the move. The exception will - * contain a single status. Possible status codes are: - * <ul> - * <li>NO_REMOTE_RESOURCE</li> - * <li>IO_FAILED</li> - * <li>NOT_AUTHORIZED</li> - * <li>UNABLE</li> - * </ul> - */ - public void moved(IPath source, IResource target, IProgressMonitor progress) throws TeamException; - - /* - * Implementor's Note: - * The following methods are required to return promptly (i.e., they may be used to determine the state of - * a resource in a UI where long delays are unacceptable). Implementations may cache these values - * and update the cache on an explicit call to #refreshState(). - * - * They are currently listed in the provider API, however, they may be moved to a new or different - * interface in the future to better reflect their UI-orientation. - */ - - /* - * Answers if the remote resource state is checked-out. If the resource has never been checked in this - * method will return <code>true</code>. - * <p> - * It is undefined whether this method tests for a resource being checked out to this workspace - * or any workspace.</p> - * - * @param resource the local resource to test. - * @return <code>true</code> if the resource is checked-out and <code>false</code> if it is not. - * @see checkout(IResource[], int, IProgressMonitor) - */ - public boolean isCheckedOut(IResource resource); - - /* - * Answers whether the resource has a corresponding remote resource. - * <p> - * Before a resource is checked-in, the resource will occur locally but not remotely, and calls to this - * method will return <code>false</code>. Once a local resource is checked in (and assuming the local - * local resource is not moved or the remote resource deleted) there will be a corresponding remote - * resource and this method returns <code>true</code>.</p> - * - * @param resource the local resource to test. - * @return <code>true</code> if the local resource has a corresponding remote resource, - * and <code>false</code> otherwise. - * @see checkin(IResource[], int, IProgressMonitor) - * @see refreshState(IResource[], int, IProgressMonitor) - */ - public boolean hasRemote(IResource resource); - - /* - * Answer if the local resource currently has a different timestamp to the base timestamp - * for this resource. - * - * @param resource the resource to test. - * @return <code>true</code> if the resource has a different modification - * timestamp, and <code>false</code> otherwise. - */ - public boolean isDirty(IResource resource); -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/CRLFtoLFInputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/CRLFtoLFInputStream.java deleted file mode 100644 index 9a52b0871..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/CRLFtoLFInputStream.java +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; - -/** - * Converts CR/LFs in the underlying input stream to LF. - * - * Supports resuming partially completed operations after an InterruptedIOException - * if the underlying stream does. Check the bytesTransferred field to determine how - * much of the operation completed; conversely, at what point to resume. - */ -public class CRLFtoLFInputStream extends FilterInputStream { - private boolean pendingByte = false; - private int lastByte = -1; - - /** - * Creates a new filtered input stream. - * @param in the underlying input stream - */ - public CRLFtoLFInputStream(InputStream in) { - super(in); - } - - /** - * Wraps the underlying stream's method. - * Translates CR/LF sequences to LFs transparently. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public int read() throws IOException { - if (! pendingByte) { - lastByte = in.read(); // ok if this throws - pendingByte = true; // remember the byte in case we throw an exception later on - } - if (lastByte == '\r') { - lastByte = in.read(); // ok if this throws - if (lastByte != '\n') { - if (lastByte == -1) pendingByte = false; - return '\r'; // leaves the byte pending for later - } - } - pendingByte = false; - return lastByte; - } - - /** - * Wraps the underlying stream's method. - * Translates CR/LF sequences to LFs transparently. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public int read(byte[] buffer, int off, int len) throws IOException { - // handle boundary cases cleanly - if (len == 0) { - return 0; - } else if (len == 1) { - int b = read(); - if (b == -1) return -1; - buffer[off] = (byte) b; - return 1; - } - // read some bytes from the stream - // prefix with pending byte from last read if any - int count = 0; - if (pendingByte) { - buffer[off] = (byte) lastByte; - pendingByte = false; - count = 1; - } - InterruptedIOException iioe = null; - try { - len = in.read(buffer, off + count, len - count); - if (len == -1) { - return (count == 0) ? -1 : count; - } - } catch (InterruptedIOException e) { - len = e.bytesTransferred; - iioe = e; - } - count += len; - // strip out CR's in CR/LF pairs - // pendingByte will be true iff previous byte was a CR - int j = off; - for (int i = off; i < off + count; ++i) { // invariant: j <= i - lastByte = buffer[i]; - if (lastByte == '\r') { - if (pendingByte) { - buffer[j++] = '\r'; // write out orphan CR - } else { - pendingByte = true; - } - } else { - if (pendingByte) { - if (lastByte != '\n') buffer[j++] = '\r'; // if LF, don't write the CR - pendingByte = false; - } - buffer[j++] = (byte) lastByte; - } - } - if (iioe != null) { - iioe.bytesTransferred = j - off; - throw iioe; - } - return j - off; - } - - /** - * Calls read() to skip the specified number of bytes - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public long skip(long count) throws IOException { - int actualCount = 0; // assumes count < Integer.MAX_INT - try { - while (count-- > 0 && read() != -1) actualCount++; // skip the specified number of bytes - return actualCount; - } catch (InterruptedIOException e) { - e.bytesTransferred = actualCount; - throw e; - } - } - - /** - * Wraps the underlying stream's method. - * Returns the number of bytes that can be read without blocking; accounts for - * possible translation of CR/LF sequences to LFs in these bytes. - * @throws IOException if an i/o error occurs - */ - public int available() throws IOException { - return in.available() / 2; // we can guarantee at least this amount after contraction - } - - /** - * Mark is not supported by the wrapper even if the underlying stream does, returns false. - */ - public boolean markSupported() { - return false; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/LFtoCRLFInputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/LFtoCRLFInputStream.java deleted file mode 100644 index 9c14ffb86..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/LFtoCRLFInputStream.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; - -/** - * Converts LFs in the underlying input stream to CR/LF. - * - * Supports resuming partially completed operations after an InterruptedIOException - * if the underlying stream does. Check the bytesTransferred field to determine how - * much of the operation completed; conversely, at what point to resume. - */ -public class LFtoCRLFInputStream extends FilterInputStream { - private boolean mustReturnLF = false; - - /** - * Creates a new filtered input stream. - * @param in the underlying input stream - */ - public LFtoCRLFInputStream(InputStream in) { - super(in); - } - - /** - * Wraps the underlying stream's method. - * Translates LFs to CR/LF sequences transparently. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public int read() throws IOException { - if (mustReturnLF) { - mustReturnLF = false; - return '\n'; - } - int b = in.read(); // ok if this throws - if (b == '\n') { - mustReturnLF = true; - b = '\r'; - } - return b; - } - - /** - * Wraps the underlying stream's method. - * Translates LFs to CR/LF sequences transparently. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public int read(byte[] buffer, int off, int len) throws IOException { - // handle boundary cases cleanly - if (len == 0) { - return 0; - } else if (len == 1) { - int b = read(); - if (b == -1) return -1; - buffer[off] = (byte) b; - return 1; - } - // prefix with remembered \n from last read, but don't expand it a second time - int count = 0; - if (mustReturnLF) { - mustReturnLF = false; - buffer[off++] = '\n'; - --len; - count = 1; - if (len < 2) return count; // is there still enough room to expand more? - } - // read some bytes from the stream into the back half of the buffer - // this guarantees that there is always room to expand - len /= 2; - int j = off + len; - InterruptedIOException iioe = null; - try { - len = in.read(buffer, j, len); - if (len == -1) { - return (count == 0) ? -1 : count; - } - } catch (InterruptedIOException e) { - len = e.bytesTransferred; - iioe = e; - } - count += len; - // copy bytes from the middle to the front of the array, expanding LF->CR/LF - while (len-- > 0) { - byte b = buffer[j++]; - if (b == '\n') { - buffer[off++] = '\r'; - count++; - } - buffer[off++] = b; - } - if (iioe != null) { - iioe.bytesTransferred = count; - throw iioe; - } - return count; - } - - /** - * Calls read() to skip the specified number of bytes - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public long skip(long count) throws IOException { - int actualCount = 0; // assumes count < Integer.MAX_INT - try { - while (count-- > 0 && read() != -1) actualCount++; // skip the specified number of bytes - return actualCount; - } catch (InterruptedIOException e) { - e.bytesTransferred = actualCount; - throw e; - } - } - - /** - * Wraps the underlying stream's method. - * Returns the number of bytes that can be read without blocking; accounts for - * possible translation of LFs to CR/LF sequences in these bytes. - * @throws IOException if an i/o error occurs - */ - public int available() throws IOException { - return in.available(); // we can guarantee at least this amount after expansion - } - - /** - * Mark is not supported by the wrapper even if the underlying stream does, returns false. - */ - public boolean markSupported() { - return false; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/PollingInputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/PollingInputStream.java deleted file mode 100644 index f8d7bc99d..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/PollingInputStream.java +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * Polls a progress monitor periodically and handles timeouts over extended durations. - * For this class to be effective, a high numAttempts should be specified, and the - * underlying stream should time out frequently on reads (every second or so). - * - * Supports resuming partially completed operations after an InterruptedIOException - * if the underlying stream does. Check the bytesTransferred field to determine how - * much of the operation completed; conversely, at what point to resume. - */ -public class PollingInputStream extends FilterInputStream { - private static final boolean DEBUG = Policy.DEBUG_STREAMS; - private int numAttempts; - private IProgressMonitor monitor; - private boolean cancellable; - - /** - * Creates a new polling input stream. - * @param in the underlying input stream - * @param numAttempts the number of attempts before issuing an InterruptedIOException, - * if 0, retries indefinitely until canceled - * @param monitor the progress monitor to be polled for cancellation - */ - public PollingInputStream(InputStream in, int numAttempts, IProgressMonitor monitor) { - super(in); - this.numAttempts = numAttempts; - this.monitor = monitor; - this.cancellable = true; - } - - /** - * Wraps the underlying stream's method. - * It may be important to wait for an input stream to be closed because it - * holds an implicit lock on a system resoure (such as a file) while it is - * open. Closing a stream may take time if the underlying stream is still - * servicing a previous request. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times - * @throws IOException if an i/o error occurs - */ - public void close() throws IOException { - int attempts = 0; - try { - readPendingInput(); - } catch (IOException e) { - // We shouldn't get an exception when we're getting the available input. - // If we do, just log it so we can close. - TeamPlugin.log(IStatus.ERROR, e.getMessage(), e); - } finally { - boolean stop = false; - while (!stop) { - try { - in.close(); - stop = true; - } catch (InterruptedIOException e) { - if (checkCancellation()) throw new OperationCanceledException(); - if (++attempts == numAttempts) - throw new InterruptedIOException(Policy.bind("PollingInputStream.closeTimeout")); //$NON-NLS-1$ - if (DEBUG) System.out.println("close retry=" + attempts); //$NON-NLS-1$ - } - } - } - } - - /** - * Wraps the underlying stream's method. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times - * and no data was received, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public int read() throws IOException { - int attempts = 0; - for (;;) { - if (checkCancellation()) throw new OperationCanceledException(); - try { - return in.read(); - } catch (InterruptedIOException e) { - if (++attempts == numAttempts) - throw new InterruptedIOException(Policy.bind("PollingInputStream.readTimeout")); //$NON-NLS-1$ - if (DEBUG) System.out.println("read retry=" + attempts); //$NON-NLS-1$ - } - } - } - - /** - * Wraps the underlying stream's method. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times - * and no data was received, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public int read(byte[] buffer, int off, int len) throws IOException { - int attempts = 0; - for (;;) { - if (checkCancellation()) throw new OperationCanceledException(); - try { - return in.read(buffer, off, len); - } catch (InterruptedIOException e) { - if (e.bytesTransferred != 0) return e.bytesTransferred; // keep partial transfer - if (++attempts == numAttempts) - throw new InterruptedIOException(Policy.bind("PollingInputStream.readTimeout")); //$NON-NLS-1$ - if (DEBUG) System.out.println("read retry=" + attempts); //$NON-NLS-1$ - } - } - } - - /** - * Wraps the underlying stream's method. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times - * and no data was received, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public long skip(long count) throws IOException { - int attempts = 0; - for (;;) { - if (checkCancellation()) throw new OperationCanceledException(); - try { - return in.skip(count); - } catch (InterruptedIOException e) { - if (e.bytesTransferred != 0) return e.bytesTransferred; // keep partial transfer - if (++attempts == numAttempts) - throw new InterruptedIOException(Policy.bind("PollingInputStream.readTimeout")); //$NON-NLS-1$ - if (DEBUG) System.out.println("read retry=" + attempts); //$NON-NLS-1$ - } - } - } - - /** - * Reads any pending input from the input stream so that - * the stream can savely be closed. - */ - protected void readPendingInput() throws IOException { - byte[] buffer= new byte[2048]; - while (true) { - int available = in.available(); - if (available < 1) break; - if (available > buffer.length) available = buffer.length; - if (in.read(buffer, 0, available) < 1) break; - } - } - - /** - * Called to set whether cancellation will be checked by this stream. Turning cancellation checking - * off can be very useful for protecting critical portions of a protocol that shouldn't be interrupted. - * For example, it is often necessary to protect login sequences. - * @param cancellable a flag controlling whether this stream will check for cancellation. - */ - public void setIsCancellable(boolean cancellable) { - this.cancellable = cancellable; - } - - /** - * Checked whether the monitor for this stream has been cancelled. If the cancellable - * flag is <code>false</code> then the monitor is never cancelled. - * @return <code>true</code> if the monitor has been cancelled and <code>false</code> - * otherwise. - */ - private boolean checkCancellation() { - if(cancellable) { - return monitor.isCanceled(); - } else { - return false; - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/PollingOutputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/PollingOutputStream.java deleted file mode 100644 index 8227c30fd..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/PollingOutputStream.java +++ /dev/null @@ -1,189 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InterruptedIOException; -import java.io.OutputStream; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.team.internal.core.Policy; - -/** - * Polls a progress monitor periodically and handles timeouts over extended durations. - * For this class to be effective, a high numAttempts should be specified, and the - * underlying stream should time out frequently on writes (every second or so). - * - * Supports resuming partially completed operations after an InterruptedIOException - * if the underlying stream does. Check the bytesTransferred field to determine how - * much of the operation completed; conversely, at what point to resume. - */ -public class PollingOutputStream extends FilterOutputStream { - private static final boolean DEBUG = Policy.DEBUG_STREAMS; - private int numAttempts; - private IProgressMonitor monitor; - private boolean cancellable; - - /** - * Creates a new polling output stream. - * @param in the underlying output stream - * @param numAttempts the number of attempts before issuing an InterruptedIOException, - * if 0, retries indefinitely until canceled - * @param monitor the progress monitor to be polled for cancellation - */ - public PollingOutputStream(OutputStream out, int numAttempts, IProgressMonitor monitor) { - super(out); - this.numAttempts = numAttempts; - this.monitor = monitor; - this.cancellable = true; - } - - /** - * Wraps the underlying stream's method. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times - * and no data was sent, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public void write(int b) throws IOException { - int attempts = 0; - for (;;) { - if (checkCancellation()) throw new OperationCanceledException(); - try { - out.write(b); - return; - } catch (InterruptedIOException e) { - if (++attempts == numAttempts) - throw new InterruptedIOException(Policy.bind("PollingOutputStream.writeTimeout")); //$NON-NLS-1$ - if (DEBUG) System.out.println("write retry=" + attempts); //$NON-NLS-1$ - } - } - } - - /** - * Wraps the underlying stream's method. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times, - * bytesTransferred will reflect the number of bytes sent - * @throws IOException if an i/o error occurs - */ - public void write(byte[] buffer, int off, int len) throws IOException { - int count = 0; - int attempts = 0; - for (;;) { - if (checkCancellation()) throw new OperationCanceledException(); - try { - out.write(buffer, off, len); - return; - } catch (InterruptedIOException e) { - int amount = e.bytesTransferred; - if (amount != 0) { // keep partial transfer - len -= amount; - if (len <= 0) return; - off += amount; - count += amount; - attempts = 0; // made some progress, don't time out quite yet - } - if (++attempts == numAttempts) { - e = new InterruptedIOException(Policy.bind("PollingOutputStream.writeTimeout")); //$NON-NLS-1$ - e.bytesTransferred = count; - throw e; - } - if (DEBUG) System.out.println("write retry=" + attempts); //$NON-NLS-1$ - } - } - } - - /** - * Wraps the underlying stream's method. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times, - * bytesTransferred will reflect the number of bytes sent - * @throws IOException if an i/o error occurs - */ - public void flush() throws IOException { - int count = 0; - int attempts = 0; - for (;;) { - if (checkCancellation()) throw new OperationCanceledException(); - try { - out.flush(); - return; - } catch (InterruptedIOException e) { - int amount = e.bytesTransferred; - if (amount != 0) { // keep partial transfer - count += amount; - attempts = 0; // made some progress, don't time out quite yet - } - if (++attempts == numAttempts) { - e = new InterruptedIOException(Policy.bind("PollingOutputStream.writeTimeout")); //$NON-NLS-1$ - e.bytesTransferred = count; - throw e; - } - if (DEBUG) System.out.println("write retry=" + attempts); //$NON-NLS-1$ - } - } - } - - /** - * Calls flush() then close() on the underlying stream. - * @throws OperationCanceledException if the progress monitor is canceled - * @throws InterruptedIOException if the underlying operation times out numAttempts times, - * bytesTransferred will reflect the number of bytes sent during the flush() - * @throws IOException if an i/o error occurs - */ - public void close() throws IOException { - int attempts = numAttempts - 1; // fail fast if flush() does times out - try { - out.flush(); - attempts = 0; - } finally { - boolean stop = false; - while (!stop) { - try { - out.close(); - stop = true; - } catch (InterruptedIOException e) { - if (checkCancellation()) throw new OperationCanceledException(); - if (++attempts == numAttempts) - throw new InterruptedIOException(Policy.bind("PollingOutputStream.closeTimeout")); //$NON-NLS-1$ - if (DEBUG) System.out.println("close retry=" + attempts); //$NON-NLS-1$ - } - } - } - } - - /** - * Called to set whether cancellation will be checked by this stream. Turning cancellation checking - * off can be very useful for protecting critical portions of a protocol that shouldn't be interrupted. - * For example, it is often necessary to protect login sequences. - * @param cancellable a flag controlling whether this stream will check for cancellation. - */ - public void setIsCancellable(boolean cancellable) { - this.cancellable = cancellable; - } - - /** - * Checked whether the monitor for this stream has been cancelled. If the cancellable - * flag is <code>false</code> then the monitor is never cancelled. - * @return <code>true</code> if the monitor has been cancelled and <code>false</code> - * otherwise. - */ - private boolean checkCancellation() { - if(cancellable) { - return monitor.isCanceled(); - } else { - return false; - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/ProgressMonitorInputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/ProgressMonitorInputStream.java deleted file mode 100644 index 54b2e4aff..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/ProgressMonitorInputStream.java +++ /dev/null @@ -1,139 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * Updates a progress monitor as bytes are read from the input stream. - * Also starts a background thread to provide responsive cancellation on read(). - * - * Supports resuming partially completed operations after an InterruptedIOException - * if the underlying stream does. Check the bytesTransferred field to determine how - * much of the operation completed; conversely, at what point to resume. - */ -public abstract class ProgressMonitorInputStream extends FilterInputStream { - private IProgressMonitor monitor; - private int updateIncrement; - private long bytesTotal; - private long bytesRead = 0; - private long lastUpdate = -1; - private long nextUpdate = 0; - - /** - * Creates a progress monitoring input stream. - * @param in the underlying input stream - * @param bytesTotal the number of bytes to read in total (passed to updateMonitor()) - * @param updateIncrement the number of bytes read between updates - * @param monitor the progress monitor - */ - public ProgressMonitorInputStream(InputStream in, long bytesTotal, int updateIncrement, IProgressMonitor monitor) { - super(in); - this.bytesTotal = bytesTotal; - this.updateIncrement = updateIncrement; - this.monitor = monitor; - update(true); - } - - protected abstract void updateMonitor(long bytesRead, long size, IProgressMonitor monitor); - - /** - * Wraps the underlying stream's method. - * Updates the progress monitor to the final number of bytes read. - * @throws IOException if an i/o error occurs - */ - public void close() throws IOException { - try { - in.close(); - } finally { - update(true); - } - } - - /** - * Wraps the underlying stream's method. - * Updates the progress monitor if the next update increment has been reached. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public int read() throws IOException { - int b = in.read(); - if (b != -1) { - bytesRead += 1; - update(false); - } - return b; - } - - /** - * Wraps the underlying stream's method. - * Updates the progress monitor if the next update increment has been reached. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public int read(byte[] buffer, int offset, int length) throws IOException { - try { - int count = in.read(buffer, offset, length); - if (count != -1) { - bytesRead += count; - update(false); - } - return count; - } catch (InterruptedIOException e) { - bytesRead += e.bytesTransferred; - update(false); - throw e; - } - } - - /** - * Wraps the underlying stream's method. - * Updates the progress monitor if the next update increment has been reached. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public long skip(long amount) throws IOException { - try { - long count = in.skip(amount); - bytesRead += count; - update(false); - return count; - } catch (InterruptedIOException e) { - bytesRead += e.bytesTransferred; - update(false); - throw e; - } - } - - /** - * Mark is not supported by the wrapper even if the underlying stream does, returns false. - */ - public boolean markSupported() { - return false; - } - - private void update(boolean now) { - if (bytesRead >= nextUpdate || now) { - nextUpdate = bytesRead - (bytesRead % updateIncrement); - if (nextUpdate != lastUpdate) updateMonitor(nextUpdate, bytesTotal, monitor); - lastUpdate = nextUpdate; - nextUpdate += updateIncrement; - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/SizeConstrainedInputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/SizeConstrainedInputStream.java deleted file mode 100644 index d7d26cac8..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/SizeConstrainedInputStream.java +++ /dev/null @@ -1,138 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; - -import org.eclipse.core.runtime.OperationCanceledException; - -/** - * Simulates a stream that represents only a portion of the underlying stream. - * Will report EOF when this portion has been fully read and prevent further reads. - * The underlying stream is not closed on close(), but the remaining unread input - * may optionally be skip()'d. - * - * Supports resuming partially completed operations after an InterruptedIOException - * if the underlying stream does. Check the bytesTransferred field to determine how - * much of the operation completed; conversely, at what point to resume. - */ -public class SizeConstrainedInputStream extends FilterInputStream { - private boolean discardOnClose; - private long bytesRemaining; - - /** - * Creates a size contrained input stream. - * @param in the underlying input stream, never actually closed by this filter - * @param size the maximum number of bytes of the underlying input stream that - * can be read through this filter - * @param discardOnClose if true, discards remaining unread bytes on close() - */ - public SizeConstrainedInputStream(InputStream in, long size, boolean discardOnClose) { - super(in); - this.bytesRemaining = size; - this.discardOnClose = discardOnClose; - } - - /** - * Prevents further reading from the stream but does not close the underlying stream. - * If discardOnClose, skip()'s over any remaining unread bytes in the constrained region. - * @throws IOException if an i/o error occurs - */ - public void close() throws IOException { - try { - if (discardOnClose) { - while (bytesRemaining != 0 && skip(bytesRemaining) != 0); - } - } catch (OperationCanceledException e) { - // The receiver is likely wrapping a PollingInputStream which could throw - // an OperationCanceledException on a skip. - // Since we're closing, just ignore the cancel and let the caller check the monitor - } finally { - bytesRemaining = 0; - } - } - - /** - * Wraps the underlying stream's method. - * Simulates an end-of-file condition if the end of the constrained region has been reached. - * @throws IOException if an i/o error occurs - */ - public int available() throws IOException { - int amount = in.available(); - if (amount > bytesRemaining) amount = (int) bytesRemaining; - return amount; - } - - /** - * Wraps the underlying stream's method. - * Simulates an end-of-file condition if the end of the constrained region has been reached. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public int read() throws IOException { - if (bytesRemaining == 0) return -1; - int b = in.read(); - if (b != -1) bytesRemaining -= 1; - return b; - } - - /** - * Wraps the underlying stream's method. - * Simulates an end-of-file condition if the end of the constrained region has been reached. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public int read(byte[] buffer, int offset, int length) throws IOException { - if (length > bytesRemaining) { - if (bytesRemaining == 0) return -1; - length = (int) bytesRemaining; - } - try { - int count = in.read(buffer, offset, length); - if (count != -1) bytesRemaining -= count; - return count; - } catch (InterruptedIOException e) { - bytesRemaining -= e.bytesTransferred; - throw e; - } - } - - /** - * Wraps the underlying stream's method. - * Simulates an end-of-file condition if the end of the constrained region has been reached. - * @throws InterruptedIOException if the operation was interrupted before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public long skip(long amount) throws IOException { - if (amount > bytesRemaining) amount = bytesRemaining; - try { - long count = in.skip(amount); - bytesRemaining -= count; - return count; - } catch (InterruptedIOException e) { - bytesRemaining -= e.bytesTransferred; - throw e; - } - } - - /** - * Mark is not supported by the wrapper even if the underlying stream does, returns false. - */ - public boolean markSupported() { - return false; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/TimeoutInputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/TimeoutInputStream.java deleted file mode 100644 index 4ea6eb809..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/TimeoutInputStream.java +++ /dev/null @@ -1,325 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InterruptedIOException; -import org.eclipse.team.internal.core.Policy; - -/** - * Wraps an input stream that blocks indefinitely to simulate timeouts on read(), - * skip(), and close(). The resulting input stream is buffered and supports - * retrying operations that failed due to an InterruptedIOException. - * - * Supports resuming partially completed operations after an InterruptedIOException - * REGARDLESS of whether the underlying stream does unless the underlying stream itself - * generates InterruptedIOExceptions in which case it must also support resuming. - * Check the bytesTransferred field to determine how much of the operation completed; - * conversely, at what point to resume. - */ -public class TimeoutInputStream extends FilterInputStream { - // unsynchronized variables - private final long readTimeout; // read() timeout in millis - private final long closeTimeout; // close() timeout in millis, or -1 - - // requests for the thread (synchronized) - private boolean closeRequested = false; // if true, close requested - - // responses from the thread (synchronized) - private Thread thread; // if null, thread has terminated - private byte[] iobuffer; // circular buffer - private int head = 0; // points to first unread byte - private int length = 0; // number of remaining unread bytes - private IOException ioe = null; // if non-null, contains a pending exception - private boolean waitingForClose = false; // if true, thread is waiting for close() - - private boolean growWhenFull = false; // if true, buffer will grow when it is full - - /** - * Creates a timeout wrapper for an input stream. - * @param in the underlying input stream - * @param bufferSize the buffer size in bytes; should be large enough to mitigate - * Thread synchronization and context switching overhead - * @param readTimeout the number of milliseconds to block for a read() or skip() before - * throwing an InterruptedIOException; 0 blocks indefinitely - * @param closeTimeout the number of milliseconds to block for a close() before throwing - * an InterruptedIOException; 0 blocks indefinitely, -1 closes the stream in the background - */ - public TimeoutInputStream(InputStream in, int bufferSize, long readTimeout, long closeTimeout) { - super(in); - this.readTimeout = readTimeout; - this.closeTimeout = closeTimeout; - this.iobuffer = new byte[bufferSize]; - thread = new Thread(new Runnable() { - public void run() { - runThread(); - } - }, "TimeoutInputStream");//$NON-NLS-1$ - thread.setDaemon(true); - thread.start(); - } - - public TimeoutInputStream(InputStream in, int bufferSize, long readTimeout, long closeTimeout, boolean growWhenFull) { - this(in, bufferSize, readTimeout, closeTimeout); - this.growWhenFull = growWhenFull; - } - - /** - * Wraps the underlying stream's method. - * It may be important to wait for a stream to actually be closed because it - * holds an implicit lock on a system resoure (such as a file) while it is - * open. Closing a stream may take time if the underlying stream is still - * servicing a previous request. - * @throws InterruptedIOException if the timeout expired - * @throws IOException if an i/o error occurs - */ - public void close() throws IOException { - Thread oldThread; - synchronized (this) { - if (thread == null) return; - oldThread = thread; - closeRequested = true; - thread.interrupt(); - checkError(); - } - if (closeTimeout == -1) return; - try { - oldThread.join(closeTimeout); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // we weren't expecting to be interrupted - } - synchronized (this) { - checkError(); - if (thread != null) throw new InterruptedIOException(); - } - } - - /** - * Returns the number of unread bytes in the buffer. - * @throws IOException if an i/o error occurs - */ - public synchronized int available() throws IOException { - if (length == 0) checkError(); - return length > 0 ? length : 0; - } - - /** - * Reads a byte from the stream. - * @throws InterruptedIOException if the timeout expired and no data was received, - * bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public synchronized int read() throws IOException { - if (! syncFill()) return -1; // EOF reached - int b = iobuffer[head++] & 255; - if (head == iobuffer.length) head = 0; - length--; - notify(); - return b; - } - - /** - * Reads multiple bytes from the stream. - * @throws InterruptedIOException if the timeout expired and no data was received, - * bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public synchronized int read(byte[] buffer, int off, int len) throws IOException { - if (! syncFill()) return -1; // EOF reached - int pos = off; - if (len > length) len = length; - while (len-- > 0) { - buffer[pos++] = iobuffer[head++]; - if (head == iobuffer.length) head = 0; - length--; - } - notify(); - return pos - off; - } - - /** - * Skips multiple bytes in the stream. - * @throws InterruptedIOException if the timeout expired before all of the - * bytes specified have been skipped, bytesTransferred may be non-zero - * @throws IOException if an i/o error occurs - */ - public synchronized long skip(long count) throws IOException { - long amount = 0; - try { - do { - if (! syncFill()) break; // EOF reached - int skip = (int) Math.min(count - amount, length); - head = (head + skip) % iobuffer.length; - length -= skip; - amount += skip; - } while (amount < count); - } catch (InterruptedIOException e) { - e.bytesTransferred = (int) amount; // assumes amount < Integer.MAX_INT - throw e; - } - notify(); - return amount; - } - - /** - * Mark is not supported by the wrapper even if the underlying stream does, returns false. - */ - public boolean markSupported() { - return false; - } - - /** - * Waits for the buffer to fill if it is empty and the stream has not reached EOF. - * @return true if bytes are available, false if EOF has been reached - * @throws InterruptedIOException if EOF not reached but no bytes are available - */ - private boolean syncFill() throws IOException { - if (length != 0) return true; - checkError(); // check errors only after we have read all remaining bytes - if (waitingForClose) return false; - notify(); - try { - wait(readTimeout); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // we weren't expecting to be interrupted - } - if (length != 0) return true; - checkError(); // check errors only after we have read all remaining bytes - if (waitingForClose) return false; - throw new InterruptedIOException(); - } - - /** - * If an exception is pending, throws it. - */ - private void checkError() throws IOException { - if (ioe != null) { - IOException e = ioe; - ioe = null; - throw e; - } - } - - /** - * Runs the thread in the background. - */ - private void runThread() { - try { - readUntilDone(); - } catch (IOException e) { - synchronized (this) { ioe = e; } - } finally { - waitUntilClosed(); - try { - in.close(); - } catch (IOException e) { - synchronized (this) { ioe = e; } - } finally { - synchronized (this) { - thread = null; - notify(); - } - } - } - } - - /** - * Waits until we have been requested to close the stream. - */ - private synchronized void waitUntilClosed() { - waitingForClose = true; - notify(); - while (! closeRequested) { - try { - wait(); - } catch (InterruptedException e) { - closeRequested = true; // alternate quit signal - } - } - } - - /** - * Reads bytes into the buffer until EOF, closed, or error. - */ - private void readUntilDone() throws IOException { - for (;;) { - int off, len; - synchronized (this) { - while (isBufferFull()) { - if (closeRequested) return; // quit signal - waitForRead(); - } - off = (head + length) % iobuffer.length; - len = ((head > off) ? head : iobuffer.length) - off; - } - int count; - try { - // the i/o operation might block without releasing the lock, - // so we do this outside of the synchronized block - count = in.read(iobuffer, off, len); - if (count == -1) return; // EOF encountered - } catch (InterruptedIOException e) { - count = e.bytesTransferred; // keep partial transfer - } - synchronized (this) { - length += count; - notify(); - } - } - } - - /* - * Wait for a read when the buffer is full (with the implication - * that space will become available in the buffer after the read - * takes place). - */ - private synchronized void waitForRead() { - try { - if (growWhenFull) { - // wait a second before growing to let reads catch up - wait(readTimeout); - } else { - wait(); - } - } catch (InterruptedException e) { - closeRequested = true; // alternate quit signal - } - // If the buffer is still full, give it a chance to grow - if (growWhenFull && isBufferFull()) { - growBuffer(); - } - } - - private synchronized void growBuffer() { - int newSize = 2 * iobuffer.length; - if (newSize > iobuffer.length) { - if (Policy.DEBUG_STREAMS) { - System.out.println("InputStream growing to " + newSize + " bytes"); //$NON-NLS-1$ //$NON-NLS-2$ - } - byte[] newBuffer = new byte[newSize]; - int pos = 0; - int len = length; - while (len-- > 0) { - newBuffer[pos++] = iobuffer[head++]; - if (head == iobuffer.length) head = 0; - } - iobuffer = newBuffer; - head = 0; - // length instance variable was not changed by this method - } - } - - private boolean isBufferFull() { - return length == iobuffer.length; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/TimeoutOutputStream.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/TimeoutOutputStream.java deleted file mode 100644 index 0041e6bbd..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/streams/TimeoutOutputStream.java +++ /dev/null @@ -1,289 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.streams; - -import java.io.BufferedOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InterruptedIOException; -import java.io.OutputStream; - -import org.eclipse.team.internal.core.Policy; - -/** - * Wraps an output stream that blocks indefinitely to simulate timeouts on write(), - * flush(), and close(). The resulting output stream is buffered and supports - * retrying operations that failed due to an InterruptedIOException. - * - * Supports resuming partially completed operations after an InterruptedIOException - * REGARDLESS of whether the underlying stream does unless the underlying stream itself - * generates InterruptedIOExceptions in which case it must also support resuming. - * Check the bytesTransferred field to determine how much of the operation completed; - * conversely, at what point to resume. - */ -public class TimeoutOutputStream extends FilterOutputStream { - // unsynchronized variables - private final long writeTimeout; // write() timeout in millis - private final long closeTimeout; // close() timeout in millis, or -1 - - // requests for the thread (synchronized) - private byte[] iobuffer; // circular buffer - private int head = 0; // points to first unwritten byte - private int length = 0; // number of remaining unwritten bytes - private boolean closeRequested = false; // if true, close requested - private boolean flushRequested = false; // if true, flush requested - - // responses from the thread (synchronized) - private Thread thread; - private boolean waitingForClose = false; // if true, the thread is waiting for close() - private IOException ioe = null; - - /** - * Creates a timeout wrapper for an output stream. - * @param out the underlying input stream - * @param bufferSize the buffer size in bytes; should be large enough to mitigate - * Thread synchronization and context switching overhead - * @param writeTimeout the number of milliseconds to block for a write() or flush() before - * throwing an InterruptedIOException; 0 blocks indefinitely - * @param closeTimeout the number of milliseconds to block for a close() before throwing - * an InterruptedIOException; 0 blocks indefinitely, -1 closes the stream in the background - */ - public TimeoutOutputStream(OutputStream out, int bufferSize, long writeTimeout, long closeTimeout) { - super(new BufferedOutputStream(out, bufferSize)); - this.writeTimeout = writeTimeout; - this.closeTimeout = closeTimeout; - this.iobuffer = new byte[bufferSize]; - thread = new Thread(new Runnable() { - public void run() { - runThread(); - } - }, "TimeoutOutputStream");//$NON-NLS-1$ - thread.setDaemon(true); - thread.start(); - } - - /** - * Wraps the underlying stream's method. - * It may be important to wait for a stream to actually be closed because it - * holds an implicit lock on a system resoure (such as a file) while it is - * open. Closing a stream may take time if the underlying stream is still - * servicing a previous request. - * @throws InterruptedIOException if the timeout expired, bytesTransferred will - * reflect the number of bytes flushed from the buffer - * @throws IOException if an i/o error occurs - */ - public void close() throws IOException { - Thread oldThread; - synchronized (this) { - if (thread == null) return; - oldThread = thread; - closeRequested = true; - thread.interrupt(); - checkError(); - } - if (closeTimeout == -1) return; - try { - oldThread.join(closeTimeout); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // we weren't expecting to be interrupted - } - synchronized (this) { - checkError(); - if (thread != null) throw new InterruptedIOException(); - } - } - - /** - * Writes a byte to the stream. - * @throws InterruptedIOException if the timeout expired and no data was sent, - * bytesTransferred will be zero - * @throws IOException if an i/o error occurs - */ - public synchronized void write(int b) throws IOException { - syncCommit(true); - iobuffer[(head + length) % iobuffer.length] = (byte) b; - length++; - notify(); - } - - /** - * Writes multiple bytes to the stream. - * @throws InterruptedIOException if the timeout expired, bytesTransferred will - * reflect the number of bytes sent - * @throws IOException if an i/o error occurs - */ - public synchronized void write(byte[] buffer, int off, int len) throws IOException { - int amount = 0; - try { - do { - syncCommit(true); - while (amount < len && length != iobuffer.length) { - iobuffer[(head + length) % iobuffer.length] = buffer[off++]; - length++; - amount++; - } - } while (amount < len); - } catch (InterruptedIOException e) { - e.bytesTransferred = amount; - throw e; - } - notify(); - } - - /** - * Flushes the stream. - * @throws InterruptedIOException if the timeout expired, bytesTransferred will - * reflect the number of bytes flushed from the buffer - * @throws IOException if an i/o error occurs - */ - public synchronized void flush() throws IOException { - int oldLength = length; - flushRequested = true; - try { - syncCommit(false); - } catch (InterruptedIOException e) { - e.bytesTransferred = oldLength - length; - throw e; - } - notify(); - } - - /** - * Waits for the buffer to drain if it is full. - * @param partial if true, waits until the buffer is partially empty, else drains it entirely - * @throws InterruptedIOException if the buffer could not be drained as requested - */ - private void syncCommit(boolean partial) throws IOException { - checkError(); // check errors before allowing the addition of new bytes - if (partial && length != iobuffer.length || length == 0) return; - if (waitingForClose) throw new IOException(Policy.bind("TimeoutOutputStream.cannotWriteToStream")); //$NON-NLS-1$ - notify(); - try { - wait(writeTimeout); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // we weren't expecting to be interrupted - } - checkError(); // check errors before allowing the addition of new bytes - if (partial && length != iobuffer.length || length == 0) return; - throw new InterruptedIOException(); - } - - /** - * If an exception is pending, throws it. - */ - private void checkError() throws IOException { - if (ioe != null) { - IOException e = ioe; - ioe = null; - throw e; - } - } - - /** - * Runs the thread in the background. - */ - private void runThread() { - try { - writeUntilDone(); - } catch (IOException e) { - synchronized (this) { ioe = e; } - } finally { - waitUntilClosed(); - try { - out.close(); - } catch (IOException e) { - synchronized (this) { ioe = e; } - } finally { - synchronized (this) { - thread = null; - notify(); - } - } - } - } - - /** - * Waits until we have been requested to close the stream. - */ - private synchronized void waitUntilClosed() { - waitingForClose = true; - notify(); - while (! closeRequested) { - try { - wait(); - } catch (InterruptedException e) { - closeRequested = true; // alternate quit signal - } - } - } - - /** - * Writes bytes from the buffer until closed and buffer is empty - */ - private void writeUntilDone() throws IOException { - int bytesUntilFlush = -1; // if > 0, then we will flush after that many bytes have been written - for (;;) { - int off, len; - synchronized (this) { - for (;;) { - if (closeRequested && length == 0) return; // quit signal - if (length != 0 || flushRequested) break; - try { - wait(); - } catch (InterruptedException e) { - closeRequested = true; // alternate quit signal - } - } - off = head; - len = iobuffer.length - head; - if (len > length) len = length; - if (flushRequested && bytesUntilFlush < 0) { - flushRequested = false; - bytesUntilFlush = length; - } - } - - // If there are bytes to be written, write them - if (len != 0) { - // write out all remaining bytes from the buffer before flushing - try { - // the i/o operation might block without releasing the lock, - // so we do this outside of the synchronized block - out.write(iobuffer, off, len); - } catch (InterruptedIOException e) { - len = e.bytesTransferred; - } - } - - // If there was a pending flush, do it - if (bytesUntilFlush >= 0) { - bytesUntilFlush -= len; - if (bytesUntilFlush <= 0) { - // flush the buffer now - try { - out.flush(); - } catch (InterruptedIOException e) { - } - bytesUntilFlush = -1; // might have been 0 - } - } - - // If bytes were written, update the circular buffer - if (len != 0) { - synchronized (this) { - head = (head + len) % iobuffer.length; - length -= len; - notify(); - } - } - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/BatchingLock.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/BatchingLock.java deleted file mode 100644 index fdb9c675c..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/BatchingLock.java +++ /dev/null @@ -1,339 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.MultiRule; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Assert; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * Provides a per-thread nested locking mechanism. A thread can acquire a - * lock on a specific resource by calling acquire(). Subsequently, acquire() can be called - * multiple times on the resource or any of its children from within the same thread - * without blocking. Other threads that try - * and acquire the lock on those same resources will be blocked until the first - * thread releases all it's nested locks. - * <p> - * The locking is managed by the platform via scheduling rules. This class simply - * provides the nesting mechnism in order to allow the client to determine when - * the lock for the thread has been released. Therefore, this lock will block if - * another thread already locks the same resource.</p> - */ -public class BatchingLock { - - private final static boolean DEBUG = Policy.DEBUG_THREADING; - - // This is a placeholder rule used to indicate that no scheduling rule is needed - /* internal use only */ static final ISchedulingRule NULL_SCHEDULING_RULE= new ISchedulingRule() { - public boolean contains(ISchedulingRule rule) { - return false; - } - public boolean isConflicting(ISchedulingRule rule) { - return false; - } - }; - - public class ThreadInfo { - private Set changedResources = new HashSet(); - private IFlushOperation operation; - private List rules = new ArrayList(); - public ThreadInfo(IFlushOperation operation) { - this.operation = operation; - } - /** - * Push a scheduling rule onto the stack for this thread and - * acquire the rule if it is not the workspace root. - * @param resource - */ - public ISchedulingRule pushRule(ISchedulingRule resource, IProgressMonitor monitor) { - // The scheduling rule is either the project or the resource's parent - ISchedulingRule rule = getRuleForResoure(resource); - if (rule != NULL_SCHEDULING_RULE) { - boolean success = false; - try { - Platform.getJobManager().beginRule(rule, monitor); - addRule(rule); - success = true; - } finally { - if (!success) { - try { - // The begin was cancelled (or some other problem occurred). - // Free the scheduling rule - // so the clients of ReentrantLock don't need to - // do an endRule when the operation is cancelled. - Platform.getJobManager().endRule(rule); - } catch (RuntimeException e) { - // Log and ignore so the original exception is not lost - TeamPlugin.log(IStatus.ERROR, "Failed to end scheduling rule", e); //$NON-NLS-1$ - } - } - } - } else { - // Record the fact that we didn't push a rule so we - // can match it when we pop - addRule(rule); - } - return rule; - } - /** - * Pop the scheduling rule from the stack and release it if it - * is not the workspace root. Flush any changed sync info to - * disk if necessary. A flush is necessary if the stack is empty - * or if the top-most non-null scheduling rule was popped as a result - * of this operation. - * @param monitor - * @throws CVSException - */ - public void popRule(ISchedulingRule rule, IProgressMonitor monitor) throws TeamException { - try { - if (isFlushRequired()) { - flush(monitor); - } - } finally { - ISchedulingRule stackedRule = removeRule(); - if (rule == null) { - rule = NULL_SCHEDULING_RULE; - } - Assert.isTrue(stackedRule.equals(rule), "end for resource '" + rule + "' does not match stacked rule '" + stackedRule + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (rule != NULL_SCHEDULING_RULE) { - Platform.getJobManager().endRule(rule); - } - } - } - private ISchedulingRule getRuleForResoure(ISchedulingRule resourceRule) { - ISchedulingRule rule; - if (resourceRule instanceof IResource) { - IResource resource = (IResource)resourceRule; - if (resource.getType() == IResource.ROOT) { - // Never lock the whole workspace - rule = NULL_SCHEDULING_RULE; - } else if (resource.getType() == IResource.PROJECT) { - rule = resource; - } else { - rule = resource.getParent(); - } - } else if (resourceRule instanceof MultiRule) { - // Create a MultiRule for all projects from the given rule - ISchedulingRule[] rules = ((MultiRule)resourceRule).getChildren(); - Set projects = new HashSet(); - for (int i = 0; i < rules.length; i++) { - ISchedulingRule childRule = rules[i]; - if (childRule instanceof IResource) { - projects.add(((IResource)childRule).getProject()); - } - } - if (projects.isEmpty()) { - rule = NULL_SCHEDULING_RULE; - } else if (projects.size() == 1) { - rule = (ISchedulingRule)projects.iterator().next(); - } else { - rule = new MultiRule((ISchedulingRule[]) projects.toArray(new ISchedulingRule[projects.size()])); - } - } else { - // Rule is not associated with resources so ignore it - rule = NULL_SCHEDULING_RULE; - } - return rule; - } - /** - * Return <code>true</code> if we are still nested in - * an acquire for this thread. - * - * @return - */ - public boolean isNested() { - return !rules.isEmpty(); - } - public void addChangedResource(IResource resource) { - changedResources.add(resource); - } - public boolean isEmpty() { - return changedResources.isEmpty(); - } - public IResource[] getChangedResources() { - return (IResource[]) changedResources.toArray(new IResource[changedResources.size()]); - } - public void flush(IProgressMonitor monitor) throws TeamException { - try { - operation.flush(this, monitor); - } catch (OutOfMemoryError e) { - throw e; - } catch (Error e) { - handleAbortedFlush(e); - throw e; - } catch (RuntimeException e) { - handleAbortedFlush(e); - throw e; - } finally { - // We have to clear the resources no matter what since the next attempt - // to fluch may not have an appropriate scheduling rule - changedResources.clear(); - } - } - private boolean isFlushRequired() { - return rules.size() == 1 || remainingRulesAreNull(); - } - /* - * Return true if all but the last rule in the stack is null - */ - private boolean remainingRulesAreNull() { - for (int i = 0; i < rules.size() - 1; i++) { - ISchedulingRule rule = (ISchedulingRule) rules.get(i); - if (rule != NULL_SCHEDULING_RULE) { - return false; - } - } - return true; - } - private void handleAbortedFlush(Throwable t) { - TeamPlugin.log(IStatus.ERROR, Policy.bind("BatchingLock.11"), t); //$NON-NLS-1$ - } - private void addRule(ISchedulingRule rule) { - rules.add(rule); - } - private ISchedulingRule removeRule() { - return (ISchedulingRule)rules.remove(rules.size() - 1); - } - public boolean ruleContains(IResource resource) { - for (Iterator iter = rules.iterator(); iter.hasNext();) { - ISchedulingRule rule = (ISchedulingRule) iter.next(); - if (rule != NULL_SCHEDULING_RULE && rule.contains(resource)) { - return true; - } - } - return false; - } - } - - public interface IFlushOperation { - public void flush(ThreadInfo info, IProgressMonitor monitor) throws TeamException; - } - - private Map infos = new HashMap(); - - /** - * Return the thread info for the current thread - * @return the thread info for the current thread - */ - protected ThreadInfo getThreadInfo() { - Thread thisThread = Thread.currentThread(); - synchronized (infos) { - ThreadInfo info = (ThreadInfo)infos.get(thisThread); - return info; - } - } - - private ThreadInfo getThreadInfo(IResource resource) { - synchronized (infos) { - for (Iterator iter = infos.values().iterator(); iter.hasNext();) { - ThreadInfo info = (ThreadInfo) iter.next(); - if (info.ruleContains(resource)) { - return info; - } - } - return null; - } - } - - public ISchedulingRule acquire(ISchedulingRule resourceRule, IFlushOperation operation, IProgressMonitor monitor) { - ThreadInfo info = getThreadInfo(); - boolean added = false; - synchronized (infos) { - if (info == null) { - info = createThreadInfo(operation); - Thread thisThread = Thread.currentThread(); - infos.put(thisThread, info); - added = true; - if(DEBUG) System.out.println("[" + thisThread.getName() + "] acquired batching lock on " + resourceRule); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - try { - return info.pushRule(resourceRule, monitor); - } catch (OperationCanceledException e) { - // The operation was cancelled. - // If this is the outermost acquire then remove the info that was just added - if (added) { - synchronized (infos) { - infos.remove(Thread.currentThread()); - } - } - throw e; - } - } - - /** - * Create the ThreadInfo instance used to cache the lock state for the - * current thread. Subclass can override to provide a subclass of - * ThreadInfo. - * @param operation the flush operation - * @return a ThreadInfo instance - */ - protected ThreadInfo createThreadInfo(IFlushOperation operation) { - return new ThreadInfo(operation); - } - - /** - * Release the lock held on any resources by this thread. The provided rule must - * be identical to the rule returned by the corresponding acquire(). If the rule - * for the release is non-null and all remaining rules held by the lock are null, - * the the flush operation provided in the acquire method will be executed. - */ - public void release(ISchedulingRule rule, IProgressMonitor monitor) throws TeamException { - ThreadInfo info = getThreadInfo(); - Assert.isNotNull(info, "Unmatched acquire/release."); //$NON-NLS-1$ - Assert.isTrue(info.isNested(), "Unmatched acquire/release."); //$NON-NLS-1$ - info.popRule(rule, monitor); - synchronized (infos) { - if (!info.isNested()) { - Thread thisThread = Thread.currentThread(); - if(DEBUG) System.out.println("[" + thisThread.getName() + "] released batching lock"); //$NON-NLS-1$ //$NON-NLS-2$ - infos.remove(thisThread); - } - } - } - - public void resourceChanged(IResource resource) { - ThreadInfo info = getThreadInfo(); - Assert.isNotNull(info, "Folder changed outside of resource lock"); //$NON-NLS-1$ - info.addChangedResource(resource); - } - - /** - * Flush any changes accumulated by the lock so far. - */ - public void flush(IProgressMonitor monitor) throws TeamException { - ThreadInfo info = getThreadInfo(); - Assert.isNotNull(info, "Flush requested outside of resource lock"); //$NON-NLS-1$ - info.flush(monitor); - } - - public boolean isWithinActiveOperationScope(IResource resource) { - synchronized (infos) { - return getThreadInfo(resource) != null; - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/ContentComparator.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/ContentComparator.java deleted file mode 100644 index c4184592f..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/ContentComparator.java +++ /dev/null @@ -1,142 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.io.*; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.*; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.variants.IResourceVariant; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * This is an internal class that is usd by the <code>ContentComparisonSyncInfoFilter</code> - * to compare the comtents of the local and remote resources - */ -public class ContentComparator { - - private boolean ignoreWhitespace = false; - - public ContentComparator(boolean ignoreWhitespace) { - this.ignoreWhitespace = ignoreWhitespace; - } - - public boolean compare(Object e1, Object e2, IProgressMonitor monitor) { - InputStream is1 = null; - InputStream is2 = null; - try { - monitor.beginTask(null, 100); - is1 = getContents(e1, Policy.subMonitorFor(monitor, 50)); - is2 = getContents(e2, Policy.subMonitorFor(monitor, 50)); - return contentsEqual(is1, is2, shouldIgnoreWhitespace()); - } catch(TeamException e) { - TeamPlugin.log(e); - return false; - } finally { - try { - try { - if (is1 != null) { - is1.close(); - } - } finally { - if (is2 != null) { - is2.close(); - } - } - } catch (IOException e) { - // Ignore - } - monitor.done(); - } - } - - protected boolean shouldIgnoreWhitespace() { - return ignoreWhitespace; - } - - /** - * Returns <code>true</code> if both input streams byte contents is - * identical. - * - * @param input1 - * first input to contents compare - * @param input2 - * second input to contents compare - * @return <code>true</code> if content is equal - */ - private boolean contentsEqual(InputStream is1, InputStream is2, boolean ignoreWhitespace) { - try { - if (is1 == is2) - return true; - - if (is1 == null && is2 == null) // no byte contents - return true; - - if (is1 == null || is2 == null) // only one has - // contents - return false; - - while (true) { - int c1 = is1.read(); - while (shouldIgnoreWhitespace() && isWhitespace(c1)) - c1 = is1.read(); - int c2 = is2.read(); - while (shouldIgnoreWhitespace() && isWhitespace(c2)) - c2 = is2.read(); - if (c1 == -1 && c2 == -1) - return true; - if (c1 != c2) - break; - - } - } catch (IOException ex) { - } finally { - try { - try { - if (is1 != null) { - is1.close(); - } - } finally { - if (is2 != null) { - is2.close(); - } - } - } catch (IOException e) { - // Ignore - } - } - return false; - } - - private boolean isWhitespace(int c) { - if (c == -1) - return false; - return Character.isWhitespace((char) c); - } - - private InputStream getContents(Object resource, IProgressMonitor monitor) throws TeamException { - try { - if (resource instanceof IFile) { - return new BufferedInputStream(((IFile) resource).getContents()); - } else if(resource instanceof IResourceVariant) { - IResourceVariant remote = (IResourceVariant)resource; - if (!remote.isContainer()) { - return new BufferedInputStream(remote.getStorage(monitor).getContents()); - } - } - return null; - } catch (CoreException e) { - throw TeamException.asTeamException(e); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/DescendantResourceVariantByteStore.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/DescendantResourceVariantByteStore.java deleted file mode 100644 index 1e7f5af9d..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/DescendantResourceVariantByteStore.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.variants.*; - -/** - * A <code>ResourceVariantByteStore</code> that optimizes the memory footprint - * of a remote resource variant tree by only storing those bytes that - * differ from a base resource variant tree. This class should only be used - * for cases where the base and remote are on the same line-of-descent. - * For example, when the remote tree represents the current state of a branch - * and the base represents the state of the same branch when the local workspace - * as last refreshed. - * <p> - * This class also contains the logic that allows subclasses to determine if - * bytes stored in the remote tree are on a different line-of-descent than the base. - * This is necessary because it is possible for the base tree to change in ways that - * invalidate the stored remote variants. For example, if the local resources are moved - * from the main trunck to a branch, any cached remote resource variants would be stale. - * - * @since 3.0 - */ -public abstract class DescendantResourceVariantByteStore extends ResourceVariantByteStore { - - ResourceVariantByteStore baseStore, remoteStore; - - public DescendantResourceVariantByteStore(ResourceVariantByteStore baseCache, ResourceVariantByteStore remoteCache) { - this.baseStore = baseCache; - this.remoteStore = remoteCache; - } - - /** - * This method will dispose the remote cache but not the base cache. - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#dispose() - */ - public void dispose() { - remoteStore.dispose(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#getBytes(org.eclipse.core.resources.IResource) - */ - public byte[] getBytes(IResource resource) throws TeamException { - byte[] remoteBytes = remoteStore.getBytes(resource); - byte[] baseBytes = baseStore.getBytes(resource); - if (baseBytes == null) { - // There is no base so use the remote bytes - return remoteBytes; - } - if (remoteBytes == null) { - if (isVariantKnown(resource)) { - // The remote is known to not exist - // TODO: The check for NO_REMOTE does not take into consideration the line-of-descent - return remoteBytes; - } else { - // The remote was either never queried or was the same as the base. - // In either of these cases, the base bytes are used. - return baseBytes; - } - } - if (isDescendant(resource, baseBytes, remoteBytes)) { - // Only use the remote bytes if they are later on the same line-of-descent as the base - return remoteBytes; - } - // Use the base sbytes since the remote bytes must be stale (i.e. are - // not on the same line-of-descent - return baseBytes; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#setBytes(org.eclipse.core.resources.IResource, byte[]) - */ - public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { - byte[] baseBytes = baseStore.getBytes(resource); - if (baseBytes != null && equals(baseBytes, bytes)) { - // Remove the existing bytes so the base will be used (thus saving space) - return remoteStore.flushBytes(resource, IResource.DEPTH_ZERO); - } else { - return remoteStore.setBytes(resource, bytes); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#removeBytes(org.eclipse.core.resources.IResource, int) - */ - public boolean flushBytes(IResource resource, int depth) throws TeamException { - return remoteStore.flushBytes(resource, depth); - } - - /** - * Return <code>true</code> if the variant associated with the given local - * resource has been cached. This method is useful for those cases when - * there are no bytes for a resource variant and the client wants to - * know if this means that the remote does exist (i.e. this method returns - * <code>true</code>) or the remote has not been fetched (i.e. this method returns - * <code>false</code>). - * @param resource the local resource - * @return <code>true</code> if the variant associated with the given local - * resource has been cached. - * @throws TeamException - */ - public abstract boolean isVariantKnown(IResource resource) throws TeamException; - - /** - * This method indicates whether the remote bytes are a later revision or version - * on the same line-of-descent as the base. A line of descent may be a branch or a fork - * (depending on the terminology used by the versioing server). If this method returns - * <code>false</code> then the remote bytes will be ignored by this tree. - * @param resource the local resource - * @param baseBytes the base bytes for the local resoource - * @param remoteBytes the remote bytes for the local resoource - * @return whether the remote bytes are later on the same line-of-descent as the base bytes - */ - protected abstract boolean isDescendant(IResource resource, byte[] baseBytes, byte[] remoteBytes) throws TeamException; - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#setVariantDoesNotExist(org.eclipse.core.resources.IResource) - */ - public boolean deleteBytes(IResource resource) throws TeamException { - return remoteStore.deleteBytes(resource); - } - - /** - * Return the base tree from which the remote is descendant. - * @return Returns the base tree. - */ - protected ResourceVariantByteStore getBaseStore() { - return baseStore; - } - - /** - * Return the remote tree which contains bytes only for the resource variants - * that differ from those in the base tree. - * @return Returns the remote tree. - */ - protected ResourceVariantByteStore getRemoteStore() { - return remoteStore; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.ResourceVariantByteStore#members(org.eclipse.core.resources.IResource) - */ - public IResource[] members(IResource resource) throws TeamException { - IResource[] remoteMembers = getRemoteStore().members(resource); - IResource[] baseMembers = getBaseStore().members(resource); - Set members = new HashSet(); - for (int i = 0; i < remoteMembers.length; i++) { - members.add(remoteMembers[i]); - } - for (int i = 0; i < baseMembers.length; i++) { - IResource member = baseMembers[i]; - // Add the base only if the remote does not know about it - // (i.e. hasn't marked it as deleted - if (!isVariantKnown(member)) { - members.add(member); - } - } - return (IResource[]) members.toArray(new IResource[members.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.variants.ResourceVariantByteStore#run(org.eclipse.core.resources.IResource, org.eclipse.core.resources.IWorkspaceRunnable, org.eclipse.core.runtime.IProgressMonitor) - */ - public void run(IResource root, IWorkspaceRunnable runnable, IProgressMonitor monitor) throws TeamException { - remoteStore.run(root, runnable, monitor); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberEventHandler.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberEventHandler.java deleted file mode 100644 index e01d94498..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberEventHandler.java +++ /dev/null @@ -1,490 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.core.resources.*; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.jobs.IJobChangeEvent; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.team.core.*; -import org.eclipse.team.core.subscribers.Subscriber; -import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.core.synchronize.SyncInfoSet; -import org.eclipse.team.internal.core.*; - -/** - * This handler collects changes and removals to resources and calculates their - * synchronization state in a background job. The result is fed input the SyncSetInput. - * - * Exceptions that occur when the job is processing the events are collected and - * returned as part of the Job's status. - */ -public class SubscriberEventHandler extends BackgroundEventHandler { - // The set that receives notification when the resource synchronization state - // has been calculated by the job. - private SyncSetInputFromSubscriber syncSetInput; - - // Changes accumulated by the event handler - private List resultCache = new ArrayList(); - - private boolean started = false; - private boolean initializing = true; - - private IProgressMonitor progressGroup; - - private int ticks; - - private IResource[] roots; - - /** - * Internal resource synchronization event. Can contain a result. - */ - class SubscriberEvent extends ResourceEvent{ - static final int REMOVAL = 1; - static final int CHANGE = 2; - static final int INITIALIZE = 3; - SyncInfo result; - - SubscriberEvent(IResource resource, int type, int depth) { - super(resource, type, depth); - } - public SubscriberEvent( - IResource resource, - int type, - int depth, - SyncInfo result) { - this(resource, type, depth); - this.result = result; - } - public SyncInfo getResult() { - return result; - } - protected String getTypeString() { - switch (getType()) { - case REMOVAL : - return "REMOVAL"; //$NON-NLS-1$ - case CHANGE : - return "CHANGE"; //$NON-NLS-1$ - case INITIALIZE : - return "INITIALIZE"; //$NON-NLS-1$ - default : - return "INVALID"; //$NON-NLS-1$ - } - } - } - - /** - * This is a special event used to reset and connect sync sets. - * The preemtive flag is used to indicate that the runnable should take - * the highest priority and thus be placed on the front of the queue - * and be processed as soon as possible, preemting any event that is currently - * being processed. The curent event will continue processing once the - * high priority event has been processed - */ - public class RunnableEvent extends Event { - static final int RUNNABLE = 1000; - private IWorkspaceRunnable runnable; - private boolean preemtive; - public RunnableEvent(IWorkspaceRunnable runnable, boolean preemtive) { - super(RUNNABLE); - this.runnable = runnable; - this.preemtive = preemtive; - } - public void run(IProgressMonitor monitor) throws CoreException { - runnable.run(monitor); - } - public boolean isPreemtive() { - return preemtive; - } - } - - /** - * Create a handler. This will initialize all resources for the subscriber associated with - * the set. - * @param set the subscriber set to feed changes into - */ - public SubscriberEventHandler(Subscriber subscriber, IResource[] roots) { - super( - Policy.bind("SubscriberEventHandler.jobName", subscriber.getName()), //$NON-NLS-1$ - Policy.bind("SubscriberEventHandler.errors", subscriber.getName())); //$NON-NLS-1$ - this.roots = roots; - this.syncSetInput = new SyncSetInputFromSubscriber(subscriber, this); - } - - /** - * Start the event handler by queuing events to prime the sync set input with the out-of-sync - * resources of the subscriber. - */ - public synchronized void start() { - // Set the started flag to enable event queueing. - // We are gaurenteed to be the first since this method is synchronized. - started = true; - IResource[] resources = this.roots; - if (resources == null) { - resources = syncSetInput.getSubscriber().roots(); - } - reset(resources, SubscriberEvent.INITIALIZE); - initializing = false; - } - - protected synchronized void queueEvent(Event event, boolean front) { - // Only post events if the handler is started - if (started) { - super.queueEvent(event, front); - } - } - /** - * Schedule the job or process the events now. - */ - public void schedule() { - Job job = getEventHandlerJob(); - if (job.getState() == Job.NONE) { - if(progressGroup != null) { - job.setSystem(false); - job.setProgressGroup(progressGroup, ticks); - } else { - job.setSystem(!initializing); - } - } - getEventHandlerJob().schedule(); - } - - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.BackgroundEventHandler#jobDone(org.eclipse.core.runtime.jobs.IJobChangeEvent) - */ - protected void jobDone(IJobChangeEvent event) { - super.jobDone(event); - progressGroup = null; - } - - /** - * Initialize all resources for the subscriber associated with the set. This will basically recalculate - * all synchronization information for the subscriber. - * <p> - * This method is sycnrhonized with the queueEvent method to ensure that the two events - * queued by this method are back-to-back - */ - public synchronized void reset(IResource[] roots) { - if (roots == null) { - roots = syncSetInput.getSubscriber().roots(); - } else { - this.roots = roots; - } - // First, reset the sync set input to clear the sync set - run(new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) throws CoreException { - syncSetInput.reset(monitor); - } - }, false /* keep ordering the same */); - // Then, prime the set from the subscriber - reset(roots, SubscriberEvent.CHANGE); - } - - /** - * Called by a client to indicate that a resource has changed and its synchronization state - * should be recalculated. - * @param resource the changed resource - * @param depth the depth of the change calculation - */ - public void change(IResource resource, int depth) { - queueEvent(new SubscriberEvent(resource, SubscriberEvent.CHANGE, depth), false); - } - - /** - * Called by a client to indicate that a resource has been removed and should be removed. The - * removal will propagate to the set. - * @param resource the resource that was removed - */ - public void remove(IResource resource) { - queueEvent( - new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_INFINITE), false); - } - - /** - * Collect the calculated synchronization information for the given resource at the given depth. The - * results are added to the provided list. - */ - private void collect( - IResource resource, - int depth, - IProgressMonitor monitor) { - - // handle any preemtive events before continuing - handlePreemptiveEvents(monitor); - - if (resource.getType() != IResource.FILE - && depth != IResource.DEPTH_ZERO) { - try { - IResource[] members = - syncSetInput.getSubscriber().members(resource); - for (int i = 0; i < members.length; i++) { - collect( - members[i], - depth == IResource.DEPTH_INFINITE - ? IResource.DEPTH_INFINITE - : IResource.DEPTH_ZERO, - monitor); - } - } catch (TeamException e) { - handleException(e, resource, ITeamStatus.SYNC_INFO_SET_ERROR, Policy.bind("SubscriberEventHandler.8", resource.getFullPath().toString(), e.getMessage())); //$NON-NLS-1$ - } - } - - monitor.subTask(Policy.bind("SubscriberEventHandler.2", resource.getFullPath().toString())); //$NON-NLS-1$ - try { - SyncInfo info = syncSetInput.getSubscriber().getSyncInfo(resource); - // resource is no longer under the subscriber control - if (info == null) { - resultCache.add( - new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_ZERO)); - } else { - resultCache.add( - new SubscriberEvent(resource, SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, info)); - } - handlePendingDispatch(monitor); - } catch (TeamException e) { - handleException(e, resource, ITeamStatus.RESOURCE_SYNC_INFO_ERROR, Policy.bind("SubscriberEventHandler.9", resource.getFullPath().toString(), e.getMessage())); //$NON-NLS-1$ - } - monitor.worked(1); - } - - private void handlePendingDispatch(IProgressMonitor monitor) { - if (isReadyForDispatch(false /*don't wait if queue is empty*/)) { - try { - dispatchEvents(Policy.subMonitorFor(monitor, 5)); - } catch (TeamException e) { - handleException(e, null, ITeamStatus.SYNC_INFO_SET_ERROR, e.getMessage()); - } - } - } - - /* - * Handle the exception by returning it as a status from the job but also by - * dispatching it to the sync set input so any down stream views can react - * accordingly. - * The resource passed may be null. - */ - private void handleException(CoreException e, IResource resource, int code, String message) { - handleException(e); - syncSetInput.handleError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, code, message, e, resource)); - } - - /** - * Called to initialize to calculate the synchronization information using the optimized subscriber method. For - * subscribers that don't support the optimization, all resources in the subscriber are manually re-calculated. - * @param resources the resources to check - * @param depth the depth - * @param monitor - * @return Event[] the change events - * @throws TeamException - */ - private void collectAll( - IResource resource, - int depth, - IProgressMonitor monitor) { - - - monitor.beginTask(null, IProgressMonitor.UNKNOWN); - try { - - // Create a monitor that will handle preemptions and dispatch if required - IProgressMonitor collectionMonitor = new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN) { - boolean dispatching = false; - public void subTask(String name) { - dispatch(); - super.subTask(name); - } - private void dispatch() { - if (dispatching) return; - try { - dispatching = true; - handlePreemptiveEvents(this); - handlePendingDispatch(this); - } finally { - dispatching = false; - } - } - public void worked(int work) { - dispatch(); - super.worked(work); - } - }; - - // Create a sync set that queues up resources and errors for dispatch - SyncInfoSet collectionSet = new SyncInfoSet() { - public void add(SyncInfo info) { - super.add(info); - resultCache.add( - new SubscriberEvent(info.getLocal(), SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, info)); - } - public void addError(ITeamStatus status) { - super.addError(status); - TeamPlugin.getPlugin().getLog().log(status); - syncSetInput.handleError(status); - } - public void remove(IResource resource) { - super.remove(resource); - resultCache.add( - new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_ZERO)); - } - }; - - syncSetInput.getSubscriber().collectOutOfSync(new IResource[] { resource }, depth, collectionSet, collectionMonitor); - - } finally { - monitor.done(); - } - } - - /** - * Feed the given events to the set. The appropriate method on the set is called - * for each event type. - * @param events - */ - private void dispatchEvents(SubscriberEvent[] events, IProgressMonitor monitor) { - // this will batch the following set changes until endInput is called. - SubscriberSyncInfoSet syncSet = syncSetInput.getSyncSet(); - try { - syncSet.beginInput(); - for (int i = 0; i < events.length; i++) { - SubscriberEvent event = events[i]; - switch (event.getType()) { - case SubscriberEvent.CHANGE : - syncSetInput.collect(event.getResult(), monitor); - break; - case SubscriberEvent.REMOVAL : - syncSet.remove(event.getResource(), event.getDepth()); - break; - } - } - } finally { - syncSet.endInput(monitor); - } - } - - /** - * Initialize all resources for the subscriber associated with the set. This will basically recalculate - * all synchronization information for the subscriber. - * @param type can be Event.CHANGE to recalculate all states or Event.INITIALIZE to perform the - * optimized recalculation if supported by the subscriber. - */ - private void reset(IResource[] roots, int type) { - IResource[] resources = roots; - for (int i = 0; i < resources.length; i++) { - queueEvent(new SubscriberEvent(resources[i], type, IResource.DEPTH_INFINITE), false); - } - } - - protected void processEvent(Event event, IProgressMonitor monitor) { - try { - // Cancellation is dangerous because this will leave the sync info in a bad state. - // Purposely not checking - - int type = event.getType(); - switch (type) { - case RunnableEvent.RUNNABLE : - executeRunnable(event, monitor); - break; - case SubscriberEvent.REMOVAL : - resultCache.add(event); - break; - case SubscriberEvent.CHANGE : - collect( - event.getResource(), - ((ResourceEvent)event).getDepth(), - monitor); - break; - case SubscriberEvent.INITIALIZE : - monitor.subTask(Policy.bind("SubscriberEventHandler.2", event.getResource().getFullPath().toString())); //$NON-NLS-1$ - collectAll( - event.getResource(), - ((ResourceEvent)event).getDepth(), - Policy.subMonitorFor(monitor, 64)); - break; - } - } catch (OperationCanceledException e) { - // the job has been cancelled. - // Clear the queue and propogate the cancellation through the sets. - resultCache.clear(); - syncSetInput.handleError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, ITeamStatus.SYNC_INFO_SET_CANCELLATION, Policy.bind("SubscriberEventHandler.12"), e, ResourcesPlugin.getWorkspace().getRoot())); //$NON-NLS-1$ - } catch (RuntimeException e) { - // handle the exception and keep processing - handleException(new TeamException(Policy.bind("SubscriberEventHandler.10"), e), event.getResource(), ITeamStatus.SYNC_INFO_SET_ERROR, Policy.bind("SubscriberEventHandler.11", event.getResource().getFullPath().toString(), e.getMessage())); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /* - * Execute the RunnableEvent - */ - private void executeRunnable(Event event, IProgressMonitor monitor) { - try { - // Dispatch any queued results to clear pending output events - dispatchEvents(Policy.subMonitorFor(monitor, 1)); - } catch (TeamException e) { - handleException(e, null, ITeamStatus.SYNC_INFO_SET_ERROR, e.getMessage()); - } - try { - ((RunnableEvent)event).run(Policy.subMonitorFor(monitor, 1)); - } catch (CoreException e) { - handleException(e, null, ITeamStatus.SYNC_INFO_SET_ERROR, e.getMessage()); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.BackgroundEventHandler#dispatchEvents() - */ - protected boolean doDispatchEvents(IProgressMonitor monitor) { - if (!resultCache.isEmpty()) { - dispatchEvents((SubscriberEvent[]) resultCache.toArray(new SubscriberEvent[resultCache.size()]), monitor); - resultCache.clear(); - return true; - } - return false; - } - - /** - * Queue up the given runnable in an event to be processed by this job - * @param runnable the runnable to be run by the handler - */ - public void run(IWorkspaceRunnable runnable, boolean frontOnQueue) { - queueEvent(new RunnableEvent(runnable, frontOnQueue), frontOnQueue); - } - - /** - * Return the sync set input that was created by this event handler - * @return - */ - public SyncSetInputFromSubscriber getSyncSetInput() { - return syncSetInput; - } - - public void setProgressGroupHint(IProgressMonitor progressGroup, int ticks) { - this.progressGroup = progressGroup; - this.ticks = ticks; - } - - /** - * @return Returns the started. - */ - protected boolean isStarted() { - return started; - } - - private void handlePreemptiveEvents(IProgressMonitor monitor) { - Event event = peek(); - if (event instanceof RunnableEvent && ((RunnableEvent)event).isPreemtive()) { - executeRunnable(nextElement(), monitor); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberResourceCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberResourceCollector.java deleted file mode 100644 index 8bc89a397..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberResourceCollector.java +++ /dev/null @@ -1,244 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.*; -import org.eclipse.team.core.subscribers.*; -import org.eclipse.team.internal.core.Assert; - -/** - * This class acts as a superclass for any class that is collecting subscriber - * resources. It provides funtionality that listens to resource deltas and subscriber change events - * in order to determine when the state of resources that are supervised by a subscriber may have changed. - */ -public abstract class SubscriberResourceCollector implements IResourceChangeListener, ISubscriberChangeListener { - - Subscriber subscriber; - - /** - * Create the collector and register it as a listener with the workspace - * and the subscriber. - */ - public SubscriberResourceCollector(Subscriber subscriber) { - Assert.isNotNull(subscriber); - this.subscriber = subscriber; - ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE); - subscriber.addListener(this); - } - - /** - * Returns the <code>Subscriber</code> associated with this collector. - * - * @return the <code>Subscriber</code> associated with this collector. - */ - public Subscriber getSubscriber() { - return subscriber; - } - - /** - * Deregister the listeners for this collector. - */ - public void dispose() { - getSubscriber().removeListener(this); - ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.sync.ITeamResourceChangeListener#teamResourceChanged(org.eclipse.team.core.sync.TeamDelta[]) - */ - public void subscriberResourceChanged(ISubscriberChangeEvent[] deltas) { - try { - beginInput(); - IResource[] roots = getRoots(); - for (int i = 0; i < deltas.length; i++) { - switch (deltas[i].getFlags()) { - case ISubscriberChangeEvent.SYNC_CHANGED : - if (isAllRootsIncluded() || isDescendantOfRoot(deltas[i].getResource(), roots)) { - change(deltas[i].getResource(), IResource.DEPTH_ZERO); - } - break; - case ISubscriberChangeEvent.ROOT_REMOVED : - remove(deltas[i].getResource()); - break; - case ISubscriberChangeEvent.ROOT_ADDED : - if (isAllRootsIncluded() || isDescendantOfRoot(deltas[i].getResource(), roots)) { - change(deltas[i].getResource(), IResource.DEPTH_INFINITE); - } - break; - } - } - } finally { - endInput(); - } - } - - /** - * This method is invoked at the beginning of a subscriber change event - * or resource delta event. The endInput methos will be invoked at some point - * following this. There may be several invokations of remove or change - * in between. - */ - protected void beginInput() { - // Do nothing by default - } - - /** - * The processing of the resource or subscriber delta has finished. - * Subclasses can accumulate removals and changes and handle them - * at this point to allow batched change events. - */ - protected void endInput() { - // Do nothing by default - } - - - /*(non-Javadoc) - * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) - */ - public void resourceChanged(IResourceChangeEvent event) { - try { - beginInput(); - processDelta(event.getDelta(), getRoots()); - } finally { - endInput(); - } - } - - /** - * Process the resource delta and posts all necessary events to the background - * event handler. - * - * @param delta the resource delta to analyse - */ - protected void processDelta(IResourceDelta delta, IResource[] roots) { - IResource resource = delta.getResource(); - int kind = delta.getKind(); - - if (resource.getType() == IResource.PROJECT) { - // Handle projects that should be removed from the collector - if (((kind & IResourceDelta.REMOVED) != 0) /* deleted project */ - || (delta.getFlags() & IResourceDelta.OPEN) != 0 && !((IProject) resource).isOpen() /* closed project */ - || !isAncestorOfRoot(resource, roots)) /* not within subscriber roots */ { - // If the project has any entries in the sync set, remove them - if (hasMembers(resource)) { - remove(resource); - } - } - } - - boolean visitChildren = false; - if (isDescendantOfRoot(resource, roots)) { - visitChildren = true; - // If the resource has changed type, remove the old resource handle - // and add the new one - if ((delta.getFlags() & IResourceDelta.TYPE) != 0) { - remove(resource); - change(resource, IResource.DEPTH_INFINITE); - } - - // Check the flags for changes the SyncSet cares about. - // Notice we don't care about MARKERS currently. - int changeFlags = delta.getFlags(); - if ((changeFlags & (IResourceDelta.OPEN | IResourceDelta.CONTENT)) != 0) { - change(resource, IResource.DEPTH_ZERO); - } - - // Check the kind and deal with those we care about - if ((delta.getKind() & (IResourceDelta.REMOVED | IResourceDelta.ADDED)) != 0) { - change(resource, IResource.DEPTH_ZERO); - } - } - - // Handle changed children - if (visitChildren || isAncestorOfRoot(resource, roots)) { - IResourceDelta[] affectedChildren = delta.getAffectedChildren(IResourceDelta.CHANGED | IResourceDelta.REMOVED | IResourceDelta.ADDED); - for (int i = 0; i < affectedChildren.length; i++) { - processDelta(affectedChildren[i], roots); - } - } - } - - /** - * Return the root resources that are to be considered by this handler. - * These may be either the subscriber roots or a set of resources that are - * contained by the subscriber's roots. - * @return the root resources that are to be considered by this handler - */ - protected IResource[] getRoots() { - return getSubscriber().roots(); - } - - /** - * Return whether the given resource, which is not - * within the roots of this handler, has children - * that are. - * @param resource the resource - * @return whether the resource has children that are being considered - * by this handler. - */ - protected boolean hasMembers(IResource resource) { - IResource[] roots = getRoots(); - for (int i = 0; i < roots.length; i++) { - IResource root = roots[i]; - if (resource.getFullPath().isPrefixOf(root.getFullPath())) { - return true; - } - } - return false; - } - - /** - * The resource is no longer of concern to the subscriber. - * Remove the resource and any of it's descendants - * from the set of resources being collected. - * @param resource the resource to be removed along with its - * descendants. - */ - protected abstract void remove(IResource resource); - - /** - * The resource sync state has changed to the depth specified. - * @param resource the resource - * @param depth the depth - */ - protected abstract void change(IResource resource, int depth); - - /** - * Return whether all roots of a subscriber are included or - * if the collector is only consider a subset of the resources. - * @return whether all roots of a subscriber are included - */ - protected boolean isAllRootsIncluded() { - return true; - } - - private boolean isAncestorOfRoot(IResource parent, IResource[] roots) { - // Always traverse into projects in case a root was removed - if (parent.getType() == IResource.ROOT) return true; - for (int i = 0; i < roots.length; i++) { - IResource resource = roots[i]; - if (parent.getFullPath().isPrefixOf(resource.getFullPath())) { - return true; - } - } - return false; - } - - private boolean isDescendantOfRoot(IResource resource, IResource[] roots) { - for (int i = 0; i < roots.length; i++) { - IResource root = roots[i]; - if (root.getFullPath().isPrefixOf(resource.getFullPath())) { - return true; - } - } - return false; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoCollector.java deleted file mode 100644 index b9de6d77c..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoCollector.java +++ /dev/null @@ -1,215 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.team.core.subscribers.Subscriber; -import org.eclipse.team.core.synchronize.*; -import org.eclipse.team.internal.core.Policy; - -/** - * This collector maintains a {@link SyncInfoSet} for a particular team subscriber keeping - * it up-to-date with both incoming changes and outgoing changes as they occur for - * resources in the workspace. The collector can be configured to consider all the subscriber's - * roots or only a subset. - * <p> - * The advantage of this collector is that it processes both resource and team - * subscriber deltas in a background thread. - * </p> - * @since 3.0 - */ -public final class SubscriberSyncInfoCollector extends SubscriberResourceCollector { - - private SyncSetInputFromSubscriber subscriberInput; - private SyncSetInputFromSyncSet filteredInput; - private SubscriberEventHandler eventHandler; - private IResource[] roots; - - /** - * Create a collector that collects out-of-sync resources that are children of - * the given roots. If the roots are <code>null</code>, then all out-of-sync resources - * from the subscriber are collected. An empty array of roots will cause no resources - * to be collected. The <code>start()</code> method must be called after creation - * to rpime the collector's sync sets. - * @param subscriber the Subscriber - * @param roots the roots of the out-of-sync resources to be collected - */ - public SubscriberSyncInfoCollector(Subscriber subscriber, IResource[] roots) { - super(subscriber); - this.roots = roots; - this.eventHandler = new SubscriberEventHandler(subscriber, roots); - this.subscriberInput = eventHandler.getSyncSetInput(); - filteredInput = new SyncSetInputFromSyncSet(subscriberInput.getSyncSet(), getEventHandler()); - filteredInput.setFilter(new SyncInfoFilter() { - public boolean select(SyncInfo info, IProgressMonitor monitor) { - return true; - } - }); - - } - - public void setProgressGroup(IProgressMonitor monitor, int ticks) { - getEventHandler().setProgressGroupHint(monitor, ticks); - } - - /** - * Start the collector. - */ - public void start() { - eventHandler.start(); - } - - /** - * This causes the calling thread to wait any background collection of out-of-sync resources - * to stop before returning. - * @param monitor a progress monitor - */ - public void waitForCollector(IProgressMonitor monitor) { - monitor.worked(1); - // wait for the event handler to process changes. - while(eventHandler.getEventHandlerJob().getState() != Job.NONE) { - monitor.worked(1); - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - Policy.checkCanceled(monitor); - } - monitor.worked(1); - } - - /** - * Clears this collector's sync info sets and causes them to be recreated from the - * associated <code>Subscriber</code>. The reset will occur in the background. If the - * caller wishes to wait for the reset to complete, they should call - * {@link waitForCollector(IProgressMonitor)}. - */ - public void reset() { - eventHandler.reset(getRoots()); - } - - /** - * Disposes of the background job associated with this collector and deregisters - * all it's listeners. This method must be called when the collector is no longer - * referenced and could be garbage collected. - */ - public void dispose() { - eventHandler.shutdown(); - subscriberInput.disconnect(); - if(filteredInput != null) { - filteredInput.disconnect(); - } - super.dispose(); - } - - /** - * Return the roots that are being considered by this collector. - * By default, the collector is interested in the roots of its - * subscriber. However, the set can be reduced using {@link setRoots(IResource)). - * @return - */ - public IResource[] getRoots() { - if (roots == null) { - return super.getRoots(); - } else { - return roots; - } - } - - /* - * Returns whether the collector is configured to collect for - * all roots of the subscriber or not - * @return <code>true</code> if the collector is considering all - * roots of the subscriber and <code>false</code> otherwise - */ - public boolean isAllRootsIncluded() { - return roots == null; - } - - /** - * Return the event handler that performs the background processing for this collector. - * The event handler also serves the purpose of serializing the modifications and adjustments - * to the collector's sync sets in order to ensure that the state of the sets is kept - * consistent. - * @return Returns the eventHandler. - */ - protected SubscriberEventHandler getEventHandler() { - return eventHandler; - } - - /** - * Return the <code>SyncInfoSet</code> that contains all the all the out-of-sync resources for the - * subscriber that are descendants of the roots of this collector. The set will contain only those resources that are children of the roots - * of the collector unless the roots of the colletor has been set to <code>null</code> - * in which case all out-of-sync resources from the subscriber are collected. - * @return the subscriber sync info set - */ - public SyncInfoTree getSubscriberSyncInfoSet() { - return subscriberInput.getSyncSet(); - } - - public SyncInfoTree getSyncInfoSet() { - return filteredInput.getSyncSet(); - } - - /** - * Set the filter for this collector. Only elements that match the filter will - * be in the out sync info set. - * @see getSyncInfoSet() - * @param filter the sync info filter - */ - public void setFilter(SyncInfoFilter filter) { - filteredInput.setFilter(filter); - filteredInput.reset(); - } - - /** - * Return the filter that is filtering the output of this collector. - * @return a sync info filter - */ - public SyncInfoFilter getFilter() { - if(filteredInput != null) { - return filteredInput.getFilter(); - } - return null; - } - - /** - * @param roots2 - */ - public void setRoots(IResource[] roots) { - this.roots = roots; - reset(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#hasMembers(org.eclipse.core.resources.IResource) - */ - protected boolean hasMembers(IResource resource) { - return getSubscriberSyncInfoSet().hasMembers(resource); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#remove(org.eclipse.core.resources.IResource) - */ - protected void remove(IResource resource) { - eventHandler.remove(resource); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#change(org.eclipse.core.resources.IResource, int) - */ - protected void change(IResource resource, int depth) { - eventHandler.change(resource, depth); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoSet.java deleted file mode 100644 index f719cb187..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoSet.java +++ /dev/null @@ -1,89 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener; -import org.eclipse.team.core.synchronize.SyncInfoTree; -import org.eclipse.team.internal.core.Policy; - -/** - * The <code>SubscriberSyncInfoSet</code> is a <code>SyncInfoSet</code> that provides the ability to add, - * remove and change <code>SyncInfo</code> and fires change event notifications to registered listeners. - * It also provides the ability - * to batch changes in a single change notification as well as optimizations for sync info retrieval. - * - * This class uses synchronized methods and synchronized blocks to protect internal data structures during both access - * and modify operations and uses an <code>ILock</code> to make modification operations thread-safe. The events - * are fired while this lock is held so clients responding to these events should not obtain their own internal locks - * while processing change events. - * - * TODO: Override modification methods to enforce use with handler - * - */ -public class SubscriberSyncInfoSet extends SyncInfoTree { - - protected SubscriberEventHandler handler; - - public SubscriberSyncInfoSet(SubscriberEventHandler handler) { - this.handler = handler; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.SyncInfoSet#connect(org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener, org.eclipse.core.runtime.IProgressMonitor) - */ - public void connect(ISyncInfoSetChangeListener listener, IProgressMonitor monitor) { - if (handler == null) { - super.connect(listener, monitor); - } else { - connect(listener); - } - } - - /** - * Variation of connect that does not need progress and does not throw an exception. - * Progress is provided by the background event handler and errors are passed through - * the chain to the view. - * @param listener - */ - public void connect(final ISyncInfoSetChangeListener listener) { - if (handler == null) { - // Should only use this connect if the set has a handler - throw new UnsupportedOperationException(); - } else { - handler.run(new IWorkspaceRunnable() { - public void run(IProgressMonitor monitor) { - try { - beginInput(); - monitor.beginTask(null, 100); - removeSyncSetChangedListener(listener); - addSyncSetChangedListener(listener); - listener.syncInfoSetReset(SubscriberSyncInfoSet.this, Policy.subMonitorFor(monitor, 95)); - } finally { - endInput(Policy.subMonitorFor(monitor, 5)); - monitor.done(); - } - } - }, true /* high priority */); - } - } - - /** - * Return the handler that is used to provide event serialization - * and thread-safety the set population. - * @return the handler that is used to provide event serialization - * and thread-safety the set population - */ - public SubscriberEventHandler getHandler() { - return handler; - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncByteConverter.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncByteConverter.java deleted file mode 100644 index e19a7e68e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncByteConverter.java +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.core.Policy; - -/** - * Utility for managing slash separated sync information fields. - */ -public class SyncByteConverter { - - protected static final byte SEPARATOR_BYTE = (byte)'/'; - - public static String[] parseIntoSubstrings(String string, String delimiter) { - List result = new ArrayList(); - int start = 0; - int index = string.indexOf(delimiter); - String next; - while (index != -1) { - next = string.substring(start, index); - result.add(next); - start = index + 1; - index = string.indexOf(delimiter, start); - } - if (start >= string.length()) { - next = "";//$NON-NLS-1$ - } else { - next = string.substring(start); - } - result.add(next); - return (String[]) result.toArray(new String[result.size()]); - } - - /** - * Method setSlot. - * @param syncBytes - * @param i - * @param b - * @return byte[] - */ - public static byte[] setSlot(byte[] syncBytes, int slot, byte[] newBytes) throws TeamException { - int start = startOfSlot(syncBytes, slot); - if (start == -1) { - throw new TeamException(Policy.bind("SyncByteConverter.1", new String(syncBytes))); //$NON-NLS-1$ - } - int end = startOfSlot(syncBytes, slot + 1); - int totalLength = start + 1 + newBytes.length; - if (end != -1) { - totalLength += syncBytes.length - end; - } - byte[] result = new byte[totalLength]; - System.arraycopy(syncBytes, 0, result, 0, start + 1); - System.arraycopy(newBytes, 0, result, start + 1, newBytes.length); - if (end != -1) { - System.arraycopy(syncBytes, end, result, start + 1 + newBytes.length, syncBytes.length - end); - } - return result; - } - - /** - * Method startOfSlot returns the index of the slash that occurs before the - * given slot index. The provided index should be >= 1 which assumes that - * slot zero occurs before the first slash. - * - * @param syncBytes - * @param i - * @return int - */ - private static int startOfSlot(byte[] syncBytes, int slot) { - int count = 0; - for (int j = 0; j < syncBytes.length; j++) { - if (syncBytes[j] == SEPARATOR_BYTE) { - count++; - if (count == slot) return j; - } - } - return -1; - } - - /** - * Return the offset the the Nth delimeter from the given start index. - * @param bytes - * @param delimiter - * @param start - * @param n - * @return int - */ - private static int getOffsetOfDelimeter(byte[] bytes, byte delimiter, int start, int n) { - int count = 0; - for (int i = start; i < bytes.length; i++) { - if (bytes[i] == delimiter) count++; - if (count == n) return i; - } - // the Nth delimeter was not found - return -1; - } - - /** - * Method getBytesForSlot. - * @param syncBytes - * @param SEPARATOR_BYTE - * @param i - * @param b - * @return byte[] - */ - public static byte[] getSlot(byte[] bytes, int index, boolean includeRest) { - // Find the starting index - byte delimiter = SEPARATOR_BYTE; - int start; - if (index == 0) { - // make start -1 so that end determination will start at offset 0. - start = -1; - } else { - start = getOffsetOfDelimeter(bytes, delimiter, 0, index); - if (start == -1) return null; - } - // Find the ending index - int end = getOffsetOfDelimeter(bytes, delimiter, start + 1, 1); - // Calculate the length - int length; - if (end == -1 || includeRest) { - length = bytes.length - start - 1; - } else { - length = end - start - 1; - } - byte[] result = new byte[length]; - System.arraycopy(bytes, start + 1, result, 0, length); - return result; - } - - public static byte[] toBytes(String[] slots) { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < slots.length; i++) { - String string = slots[i]; - buffer.append(string); - buffer.append(new String(new byte[] {SyncByteConverter.SEPARATOR_BYTE })); - } - return buffer.toString().getBytes(); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoStatistics.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoStatistics.java deleted file mode 100644 index ad8d44eb7..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoStatistics.java +++ /dev/null @@ -1,107 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import org.eclipse.team.core.synchronize.SyncInfo; - -/** - * Counts SyncInfo states and allows for easy querying for different sync states. - */ -public class SyncInfoStatistics { - // {int sync kind -> int number of infos with that sync kind in this sync set} - protected Map stats = new HashMap(); - - /** - * Count this sync kind. Only the type of the sync info is stored. - * @param info the new info - */ - public void add(SyncInfo info) { - // update statistics - Long count = (Long)stats.get(new Integer(info.getKind())); - if(count == null) { - count = new Long(0); - } - stats.put(new Integer(info.getKind()), new Long(count.longValue() + 1)); - } - - /** - * Remove this sync kind. - * @param info the info type to remove - */ - public void remove(SyncInfo info) { - // update stats - Integer kind = new Integer(info.getKind()); - Long count = (Long)stats.get(kind); - if(count == null) { - // error condition, shouldn't be removing if we haven't added yet - // programmer error calling remove before add. - } else { - long newCount = count.intValue() - 1; - if(newCount > 0) { - stats.put(kind, new Long(newCount)); - } else { - stats.remove(kind); - } - } - } - - /** - * Return the count of sync infos for the specified sync kind. A mask can be used to acucmulate - * counts for specific directions or change types. - * To return the number of outgoing changes: - * long outgoingChanges = stats.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK); - * - * @param kind the sync kind for which to return the count - * @param mask the mask applied to the stored sync kind - * @return the number of sync info types added for the specific kind - */ - public long countFor(int kind, int mask) { - if(mask == 0) { - Long count = (Long)stats.get(new Integer(kind)); - return count == null ? 0 : count.longValue(); - } else { - Iterator it = stats.keySet().iterator(); - long count = 0; - while (it.hasNext()) { - Integer key = (Integer) it.next(); - if((key.intValue() & mask) == kind) { - count += ((Long)stats.get(key)).intValue(); - } - } - return count; - } - } - - /** - * Clear the statistics counts. All calls to countFor() will return 0 until new - * sync infos are added. - */ - public void clear() { - stats.clear(); - } - - /** - * For debugging - */ - public String toString() { - StringBuffer out = new StringBuffer(); - Iterator it = stats.keySet().iterator(); - while (it.hasNext()) { - Integer kind = (Integer) it.next(); - out.append(SyncInfo.kindToString(kind.intValue()) + ": " + stats.get(kind) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ - } - return out.toString(); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoTreeChangeEvent.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoTreeChangeEvent.java deleted file mode 100644 index db58b435b..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoTreeChangeEvent.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.*; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.synchronize.ISyncInfoTreeChangeEvent; -import org.eclipse.team.core.synchronize.SyncInfoSet; - -public class SyncInfoTreeChangeEvent extends SyncSetChangedEvent implements ISyncInfoTreeChangeEvent { - - private Set removedSubtrees = new HashSet(); - private Set addedSubtrees = new HashSet(); - - public SyncInfoTreeChangeEvent(SyncInfoSet set) { - super(set); - } - - public void removedSubtreeRoot(IResource root) { - if (addedSubtrees.contains(root)) { - // The root was added and removed which is a no-op - addedSubtrees.remove(root); - } else if (isDescendantOfAddedRoot(root)) { - // Nothing needs to be done since no listeners ever knew about the root - } else { - // check if the root is a child of an existing root - // (in which case it need not be added). - // Also, remove any exisiting roots that are children - // of the new root - for (Iterator iter = removedSubtrees.iterator(); iter.hasNext();) { - IResource element = (IResource) iter.next(); - // check if the root is already in the list - if (root.equals(element)) return; - if (isParent(root, element)) { - // the root invalidates the current element - iter.remove(); - } else if (isParent(element, root)) { - // the root is a child of an existing element - return; - } - } - removedSubtrees.add(root); - } - } - - private boolean isParent(IResource root, IResource element) { - return root.getFullPath().isPrefixOf(element.getFullPath()); - } - - public void addedSubtreeRoot(IResource parent) { - if (removedSubtrees.contains(parent)) { - // The root was re-added. Just removing the removedRoot - // may not give the proper event. - // Since we can't be sure, just force a reset. - reset(); - } else { - // only add the root if their isn't a higher root in the list already - if (!isDescendantOfAddedRoot(parent)) { - addedSubtrees.add(parent); - } - } - } - - private boolean isDescendantOfAddedRoot(IResource resource) { - for (Iterator iter = addedSubtrees.iterator(); iter.hasNext();) { - IResource root = (IResource) iter.next(); - if (isParent(root, resource)) { - // There is a higher added root already in the list - return true; - } - } - return false; - } - - public IResource[] getAddedSubtreeRoots() { - return (IResource[]) addedSubtrees.toArray(new IResource[addedSubtrees.size()]); - } - - public IResource[] getRemovedSubtreeRoots() { - return (IResource[]) removedSubtrees.toArray(new IResource[removedSubtrees.size()]); - } - - public boolean isEmpty() { - return super.isEmpty() && removedSubtrees.isEmpty() && addedSubtrees.isEmpty(); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoWorkingSetFilter.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoWorkingSetFilter.java deleted file mode 100644 index 5a671b41e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncInfoWorkingSetFilter.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.*; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.*; -import org.eclipse.team.core.synchronize.*; -import org.eclipse.team.internal.core.TeamPlugin; - -/** - * WorkingSet filter for a SyncSet. - */ -public class SyncInfoWorkingSetFilter extends FastSyncInfoFilter { - - private IResource[] resources; - - /* (non-Javadoc) - * @see org.eclipse.team.ui.sync.SyncInfoFilter#select(org.eclipse.team.core.subscribers.SyncInfo) - */ - public boolean select(SyncInfo info) { - // if there's no set, the resource is included - if (isEmpty()) return true; - return isIncluded(info.getLocal()); - } - - /* - * Answer true if the given resource is included in the working set - */ - private boolean isIncluded(IResource resource) { - // otherwise, if their is a parent of the resource in the set, - // it is included - for (int i = 0; i < resources.length; i++) { - IResource setResource = resources[i]; - if (isParent(setResource, resource)) { - return true; - } - } - return false; - } - - private boolean isParent(IResource parent, IResource child) { - return (parent.getFullPath().isPrefixOf(child.getFullPath())); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.SyncSetInputFromSubscriber#getRoots() - */ - public IResource[] getRoots(Subscriber subscriber) { - IResource[] roots = subscriber.roots(); - if (isEmpty()) return roots; - - // filter the roots by the selected working set - Set result = new HashSet(); - for (int i = 0; i < roots.length; i++) { - IResource resource = roots[i]; - result.addAll(Arrays.asList(getIntersectionWithSet(subscriber, resource))); - } - return (IResource[]) result.toArray(new IResource[result.size()]); - } - - /* - * Answer the intersection between the given resource and it's children - * and the receiver's working set. - */ - private IResource[] getIntersectionWithSet(Subscriber subscriber, IResource resource) { - List result = new ArrayList(); - for (int i = 0; i < resources.length; i++) { - IResource setResource = resources[i]; - if (setResource != null) { - if (isParent(resource, setResource)) { - try { - if (subscriber.isSupervised(setResource)) { - result.add(setResource); - } - } catch (TeamException e) { - // Log the exception and add the resource to the list - TeamPlugin.log(e); - result.add(setResource); - } - } else if (isParent(setResource, resource)) { - result.add(resource); - } - } - } - return (IResource[]) result.toArray(new IResource[result.size()]); - } - - public void setWorkingSet(IResource[] resources) { - this.resources = resources; - } - - public IResource[] getWorkingSet() { - return this.resources; - } - - private boolean isEmpty() { - return resources == null || resources.length == 0; - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetChangedEvent.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetChangedEvent.java deleted file mode 100644 index c9dd433e4..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetChangedEvent.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import java.util.*; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.ITeamStatus; -import org.eclipse.team.core.synchronize.*; - -/** - * This event keeps track of the changes in a sync set - */ -public class SyncSetChangedEvent implements ISyncInfoSetChangeEvent { - - private SyncInfoSet set; - - // List that accumulate changes - // SyncInfo - private Map changedResources = new HashMap(); - private Set removedResources = new HashSet(); - private Map addedResources = new HashMap(); - - private boolean reset = false; - - private List errors = new ArrayList(); - - public SyncSetChangedEvent(SyncInfoSet set) { - super(); - this.set = set; - } - - public void added(SyncInfo info) { - if (removedResources.contains(info.getLocal())) { - // A removal followed by an addition is treated as a change - removedResources.remove(info.getLocal()); - changed(info); - } else { - addedResources.put(info.getLocal(), info); - } - } - - public void removed(IResource resource, SyncInfo info) { - if (changedResources.containsKey(resource)) { - // No use in reporting the change since it has subsequently been removed - changedResources.remove(resource); - } else if (addedResources.containsKey(resource)) { - // An addition followed by a removal can be dropped - addedResources.remove(resource); - return; - } - removedResources.add(resource); - } - - public void changed(SyncInfo info) { - IResource resource = info.getLocal(); - if (addedResources.containsKey(resource)) { - // An addition followed by a change is an addition - addedResources.put(resource, info); - return; - } - changedResources.put(resource, info); - } - - public SyncInfo[] getAddedResources() { - return (SyncInfo[]) addedResources.values().toArray(new SyncInfo[addedResources.size()]); - } - - public SyncInfo[] getChangedResources() { - return (SyncInfo[]) changedResources.values().toArray(new SyncInfo[changedResources.size()]); - } - - public IResource[] getRemovedResources() { - return (IResource[]) removedResources.toArray(new IResource[removedResources.size()]); - } - - public SyncInfoSet getSet() { - return set; - } - - public void reset() { - reset = true; - } - - public boolean isReset() { - return reset; - } - - public boolean isEmpty() { - return changedResources.isEmpty() && removedResources.isEmpty() && addedResources.isEmpty() && errors.isEmpty(); - } - - public void errorOccurred(ITeamStatus status) { - errors.add(status); - } - - public ITeamStatus[] getErrors() { - return (ITeamStatus[]) errors.toArray(new ITeamStatus[errors.size()]); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInput.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInput.java deleted file mode 100644 index 716322230..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInput.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.synchronize.*; -import org.eclipse.team.internal.core.Policy; - -/** - * This is the superclass for all SyncSet input providers - */ -public abstract class SyncSetInput { - - private SubscriberSyncInfoSet syncSet; - private SyncInfoFilter filter = new FastSyncInfoFilter(); - - public SyncSetInput(SubscriberEventHandler handler) { - syncSet = new SubscriberSyncInfoSet(handler); - } - - public SubscriberSyncInfoSet getSyncSet() { - return syncSet; - } - - /** - * This method is invoked from reset to get all the sync information from - * the input source. - */ - protected abstract void fetchInput(IProgressMonitor monitor) throws TeamException; - - /** - * The input is no longer being used. Disconnect it from its source. - */ - public abstract void disconnect(); - - /** - * Reset the input. This will clear the current contents of the sync set and - * obtain the contents from the input source. - */ - public void reset(IProgressMonitor monitor) throws TeamException { - - try { - syncSet.beginInput(); - monitor = Policy.monitorFor(monitor); - monitor.beginTask(null, 100); - syncSet.clear(); - fetchInput(Policy.subMonitorFor(monitor, 90)); - } finally { - syncSet.endInput(Policy.subMonitorFor(monitor, 10)); - monitor.done(); - } - } - - /** - * Collect the change in the provided sync info. - */ - protected void collect(SyncInfo info, IProgressMonitor monitor) { - boolean isOutOfSync = filter.select(info, monitor); - SyncInfo oldInfo = syncSet.getSyncInfo(info.getLocal()); - boolean wasOutOfSync = oldInfo != null; - if (isOutOfSync) { - syncSet.add(info); - } else if (wasOutOfSync) { - syncSet.remove(info.getLocal()); - } - } - - protected void remove(IResource resource) { - SyncInfo oldInfo = syncSet.getSyncInfo(resource); - if (oldInfo != null) { - syncSet.remove(resource); - } - } - - public SyncInfoFilter getFilter() { - return filter; - } - - public void setFilter(SyncInfoFilter filter) { - this.filter = filter; - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInputFromSubscriber.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInputFromSubscriber.java deleted file mode 100644 index 9e0585325..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInputFromSubscriber.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.ITeamStatus; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.Subscriber; - -/** - * Records resource synchronization changes from a Team subscriber. The actual changes - * are calculated via the SubscriberEventHandler and stored in this input. - */ -public class SyncSetInputFromSubscriber extends SyncSetInput { - - private Subscriber subscriber; - - public SyncSetInputFromSubscriber(Subscriber subscriber, SubscriberEventHandler handler) { - super(handler); - this.subscriber = subscriber; - } - - public void disconnect() { - } - - public Subscriber getSubscriber() { - return subscriber; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.sync.views.SyncSetInput#fetchInput(org.eclipse.core.runtime.IProgressMonitor) - */ - protected void fetchInput(IProgressMonitor monitor) throws TeamException { - // don't calculate changes. The SubscriberEventHandler will fetch the - // input in a job and update this sync set when the changes are - // calculated. - } - - /** - * Handle an error that occurred while populating the receiver's set. - * The <code>ITeamStatus</code> includes the resource for which the - * error occurred. - * This error is propogated to any set listeners. - * @param status the error status - */ - public void handleError(ITeamStatus status) { - getSyncSet().addError(status); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInputFromSyncSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInputFromSyncSet.java deleted file mode 100644 index 13deb259e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SyncSetInputFromSyncSet.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.ITeamStatus; -import org.eclipse.team.core.synchronize.*; -import org.eclipse.team.internal.core.Policy; - -/** - * Ths class uses the contents of one sync set as the input of another. - */ -public class SyncSetInputFromSyncSet extends SyncSetInput implements ISyncInfoSetChangeListener { - - SubscriberSyncInfoSet inputSyncSet; - - public SyncSetInputFromSyncSet(SubscriberSyncInfoSet set, SubscriberEventHandler handler) { - super(handler); - this.inputSyncSet = set; - inputSyncSet.addSyncSetChangedListener(this); - } - - public SyncInfoSet getInputSyncSet() { - return inputSyncSet; - } - - public void disconnect() { - if (inputSyncSet == null) return; - inputSyncSet.removeSyncSetChangedListener(this); - inputSyncSet = null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.AbstractSyncSet#initialize(java.lang.String, org.eclipse.core.runtime.IProgressMonitor) - */ - protected void fetchInput(IProgressMonitor monitor) { - if (inputSyncSet == null) return; - SyncInfo[] infos = inputSyncSet.getSyncInfos(); - for (int i = 0; i < infos.length; i++) { - collect(infos[i], monitor); - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.ccvs.syncviews.views.ISyncSetChangedListener#syncSetChanged(org.eclipse.team.ccvs.syncviews.views.SyncSetChangedEvent) - */ - public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { - SyncInfoSet syncSet = getSyncSet(); - try { - syncSet.beginInput(); - monitor.beginTask(null, 105); - syncSetChanged(event.getChangedResources(), Policy.subMonitorFor(monitor, 50)); - syncSetChanged(event.getAddedResources(), Policy.subMonitorFor(monitor, 50)); - remove(event.getRemovedResources()); - } finally { - syncSet.endInput(Policy.subMonitorFor(monitor, 5)); - } - } - - private void syncSetChanged(SyncInfo[] infos, IProgressMonitor monitor) { - for (int i = 0; i < infos.length; i++) { - collect(infos[i], monitor); - } - } - - private void remove(IResource[] resources) { - for (int i = 0; i < resources.length; i++) { - remove(resources[i]); - } - } - - public void reset() { - inputSyncSet.connect(this); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.subscribers.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { - if(inputSyncSet == null) { - set.removeSyncSetChangedListener(this); - } else { - SyncInfoSet syncSet = getSyncSet(); - try { - syncSet.beginInput(); - monitor.beginTask(null, 100); - syncSet.clear(); - fetchInput(Policy.subMonitorFor(monitor, 95)); - } finally { - syncSet.endInput(Policy.subMonitorFor(monitor, 5)); - monitor.done(); - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.subscribers.ISyncInfoSetChangeListener#syncInfoSetError(org.eclipse.team.core.subscribers.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { - SubscriberSyncInfoSet syncSet = getSyncSet(); - try { - syncSet.beginInput(); - for (int i = 0; i < errors.length; i++) { - ITeamStatus status = errors[i]; - syncSet.addError(status); - } - } finally { - syncSet.endInput(monitor); - } - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/ThreeWayBaseTree.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/ThreeWayBaseTree.java deleted file mode 100644 index 1d7d1cb67..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/ThreeWayBaseTree.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.variants.IResourceVariant; -import org.eclipse.team.core.variants.ResourceVariantByteStore; -import org.eclipse.team.core.variants.ResourceVariantTree; -import org.eclipse.team.core.variants.ThreeWaySubscriber; - -/** - * Allow access to the base resource variants but do not support refresh - * or modification. - */ -public final class ThreeWayBaseTree extends ResourceVariantTree { - - private ThreeWaySubscriber subscriber; - - /* - * A resource variant byte store that accesses the base bytes from a three-way - * synchronizer. The modification methods are disabled as the base should - * only be modified in the synchronizer directly. - */ - static class BaseResourceVariantByteStore extends ResourceVariantByteStore { - private ThreeWaySubscriber subscriber; - public BaseResourceVariantByteStore(ThreeWaySubscriber subscriber) { - this.subscriber = subscriber; - } - public void dispose() { - // Nothing to do - } - public byte[] getBytes(IResource resource) throws TeamException { - return subscriber.getSynchronizer().getBaseBytes(resource); - } - public boolean setBytes(IResource resource, byte[] bytes) throws TeamException { - // Base bytes are set directly in the synchronizer - return false; - } - public boolean flushBytes(IResource resource, int depth) throws TeamException { - // Base bytes are flushed directly in the synchronizer - return false; - } - public boolean deleteBytes(IResource resource) throws TeamException { - // Base bytes are deleted directly in the synchronizer - return false; - } - public IResource[] members(IResource resource) throws TeamException { - return subscriber.getSynchronizer().members(resource); - } - } - - /** - * Create a base resource variant tree that accesses the base bytes - * from a three-way synchronizer. - * @param subscriber the three-way subscriber - */ - public ThreeWayBaseTree(ThreeWaySubscriber subscriber) { - super(new BaseResourceVariantByteStore(subscriber)); - this.subscriber = subscriber; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.AbstractResourceVariantTree#refresh(org.eclipse.core.resources.IResource[], int, org.eclipse.core.runtime.IProgressMonitor) - */ - public IResource[] refresh(IResource[] resources, int depth, IProgressMonitor monitor) throws TeamException { - return new IResource[0]; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.AbstractResourceVariantTree#fetchMembers(org.eclipse.team.core.synchronize.IResourceVariant, org.eclipse.core.runtime.IProgressMonitor) - */ - protected IResourceVariant[] fetchMembers(IResourceVariant variant, IProgressMonitor progress) throws TeamException { - // Refresh not supported - return new IResourceVariant[0]; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.AbstractResourceVariantTree#fetchVariant(org.eclipse.core.resources.IResource, int, org.eclipse.core.runtime.IProgressMonitor) - */ - protected IResourceVariant fetchVariant(IResource resource, int depth, IProgressMonitor monitor) throws TeamException { - // Refresh not supported - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#roots() - */ - public IResource[] roots() { - return getSubscriber().roots(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.caches.IResourceVariantTree#getResourceVariant(org.eclipse.core.resources.IResource) - */ - public IResourceVariant getResourceVariant(IResource resource) throws TeamException { - return getSubscriber().getResourceVariant(resource, getByteStore().getBytes(resource)); - } - - private ThreeWaySubscriber getSubscriber() { - return subscriber; - } - -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/WorkingSetFilteredSyncInfoCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/WorkingSetFilteredSyncInfoCollector.java deleted file mode 100644 index dce19545e..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/WorkingSetFilteredSyncInfoCollector.java +++ /dev/null @@ -1,195 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.core.synchronize.SyncInfoFilter; -import org.eclipse.team.core.synchronize.SyncInfoSet; -import org.eclipse.team.core.synchronize.SyncInfoTree; -import org.eclipse.team.internal.core.Policy; - -/** - * This collector maintains a {@link SyncInfoSet} for a particular team subscriber keeping - * it up-to-date with both incoming changes and outgoing changes as they occur for - * resources in the workspace. The collector can be configured to consider all the subscriber's - * roots or only a subset. - * <p> - * The advantage of this collector is that it processes both resource and team - * subscriber deltas in a background thread. - * </p> - * @since 3.0 - */ -public final class WorkingSetFilteredSyncInfoCollector { - - private WorkingSetSyncSetInput workingSetInput; - private SyncSetInputFromSyncSet filteredInput; - private SubscriberEventHandler eventHandler; - private IResource[] roots; - - /** - * Create a collector that collects out-of-sync resources that are children of - * the given roots. If the roots are <code>null</code>, then all out-of-sync resources - * from the subscriber are collected. An empty array of roots will cause no resources - * to be collected. The <code>start()</code> method must be called after creation - * to rpime the collector's sync sets. - * @param subscriber the Subscriber - * @param roots the roots of the out-of-sync resources to be collected - */ - public WorkingSetFilteredSyncInfoCollector(SubscriberSyncInfoCollector collector, IResource[] roots) { - this.roots = roots; - this.eventHandler = collector.getEventHandler(); - // TODO: optimize and don't use working set if no roots are passed in - workingSetInput = new WorkingSetSyncSetInput((SubscriberSyncInfoSet)collector.getSyncInfoSet(), getEventHandler()); - filteredInput = new SyncSetInputFromSyncSet(workingSetInput.getSyncSet(), getEventHandler()); - filteredInput.setFilter(new SyncInfoFilter() { - public boolean select(SyncInfo info, IProgressMonitor monitor) { - return true; - } - }); - } - - /** - * Return the set that provides access to the out-of-sync resources for the collector's - * subscriber that are descendants of the roots for the collector, - * are in the collector's working set and match the collectors filter. - * @see getSubscriberSyncInfoSet() - * @see getWorkingSetSyncInfoSet() - * @return a SyncInfoSet containing out-of-sync resources - */ - public SyncInfoTree getSyncInfoTree() { - return filteredInput.getSyncSet(); - } - - /** - * This causes the calling thread to wait any background collection of out-of-sync resources - * to stop before returning. - * @param monitor a progress monitor - */ - public void waitForCollector(IProgressMonitor monitor) { - monitor.worked(1); - // wait for the event handler to process changes. - while(eventHandler.getEventHandlerJob().getState() != Job.NONE) { - monitor.worked(1); - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - Policy.checkCanceled(monitor); - } - monitor.worked(1); - } - - /** - * Return the roots that are being considered by this collector. - * By default, the collector is interested in the roots of its - * subscriber. However, the set can be reduced using {@link setRoots(IResource)). - * @return - */ - public IResource[] getRoots() { - return roots; - } - - /** - * Clears this collector's sync info sets and causes them to be recreated from the - * associated <code>Subscriber</code>. The reset will occur in the background. If the - * caller wishes to wait for the reset to complete, they should call - * {@link waitForCollector(IProgressMonitor)}. - */ - public void reset() { - workingSetInput.reset(); - } - - /** - * Disposes of the background job associated with this collector and deregisters - * all it's listeners. This method must be called when the collector is no longer - * referenced and could be garbage collected. - */ - public void dispose() { - workingSetInput.disconnect(); - if(filteredInput != null) { - filteredInput.disconnect(); - } - } - - /** - * Return the event handler that performs the background processing for this collector. - * The event handler also serves the purpose of serializing the modifications and adjustments - * to the collector's sync sets in order to ensure that the state of the sets is kept - * consistent. - * @return Returns the eventHandler. - */ - protected SubscriberEventHandler getEventHandler() { - return eventHandler; - } - - /** - * Set the working set resources used to filter the output <code>SyncInfoSet</code>. - * @see getWorkingSetSyncInfoSet() - * @param resources the working set resources - */ - public void setWorkingSet(IResource[] resources) { - workingSetInput.setWorkingSet(resources); - workingSetInput.reset(); - } - - /** - * Get th working set resources used to filter the output sync info set. - * @return the working set resources - */ - public IResource[] getWorkingSet() { - return workingSetInput.getWorkingSet(); - } - - /** - * Set the filter for this collector. Only elements that match the filter will - * be in the out sync info set. - * @see getSyncInfoSet() - * @param filter the sync info filter - */ - public void setFilter(SyncInfoFilter filter) { - filteredInput.setFilter(filter); - filteredInput.reset(); - } - - /** - * Return the filter that is filtering the output of this collector. - * @return a sync info filter - */ - public SyncInfoFilter getFilter() { - if(filteredInput != null) { - return filteredInput.getFilter(); - } - return null; - } - - /** - * Return a <code>SyncInfoSet</code> that contains the out-of-sync elements - * from the subsciber sync info set filtered - * by the working set resources but not the collector's <code>SyncInfoFilter</code>. - * @see getSubscriberSyncInfoSet() - * @return a <code>SyncInfoSet</code> - */ - public SyncInfoSet getWorkingSetSyncInfoSet() { - return workingSetInput.getSyncSet(); - } - - /** - * Run the given runnable in the event handler of the collector - * @param runnable a runnable - */ - public void run(IWorkspaceRunnable runnable) { - eventHandler.run(runnable, true /* front of queue */); - } -} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/WorkingSetSyncSetInput.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/WorkingSetSyncSetInput.java deleted file mode 100644 index 2f220a7eb..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/WorkingSetSyncSetInput.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.core.subscribers; - -import org.eclipse.core.resources.IResource; -import org.eclipse.team.core.subscribers.Subscriber; - -public class WorkingSetSyncSetInput extends SyncSetInputFromSyncSet { - - private SyncInfoWorkingSetFilter workingSetFilter = new SyncInfoWorkingSetFilter(); - - public WorkingSetSyncSetInput(SubscriberSyncInfoSet set, SubscriberEventHandler handler) { - super(set, handler); - setFilter(workingSetFilter); - } - - public void setWorkingSet(IResource[] resources) { - workingSetFilter.setWorkingSet(resources); - } - - public IResource[] getWorkingSet() { - return workingSetFilter.getWorkingSet(); - } - - public IResource[] roots(Subscriber subscriber) { - return workingSetFilter.getRoots(subscriber); - } -} |