Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Macguire2002-05-07 00:14:59 +0000
committerKevin Macguire2002-05-07 00:14:59 +0000
commita3cefc92a8475885542405578f8b8c16016ae570 (patch)
tree4f2b5326c69c58b6f5e8059fd830c6c680e46e5e
parent69c5f62ba8c29300885ffcb08a5a6fc0ddfea2e9 (diff)
downloadeclipse.platform.team-a3cefc92a8475885542405578f8b8c16016ae570.tar.gz
eclipse.platform.team-a3cefc92a8475885542405578f8b8c16016ae570.tar.xz
eclipse.platform.team-a3cefc92a8475885542405578f8b8c16016ae570.zip
*** empty log message ***
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/ResourceState.java8
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/StreamUtil.java52
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/Symmetria.java252
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/SynchronizedTargetProvider.java441
-rw-r--r--bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/messages.properties11
5 files changed, 760 insertions, 4 deletions
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/ResourceState.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/ResourceState.java
index e31e217d1..3e4a78f1e 100644
--- a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/ResourceState.java
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/ResourceState.java
@@ -66,7 +66,7 @@ public abstract class ResourceState {
*/
public ResourceState(IResource localResource) {
super();
- StateFactory.getSynchronizer().add(getStateType());
+ SynchronizedTargetProvider.getSynchronizer().add(getStateType());
this.localResource = localResource;
}
@@ -335,7 +335,7 @@ public abstract class ResourceState {
public final void loadState() {
try {
byte[] storedState =
- StateFactory.getSynchronizer().getSyncInfo(getStateType(), localResource);
+ SynchronizedTargetProvider.getSynchronizer().getSyncInfo(getStateType(), localResource);
if (storedState != null)
fromBytes(storedState);
} catch (CoreException e) {
@@ -371,7 +371,7 @@ public abstract class ResourceState {
public final void storeState() {
try {
- StateFactory.getSynchronizer().setSyncInfo(
+ SynchronizedTargetProvider.getSynchronizer().setSyncInfo(
getStateType(),
localResource,
toBytes());
@@ -416,7 +416,7 @@ public abstract class ResourceState {
final public void removeState() {
try {
- StateFactory.getSynchronizer().flushSyncInfo(
+ SynchronizedTargetProvider.getSynchronizer().flushSyncInfo(
getStateType(),
localResource,
IResource.DEPTH_INFINITE);
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/StreamUtil.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/StreamUtil.java
new file mode 100644
index 000000000..3294b02e5
--- /dev/null
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/StreamUtil.java
@@ -0,0 +1,52 @@
+package org.eclipse.team.internal.core.target;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.team.internal.core.Policy;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class StreamUtil {
+
+ protected final static byte[] COPY_BUFFER = new byte[4096];
+
+ /*
+ *
+ */
+ public static void pipe(
+ InputStream in,
+ OutputStream out,
+ long sizeEstimate,
+ IProgressMonitor progress,
+ String title)
+ throws IOException {
+
+ // Only show progress for files larger than 25Kb.
+ Long kilobytesEstimate = new Long(sizeEstimate / 1024);
+ boolean showProgress = (progress != null) && (sizeEstimate > 25000);
+ long bytesCopied = 0;
+
+ synchronized (COPY_BUFFER) {
+ // Read the initial chunk.
+ int read = in.read(COPY_BUFFER, 0, COPY_BUFFER.length);
+
+ while (read != -1) {
+ out.write(COPY_BUFFER, 0, read);
+
+ // Report progress
+ if (showProgress) {
+ bytesCopied = bytesCopied + read;
+ progress.subTask(
+ Policy.bind(
+ "filetransfer.monitor",
+ new Object[] { title, new Long(bytesCopied / 1024), kilobytesEstimate }));
+ }
+
+ // Read the next chunk.
+ read = in.read(COPY_BUFFER, 0, COPY_BUFFER.length);
+ } // end while
+ } // end synchronized
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/Symmetria.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/Symmetria.java
new file mode 100644
index 000000000..aef6aaded
--- /dev/null
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/Symmetria.java
@@ -0,0 +1,252 @@
+package org.eclipse.team.internal.core.target;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.TeamPlugin;
+import sun.security.action.GetLongAction;
+import org.eclipse.team.core.RepositoryProvider;
+
+/**
+ * Synchronizes the given folder between the workspace and provider.
+ */
+public class Symmetria {
+
+ /**
+ * Remote knows best.
+ */
+ public IStatus get(
+ ResourceState resourceState,
+ int depth,
+ IProgressMonitor progress) {
+
+ IResource localResource = resourceState.getLocal();
+
+ // If remote does not exist then simply ensure no local resource exists.
+ if (!resourceState.hasRemote())
+ return deleteLocal(localResource, progress);
+
+ // If the remote resource is a file.
+ if (resourceState.getRemoteType() == IResource.FILE) {
+ // Replace any existing local resource with a copy of the remote file.
+ IStatus deleteStatus = deleteLocal(localResource, progress);
+ if (!deleteStatus.isOK())
+ return deleteStatus;
+ return resourceState.download(progress);
+ }
+
+ // The remote resource is a container.
+
+ // If the local resource is a file, we must remove it first.
+ if (localResource.getType() == IResource.FILE) {
+ IStatus deleteStatus = deleteLocal(localResource, progress); // May not exist.
+ if (!deleteStatus.isOK())
+ return deleteStatus;
+ }
+
+ // If the local resource does not exist then it is created as a container.
+ if (!localResource.exists()) {
+ // Create a corresponding local directory.
+ IStatus mkdirsStatus = mkLocalDirs(localResource, progress);
+ if (!mkdirsStatus.isOK())
+ return mkdirsStatus;
+ }
+
+ // Finally, resolve the collection membership based upon the depth parameter.
+ switch (depth) {
+ case IResource.DEPTH_ZERO :
+ // If we are not considering members of the collection then we are done.
+ return ITeamStatusConstants.OK_STATUS;
+ case IResource.DEPTH_ONE :
+ // If we are considering only the immediate members of the collection
+ try {
+ getFolderShallow(resourceState, progress);
+ } catch (TeamException exception) {
+ return exception.getStatus();
+ }
+ return ITeamStatusConstants.OK_STATUS;
+ case IResource.DEPTH_INFINITE :
+ // We are going in deep.
+ return getFolderDeep(resourceState, progress);
+ default :
+ // We have covered all the legal cases.
+ Assert.isLegal(false);
+ return null; // Never reached.
+ } // end switch
+ }
+
+ /**
+ * Synch the remote and local folder to depth.
+ */
+ protected IStatus getFolderDeep(
+ ResourceState collection,
+ IProgressMonitor progress) {
+
+ ResourceState[] childFolders;
+ try {
+ childFolders = getFolderShallow(collection, progress);
+ } catch (TeamException exception) {
+ // Problem getting the folder at this level.
+ return exception.getStatus();
+ }
+
+ // If there are no further children then we are done.
+ if (childFolders.length == 0)
+ return ITeamStatusConstants.OK_STATUS;
+
+ // There are children and we are going deep, the response will be a multi-status.
+ MultiStatus multiStatus =
+ new MultiStatus(
+ ITeamStatusConstants.OK_STATUS.getPlugin(),
+ ITeamStatusConstants.OK_STATUS.getCode(),
+ ITeamStatusConstants.OK_STATUS.getMessage(),
+ ITeamStatusConstants.OK_STATUS.getException());
+
+ // Collect the responses in the multistatus.
+ for (int i = 0; i < childFolders.length; i++)
+ multiStatus.add(get(childFolders[i], IResource.DEPTH_INFINITE, progress));
+
+ return multiStatus;
+ }
+
+ /**
+ * Synchronize from the remote provider to the workspace.
+ * Assume that the 'remote' folder is correct, and change the local
+ * folder to look like the remote folder.
+ *
+ * returns an array of children of the remote resource that are themselves
+ * collections.
+ */
+ protected ResourceState[] getFolderShallow(
+ ResourceState containerState,
+ IProgressMonitor progress) throws TeamException {
+
+ // We are assuming that the resource is a container.
+ Assert.isLegal(containerState.getLocal() instanceof IContainer);
+ IContainer localContainer = (IContainer)containerState.getLocal();
+
+ // Get list of all _remote_ children.
+ ResourceState[] remoteChildren = containerState.getRemoteChildren();
+
+ // This will be the list of remote children that are themselves containers.
+ Set remoteChildFolders = new HashSet();
+
+ // Make a list of _local_ children that have not yet been processed,
+ IResource[] localChildren = getLocalChildren(localContainer);
+ Set surplusLocalChildren = new HashSet(localChildren.length);
+ surplusLocalChildren.addAll(Arrays.asList(localChildren));
+
+ // For each remote child that is a file, make the local file content equivalent.
+ for (int i = 0; i < remoteChildren.length; i++) {
+ ResourceState remoteChildState = remoteChildren[i];
+ // If the remote child is a container add it to the list, and ensure that the local child
+ // is a folder if it exists.
+ if (remoteChildState.getRemoteType() == IResource.FILE) {
+ // The remote resource is a file. Copy the content of the remote file
+ // to the local file, overwriting any existing content that may exist, and
+ // creating the file if it doesn't.
+ IStatus downloadStatus = remoteChildState.download(progress);
+ if (!downloadStatus.isOK())
+ throw new TeamException(downloadStatus);
+ // Remember that we have processed this child.
+ surplusLocalChildren.remove(remoteChildState.getLocal());
+ } else {
+ // The remote resource is a container.
+ remoteChildFolders.add(remoteChildState);
+ // If the local child is not a container then it must be deleted.
+ IResource localChild = remoteChildState.getLocal();
+ if (localChild.exists() && (!(localChild instanceof IContainer)))
+ checkedDeleteLocal(localChild, progress);
+ } // end if
+ } // end for
+
+ // Remove each local child that does not have a corresponding remote resource.
+ Iterator childrenItr = surplusLocalChildren.iterator();
+ while (childrenItr.hasNext()) {
+ IResource unseenChild = (IResource) childrenItr.next();
+ checkedDeleteLocal(unseenChild, progress);
+ } // end-while
+
+ // Answer the array of children seen on the remote collection that are
+ // themselves collections (to support depth operations).
+ return (ResourceState[]) remoteChildFolders.toArray(
+ new ResourceState[remoteChildFolders.size()]);
+ }
+
+ /**
+ * Calls delete local and throws an exceptionif a problem arises.
+ */
+ protected void checkedDeleteLocal(
+ IResource resource,
+ IProgressMonitor progress) throws TeamException {
+
+ IStatus deleteStatus = deleteLocal(resource, progress);
+ if (!deleteStatus.isOK())
+ throw new TeamException(ITeamStatusConstants.CONFLICT_STATUS);
+ }
+
+ /**
+ * Delete the local resource represented by the resource state. Do not complain if the resource does not exist.
+ */
+ protected IStatus deleteLocal(
+ IResource resource,
+ IProgressMonitor progress) {
+
+ try {
+ resource.delete(true, progress);
+ } catch (CoreException exception) {
+ //todo: we need to return the real exception
+ return ITeamStatusConstants.IO_FAILED_STATUS;
+ }
+
+ // The delete succeeded.
+ return ITeamStatusConstants.OK_STATUS;
+ }
+
+ /**
+ * Make local directories matching the description of the local resource state.
+ * XXX There has to be a better way.
+ */
+ protected IStatus mkLocalDirs(IResource resource, IProgressMonitor progress) {
+
+ IContainer project = resource.getProject();
+ IPath path = resource.getProjectRelativePath();
+ IFolder folder = project.getFolder(path);
+
+ try {
+ folder.create(false, true, progress); // No force, yes make local.
+ } catch (CoreException exception) {
+ // The creation failed.
+ return ITeamStatusConstants.IO_FAILED_STATUS;
+ }
+ return ITeamStatusConstants.OK_STATUS;
+ }
+
+ /**
+ * Get an array of local children of the given container, or an empty array if the
+ * container does not exist or has no children.
+ */
+ protected IResource[] getLocalChildren(IContainer container) throws TeamException {
+ if (container.exists())
+ try {
+ return container.members();
+ } catch (CoreException exception) {
+ throw new TeamException(ITeamStatusConstants.IO_FAILED_STATUS);
+ }
+ return new IResource[0];
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/SynchronizedTargetProvider.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/SynchronizedTargetProvider.java
new file mode 100644
index 000000000..4d2f1e80f
--- /dev/null
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/SynchronizedTargetProvider.java
@@ -0,0 +1,441 @@
+package org.eclipse.team.internal.core.target;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ISynchronizer;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.team.core.*;
+import org.eclipse.team.internal.core.Policy;
+
+public abstract class SynchronizedTargetProvider extends TargetProvider {
+
+ /*
+ * Configuration serialization identifier.
+ */
+
+ private static final int CONFIG_FORMAT_VERSION = 2;
+
+ private final int depth = IResource.DEPTH_INFINITE;
+
+ /**
+ * These interfaces are to operations that can be performed on the array of resources,
+ * and on all resources identified by the depth parameter.
+ * @see execute(IOperation, IResource[], int, IProgressMonitor)
+ */
+ protected static interface IOperation {
+ }
+ protected static interface IIterativeOperation extends IOperation {
+ public IStatus visit(IResource resource, int depth, IProgressMonitor progress);
+ }
+ protected static interface IRecursiveOperation extends IOperation {
+ public IStatus visit(IResource resource, IProgressMonitor progress);
+ }
+
+ /**
+ * Create a new simple team provider initialized with the given state factory.
+ */
+ public SynchronizedTargetProvider() {
+ super();
+ }
+
+ /*************** State Factory ***************/
+
+ /**
+ * Answers the synchronizer.
+ */
+ final protected static ISynchronizer getSynchronizer() {
+ return ResourcesPlugin.getWorkspace().getSynchronizer();
+ }
+
+ /**
+ * Get the state descriptor for a given resource.
+ */
+ public ResourceState getState(IResource resource) {
+ // Create a new resource state with default values.
+ ResourceState state = newState(resource);
+ state.loadState();
+ return state;
+ }
+
+ /**
+ * Answers a new state based on an existing local resource.
+ */
+ abstract public ResourceState newState(IResource resource);
+
+ abstract public String getLocatorString(IResource resource);
+
+ /**
+ * Providers must override this method to configure instances based on the given
+ * properties map. Different providers will require different types of configuration,
+ * and therefore they will look for different keys in the properties table. If the provider
+ * cannot be configured with the values given a <code>TeamException</code> is
+ * thrown. Subclasses should override this method (and call <code>
+ * super.configureProvider(Properties)</code>).
+ */
+ abstract public void configure(Properties properties) throws TeamException;
+
+
+
+ /*************** Inherited Methods ***************/
+
+ /**
+ * Get the resource from the provider to the workspace, and remember the fetched
+ * state as the base state of the resource.
+ *
+ * @see ITeamProvider.get(IResource[], int, IProgressMonitor)
+ */
+ public void get(IResource[] resources, IProgressMonitor progress)
+ throws TeamException {
+ execute(new IIterativeOperation() {
+ public IStatus visit(IResource resource, int depth, IProgressMonitor progress) {
+ ResourceState state = getState(resource);
+ return new Symmetria().get(state, depth, progress);
+ }
+ }, resources, depth, progress);
+ }
+
+
+ /**
+ * Put the resources to the remote.
+ */
+ public void put(
+ IResource[] resources,
+ IProgressMonitor progress)
+ throws TeamException {
+
+ execute(new IRecursiveOperation() {
+ public IStatus visit(IResource resource, IProgressMonitor progress) {
+ // The resource state must be checked-out.
+ ResourceState state = getState(resource);
+ return state.checkin(progress);
+ }
+ }, resources, depth, progress);
+ }
+
+ /**
+ * Delete the corresponding remote resource.
+ * Note that deletes are always deep.
+ */
+ public void delete(IResource[] resources, IProgressMonitor progress)
+ throws TeamException {
+ execute(new IIterativeOperation() {
+ public IStatus visit(IResource resource, int depth, IProgressMonitor progress) {
+ ResourceState state = getState(resource);
+ return state.delete(progress);
+ }
+ }, resources, IResource.DEPTH_INFINITE, progress);
+ }
+
+ /**
+ * 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.
+ * @see ITeamSynch#isDirty(IResource)
+ */
+ public boolean isDirty(IResource resource) {
+ ResourceState state = getState(resource);
+ return state.isDirty(resource);
+ }
+
+ /**
+ * Answers true if the base identifier of the given resource is different to the
+ * current released state of the resource.
+ *
+ * @param resource the resource state to test.
+ * @return <code>true</code> if the resource base identifier is different to the
+ * current released state of the resource, and <code>false</code> otherwise.
+ * @see ITeamSynch#isOutOfDate(IResource)
+ */
+ public boolean isOutOfDate(IResource resource) {
+ ResourceState state = getState(resource);
+ return state.isOutOfDate();
+ }
+
+ /**
+ * Answer whether the resource has a corresponding remote resource in the provider.
+ *
+ * @param resource the resource state to test.
+ * @return <code>true</code> if the resource has a corresponding remote resource,
+ * and <code>false</code> otherwise.
+ * @see ITeamSynch#hasRemote(IResource)
+ */
+ public boolean hasRemote(IResource resource) {
+ ResourceState state = getState(resource);
+ return state.hasRemote();
+ }
+
+ /*
+ * @see ITeamProvider#refreshState(IResource[], int, IProgressMonitor)
+ */
+ public void refreshState(
+ IResource[] resources,
+ int depth,
+ IProgressMonitor progress)
+ throws TeamException {
+ }
+
+ public String getDecorationTextPostFix(IResource resource) {
+ return "";
+ }
+
+ public String getDecorationLocation(IResource resource) {
+ return getLocatorString(resource);
+ }
+
+
+ /**
+ * Perform the given operation on the array of resources, each to the
+ * specified depth. Throw an exception if a problem ocurs, otherwise
+ * remain silent.
+ */
+ protected void execute(
+ IOperation operation,
+ IResource[] resources,
+ int depth,
+ IProgressMonitor progress)
+ throws TeamException {
+
+ // Create an array to hold the status for each resource.
+ IStatus[] statuses = new IStatus[resources.length];
+
+ // Remember if a failure occurred in any resource, so we can throw an exception at the end.
+ boolean failureOccurred = false;
+
+ // For each resource in the local resources array.
+ for (int i = 0; i < resources.length; i++) {
+ if (operation instanceof IRecursiveOperation)
+ statuses[i] = execute((IRecursiveOperation)operation, resources[i], depth, progress);
+ else
+ statuses[i] = ((IIterativeOperation)operation).visit(resources[i], depth, progress);
+ failureOccurred = failureOccurred || (!statuses[i].isOK());
+ }
+
+ // Finally, if any problems occurred, throw the exeption with all the statuses,
+ // but if there were no problems exit silently.
+ if (failureOccurred)
+ throw new TeamException(
+ new MultiStatus(
+ TeamPlugin.ID,
+ IStatus.ERROR,
+ statuses,
+ Policy.bind("multiStatus.errorsOccurred"),
+ null));
+
+ // Cause all the resource changes to be broadcast to listeners.
+// TeamPlugin.getManager().broadcastResourceStateChanges(resources);
+ }
+
+ /**
+ * Perform the given operation on a resource to the given depth.
+ */
+ protected IStatus execute(
+ IRecursiveOperation operation,
+ IResource resource,
+ int depth,
+ IProgressMonitor progress) {
+
+ // Visit the given resource first.
+ IStatus status = operation.visit(resource, progress);
+
+ // If the resource is a file then the depth parameter is irrelevant.
+ if (resource.getType() == IResource.FILE)
+ return status;
+
+ // If we are not considering any members of the container then we are done.
+ if (depth == IResource.DEPTH_ZERO)
+ return status;
+
+ // If the operation was unsuccessful, do not attempt to go deep.
+ if (!status.isOK())
+ return status;
+
+ // If the container has no children then we are done.
+ IResource[] members = getMembers(resource);
+ if (members.length == 0)
+ return status;
+
+ // There are children and we are going deep, the response will be a multi-status.
+ MultiStatus multiStatus =
+ new MultiStatus(
+ status.getPlugin(),
+ status.getCode(),
+ status.getMessage(),
+ status.getException());
+
+ // The next level will be one less than the current level...
+ int childDepth =
+ (depth == IResource.DEPTH_ONE)
+ ? IResource.DEPTH_ZERO
+ : IResource.DEPTH_INFINITE;
+
+ // Collect the responses in the multistatus.
+ for (int i = 0; i < members.length; i++)
+ multiStatus.add(execute(operation, members[i], childDepth, progress));
+
+ return multiStatus;
+ }
+
+ /**
+ * Answers an array of local resource members for the given resource
+ * or an empty arrray if the resource has no members.
+ *
+ * @param resource the local resource whose members are required.
+ * @return an array of <code>IResource</code> or an empty array if
+ * the resource has no members.
+ */
+ protected IResource[] getMembers(IResource resource) {
+ if (resource.getType() != IResource.FILE) {
+ try {
+ return ((IContainer) resource).members();
+ } catch (CoreException exception) {
+ exception.printStackTrace();
+ throw new RuntimeException();
+ }
+ } //end-if
+ else
+ return new IResource[0];
+ }
+
+ /*
+ * @see IProjectNature#setProject()
+ */
+ public void setProject(IProject project) {
+ super.setProject(project);
+ try {
+ restoreConfiguration();
+ } catch (CoreException e) {
+ TeamPlugin.log(IStatus.ERROR, "Error configuring project", e);
+ } catch (IOException e) {
+ TeamPlugin.log(IStatus.ERROR, "Error configuring project", e);
+ }
+ }
+
+
+
+ /*************** Config Info Persisting ***************/
+
+ /*
+ * Retrieve configuration information for the receiver
+ * if previously configure, and reinstantiate that configuration.
+ */
+
+ public void restoreConfiguration() throws CoreException, IOException {
+ QualifiedName configKey = getIdentifier();
+ QualifiedName[] partners = getSynchronizer().getPartners();
+ boolean registered = false;
+
+ for (int i = 0; i < partners.length; i++) {
+ if(partners[i].equals(configKey))
+ registered = true;
+ }
+
+ if(registered) {
+ Properties properties = loadConfiguration();
+ if(properties == null) {
+ return;
+ }
+ storeConfiguration(properties);
+ }
+ }
+
+
+ /*
+ * This method is called once to configure the receiver after creation.
+ */
+ public void configure(Properties configuration, IProject project) throws IOException, CoreException, TeamException {
+ Assert.isNotNull(configuration);
+
+ setProject(project);
+
+ // Configure the receiver with the new config info.
+ configure(configuration);
+
+ // Store the new configuration for future.
+ storeConfiguration(configuration);
+ }
+
+ /*
+ * @see IProjectNature#deconfigure()
+ */
+ public void deconfigure() throws CoreException {
+ }
+
+ /**
+ * Associates the given configuration with the given project.
+ * Stores the configuration under the <code>getType()</code> key.
+ */
+ private void storeConfiguration(Properties configuration) throws IOException, CoreException {
+ // Remove any old configuration first.
+ QualifiedName configKey = getIdentifier();
+ getSynchronizer().flushSyncInfo(configKey, getProject(), IResource.DEPTH_INFINITE);
+
+ // Flatten the configuration to bytes.
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ byteStream.write(CONFIG_FORMAT_VERSION);
+ configuration.store(byteStream, null);
+ byteStream.close();
+ byte[] bytes = byteStream.toByteArray();
+
+ // Store the configuration persistently.
+ getSynchronizer().setSyncInfo(configKey, getProject(), bytes);
+ ResourcesPlugin.getWorkspace().save(false, null);
+ }
+
+
+ /**
+ * Loads a configuration serialized from a given project.
+ * Returns <code>null</code> if there is no serialized configuration or
+ * the configuration is invalid.
+ *
+ * @param project the project with an associated configuration.
+ * @return the loaded configuration, or <code>null</code> if there is
+ * no such configuration.
+ */
+ private Properties loadConfiguration() {
+ // The project must exist for us to get the configuration.
+ if (!getProject().exists())
+ return null;
+
+ try {
+ // Get the stored byte representation, if any.
+ QualifiedName configKey = getIdentifier();
+ byte[] bytes = getSynchronizer().getSyncInfo(configKey, getProject());
+ if ((bytes == null) || (bytes.length == 0))
+ return null;
+
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+
+ // Check version identifier.
+ if (CONFIG_FORMAT_VERSION != inputStream.read())
+ return null;
+ // Read the properties from the stream.
+ Properties result = new Properties();
+ result.load(inputStream);
+ return result;
+ } catch (IOException e) {
+ return null;
+ } catch (CoreException e) {
+ e.printStackTrace();
+ throw new RuntimeException();
+ }
+ }
+
+
+ } \ No newline at end of file
diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/messages.properties b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/messages.properties
new file mode 100644
index 000000000..39c4b3943
--- /dev/null
+++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/target/messages.properties
@@ -0,0 +1,11 @@
+
+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.
+provider.configuration.missing=Required configuration value missing.
+provider.configuration.invalid=Configuration value is invalid.
+filetransfer.monitor={0} ({1}K of {2}K bytes)
+multiStatus.errorsOccurred=Errors occurred. \ No newline at end of file

Back to the top