in source/com.microsoft.tfs.client.clc/src/com/microsoft/tfs/client/clc/vc/commands/CommandDifference.java [1722:1975]
private DiffItem generateRootDiffItem(
final String item,
VersionSpec version,
final File tempDirectory,
final Workspace workspace) throws CLCException {
Check.notNull(item, "item"); //$NON-NLS-1$
Check.notNull(tempDirectory, "tempDirectory"); //$NON-NLS-1$
Check.notNull(workspace, "workspace"); //$NON-NLS-1$
boolean isWorkspaceVersion = version instanceof WorkspaceVersionSpec;
String serverPath = null;
String localPath = null;
/*
* Attempt to match the given item to a working folder mapping. If this
* fails we leave the localPath or serverPath elements null and deal
* with those later.
*/
if (ServerPath.isServerPath(item)) {
serverPath = ServerPath.canonicalize(item);
final PathTranslation translation = workspace.translateServerPathToLocalPath(serverPath);
if (translation != null) {
localPath = translation.getTranslatedPath();
}
} else {
localPath = LocalPath.canonicalize(item);
final PathTranslation translation = workspace.translateLocalPathToServerPath(localPath);
if (translation != null) {
serverPath = translation.getTranslatedPath();
}
}
/*
* Use the latest version if an unmapped server path was given.
*/
if (version == null && localPath == null) {
version = LatestVersionSpec.INSTANCE;
}
/*
* If version is null, this is for a local item.
*/
if (version == null) {
ItemType itemType;
boolean inRepository = false;
boolean isFolder = false;
long lastModified = 0;
if (localPath == null) {
final String messageFormat = Messages.getString("CommandDifference.NoWorkingFolderMappingFormat"); //$NON-NLS-1$
final String message = MessageFormat.format(messageFormat, item);
throw new CLCException(message);
}
final File localFile = new File(localPath);
final FileSystemAttributes localFileAttributes = FileSystemUtils.getInstance().getAttributes(localPath);
if (localFile.isDirectory() && localFile.exists()) {
itemType = ItemType.FOLDER;
isFolder = true;
} else if (localFile.exists()) {
itemType = ItemType.FILE;
lastModified = localFile.lastModified();
} else {
final String messageFormat = Messages.getString("CommandDifference.FileOrFolderDoesNotExistFormat"); //$NON-NLS-1$
final String message = MessageFormat.format(messageFormat, localPath);
throw new CLCException(message);
}
/*
* File or folder exists, cross-check the data with the server
* information.
*/
final VersionSpec checkVersionSpec = new WorkspaceVersionSpec(workspace);
isWorkspaceVersion = true;
Item[] items = null;
if (serverPath != null) {
items = getFilteredServerItemList(serverPath, checkVersionSpec, false, false, false, true);
}
int codePage = 0;
if (items != null && items.length > 0 && ServerPath.equals(items[0].getServerItem(), serverPath)) {
if (isFolder == false && items[0].getItemType() != ItemType.FOLDER) {
itemType = ItemType.FILE;
codePage = items[0].getEncoding().getCodePage();
}
inRepository = true;
}
/*
* Folders can be returned with no further investigation.
*/
if (itemType == ItemType.FOLDER) {
return new DiffFolderItem(serverPath, localPath, localPath, null, inRepository, version);
} else {
/*
* Determine if the file is a pending change in the current
* workspace.
*/
boolean isPendingChange = false;
if (inRepository && isWorkspaceVersion) {
final PendingSet pendingSet = workspace.getPendingChanges(new String[] {
serverPath
}, RecursionType.NONE, false);
if (pendingSet != null
&& pendingSet.getPendingChanges() != null
&& pendingSet.getPendingChanges().length > 0) {
Check.isTrue(
pendingSet.getPendingChanges().length == 1,
"pendingSet.getPendingChanges().length == 1"); //$NON-NLS-1$
if (pendingSet.getPendingChanges()[0].getChangeType().contains(ChangeType.EDIT)) {
isPendingChange = true;
/*
* Use this code page instead of the item we queried
* from the server, beacuse this one might include a
* pending encoding change.
*/
codePage = pendingSet.getPendingChanges()[0].getEncoding();
}
}
}
if (codePage == 0) {
codePage =
FileEncodingDetector.detectEncoding(localPath, FileEncoding.AUTOMATICALLY_DETECT).getCodePage();
}
final DiffItem ret = new DiffItem(
serverPath,
localPath,
localPath,
codePage,
null,
itemType,
lastModified,
inRepository,
version);
ret.setWritable(
inRepository
&& isWorkspaceVersion
&& localFile.exists()
&& localFileAttributes.isReadOnly() == false);
ret.setIsPendingChange(isPendingChange);
return ret;
}
} else if (serverPath == null) {
/*
* Could not fully qualify the server path with the working folder
* mappings.
*/
final String messageFormat = Messages.getString("CommandDifference.FileOrFolderDoesNotExistFormat"); //$NON-NLS-1$
final String message = MessageFormat.format(messageFormat, item);
throw new CLCException(message);
} else {
/*
* Fully qualified server path, ensure it exists.
*/
final Item[] items = getFilteredServerItemList(serverPath, version, false, false, false, true);
if (items == null || items.length < 1 || ServerPath.equals(items[0].getServerItem(), serverPath) == false) {
if (version != null && version instanceof WorkspaceVersionSpec) {
final WorkspaceVersionSpec workspaceSpec = (WorkspaceVersionSpec) version;
if (Workspace.matchName(workspaceSpec.getName(), workspace.getName())
&& workspace.ownerNameMatches(workspaceSpec.getOwner())) {
final String messageFormat =
Messages.getString("CommandDifference.ItemNotFoundInCurrentWorkspaceFormat"); //$NON-NLS-1$
final String message = MessageFormat.format(messageFormat, serverPath);
throw new CLCException(message);
}
} else {
final String messageFormat =
Messages.getString("CommandDifference.ItemNotFoundInTheRepositoryFormat"); //$NON-NLS-1$
final String message = MessageFormat.format(messageFormat, serverPath);
throw new CLCException(message);
}
}
/*
* Create an intermediate path entry in the temp folder this method
* was given so a diff tool doesn't sense a top-level rename. This
* works for files and folders.
*/
final String newTempPath = new File(tempDirectory, ServerPath.getFileName(serverPath)).getAbsolutePath();
if (items[0].getItemType() == ItemType.FOLDER) {
return new DiffFolderItem(serverPath, localPath, newTempPath, null, true, version);
} else {
int codePage = items[0].getEncoding().getCodePage();
boolean isPendingChange = false;
if (isWorkspaceVersion) {
final PendingSet pendingSet = workspace.getPendingChanges(new String[] {
serverPath
}, RecursionType.NONE, false);
if (pendingSet != null
&& pendingSet.getPendingChanges() != null
&& pendingSet.getPendingChanges().length > 0) {
Check.isTrue(
pendingSet.getPendingChanges().length == 1,
"pendingSet.getPendingChanges().length == 1"); //$NON-NLS-1$
if (pendingSet.getPendingChanges()[0].getChangeType().contains(ChangeType.EDIT)) {
isPendingChange = true;
/*
* Use this code page instead of the item we queried
* from the server, beacuse this one might include a
* pending encoding change.
*/
codePage = pendingSet.getPendingChanges()[0].getEncoding();
}
}
}
final DiffItem ret = new DiffItem(items[0], localPath, newTempPath, null, version);
ret.setCodePage(codePage);
if (isWorkspaceVersion && localPath != null) {
final FileSystemAttributes localFileAttributes =
FileSystemUtils.getInstance().getAttributes(localPath);
if (localFileAttributes.exists() && localFileAttributes.isReadOnly() == false) {
ret.setWritable(true);
}
} else {
ret.setWritable(false);
}
ret.setIsPendingChange(isPendingChange);
return ret;
}
}
}