Ejemplo n.º 1
0
 public PartialGisDataset?PatchReplacementDataset(GisDataset source)
 {
     if (ReplacementDataset == null)
     {
         return(null);
     }
     return(PatchDataset(source, ReplacementDataset.Value));
 }
Ejemplo n.º 2
0
 public PartialGisDataset?PatchNewDataset(GisDataset source)
 {
     if (NewDataset == null)
     {
         return(null);
     }
     return(PatchDataset(source, NewDataset.Value));
 }
Ejemplo n.º 3
0
        public Solution?GetSolution(GisDataset oldDataset, DateTime since = default)
        {
            // default for since is the earliest possible DateTime, which will consider all moves in the database
            // Returns the first move in the database since the date given.  The solution will have a timestamp when the move was made
            // Be sure to call this again after the user has applied the given fix to see if there are subsequent moves that should be
            // applied to the fix.  Keep going until there are no more solutions.
            // Example: at time 1 /a/b/c is moved to /d/e/f
            // then at time 2 /d/e/f is moved to /g/h/i
            // then at time 3 /g/h/i is deleted and replaced by  /1/2/3.
            // ultimately, the user should not be given the option to use /d/e/f since it doesn't exist.
            // however this gets complicated.  For example
            // At time 1 /a/b/c is moved to the archive and a replacement of /d/e/f is offered
            // at time 2 archive/a/b/c is moved to the trash and replaced by /1/2/3
            // at time 3 /d/e/f is moved to archive and replaced by /4/5/6
            // The user with /a/b/c might want 1/2/3, 4/5/6, archive/d/e/f or trash/a/b/c.  To resolve this
            // The user should be given the choice from time 1, then the choice from time 2 or time 3 depending
            // on the first choice.

            // The timestamp is really not that helpful. It is only useful when doing a second search, and then
            // the moves that are known by date to be not applicable can be skipped.

            // IMPORTANT: the timestamp does not solve this problem:
            // at time 1 dataset /a/b/c is created (creates are not logged in the moves dataset)
            // at time 2 dataset /a/b/c is moved to /d/e/f (and logged)
            // at time 3 a new dataset /a/b/c is created (not logged)
            // at time 4 new dataset /a/b/c is moved to /g/h/i (logged)
            // GetSolution will always return the move at time 2 when first checking /a/b/c.
            // GetSolution could correctly return the move at time4 if given a start time after time 2.
            // However, we do not know if the map added data /a/b/c before time 2 or after time 3.
            // The date a layer is added is not stored in the map document.
            // We will try to discourage this kind of renaming situation.

            if (!oldDataset.Workspace.IsOnPds)
            {
                return(null);
            }

            Move?maybeMove = FindFirstMatchingMove(oldDataset, since);

            if (maybeMove == null)
            {
                return(null);
            }

            Move move               = maybeMove.Value;
            var  newDataset         = move.PatchNewDataset(oldDataset);
            var  replacementDataset = move.PatchReplacementDataset(oldDataset);
            var  layerFile          = move.ReplacementLayerFilePath;
            var  remarks            = move.Remarks;

            if (newDataset == null && replacementDataset == null && layerFile == null && remarks == null)
            {
                return(null);
            }

            return(new Solution(move.Timestamp, newDataset?.ToGisDataset(oldDataset), replacementDataset?.ToGisDataset(oldDataset), layerFile, remarks));
        }
Ejemplo n.º 4
0
 public GisDataset ToGisDataset(GisDataset gisDataset)
 {
     return(new GisDataset(
                Workspace.Folder,
                WorkspaceProgId ?? gisDataset.WorkspaceProgId,
                DatasourceName ?? gisDataset.DatasourceName,
                DatasourceType ?? gisDataset.DatasourceType
                ));
 }
Ejemplo n.º 5
0
        private bool IsWorkspaceMatch(GisDataset dataset, PartialGisDataset moveFrom)
        {
            // Assumes workspace paths in moves do not have volume information
            string movePath = moveFrom.Workspace.Folder;
            string fullPath = dataset.Workspace.WithoutVolume;

            // TODO: The WorkspaceProgId from map data may have a ".1" (or other number?) suffix  (everything in Theme Manager ends in '.1')
            if (moveFrom.WorkspaceProgId != null && moveFrom.WorkspaceProgId == dataset.WorkspaceProgId)
            {
                return(false);
            }
            return(string.Compare(fullPath, movePath, StringComparison.OrdinalIgnoreCase) == 0);
        }
Ejemplo n.º 6
0
        private bool IsPartialWorkspaceMatch(GisDataset dataset, PartialGisDataset moveFrom)
        {
            // A partial workspace match (i.e. the current or an ancestral folder has moved) is only valid
            // if the moveFrom.DatasourceName is null; if not null, then we must do a DataSourceMatch
            if (moveFrom.DatasourceName != null)
            {
                return(false);
            }
            // Assumes workspace paths in moves do not have volume information
            string movePath = moveFrom.Workspace.Folder;
            string fullPath = dataset.Workspace.WithoutVolume;

            // Just searching for oldPath somewhere in newPath could yield some false positives.
            // Instead, strip the volume and only match the beginning of the string
            return(fullPath.StartsWith(movePath, StringComparison.OrdinalIgnoreCase));
        }
Ejemplo n.º 7
0
        private Move?FindFirstMatchingMove(GisDataset dataset, DateTime since)
        {
            // Assumes moves list is in chronological order
            foreach (Move move in _moves)
            {
                if (move.Timestamp <= since)
                {
                    continue;
                }

                if (IsDataSourceMatch(dataset, move.OldDataset) ||
                    IsPartialWorkspaceMatch(dataset, move.OldDataset))
                {
                    return(move);
                }
            }
            return(null);
        }
Ejemplo n.º 8
0
 private bool IsDataSourceMatch(GisDataset dataset, PartialGisDataset moveFrom)
 {
     if (dataset.DatasourceName == null)
     {
         return(false);
     }
     if (moveFrom.DatasourceName == null)
     {
         return(false);
     }
     if (String.Compare(dataset.DatasourceName, moveFrom.DatasourceName, StringComparison.OrdinalIgnoreCase) != 0)
     {
         return(false);
     }
     if (moveFrom.DatasourceType != null && moveFrom.DatasourceType != dataset.DatasourceType)
     {
         return(false);
     }
     return(IsWorkspaceMatch(dataset, moveFrom));
 }
Ejemplo n.º 9
0
            private PartialGisDataset?PatchDataset(GisDataset source, PartialGisDataset newDataset)
            {
                //A partial dataset must have a fully specified workspace, but a move may describe a parent folder
                //This method patches the new dataset by applying the move to the source workspace
                //The workspace in the move's old dataset must be a prefix of the input source for this method to return a non-null result

                var searchString           = OldDataset.Workspace.Folder;
                int positionOfSearchString = source.Workspace.Folder.IndexOf(searchString, StringComparison.OrdinalIgnoreCase);

                if (positionOfSearchString < 0)
                {
                    return(null);
                }
                var newWorkspace = source.Workspace.Folder.Substring(0, positionOfSearchString) +
                                   newDataset.Workspace.Folder +
                                   source.Workspace.Folder.Substring(positionOfSearchString + searchString.Length);

                return(new PartialGisDataset(
                           newWorkspace,
                           newDataset.WorkspaceProgId,
                           newDataset.DatasourceName,
                           newDataset.DatasourceType
                           ));
            }