Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java')
-rw-r--r--bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java953
1 files changed, 0 insertions, 953 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java
deleted file mode 100644
index e8b7f7045..000000000
--- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/syncinfo/ResourceSyncInfo.java
+++ /dev/null
@@ -1,953 +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.ccvs.core.syncinfo;
-
-
-import java.text.ParseException;
-import java.util.Date;
-
-import org.eclipse.team.internal.ccvs.core.CVSException;
-import org.eclipse.team.internal.ccvs.core.CVSTag;
-import org.eclipse.team.internal.ccvs.core.Policy;
-import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption;
-import org.eclipse.team.internal.ccvs.core.resources.CVSEntryLineTag;
-import org.eclipse.team.internal.ccvs.core.util.Assert;
-import org.eclipse.team.internal.ccvs.core.util.CVSDateFormatter;
-import org.eclipse.team.internal.ccvs.core.util.Util;
-
-/**
- * Value (immutable) object that represents workspace state information about a resource contained in
- * a CVS repository. It is a specialized representation of a line in the CVS/Entry file with the addition of
- * file permissions.
- * <p>
- * ResourceSyncInfo instances are created from entry lines from the CVS server and from the CVS/Entries
- * file. Although both entry lines have slightly different formats (e.g. timestamps) they can safely be passed
- * to the constructor.</p>
- * <p>
- * A class named <code>MutableResourceSyncInfo</code> can be used to modify an existing resource
- * sync or create sync info without an entry line.</p>
- *
- * Example entry line from the CVS/Entry file:
- *
- * /new.java/1.2/Fri Dec 7 00:17:52 2001/-kb/
- * D/src////
- *
- * @see MutableResourceSyncInfo
- * @see ICVSResource#getSyncInfo()
- */
-public class ResourceSyncInfo {
-
- // [Note: permissions aren't honoured in this current implementation]
- // safe default permissions. Permissions are saved separately so that the correct permissions
- // can be sent back to the server on systems that don't save execute bits (e.g. windows).
- private static final String DEFAULT_PERMISSIONS = "u=rw,g=rw,o=r"; //$NON-NLS-1$
-
- // file sync information can be associated with a local resource that has been deleted. This is
- // noted by prefixing the revision with this character.
- private static final String DELETED_PREFIX = "-"; //$NON-NLS-1$
- private static final byte DELETED_PREFIX_BYTE = '-';
-
- // a sync element with a revision of '0' is considered a new file that has
- // not been comitted to the repo. Is visible so that clients can create sync infos
- // for new files.
- public static final String ADDED_REVISION = "0"; //$NON-NLS-1$
-
- // Timestamp constants used to identify special cases
- protected static final int TYPE_REGULAR = 1;
- protected static final int TYPE_MERGED = 2;
- protected static final int TYPE_MERGED_WITH_CONFLICTS = 3;
-
- protected static final String TIMESTAMP_DUMMY = "dummy timestamp"; //$NON-NLS-1$
- protected static final String TIMESTAMP_MERGED = "Result of merge"; //$NON-NLS-1$
- protected static final String TIMESTAMP_MERGED_WITH_CONFLICT = TIMESTAMP_MERGED + "+"; //$NON-NLS-1$
-
- protected static final String TIMESTAMP_SERVER_MERGED = "+modified"; //$NON-NLS-1$
- protected static final String TIMESTAMP_SERVER_MERGED_WITH_CONFLICT = "+="; //$NON-NLS-1$
-
- // a directory sync info will have nothing more than a name
- protected boolean isDirectory = false;
- protected boolean isDeleted = false;
-
- // utility constants
- protected static final String DIRECTORY_PREFIX = "D"; //$NON-NLS-1$
- protected static final String SEPARATOR = "/"; //$NON-NLS-1$
- protected static final byte SEPARATOR_BYTE = (byte)'/';
-
- // fields describing the synchronization of a resource in CVS parlance
- protected String name;
- protected String revision;
- protected Date timeStamp;
- protected KSubstOption keywordMode;
- protected CVSEntryLineTag tag;
- protected String permissions;
-
- // type of sync
- protected int syncType = TYPE_REGULAR;
- protected ResourceSyncInfo() {
- // Added for use by subclasses
- }
-
- public ResourceSyncInfo(byte[] entryLine) throws CVSException {
- this(new String(entryLine), null, null);
- }
-
- /**
- * Constructor to create a sync object from entry line formats. The entry lines are parsed by this class.
- * The constructor can handle parsing entry lines from the server or from an entry file.
- *
- * @param entryLine the entry line (e.g. /new.java/1.2/Fri Dec 07 00:17:52 2001/-kb/)
- * @param permissions the file permission (e.g. u=rw,g=rw,o=r). May be <code>null</code>.
- * @param timestamp if not included in the entry line. May be <code>null</code>.
- *
- * @exception CVSException is thrown if the entry cannot be parsed.
- */
- public ResourceSyncInfo(String entryLine, String permissions, Date timestamp) throws CVSException {
- Assert.isNotNull(entryLine);
- setEntryLine(entryLine);
-
- if (permissions != null) {
- this.permissions = permissions;
- }
- // override the timestamp that may of been in entryLine. In some cases the timestamp is not in the
- // entry line (e.g. receiving entry lines from the server versus reading them from the Entry file).
- if(timestamp!=null) {
- this.timeStamp = timestamp;
- }
- }
-
- /**
- * Constructor to create a resource sync object for a folder.
- *
- * @param name of the resource for which this sync state is associatied, cannot be <code>null</code>.
- */
- public ResourceSyncInfo(String name) {
- Assert.isNotNull(name);
- this.name = name;
- this.isDirectory = true;
- }
- /**
- * Answers if this sync information is for a folder in which case only a name is
- * available.
- *
- * @return <code>true</code> if the sync information is for a folder and <code>false</code>
- * if it is for a file.
- */
- public boolean isDirectory() {
- return isDirectory;
- }
-
- /**
- * Answers if this sync information is for a resource that has been merged by the cvs server with
- * conflicts and has not been modified yet relative to the given timestamp.
- *
- * @param otherTimestamp is the timestamp of the file associated with this resource sync
- * @return <code>true</code> if the sync information is for a file that has been merged and
- * <code>false</code> for folders and for files that have not been merged.
- */
- public boolean isNeedsMerge(Date otherTimestamp) {
- return syncType == TYPE_MERGED_WITH_CONFLICTS && timeStamp.equals(otherTimestamp);
- }
-
- /**
- * Answers if this sync information is for a resource that has been merged with conflicts by the
- * cvs server.
- *
- * @return <code>true</code> if the sync information is for a file that has been merged and
- * <code>false</code> for folders and for files that have not been merged.
- */
- public boolean isMergedWithConflicts() {
- return syncType == TYPE_MERGED_WITH_CONFLICTS;
- }
-
- /**
- * Answers if this sync information is for a resource that has been merged by the cvs server.
- *
- * @return <code>true</code> if the sync information is for a file that has been merged and
- * <code>false</code> for folders and for files that have not been merged.
- */
- public boolean isMerged() {
- return syncType == TYPE_MERGED || isMergedWithConflicts();
- }
-
- /**
- * Answers if this sync information is for a file that has been added but not comitted
- * to the CVS repository yet.
- *
- * @return <code>true</code> if the sync information is new or <code>false</code> if
- * the sync is for an file that exists remotely. For folder sync info this returns
- * <code>false</code>.
- */
- public boolean isAdded() {
- if(!isDirectory) {
- return getRevision().equals(ADDED_REVISION);
- } else {
- return false;
- }
- }
-
- /**
- * Answers if this sync information is for a file that is scheduled to be deleted
- * from the repository but the deletion has not yet been comitted.
- *
- * @return <code>true</code> if the sync information is deleted or <code>false</code> if
- * the sync is for an file that exists remotely.
- */
- public boolean isDeleted() {
- return isDeleted;
- }
-
- /**
- * Returns an entry line that can be saved in the CVS/Entries file. For sending entry lines to the
- * server use <code>getServerEntryLine</code>.
- *
- * @return a file or folder entry line reflecting the state of this sync object.
- */
- public String getEntryLine() {
- return getEntryLine(true /*include timestamps*/, null /*no timestamp override*/);
- }
-
- /**
- * Same as <code>getEntryLine</code> except it considers merged files in entry line timestamp format.
- * This is only valid for sending the file to the server.
- *
- * @param fileTimestamp is timestamp of the resource associated with this sync info.
- * @return a file or folder entry line reflecting the state of this sync object.
- */
- public String getServerEntryLine(Date fileTimestamp) {
- String serverTimestamp;
- if(fileTimestamp != null && (isMerged() || isMergedWithConflicts())) {
- if(isNeedsMerge(fileTimestamp)) {
- serverTimestamp = TIMESTAMP_SERVER_MERGED_WITH_CONFLICT;
- } else {
- serverTimestamp = TIMESTAMP_SERVER_MERGED;
- }
- return getEntryLine(true, serverTimestamp);
- } else {
- return getEntryLine(false, null);
- }
- }
-
- /**
- * Anwsers a compatible permissions line for files.
- *
- * @return a permission line for files and <code>null</code> if this sync object is
- * a directory.
- */
- public String getPermissionLine() {
- if(isDirectory) {
- return null;
- } else {
- String permissions = this.permissions;
- if (permissions == null)
- permissions = DEFAULT_PERMISSIONS;
- return SEPARATOR + name + SEPARATOR + permissions;
- }
- }
-
- /**
- * Gets the permissions. Returns <code>null</code> for directories and
- * a non-null permission for files.
- *
- * @return a string of the format "u=rw,g=rw,o=r"
- */
- public String getPermissions() {
- if(isDirectory) {
- return null;
- } else {
- if(permissions==null) {
- return DEFAULT_PERMISSIONS;
- } else {
- return permissions;
- }
- }
- }
- /**
- * Gets the tag or <code>null</code> if a tag is not available.
- *
- * @return Returns a String
- */
- public CVSTag getTag() {
- return tag;
- }
- /**
- * Gets the timeStamp or <code>null</code> if a timestamp is not available.
- *
- * @return a date instance representing the timestamp
- */
- public Date getTimeStamp() {
- return timeStamp;
- }
- /**
- * Gets the version or <code>null</code> if this is a folder sync info. The returned
- * revision will never include the DELETED_PREFIX. To found out if this sync info is
- * for a deleted resource call isDeleted().
- *
- * @return Returns a String
- */
- public String getRevision() {
- return revision;
- }
-
- /**
- * Gets the name.
- *
- * @return Returns a String
- */
- public String getName() {
- return name;
- }
- /**
- * Gets the keyword mode.
- * @return the keyword substitution option
- */
- public KSubstOption getKeywordMode() {
- return keywordMode;
- }
-
- /**
- * Answers the default permissions string.
- */
- public static String getDefaultPermissions() {
- return DEFAULT_PERMISSIONS;
- }
-
- /**
- * Name equality between resource sync info objects.
- */
- public boolean equals(Object other) {
- if(other instanceof ResourceSyncInfo) {
- ResourceSyncInfo syncInfo = ((ResourceSyncInfo)other);
- if(other == this) return true;
- if(getName() == syncInfo.getName()) return true;
- return getName().equals(syncInfo.getName());
- } else {
- return false;
- }
- }
-
- public int hashCode() {
- return getName().hashCode();
- }
-
- /*
- * @see Object#toString()
- */
- public String toString() {
- return getEntryLine(true, null /*no timestamp override*/);
- }
- public MutableResourceSyncInfo cloneMutable() {
- MutableResourceSyncInfo newSync = new MutableResourceSyncInfo(this);
- return newSync;
- }
- /**
- * Sets the tag for the resource.
- */
- protected void setTag(CVSTag tag) {
- if(tag!=null) {
- this.tag = new CVSEntryLineTag(tag);
- } else {
- this.tag = null;
- }
- }
-
-
- /*
- * Sets the sync type
- */
- protected void setSyncType(int syncType) {
- this.syncType = syncType;
- }
- /**
- * Sets the version and decides if the revision is for a deleted resource the revision field
- * will not include the deleted prefix '-'.
- *
- * @param version the version to set
- */
- protected void setRevision(String revision) {
- if(revision==null || revision.equals(ADDED_REVISION)) {
- this.revision = ADDED_REVISION;
- timeStamp = null;
- syncType = TYPE_REGULAR;
- isDeleted = false;
- } else if(revision.startsWith(DELETED_PREFIX)) {
- this.revision = revision.substring(DELETED_PREFIX.length());
- isDeleted = true;
- } else {
- this.revision = revision;
- isDeleted = false;
- }
- }
-
- /**
- * Set the entry line
- *
- * @throws CVSException if the entryLine is malformed
- */
- protected void setEntryLine(String entryLine) throws CVSException {
-
- String[] strings = Util.parseIntoSubstrings(entryLine, SEPARATOR);
- if(strings.length < 6) {
- throw new CVSException(Policy.bind("Malformed_entry_line___11") + entryLine); //$NON-NLS-1$
- }
-
- isDirectory = (strings[0].equals(DIRECTORY_PREFIX));
-
- name = strings[1];
-
- if(name.length()==0) {
- throw new CVSException(Policy.bind("Malformed_entry_line,_missing_name___12") + entryLine); //$NON-NLS-1$
- }
-
- String rev = strings[2];
-
- if(rev.length()==0 && !isDirectory()) {
- throw new CVSException(Policy.bind("Malformed_entry_line,_missing_revision___13") + entryLine); //$NON-NLS-1$
- } else {
- setRevision(rev);
- }
-
- String date = strings[3];
-
- // possible timestamps are:
- // from server: "+=" and "+modified"
- // from entry line: "Result of Merge+Thu May 25 12:33:33 2002"
- // "Result of Merge"
- // "Thu May 25 12:33:33 2002"
- //
- // The server will send a timestamp of "+=" if
- // the file was merged with conflicts. The '+' indicates that there are conflicts and the
- // '=' indicate that the timestamp for the file should be used. If the merge does not
- // have conflicts, simply add a text only timestamp and the file will be regarded as
- // having outgoing changes.
- // The purpose for having the two different timestamp options for merges is to
- // dissallow commit of files that have conflicts until they have been manually edited.
- if(date.indexOf(ResourceSyncInfo.TIMESTAMP_SERVER_MERGED) != -1) {
- syncType = TYPE_MERGED;
- date = null;
- } else if(date.indexOf(ResourceSyncInfo.TIMESTAMP_SERVER_MERGED_WITH_CONFLICT) != -1) {
- syncType = TYPE_MERGED_WITH_CONFLICTS;
- date = null;
- } else if(date.indexOf(TIMESTAMP_MERGED_WITH_CONFLICT)!=-1) {
- date = date.substring(date.indexOf("+") + 1); //$NON-NLS-1$
- syncType = TYPE_MERGED_WITH_CONFLICTS;
- } else if(date.indexOf(TIMESTAMP_MERGED)!=-1) {
- syncType = TYPE_MERGED;
- date = null;
- }
-
- if(date==null || "".equals(date)) { //$NON-NLS-1$
- timeStamp = null;
- } else {
- try {
- timeStamp = CVSDateFormatter.entryLineToDate(date);
- } catch(ParseException e) {
- // something we don't understand, just make this sync have no timestamp and
- // never be in sync with the server.
- timeStamp = null;
- }
- }
- keywordMode = KSubstOption.fromMode(strings[4]);
- String tagEntry;
- if (strings.length == 6) {
- tagEntry = strings[5];
- } else {
- // It turns out that CVS supports slashes (/) in the tag even though this breaks the spec
- // See http://dev.eclipse.org/bugs/show_bug.cgi?id=26717
- StringBuffer buffer = new StringBuffer();
- for (int i = 5; i < strings.length; i++) {
- buffer.append(strings[i]);
- if (i < strings.length - 1) {
- buffer.append(SEPARATOR);
- }
- }
- tagEntry = buffer.toString();
- }
-
- if(tagEntry.length()>0) {
- tag = new CVSEntryLineTag(tagEntry);
- } else {
- tag = null;
- }
- }
-
- private String getEntryLine(boolean includeTimeStamp, String timestampOverride) {
- StringBuffer result = new StringBuffer();
-
- if(isDirectory) {
- result.append(DIRECTORY_PREFIX);
- result.append(SEPARATOR);
- result.append(name);
- for (int i = 0; i < 4; i++) {
- result.append(SEPARATOR);
- }
- } else {
- result.append(SEPARATOR);
- result.append(name);
- result.append(SEPARATOR);
-
- if(isDeleted){
- result.append(DELETED_PREFIX);
- }
- result.append(revision);
- result.append(SEPARATOR);
- if(includeTimeStamp) {
- String entryLineTimestamp = ""; //$NON-NLS-1$
- if(timestampOverride!=null) {
- entryLineTimestamp = timestampOverride;
- } else {
- switch(syncType) {
- case TYPE_REGULAR:
- if(timeStamp==null) {
- entryLineTimestamp = TIMESTAMP_DUMMY;
- } else {
- entryLineTimestamp = CVSDateFormatter.dateToEntryLine(timeStamp);
- } break;
- case TYPE_MERGED:
- entryLineTimestamp = TIMESTAMP_MERGED; break;
- case TYPE_MERGED_WITH_CONFLICTS:
- entryLineTimestamp = TIMESTAMP_MERGED_WITH_CONFLICT + CVSDateFormatter.dateToEntryLine(timeStamp); break;
- }
- }
- result.append(entryLineTimestamp);
- }
- result.append(SEPARATOR);
- if (keywordMode != null) result.append(keywordMode.toMode());
- result.append(SEPARATOR);
- if (tag != null) {
- result.append(tag.toEntryLineFormat(true));
- }
- }
- return result.toString();
- }
-
- public boolean needsReporting() {
- return false;
- }
-
- public void reported() {
- // do nothing
- }
-
- /**
- * Method getBytes.
- * @return byte[]
- */
- public byte[] getBytes() {
- return getEntryLine().getBytes();
- }
-
- /**
- * Method getName.
- * @param syncBytes
- * @return String
- */
- public static String getName(byte[] syncBytes) throws CVSException {
- String name = Util.getSubstring(syncBytes, SEPARATOR_BYTE, 1, false);
- if (name == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- return name;
- }
-
- /**
- * Method getKeywordMode.
- * @param syncBytes
- * @return String
- */
- public static KSubstOption getKeywordMode(byte[] syncBytes) throws CVSException {
- String mode = Util.getSubstring(syncBytes, SEPARATOR_BYTE, 4, false);
- if (mode == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- return KSubstOption.fromMode(mode);
- }
-
- /**
- * Method getKeywordMode.
- * @param syncBytes
- * @return String
- */
- public static byte[] setKeywordMode(byte[] syncBytes, KSubstOption mode) throws CVSException {
- return setKeywordMode(syncBytes, mode.toMode().getBytes());
- }
-
- /**
- * Method getKeywordMode.
- * @param syncBytes
- * @return String
- */
- public static byte[] setKeywordMode(byte[] syncBytes, byte[] modeBytes) throws CVSException {
- return setSlot(syncBytes, 4, modeBytes);
- }
-
- /**
- * Return whether the provided syncBytes represent a binary file.
- * @param syncBytes
- * @return boolean
- * @throws CVSException
- */
- public static boolean isBinary(byte[] syncBytes) throws CVSException {
- if (syncBytes == null) return false;
- String mode = Util.getSubstring(syncBytes, SEPARATOR_BYTE, 4, false);
- if (mode == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- return "-kb".equals(mode); //$NON-NLS-1$
- }
-
- /**
- * Method isFolder.
- * @param syncBytes
- * @return boolean
- */
- public static boolean isFolder(byte[] syncBytes) {
- return syncBytes.length > 0 && syncBytes[0] == 'D';
- }
-
- /**
- * Method isAddition.
- * @param syncBytes
- * @return boolean
- */
- public static boolean isAddition(byte[] syncBytes) throws CVSException {
- int start = startOfSlot(syncBytes, 2);
- if (start == -1 || start >= syncBytes.length) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- return syncBytes[start + 1] == '0';
- }
-
- /**
- * Method isDeleted.
- * @param syncBytes
- * @return boolean
- */
- public static boolean isDeletion(byte[] syncBytes) throws CVSException {
- int start = startOfSlot(syncBytes, 2);
- if (start == -1 || start >= syncBytes.length) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- return syncBytes[start + 1] == DELETED_PREFIX_BYTE;
- }
-
- /**
- * Method convertToDeletion.
- * @param syncBytes
- * @return byte[]
- */
- public static byte[] convertToDeletion(byte[] syncBytes) throws CVSException {
- int index = startOfSlot(syncBytes, 2);
- if (index == -1) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- if (syncBytes.length > index && syncBytes[index+1] != DELETED_PREFIX_BYTE) {
- byte[] newSyncBytes = new byte[syncBytes.length + 1];
- System.arraycopy(syncBytes, 0, newSyncBytes, 0, index + 1);
- newSyncBytes[index + 1] = DELETED_PREFIX_BYTE;
- System.arraycopy(syncBytes, index + 1, newSyncBytes, index + 2, syncBytes.length - index - 1);
- return newSyncBytes;
- }
- return syncBytes;
- }
-
- /**
- * Method convertFromDeletion.
- * @param syncBytes
- * @return byte[]
- */
- public static byte[] convertFromDeletion(byte[] syncBytes) throws CVSException {
- int index = startOfSlot(syncBytes, 2);
- if (index == -1) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- if (syncBytes.length > index && syncBytes[index+1] == DELETED_PREFIX_BYTE) {
- byte[] newSyncBytes = new byte[syncBytes.length - 1];
- System.arraycopy(syncBytes, 0, newSyncBytes, 0, index + 1);
- System.arraycopy(syncBytes, index + 2, newSyncBytes, index + 1, newSyncBytes.length - index - 1);
- return newSyncBytes;
- }
- return syncBytes;
- }
- /**
- * 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;
- }
-
- /**
- * Method setSlot.
- * @param syncBytes
- * @param i
- * @param b
- * @return byte[]
- */
- private static byte[] setSlot(byte[] syncBytes, int slot, byte[] newBytes) throws CVSException {
- int start = startOfSlot(syncBytes, slot);
- if (start == -1) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", 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;
- }
-
- /**
- * Return the timestamp portion of the sync info that is to be sent to the
- * server.
- *
- * @param syncBytes
- * @param fileTimestamp
- * @return String
- */
- public static String getTimestampToServer(byte[] syncBytes, Date fileTimestamp) throws CVSException {
- if(fileTimestamp != null) {
- String syncTimestamp = Util.getSubstring(syncBytes, SEPARATOR_BYTE, 3, false);
- if (syncTimestamp == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- int syncType = getSyncType(syncTimestamp);
- if (syncType != TYPE_REGULAR) {
- if (syncType == TYPE_MERGED_WITH_CONFLICTS && fileTimestamp.equals(getTimestamp(syncTimestamp))) {
- return TIMESTAMP_SERVER_MERGED_WITH_CONFLICT;
- } else {
- return TIMESTAMP_SERVER_MERGED;
- }
- }
- }
- return null;
- }
- /**
- * Method getTimestamp.
- * @param syncTimestamp
- * @return Object
- */
- private static Date getTimestamp(String syncTimestamp) {
- String dateString= syncTimestamp;
- if(syncTimestamp.indexOf(ResourceSyncInfo.TIMESTAMP_SERVER_MERGED) != -1) {
- dateString = null;
- } else if(syncTimestamp.indexOf(ResourceSyncInfo.TIMESTAMP_SERVER_MERGED_WITH_CONFLICT) != -1) {
- dateString = null;
- } else if(syncTimestamp.indexOf(TIMESTAMP_MERGED_WITH_CONFLICT)!=-1) {
- dateString = syncTimestamp.substring(syncTimestamp.indexOf("+") + 1); //$NON-NLS-1$
- } else if(syncTimestamp.indexOf(TIMESTAMP_MERGED)!=-1) {
- dateString = null;
- }
-
- if(dateString==null || "".equals(dateString)) { //$NON-NLS-1$
- return null;
- } else {
- try {
- return CVSDateFormatter.entryLineToDate(dateString);
- } catch(ParseException e) {
- // something we don't understand, just make this sync have no timestamp and
- // never be in sync with the server.
- return null;
- }
- }
- }
-
- /**
- * Method getSyncType.
- * @param syncTimestamp
- * @return int
- */
- private static int getSyncType(String date) {
- if(date.indexOf(ResourceSyncInfo.TIMESTAMP_SERVER_MERGED) != -1) {
- return TYPE_MERGED;
- } else if(date.indexOf(ResourceSyncInfo.TIMESTAMP_SERVER_MERGED_WITH_CONFLICT) != -1) {
- return TYPE_MERGED_WITH_CONFLICTS;
- } else if(date.indexOf(TIMESTAMP_MERGED_WITH_CONFLICT)!=-1) {
- return TYPE_MERGED_WITH_CONFLICTS;
- } else if(date.indexOf(TIMESTAMP_MERGED)!=-1) {
- return TYPE_MERGED;
- }
- return TYPE_REGULAR;
- }
-
- /**
- * Method getTag.
- * @param syncBytes
- * @return String
- */
- public static byte[] getTagBytes(byte[] syncBytes) throws CVSException {
- byte[] tag = Util.getBytesForSlot(syncBytes, SEPARATOR_BYTE, 5, true);
- if (tag == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- return tag;
- }
-
- /**
- * Method setTag.
- * @param syncBytes
- * @param tagString
- * @return byte[]
- */
- public static byte[] setTag(byte[] syncBytes, byte[] tagBytes) throws CVSException {
- return setSlot(syncBytes, 5, tagBytes);
- }
-
- /**
- * Method setTag.
- * @param syncBytes
- * @param tag
- * @return ResourceSyncInfo
- */
- public static byte[] setTag(byte[] syncBytes, CVSTag tag) throws CVSException {
- CVSEntryLineTag entryTag;
- if (tag instanceof CVSEntryLineTag) {
- entryTag = (CVSEntryLineTag)tag;
- } else {
- entryTag = new CVSEntryLineTag(tag);
- }
- return setTag(syncBytes, entryTag.toEntryLineFormat(true).getBytes());
- }
-
- /**
- * Method getRevision.
- * @param syncBytes
- */
- public static String getRevision(byte[] syncBytes) throws CVSException {
- String revision = Util.getSubstring(syncBytes, SEPARATOR_BYTE, 2, false);
- if (revision == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- if(revision.startsWith(DELETED_PREFIX)) {
- revision = revision.substring(DELETED_PREFIX.length());
- }
- return revision;
- }
-
- /**
- * Method setRevision.
- * @param syncBytes
- * @param revision
- * @return byte[]
- */
- public static byte[] setRevision(byte[] syncBytes, String revision) throws CVSException {
- return setSlot(syncBytes, 2, revision.getBytes());
- }
-
- /**
- * Method isMerge.
- * @param syncBytes1
- * @return boolean
- */
- public static boolean isMerge(byte[] syncBytes) throws CVSException {
- String timestamp = Util.getSubstring(syncBytes, SEPARATOR_BYTE, 3, false);
- if (timestamp == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- int syncType = getSyncType(timestamp);
- return syncType == TYPE_MERGED || syncType == TYPE_MERGED_WITH_CONFLICTS;
- }
-
- /**
- * Method isMerge.
- * @param syncBytes1
- * @return boolean
- */
- public static boolean isMergedWithConflicts(byte[] syncBytes) throws CVSException {
- String timestamp = Util.getSubstring(syncBytes, SEPARATOR_BYTE, 3, false);
- if (timestamp == null) {
- throw new CVSException(Policy.bind("ResourceSyncInfo.malformedSyncBytes", new String(syncBytes))); //$NON-NLS-1$
- }
- int syncType = getSyncType(timestamp);
- return syncType == TYPE_MERGED_WITH_CONFLICTS;
- }
-
-
- /**
- * Return <code>true</code> if the remoteBytes represents a later revision on the same
- * branch as localBytes. Return <code>false</code> if remoteBytes is the same or an earlier
- * revision or if the bytes are on a separate branch (or tag)
- * @param remoteBytes
- * @param localBytes
- * @return
- */
- public static boolean isLaterRevisionOnSameBranch(byte[] remoteBytes, byte[] localBytes) throws CVSException {
- // If the two byte arrays are the same, then the remote isn't a later revision
- if (remoteBytes == localBytes) return false;
- // If the tags differ, then the remote isn't a later revision
- byte[] remoteTag = ResourceSyncInfo.getTagBytes(remoteBytes);
- byte[] localTag = ResourceSyncInfo.getTagBytes(localBytes);
- if (!Util.equals(remoteTag, localTag)) return false;
- // If the revisions are the same, the remote isn't later
- String remoteRevision = ResourceSyncInfo.getRevision(remoteBytes);
- String localRevision = ResourceSyncInfo.getRevision(localBytes);
- if (remoteRevision.equals(localRevision)) return false;
- return isLaterRevision(remoteRevision, localRevision);
- }
-
- /**
- * Return true if the remoteRevision represents a later revision than the local revision
- * on the same branch.
- * @param remoteRevision
- * @param localRevision
- * @return
- */
- public static boolean isLaterRevision(String remoteRevision, String localRevision) {
- int localDigits[] = Util.convertToDigits(localRevision);
- if (localDigits.length == 0) return false;
- int remoteDigits[] = Util.convertToDigits(remoteRevision);
- if (remoteDigits.length == 0) return false;
-
- if (localRevision.equals(ADDED_REVISION)) {
- return (remoteDigits.length >= 2);
- }
- if (localDigits.length > remoteDigits.length) {
- // If there are more digits in the local revision then there is
- // no way that the remote is later on the same branch
- return false;
- }
- if (localDigits.length < remoteDigits.length) {
- // If there are more digits in the remote revision then all
- // the leading digits must match
- for (int i = 0; i < localDigits.length; i++) {
- int localDigit = localDigits[i];
- int remoteDigit = remoteDigits[i];
- if (remoteDigit != localDigit) return false;
- }
- return true;
- }
- // They are the same length so the last digit must differ and all others must be the same
- for (int i = 0; i < localDigits.length - 1; i++) {
- int localDigit = localDigits[i];
- int remoteDigit = remoteDigits[i];
- if (remoteDigit != localDigit) return false;
- }
- // All the leading digits are equals so the remote is later if the last digit is greater
- return localDigits[localDigits.length - 1] < remoteDigits[remoteDigits.length - 1] ;
- }
-} \ No newline at end of file

Back to the top