diff options
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.java | 953 |
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 |