Пример #1
0
        private FolderMetaData GetMetadataForUpdate(IHttpRequest request, UpdateReportData updatereport, TFSSourceControlProvider sourceControlProvider, out int targetRevision)
        {
            string         basePath = PathParser.GetLocalPath(request, updatereport.SrcPath);
            FolderMetaData metadata;

            if (updatereport.TargetRevision != null)
            {
                targetRevision = int.Parse(updatereport.TargetRevision);
            }
            else
            {
                targetRevision = sourceControlProvider.GetLatestVersion();
            }
            if (updatereport.IsCheckOut)
            {
                metadata = (FolderMetaData)sourceControlProvider.GetItemsWithoutProperties(targetRevision, basePath, Recursion.Full);
            }
            else
            {
                metadata = sourceControlProvider.GetChangedItems(basePath,
                                                                 int.Parse(updatereport.Entries[0].Rev),
                                                                 targetRevision,
                                                                 updatereport);
            }
            if (metadata != null)
            {
                loader = new AsyncItemLoader(metadata, sourceControlProvider);
                ThreadPool.QueueUserWorkItem(state => loader.Start());
            }
            return(metadata);
        }
Пример #2
0
        private bool IsMissing(UpdateReportData data, string localPath, string name)
        {
            if (data.Missing == null || data.Missing.Count == 0)
            {
                return(false);
            }

            string path = localPath.Substring(1);

            if (path.EndsWith("/") == false)
            {
                path += "/";
            }
            if (name.StartsWith(path))
            {
                name = name.Substring(path.Length);
            }

            if (data.Missing.Contains(name))
            {
                return(true);
            }
            foreach (string missing in data.Missing)
            {
                if (name.StartsWith(missing))// the missing is the parent of this item
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #3
0
        private void ReplayReport(IHttpRequest request, IHttpResponse response, TFSSourceControlProvider sourceControlProvider, ReplayReportData replayReport)
        {
            if (replayReport.Revision == 0)
            {
                response.StatusCode = (int)HttpStatusCode.OK;
                using (var output = new StreamWriter(response.OutputStream))
                {
                    output.Write(
                        @"<?xml version=""1.0"" encoding=""utf-8""?>
<S:editor-report xmlns:S=""svn:"">
<S:target-revision rev=""0""/>
</S:editor-report>");
                    return;
                }
            }

            var data = new UpdateReportData();

            data.SrcPath = request.Url.AbsoluteUri;
            data.Entries = new List <EntryData>();
            var     item      = new EntryData();
            string  localPath = PathParser.GetLocalPath(request);
            LogItem log       = sourceControlProvider.GetLog(localPath, 0,
                                                             sourceControlProvider.GetLatestVersion(),
                                                             Recursion.None, 1);

            if (log.History.Length == 0)
            {
                WriteFileNotFoundResponse(request, response);
            }

            item.Rev            = (replayReport.Revision - 1).ToString();
            data.TargetRevision = (replayReport.Revision).ToString();
            data.Entries.Add(item);
            SetResponseSettings(response, "text/xml; charset=\"utf-8\"", Encoding.UTF8, 200);
            response.SendChunked = true;
            using (var output = new StreamWriter(response.OutputStream))
            {
                try
                {
                    output.Write(@"<?xml version=""1.0"" encoding=""utf-8""?>
<S:editor-report xmlns:S=""svn:"">");

                    int            targetRevision;
                    FolderMetaData metadata = GetMetadataForUpdate(request, data, sourceControlProvider,
                                                                   out targetRevision);
                    output.WriteLine("<S:target-revision rev=\"{0}\"/>", targetRevision);

                    OutputEditorReport(sourceControlProvider, metadata, replayReport.Revision,
                                       localPath == "/",
                                       output);

                    output.Write("</S:editor-report>");
                }
                catch (FileNotFoundException)
                {
                    WriteFileNotFoundResponse(request, response);
                }
            }
        }
Пример #4
0
        private string GetSrcPath(UpdateReportData updateReportRequest)
        {
            string url = handler.GetLocalPathFromUrl(updateReportRequest.SrcPath);

            if (updateReportRequest.UpdateTarget != null)
            {
                return(url + "/" + updateReportRequest.UpdateTarget);
            }
            return(url);
        }
Пример #5
0
        private void UpdateReport(TFSSourceControlProvider sourceControlProvider, UpdateReportData updatereport, StreamWriter output, FolderMetaData metadata, int targetRevision)
        {
            output.Write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
            output.Write("<S:update-report xmlns:S=\"svn:\" xmlns:V=\"http://subversion.tigris.org/xmlns/dav/\" xmlns:D=\"DAV:\" send-all=\"true\">\n");
            output.Write("<S:target-revision rev=\"" + targetRevision + "\"/>\n");

            UpdateReportService updateReportService = new UpdateReportService(this, sourceControlProvider);

            updateReportService.ProcessUpdateReportForDirectory(updatereport, metadata, output, true, false);

            output.Write("</S:update-report>\n");
        }
Пример #6
0
 private bool ItemExistsAtTheClient(ItemMetaData item, UpdateReportData updateReportRequest, string srcPath, int clientRevisionForItem)
 {
     if (sourceControlProvider != null)
     {
         return(updateReportRequest.IsCheckOut == false &&
                IsMissing(updateReportRequest, srcPath, item.Name) == false &&
                // we need to check both name and id to ensure that the item was not renamed
                sourceControlProvider.ItemExists(item.Name, clientRevisionForItem) &&
                sourceControlProvider.ItemExists(item.Id, clientRevisionForItem));
     }
     else
     {
         return(false);
     }
 }
Пример #7
0
 private bool ShouldDeleteItemBeforeSendingToClient(ItemMetaData folder,
                                                    UpdateReportData updateReportRequest,
                                                    string srcPath,
                                                    int clientRevisionForItem,
                                                    bool existingFolder)
 {
     if (sourceControlProvider != null)
     {
         return(existingFolder == false && updateReportRequest.IsCheckOut == false &&
                IsMissing(updateReportRequest, srcPath, folder.Name) == false &&
                sourceControlProvider.ItemExists(folder.Name, clientRevisionForItem));
     }
     else
     {
         return(existingFolder == false && updateReportRequest.IsCheckOut == false &&
                IsMissing(updateReportRequest, srcPath, folder.Name) == false);
     }
 }
Пример #8
0
        private static Dictionary <string, int> GetClientExistingFiles(string path, UpdateReportData reportData)
        {
            Dictionary <string, int> clientExistingFiles = new Dictionary <string, int>();

            if (reportData.Entries != null)
            {
                foreach (EntryData entryData in reportData.Entries)
                {
                    if (string.IsNullOrEmpty(path))
                    {
                        clientExistingFiles["/" + entryData.path] = int.Parse(entryData.Rev);
                    }
                    else
                    {
                        clientExistingFiles["/" + path + "/" + entryData.path] = int.Parse(entryData.Rev);
                    }
                }
            }
            return(clientExistingFiles);
        }
Пример #9
0
        private static Dictionary <string, string> GetClientDeletedFiles(string path, UpdateReportData reportData)
        {
            Dictionary <string, string> clientDeletedFiles = new Dictionary <string, string>();

            if (reportData.Missing != null)
            {
                foreach (string missingPath in reportData.Missing)
                {
                    if (string.IsNullOrEmpty(path))
                    {
                        clientDeletedFiles["/" + missingPath] = missingPath;
                    }
                    else
                    {
                        clientDeletedFiles["/" + path + "/" + missingPath] = missingPath;
                    }
                }
            }
            return(clientDeletedFiles);
        }
Пример #10
0
        public void CalculateDiff(string checkoutRootPath, int versionTo, int versionFrom, FolderMetaData checkoutRoot, UpdateReportData updateReportData)
        {
            clientExistingFiles = GetClientExistingFiles(checkoutRootPath, updateReportData);
            clientMissingFiles  = GetClientDeletedFiles(checkoutRootPath, updateReportData);
            string projectRootPath = GetProjectRoot(checkoutRootPath);

            if (updateReportData.Entries != null)
            {
                foreach (EntryData data in updateReportData.Entries)
                {
                    int itemVersionFrom = int.Parse(data.Rev);
                    if (itemVersionFrom < versionFrom)
                    {
                        string rootPath = checkoutRootPath;
                        if (updateReportData.UpdateTarget != null)
                        {
                            rootPath += "/" + updateReportData.UpdateTarget;
                        }

                        string targetPath = rootPath + "/" + data.path;

                        if (targetPath.StartsWith("/"))
                        {
                            targetPath = targetPath.Substring(1);
                        }

                        CalculateChangeBetweenVersions(projectRootPath, targetPath, itemVersionFrom, checkoutRoot, itemVersionFrom, versionFrom);
                    }
                }
            }

            if (versionFrom != versionTo)
            {
                // we have to calculate the difference from the project root
                // this is because we may have a file move from below the checkoutRootPath,
                // which we still need to consider
                FolderMetaData projectRoot = checkoutRoot;
                if (projectRootPath != checkoutRootPath)
                {
                    projectRoot = (FolderMetaData)sourceControlProvider.GetItems(versionTo, projectRootPath, Recursion.None);
                    string path = checkoutRootPath.Substring(0, checkoutRootPath.LastIndexOf('/'));
                    path = path.Substring(path.IndexOf('/') + 1);
                    FolderMetaData result = (FolderMetaData)FindItemOrCreateItem(projectRoot, projectRootPath, path, versionTo, Recursion.None);
                    result.Items.Add(checkoutRoot);
                }

                CalculateChangeBetweenVersions(projectRootPath, -1, projectRoot, versionFrom, versionTo);
            }

            foreach (string missingItem in clientMissingFiles.Values)
            {
                if (sourceControlProvider.ItemExists(checkoutRootPath + "/" + missingItem, versionTo))
                {
                    FindItemOrCreateItem(checkoutRoot, checkoutRootPath, missingItem, versionTo, Recursion.Full);
                }
            }
            FlattenDeletedFolders(checkoutRoot);
            RemoveMissingItemsWhichAreChildrenOfRenamedItem(checkoutRoot);
            VerifyNoMissingItemMetaDataRemained(checkoutRoot);
        }
Пример #11
0
        public void ProcessUpdateReportForFile(UpdateReportData updateReportRequest, ItemMetaData item, StreamWriter output, bool parentFolderWasDeleted)
        {
            if (item is DeleteMetaData)
            {
                if (!parentFolderWasDeleted)
                {
                    output.Write("<S:delete-entry name=\"" + Helper.EncodeB(GetFileName(item.Name)) + "\"/>\n");
                }
            }
            else
            {
                bool   existingFile          = false;
                string srcPath               = GetSrcPath(updateReportRequest);
                int    clientRevisionForItem = GetClientRevisionFor(updateReportRequest.Entries, StripBasePath(item, srcPath));
                if (ItemExistsAtTheClient(item, updateReportRequest, srcPath, clientRevisionForItem))
                {
                    existingFile = true;
                }

                //another item with the same name already exists, need to remove it.
                if (!parentFolderWasDeleted && ShouldDeleteItemBeforeSendingToClient(item, updateReportRequest, srcPath, clientRevisionForItem, existingFile))
                {
                    output.Write("<S:delete-entry name=\"" + Helper.EncodeB(GetFileName(item.Name)) + "\"/>\n");
                }

                if (existingFile)
                {
                    output.Write("<S:open-file name=\"" + Helper.EncodeB(GetFileName(item.Name)) + "\" rev=\"" +
                                 clientRevisionForItem + "\">\n");
                }
                else
                {
                    output.Write("<S:add-file name=\"" + Helper.EncodeB(GetFileName(item.Name)) + "\">\n");
                }

                string localPath = handler.GetLocalPath("/!svn/ver/" + item.Revision + "/" + Helper.Encode(item.Name, true));
                output.Write("<D:checked-in><D:href>" + localPath + "</D:href></D:checked-in>\n");
                output.Write("<S:set-prop name=\"svn:entry:committed-rev\">" + item.Revision + "</S:set-prop>\n");
                output.Write("<S:set-prop name=\"svn:entry:committed-date\">" + Helper.FormatDate(item.LastModifiedDate) + "</S:set-prop>\n");
                output.Write("<S:set-prop name=\"svn:entry:last-author\">" + item.Author + "</S:set-prop>\n");
                if (sourceControlProvider == null)
                {
                    output.Write("<S:set-prop name=\"svn:entry:uuid\">" + new Guid() + "</S:set-prop>\n");
                }
                else
                {
                    output.Write("<S:set-prop name=\"svn:entry:uuid\">" + sourceControlProvider.GetRepositoryUuid() + "</S:set-prop>\n");
                }
                foreach (KeyValuePair <string, string> property in item.Properties)
                {
                    output.Write("<S:set-prop name=\"" + property.Key + "\">" + property.Value + "</S:set-prop>\n");
                }

                while (item.DataLoaded == false)                 // <== Uha
                {
                    Thread.Sleep(100);
                }

                output.Write("<S:txdelta>");
                output.Write(item.Base64DiffData);
                output.Write("\n</S:txdelta>");
                output.Write("<S:prop><V:md5-checksum>" + item.Md5Hash + "</V:md5-checksum></S:prop>\n");

                // Release data memory
                item.DataLoaded     = false;
                item.Base64DiffData = null;

                if (existingFile)
                {
                    output.Write("</S:open-file>\n");
                }
                else
                {
                    output.Write("</S:add-file>\n");
                }
            }
        }
Пример #12
0
        public void ProcessUpdateReportForDirectory(UpdateReportData updateReportRequest, FolderMetaData folder, StreamWriter output, bool rootFolder, bool parentFolderWasDeleted)
        {
            if (folder is DeleteFolderMetaData)
            {
                if (!parentFolderWasDeleted)
                {
                    output.Write("<S:delete-entry name=\"" + Helper.EncodeB(GetFileName(folder.Name)) + "\"/>\n");
                }
            }
            else
            {
                bool existingFolder   = false;
                bool folderWasDeleted = parentFolderWasDeleted;
                if (rootFolder)
                {
                    output.Write("<S:open-directory rev=\"" + updateReportRequest.Entries[0].Rev + "\">\n");
                }
                else
                {
                    string srcPath = GetSrcPath(updateReportRequest);
                    int    clientRevisionForItem = GetClientRevisionFor(updateReportRequest.Entries, StripBasePath(folder, srcPath));
                    if (ItemExistsAtTheClient(folder, updateReportRequest, srcPath, clientRevisionForItem))
                    {
                        existingFolder = true;
                    }

                    //another item with the same name already exists, need to remove it.
                    if (!parentFolderWasDeleted && ShouldDeleteItemBeforeSendingToClient(folder, updateReportRequest, srcPath, clientRevisionForItem, existingFolder))
                    {
                        output.Write("<S:delete-entry name=\"" + Helper.EncodeB(GetFileName(folder.Name)) + "\"/>\n");
                        folderWasDeleted = true;
                    }

                    if (existingFolder)
                    {
                        output.Write("<S:open-directory name=\"" + Helper.EncodeB(GetFileName(folder.Name)) +
                                     "\" rev=\"" + updateReportRequest.Entries[0].Rev + "\">\n");
                    }
                    else
                    {
                        output.Write("<S:add-directory name=\"" + Helper.EncodeB(GetFileName(folder.Name)) +
                                     "\" bc-url=\"" + handler.GetLocalPath("/!svn/bc/" + folder.Revision + "/" + Helper.Encode(folder.Name, true)) +
                                     "\">\n");
                    }
                }
                if (!rootFolder || updateReportRequest.UpdateTarget == null)
                {
                    string svnVer = handler.GetLocalPath("/!svn/ver/" + folder.Revision + "/" + Helper.Encode(folder.Name, true));
                    output.Write("<D:checked-in><D:href>" + svnVer + "</D:href></D:checked-in>\n");
                    output.Write("<S:set-prop name=\"svn:entry:committed-rev\">" + folder.Revision +
                                 "</S:set-prop>\n");
                    output.Write("<S:set-prop name=\"svn:entry:committed-date\">" +
                                 Helper.FormatDate(folder.LastModifiedDate) + "</S:set-prop>\n");
                    output.Write("<S:set-prop name=\"svn:entry:last-author\">" + folder.Author + "</S:set-prop>\n");
                    if (sourceControlProvider == null)
                    {
                        output.Write("<S:set-prop name=\"svn:entry:uuid\">" + new Guid() + "</S:set-prop>\n");
                    }
                    else
                    {
                        output.Write("<S:set-prop name=\"svn:entry:uuid\">" + sourceControlProvider.GetRepositoryUuid() + "</S:set-prop>\n");
                    }
                    foreach (KeyValuePair <string, string> property in folder.Properties)
                    {
                        output.Write("<S:set-prop name=\"" + property.Key + "\">" + property.Value + "</S:set-prop>\n");
                    }
                }

                for (int i = 0; i < folder.Items.Count; i++)
                {
                    ItemMetaData item = folder.Items[i];
                    if (item.ItemType == ItemType.Folder)
                    {
                        ProcessUpdateReportForDirectory(updateReportRequest, (FolderMetaData)item, output, false, folderWasDeleted);
                    }
                    else
                    {
                        ProcessUpdateReportForFile(updateReportRequest, item, output, folderWasDeleted);
                    }
                }
                output.Write("<S:prop></S:prop>\n");
                if (rootFolder || existingFolder)
                {
                    output.Write("</S:open-directory>\n");
                }
                else
                {
                    output.Write("</S:add-directory>\n");
                }
            }
        }
Пример #13
0
        public FolderMetaData GetChangedItems(string path, int versionFrom, int versionTo, UpdateReportData reportData)
        {
            if (path.StartsWith("/"))
            {
                path = path.Substring(1);
            }

            var root = (FolderMetaData)QueryItems(path, versionTo, Recursion.Full);

            if (root != null)
            {
                root.Properties.Clear();
            }

            // the item doesn't exist and the request was for a specific target
            if (root == null && reportData.UpdateTarget != null)
            {
                root = new FolderMetaData();
                var deletedFile = new DeleteMetaData
                {
                    ItemRevision = versionTo,
                    Name         = reportData.UpdateTarget
                };
                root.Items.Add(deletedFile);
                return(root);
            }

            if (root == null)
            {
                throw new FileNotFoundException(path);
            }

            /*
             * var udc = new UpdateDiffCalculator(this);
             * udc.CalculateDiff(path, versionTo, versionFrom, root, reportData);
             * if (reportData.UpdateTarget != null)
             * {
             *  string targetPath = "/" + Helper.CombinePath(path, reportData.UpdateTarget);
             *  foreach (ItemMetaData item in new List<ItemMetaData>(root.Items))
             *  {
             *      string name = item.Name;
             *      if (name.StartsWith("/") == false)
             *          name = "/" + name;
             *      if (name.Equals(targetPath, StringComparison.InvariantCultureIgnoreCase) == false)
             *          root.Items.Remove(item);
             *  }
             * }*/
            return(root);
        }
Пример #14
0
        protected override void Handle(IHttpContext context, TFSSourceControlProvider sourceControlProvider)
        {
            IHttpRequest  request  = context.Request;
            IHttpResponse response = context.Response;
            string        path     = GetPath(request);

            using (XmlReader reader = XmlReader.Create(request.InputStream, Helper.InitializeNewXmlReaderSettings()))
            {
                reader.MoveToContent();
                object data = null;
                try
                {
                    if (reader.NamespaceURI == WebDav.Namespaces.SVN && reader.LocalName == "get-locks-report")
                    {
                        SetResponseSettings(response, "text/xml; charset=\"utf-8\"", Encoding.UTF8, 200);
                        response.SendChunked = true;
                        using (var writer = new StreamWriter(response.OutputStream))
                        {
                            GetLocksReport(writer);
                        }
                    }
                    else if (reader.NamespaceURI == WebDav.Namespaces.SVN && reader.LocalName == "update-report")
                    {
                        data = Helper.DeserializeXml <UpdateReportData>(reader);

                        UpdateReportData dt = (UpdateReportData)data;
                        int targetRevision;
                        if (dt != null && dt.TargetRevision != null)
                        {
                            targetRevision = int.Parse(dt.TargetRevision);
                        }
                        else
                        {
                            targetRevision = -1;
                        }

                        /*
                         * const string latestVersion = "Repository.Latest.Version";
                         * if (RequestCache.Items[latestVersion] == null)
                         * {
                         *  RequestCache.Items[latestVersion] = targetRevision = GetSDKObject().GetLastestVersionNum(path);
                         * }
                         * else
                         * {
                         *  targetRevision = (int)RequestCache.Items[latestVersion];
                         * }
                         */
                        //    FolderMetaData update = GetMetadataForUpdate(request, (UpdateReportData)data, sourceControlProvider, out targetRevision);
                        string       rep;
                        string       str = PathParser.GetLocalPath(request, dt.SrcPath);
                        ItemMetaData up  = QueryItems(ParsePath(str, out rep), targetRevision, Recursion.Full);
                        if (up != null)
                        {
                            FolderMetaData update;
                            if (up is FolderMetaData)
                            {
                                update = up as FolderMetaData;
                            }
                            else
                            {
                                update = new FolderMetaData();
                                update.Items.Add(up);
                            }
                            SetResponseSettings(response, "text/xml; charset=\"utf-8\"", Encoding.UTF8, 200);
                            response.SendChunked = true;
                            using (var output = new StreamWriter(response.OutputStream))
                            {
                                UpdateReport(sourceControlProvider, (UpdateReportData)data, output, update, targetRevision);
                            }
                        }
                        else
                        {
                            SendTargetDoesNotExistResponse(response);
                        }
                    }
                    else if (reader.NamespaceURI == WebDav.Namespaces.SVN && reader.LocalName == "replay-report")
                    {
                        var relayReport = Helper.DeserializeXml <ReplayReportData>(reader);
                        ReplayReport(request, response, sourceControlProvider, relayReport);
                    }
                    else if (reader.NamespaceURI == WebDav.Namespaces.SVN && reader.LocalName == "log-report")
                    {
                        data = Helper.DeserializeXml <LogReportData>(reader);
                        SetResponseSettings(response, "text/xml; charset=\"utf-8\"", Encoding.UTF8, 200);
                        response.SendChunked  = true;
                        response.BufferOutput = false;
                        using (var output = new StreamWriter(response.OutputStream))
                        {
                            LogReport(sourceControlProvider, (LogReportData)data, path, output);
                        }
                    }
                    else if (reader.NamespaceURI == WebDav.Namespaces.SVN && reader.LocalName == "get-locations")
                    {
                        data = Helper.DeserializeXml <GetLocationsReportData>(reader);
                        SetResponseSettings(response, "text/xml; charset=\"utf-8\"", Encoding.UTF8, 200);
                        response.SendChunked = true;
                        using (var output = new StreamWriter(response.OutputStream))
                        {
                            GetLocationsReport(sourceControlProvider, (GetLocationsReportData)data, path, output);
                        }
                    }
                    else if (reader.NamespaceURI == WebDav.Namespaces.SVN && reader.LocalName == "dated-rev-report")
                    {
                        data = Helper.DeserializeXml <DatedRevReportData>(reader);
                        SetResponseSettings(response, "text/xml; charset=\"utf-8\"", Encoding.UTF8, 200);
                        response.SendChunked = true;
                        using (var output = new StreamWriter(response.OutputStream))
                        {
                            GetDatedRevReport(sourceControlProvider, (DatedRevReportData)data, output, path);
                        }
                    }
                    else if (reader.NamespaceURI == WebDav.Namespaces.SVN && reader.LocalName == "file-revs-report")
                    {
                        data = Helper.DeserializeXml <FileRevsReportData>(reader);
                        string serverPath = "/";
                        if (path.IndexOf('/', 9) > -1)
                        {
                            serverPath = path.Substring(path.IndexOf('/', 9));
                        }
                        SendBlameResponse(request, response, sourceControlProvider, serverPath, (FileRevsReportData)data);
                        return;
                    }
                    else
                    {
                        SendUnknownReportResponse(response);
                    }
                    //if (data != null)
                    //{
                    //    RequestCache.Items["RequestBody"] = data;
                    //    DefaultLogger logger = Container.Resolve<DefaultLogger>();
                    //    logger.ErrorFullDetails(new Exception("Logging"), context);
                    //}
                }
                catch
                {
                    RequestCache.Items["RequestBody"] = data;
                    throw;
                }
            }
        }