Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Valenta2002-03-15 11:45:13 -0500
committerMichael Valenta2002-03-15 11:45:13 -0500
commit064a808c1e329caa95250995c226e172b2562e92 (patch)
tree9715177404e53a50453fa2c762e1d1257d95a45e
parent5cf1495343036ffbe61431025907f54dad14627b (diff)
downloadeclipse.platform.team-project-branch.tar.gz
eclipse.platform.team-project-branch.tar.xz
eclipse.platform.team-project-branch.zip
.project workproject-branch
-rw-r--r--bundles/org.eclipse.team.cvs.core/plugin.properties3
-rw-r--r--bundles/org.eclipse.team.cvs.core/plugin.xml7
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/FileInputStreamProvider.java188
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java8
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/OrphanedFolderListener.java118
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ProjectDescriptionManager.java29
6 files changed, 231 insertions, 122 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/plugin.properties b/bundles/org.eclipse.team.cvs.core/plugin.properties
index aaa56cf85..dec360e84 100644
--- a/bundles/org.eclipse.team.cvs.core/plugin.properties
+++ b/bundles/org.eclipse.team.cvs.core/plugin.properties
@@ -1,2 +1,3 @@
pluginName = CVS Team Provider
-cvsNature=CVS Team Nature \ No newline at end of file
+cvsNature=CVS Team Nature
+vcmMetaMarker=VCM meta file \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/plugin.xml b/bundles/org.eclipse.team.cvs.core/plugin.xml
index 3d1a367d1..89aad520f 100644
--- a/bundles/org.eclipse.team.cvs.core/plugin.xml
+++ b/bundles/org.eclipse.team.cvs.core/plugin.xml
@@ -60,4 +60,11 @@
<ignore pattern = "*.class" selected = "true"/>
</extension>
+ <!-- *************** Markers **************** -->
+ <extension id="cvsmarker" point="org.eclipse.core.resources.markers"/>
+ <extension id="vcmmeta" point="org.eclipse.core.resources.markers" name="%vcmMetaMarker">
+ <super type="org.eclipse.core.resources.problemmarker"/>
+ <super type="org.eclipse.team.cvs.core.cvsmarker"/>
+ <persistent value="true"/>
+ </extension>
</plugin> \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/FileInputStreamProvider.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/FileInputStreamProvider.java
new file mode 100644
index 000000000..4922c9455
--- /dev/null
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/client/FileInputStreamProvider.java
@@ -0,0 +1,188 @@
+package org.eclipse.team.internal.ccvs.core.client;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2002.
+ * All Rights Reserved.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.internal.ccvs.core.CVSException;
+import org.eclipse.team.internal.ccvs.core.Policy;
+
+/**
+ * This class can be used to transfer a file from the CVS server to a local IFile
+ */
+public class FileInputStreamProvider {
+
+ // default file transfer buffer size (in bytes)
+ private static int TRANSFER_BUFFER_SIZE = 8192;
+ // update progress bar in increments of this size (in bytes)
+ // no incremental progress shown for files smaller than this size
+ private static int TRANSFER_PROGRESS_INCREMENT = 32768;
+
+ // the platform's line termination sequence
+ private static final byte[] PLATFORM_NEWLINE_BYTES =
+ System.getProperty("line.separator").getBytes(); //$NON-NLS-1$ // at least one byte long
+ // the server's line termination sequence
+ private static final int SERVER_NEWLINE_BYTE = 0x0a; // exactly one byte long
+ private static final byte[] SERVER_NEWLINE_BYTES = new byte[] { SERVER_NEWLINE_BYTE };
+ // true iff newlines must be converted between platform and server formats
+ private static boolean DONT_CONVERT_NEWLINES = PLATFORM_NEWLINE_BYTES.length == 1
+ && PLATFORM_NEWLINE_BYTES[0] == SERVER_NEWLINE_BYTE;
+
+ // VCM 1.0 comitted files using CR/LF as a delimiter
+ private static final int CARRIAGE_RETURN_BYTE = 0x0d;
+
+ private InputStream input;
+ private int fileSize;
+ private int totalRead;
+ private boolean isBinary;
+ private IProgressMonitor monitor;
+ private byte[] buffer;
+ private int nextProgressThresh;
+
+ private static final byte[] BUFFER = new byte[TRANSFER_BUFFER_SIZE / 2];
+ private static final byte[] EXPANSION_BUFFER = new byte[TRANSFER_BUFFER_SIZE];
+
+ private int position;
+ private int bufferLength;
+ private String title;
+
+ public FileInputStreamProvider(InputStream input, int fileSize, boolean isBinary, String title, IProgressMonitor monitor) {
+ this.input = input;
+ this.fileSize = fileSize;
+ this.totalRead = 0;
+ this.isBinary = isBinary;
+ this.monitor = monitor;
+ this.buffer = BUFFER;
+ this.nextProgressThresh = TRANSFER_PROGRESS_INCREMENT;
+ this.title = title;
+ }
+
+ public class InputStreamFromServer extends InputStream {
+ public int read() throws IOException {
+ if (position >= bufferLength) {
+ if (fill() == -1)
+ return -1;
+ }
+ return buffer[position++];
+ }
+ public int read(byte[] bytes) throws IOException {
+ return read(bytes, 0, bytes.length);
+ }
+ public int read(byte[] bytes, int offset, int length) throws IOException {
+ if (position >= bufferLength) {
+ if (fill() == -1)
+ return -1;
+ }
+ length = Math.min(bufferLength - position, length);
+ System.arraycopy(buffer, position, bytes, offset, length);
+ position += length;
+ return length;
+ }
+ }
+
+ /**
+ * Return a stream that can be passed to IFile#setContent()
+ * After the call to setContent, the receiver's input stream will be at the byte
+ * after the received file.
+ */
+ public InputStream getInputStream() {
+ return new InputStreamFromServer();
+ }
+
+ /*
+ * Transfers a file to or from the remove CVS server, possibly expanding line delimiters.
+ * <p>
+ * Line termination sequences are only converted upon request by specifying an
+ * array containing the expected sequence of bytes representing an outbound newline,
+ * and a single byte representing an inbound newline. If null is passed for the
+ * former, the file is assumed to have binary contents, hence no translation is
+ * performed.
+ * </p><p>
+ * Translation is performed on-the-fly, so the file need not fit in available memory.
+ * </p>
+ * @param in the input stream
+ * @param out the output stream
+ * @param size the source file size
+ * @param newlineIn the single byte for a received newline, ignored if binary
+ * @param newlineOut the sequence of bytes for sent newline, or null if binary
+ * @param monitor the progress monitor
+ * @param title the name of the file being received (as shown in the monitor)
+ */
+ private int fill() throws IOException {
+
+ // Check if we've read the entire file
+ if (totalRead == fileSize) {
+ return -1;
+ } else if (position < bufferLength) {
+ return bufferLength - position;
+ }
+
+ position = 0;
+
+ // If we're not converting, use the big buffer to read
+ if (isBinary || DONT_CONVERT_NEWLINES) {
+ buffer = EXPANSION_BUFFER;
+ } else {
+ buffer = BUFFER;
+ }
+
+ bufferLength = input.read(buffer, 0, (int) Math.min(buffer.length, fileSize - totalRead));
+ if (bufferLength == -1) {
+ // Unexpected end of stream
+ throw new IOException(Policy.bind("Session.readError")); //$NON-NLS-1$
+ }
+ totalRead += bufferLength;
+
+ if (isBinary || DONT_CONVERT_NEWLINES) {
+ return bufferLength;
+ }
+
+ bufferLength = convertNewLines(BUFFER, EXPANSION_BUFFER, bufferLength);
+ buffer = EXPANSION_BUFFER;
+
+ // update progress monitor
+ if (totalRead > nextProgressThresh) {
+ monitor.subTask(Policy.bind("Session.transfer", //$NON-NLS-1$
+ new Object[] { title, new Long(totalRead / 1024), new Long(fileSize / 1024)}));
+ nextProgressThresh = totalRead + TRANSFER_PROGRESS_INCREMENT;
+ }
+
+ return bufferLength;
+ }
+
+ /*
+ * Copy the bytes from the source to the target, converting any LF to the platform newline byte.
+ *
+ * There is special handling that will skip incoming CRs that precede LF.
+ */
+ private int convertNewLines(byte[] source, byte[] target, int length) {
+ boolean seenCR = false;
+ int targetPosition = 0;
+ for (int sourcePosition = 0; sourcePosition < length; ++sourcePosition) {
+ final byte b = source[sourcePosition];
+ if (b == CARRIAGE_RETURN_BYTE) {
+ // We keep track of CRs to perform autocorrection for improperly stored text files
+ seenCR = true;
+ } else {
+ if (b == SERVER_NEWLINE_BYTE) {
+ // if fixCRLF we ignore previous CR (if there was one)
+ // replace newlineIn with newlineOut
+ for (int x = 0; x < PLATFORM_NEWLINE_BYTES.length; ++x) target[targetPosition++] = PLATFORM_NEWLINE_BYTES[x];
+ } else {
+ if (seenCR) target[targetPosition++] = CARRIAGE_RETURN_BYTE; // preserve stray CR's
+ target[targetPosition++] = b;
+ }
+ seenCR = false;
+ }
+ }
+ if (seenCR) target[targetPosition++] = CARRIAGE_RETURN_BYTE;
+
+ return targetPosition;
+ }
+}
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
index bc7205d57..b07b10ea8 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/resources/EclipseFile.java
@@ -74,7 +74,13 @@ class EclipseFile extends EclipseResource implements ICVSFile {
try {
IFile file = getIFile();
if (responseType == CREATED || (responseType == UPDATED && ! resource.exists())) {
- file.create(new ByteArrayInputStream(toByteArray()), false /*force*/, null);
+ if (resource.exists()) {
+ // Special handling for the .project meta-file
+ // XXX This behavior should be restricted to the meta file!
+ file.setContents(new ByteArrayInputStream(toByteArray()), true /*force*/, true /*keep history*/, null);
+ } else {
+ file.create(new ByteArrayInputStream(toByteArray()), false /*force*/, null);
+ }
} else if(responseType == UPDATE_EXISTING) {
file.setContents(new ByteArrayInputStream(toByteArray()), false /*force*/, keepLocalHistory /*keep history*/, null);
} else {
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/OrphanedFolderListener.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/OrphanedFolderListener.java
deleted file mode 100644
index 93407ed21..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/OrphanedFolderListener.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package org.eclipse.team.internal.ccvs.core.util;
-
-/*
- * (c) Copyright IBM Corp. 2000, 2001.
- * All Rights Reserved.
- */
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.team.ccvs.core.CVSProviderPlugin;
-import org.eclipse.team.ccvs.core.ICVSFile;
-import org.eclipse.team.ccvs.core.ICVSFolder;
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.client.Session;
-import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
-import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
-
-/**
- * Listen for the addition of orphaned subtrees as a result of a copy or move.
- *
- * Listen in IResourceChangeEvent.PRE_AUTO_BUILD so that other interested parties
- * (most notably, the file synchronizer) will receive up to date notifications
- */
-public class OrphanedFolderListener extends ResourceDeltaVisitor {
-
- private void handleOrphanedSubtree(IResource resource) {
- if (resource.getType() == IResource.FOLDER) {
- try {
- ICVSFolder mFolder = CVSWorkspaceRoot.getCVSFolderFor((IContainer)resource);
- if (mFolder.isCVSFolder() && ! mFolder.isManaged() && mFolder.getParent().isCVSFolder()) {
- mFolder.unmanage();
- }
- } catch (CVSException e) {
- CVSProviderPlugin.log(e);
- }
- }
- }
-
- private void handleDeletedResource(IResource resource) {
- if (resource.getType() == IResource.FILE) {
- try {
- ICVSFile mFile = CVSWorkspaceRoot.getCVSFileFor((IFile)resource);
- if (mFile.isManaged()) {
- ResourceSyncInfo info = mFile.getSyncInfo();
- if (info.isAdded()) {
- mFile.unmanage();
- } else {
- mFile.setSyncInfo(new ResourceSyncInfo(info.getName(), info.DELETED_PREFIX + info.getRevision(), info.getTimeStamp(), info.getKeywordMode(), info.getTag(), info.getPermissions()));
- }
- }
- } catch (CVSException e) {
- CVSProviderPlugin.log(e);
- }
- }
- }
-
- /*
- * Handle the case where an added file has the same name as a "cvs removed" file
- * by restoring the sync info to what it was before the delete
- */
- private void handleReplacedDeletion(IResource resource) {
- if (resource.getType() == IResource.FILE) {
- try {
- ICVSFile mFile = CVSWorkspaceRoot.getCVSFileFor((IFile)resource);
- if (mFile.isManaged()) {
- ResourceSyncInfo info = mFile.getSyncInfo();
- if (info.isDeleted()) {
- mFile.setSyncInfo(new ResourceSyncInfo(info.getName(), info.getRevision(), info.getTimeStamp(), info.getKeywordMode(), info.getTag(), info.getPermissions()));
- }
- }
- } catch (CVSException e) {
- CVSProviderPlugin.log(e);
- }
- }
- }
-
- /*
- * @see ResourceDeltaVisitor#handleAdded(IResource[])
- */
- protected void handleAdded(IResource[] resources) {
- for (int i = 0; i < resources.length; i++) {
- if (resources[i].getType() == IResource.FOLDER) {
- handleOrphanedSubtree(resources[i]);
- } else if (resources[i].getType() == IResource.FILE) {
- handleReplacedDeletion(resources[i]);
- }
- }
- }
-
- /*
- * @see ResourceDeltaVisitor#handleRemoved(IResource[])
- */
- protected void handleRemoved(IResource[] resources) {
- for (int i = 0; i < resources.length; i++) {
- handleDeletedResource(resources[i]);
- }
- }
-
- /*
- * @see ResourceDeltaVisitor#handleChanged(IResource[])
- */
- protected void handleChanged(IResource[] resources) {
- }
-
- /*
- * @see ResourceDeltaVisitor#finished()
- */
- protected void finished() {
- }
-
- protected int getEventMask() {
- return IResourceChangeEvent.PRE_AUTO_BUILD;
- }
-
-} \ No newline at end of file
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ProjectDescriptionManager.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ProjectDescriptionManager.java
index 7352733c7..5c902e35d 100644
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ProjectDescriptionManager.java
+++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/ProjectDescriptionManager.java
@@ -13,6 +13,7 @@ import java.io.InputStream;
import org.apache.xerces.parsers.SAXParser;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
@@ -45,8 +46,11 @@ import org.xml.sax.SAXException;
public class ProjectDescriptionManager {
public final static IPath PROJECT_DESCRIPTION_PATH = new Path(".vcm_meta"); //$NON-NLS-1$
+ public final static IPath CORE_PROJECT_DESCRIPTION_PATH = new Path(".project"); //$NON-NLS-1$
public final static boolean UPDATE_PROJECT_DESCRIPTION_ON_LOAD = true;
+ public static final String VCMMETA_MARKER = "org.eclipse.team.cvs.core.vcmmeta";
+
/*
* Read the project meta file into the provider description
*/
@@ -141,7 +145,7 @@ public class ProjectDescriptionManager {
is.close();
}
try {
- project.setDescription(desc, progress);
+ project.setDescription(desc, IResource.FORCE | IResource.KEEP_HISTORY, progress);
} catch (CoreException ex) {
// Failing to set the description is probably due to a missing nature
// Other natures are still set
@@ -157,6 +161,10 @@ public class ProjectDescriptionManager {
Util.logError(Policy.bind("ProjectDescriptionManager.unableToSetDescription"), ex); //$NON-NLS-1$
}
}
+ // Mark the .vcm_meta file with a problem marker
+ if (project.getFile(CORE_PROJECT_DESCRIPTION_PATH).exists()) {
+ createVCMMetaMarker(descResource);
+ }
} catch(TeamException ex) {
Util.logError(Policy.bind("ProjectDescriptionManager.unableToReadDescription"), ex); //$NON-NLS-1$
// something went wrong, delete the project description file
@@ -178,7 +186,9 @@ public class ProjectDescriptionManager {
public static void writeProjectDescriptionIfNecessary(CVSTeamProvider provider, IResource resource, IProgressMonitor monitor) throws CVSException {
if (resource.getType() == IResource.PROJECT || isProjectDescription(resource)) {
IProject project = resource.getProject();
- writeProjectDescription(project, monitor);
+ if (project.getFile(PROJECT_DESCRIPTION_PATH).exists() /* || ! project.getFile(CORE_PROJECT_DESCRIPTION_PATH).exists() */) {
+ writeProjectDescription(project, monitor);
+ }
}
}
@@ -233,4 +243,19 @@ public class ProjectDescriptionManager {
};
ResourcesPlugin.getWorkspace().addResourceChangeListener(changeListener, IResourceChangeEvent.PRE_AUTO_BUILD);
}
+
+ protected static IMarker createVCMMetaMarker(IResource resource) {
+ try {
+ IMarker[] markers = resource.findMarkers(VCMMETA_MARKER, false, IResource.DEPTH_ZERO);
+ if (markers.length == 1) {
+ return markers[0];
+ }
+ IMarker marker = resource.createMarker(VCMMETA_MARKER);
+ marker.setAttribute(IMarker.MESSAGE, resource.getName() + " file exists in " + resource.getProject().getName() + " but is no longer required and can be deleted");
+ return marker;
+ } catch (CoreException e) {
+ Util.logError("Error creating deletion marker", e);
+ }
+ return null;
+ }
} \ No newline at end of file

Back to the top