diff options
author | Michael Valenta | 2002-03-15 16:45:13 +0000 |
---|---|---|
committer | Michael Valenta | 2002-03-15 16:45:13 +0000 |
commit | 064a808c1e329caa95250995c226e172b2562e92 (patch) | |
tree | 9715177404e53a50453fa2c762e1d1257d95a45e | |
parent | 5cf1495343036ffbe61431025907f54dad14627b (diff) | |
download | eclipse.platform.team-project-branch.tar.gz eclipse.platform.team-project-branch.tar.xz eclipse.platform.team-project-branch.zip |
.project workproject-branch
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 |