private DiffItem generateRootDiffItem()

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;
            }
        }
    }