예제 #1
0
        protected override void GetChildItems(string path, bool recurse)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::GetChildItems(Path = '{0}', recurse = '{1}')",
                                       path, recurse));

            string xpath = XmlProviderUtils.NormalizePath(path);

            // Don't need to remove the drive from the path since container provider infrastructure does that
            // for me automatically
            XmlDriveInfo drive = base.PSDriveInfo as XmlDriveInfo;
            XmlDocument  xml   = drive.XmlDocument;
            XmlNodeList  nodes = xml.SelectNodes(xpath, drive.NamespaceManager);

            // ------------------------------
            // NOTE: We could create an ErrorRecord and call WriteError() if SelectNodes() returns null.
            // In this case I decided not to because the fact that get-item returns
            // nothing indicates that case. For other operations such as clear-item or set-item
            // it is a good idea to throw that exception to indicate specifically why you're unable to
            // perform the action.
            // ------------------------------

            foreach (XmlNode node in nodes)
            {
                foreach (XmlNode innerNode in node.ChildNodes)
                {
                    WriteItemObject(innerNode, path, IsNodeContainer(innerNode));
                }
            }
        }
예제 #2
0
        protected override bool IsValidPath(string path)
        {
            Console.WriteLine("XmlNavigationProvider::IsValidPath(Path = '{0}')", path);
            WriteVerbose(string.Format("XmlNavigationProvider::IsValidPath(Path = '{0}')", path));

            // Check if the path is null or empty.
            if (string.IsNullOrEmpty(path))
            {
                return(false);
            }

            // Convert all separators in the path to a uniform one.
            path = XmlProviderUtils.NormalizePath(path);

            // Split path
            string[] pathChunks = path.Split(XmlProviderUtils.XML_PATH_SEP.ToCharArray());

            foreach (string pathChunk in pathChunks)
            {
                if (pathChunk.Length == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        /// <summary>
        /// move-item cmdlet callback
        /// Basically the same as CopyItem except we remove the nodes from their original location after
        /// they get copied over.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="destination"></param>
        protected override void MoveItem(string path, string destination)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::MoveItem(Path = '{0}', destination = '{1}')",
                                       path, destination));

            string      xpath = XmlProviderUtils.NormalizePath(path);
            XmlNodeList nodes = GetXmlNodesFromPath(xpath);

            XmlNode destNode = GetSingleXmlNodeFromPath(destination);

            XmlDocument xmldoc = GetXmlDocumentFromCurrentDrive();

            if (xmldoc == null)
            {
                return;
            }

            foreach (XmlNode nd in nodes)
            {
                if (base.ShouldProcess(nd.Name))
                {
                    destNode.AppendChild(nd.Clone());

                    // remove node from old location
                    nd.ParentNode.RemoveChild(nd);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// get-item cmdlet callback
        /// </summary>
        /// <param name="path"></param>
        protected override void GetItem(string path)
        {
            WriteVerbose(string.Format("XmlItemProvider::GetItem(Path = '{0}')", path));
            string npath = XmlProviderUtils.NormalizePath(path);
            string xpath = XmlProviderUtils.PathNoDrive(npath);

            XmlDriveInfo drive = XmlProviderUtils.GetDriveFromPath(path, base.ProviderInfo);

            if (drive == null)
            {
                ErrorRecord error = new ErrorRecord(new InvalidProgramException("Unable to retrieve the drive for this path"),
                                                    "drive", ErrorCategory.InvalidData, null);
                WriteError(error);
            }

            XmlDocument xml   = drive.XmlDocument;
            XmlNodeList nodes = xml.SelectNodes(xpath, drive.NamespaceManager);

            // ------------------------------
            // NOTE: We could throw an ItemNotFoundException here if the nodelist returned is null
            // or empty. In this case I decided not to because the fact that get-item returns
            // nothing indicates that case. For other operations such as clear-item or set-item
            // it is a good idea to throw that exception to indicate specifically why you're unable to
            // perform the action.
            // ------------------------------

            foreach (XmlNode node in nodes)
            {
                WriteItemObject(node, path, false);
            }
        }
예제 #5
0
        //clear-item, get-item, invoke-item, set-item
        // resolve-path, test-path
        #region ItemCmdletProvider overrides

        /// <summary>
        /// clear-item cmdlet callback
        /// </summary>
        /// <param name="path"></param>
        protected override void ClearItem(string path)
        {
            WriteVerbose(string.Format("XmlItemProvider::ClearItem(Path = '{0}')", path));

            string npath = XmlProviderUtils.NormalizePath(path);
            string xpath = XmlProviderUtils.PathNoDrive(npath);

            XmlNodeList nodes = GetXmlNodesFromPath(xpath);

            // throw terminating error if we can't find any items at path
            // ------------------------------------------------
            if (nodes == null || nodes.Count == 0)
            {
                ErrorRecord error = new ErrorRecord(new ItemNotFoundException(),
                                                    "ItemNotFound", ErrorCategory.ObjectNotFound, null);
                ThrowTerminatingError(error);
            }

            foreach (XmlNode node in nodes)
            {
                // ShouldProcess() enables use of -whatif & -confirm flags for clear-item
                // If path returns more than a single XMLNode, we call ShouldProcess() for each
                // node not one call to ShouldProcess for the entire operation
                // -----------------------------------------------------------
                if (base.ShouldProcess(node.Name))
                {
                    node.RemoveAll();
                }
            }
        }
예제 #6
0
        /// <summary>
        /// verifies item specified by path is a container which will allow the usre to navigate to this location as well
        /// as other container related operations.
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        protected override bool IsItemContainer(string path)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::IsItemContainer(Path = '{0}')",
                                       path));

            // see if item exists at path and indicate if it is container
            // if its a container, we can set-location to it
            string xpath = XmlProviderUtils.NormalizePath(path);

            // Note: We assume that user is setting location to the first XMLNode of possibly more than
            // one. What we might want to do is provide some syntax that indicates which of multiple nodes of same name
            // to change to. Something like 'drive:\root\node[4]' to indicate the 4th node. This will require more manipulation
            // of the path to make sure we strip it before it does to the xpath query.
            // -----------------------------------------------------------------------
            XmlNode node = GetSingleXmlNodeFromPath(xpath);

            if (node == null)
            {
                return(false);
            }
            else
            {
                return(IsNodeContainer(node));
            }
        }
예제 #7
0
        // copy-item, get-childitem, new-item, remove-item, rename-item
        #region ContainerCmdletProvider overrides

        /// <summary>
        /// cmdlet callback for copy-item
        /// </summary>
        /// <param name="path"></param>
        /// <param name="copyPath"></param>
        /// <param name="recurse"></param>
        protected override void CopyItem(string path, string copyPath, bool recurse)
        {
            WriteVerbose(string.Format("XmlContainerProvider::CopyItem(Path = '{0}', CopyPath = '{1}', recurse = '{2}')",
                                       path, copyPath, recurse));

            string xpath = XmlProviderUtils.NormalizePath(path);

            XmlNodeList nodes = GetXmlNodesFromPath(xpath);

            if (nodes == null || nodes.Count == 0)
            {
                ErrorRecord error = new ErrorRecord(new ItemNotFoundException("Source item not found"),
                                                    "ItemNotFound", ErrorCategory.ObjectNotFound, path);
                WriteError(error);
            }

            // Now that we have the node(s) to copy we need to figure out where to copy them
            // There are 3 possible scenarios here:
            // 1) there's already an XML node at the place indicated by copyPath
            // 2) There's not a node there but the node indicated by the path minus the childitem name exists
            //    i.e. \root\one\two\three , \root\one\two exists but \root\one\two\three doesn't
            // 3) The path doesn't exist somewhere in the middle, there is no item.
            //    i.e. \root\one\two\three , \root\one exists but not \root\one\two. which means we couldn't copy
            //         to \root\one\two\three without creating the \two\ item inbetween one & three. This is one of
            //         those internal provider details. The typical behavior here is to create any missing inbetween
            //         nodes if the -force flag is specified.
            XmlNode destNode = GetSingleXmlNodeFromPath(copyPath);

            if (destNode == null)
            {
                ErrorRecord error = new ErrorRecord(new ItemNotFoundException("Destination item not found"),
                                                    "ItemNotFound", ErrorCategory.ObjectNotFound, copyPath);
                WriteError(error);
            }

            XmlDocument xmldoc = GetXmlDocumentFromCurrentDrive();

            if (xmldoc == null)
            {
                return;
            }

            foreach (XmlNode nd in nodes)
            {
                if (base.ShouldProcess(nd.Name))
                {
                    destNode.AppendChild(nd.Clone());
                }
            }
        }
예제 #8
0
        // copy-item, get-childitem, new-item, remove-item, rename-item
        #region ContainerCmdletProvider overrides

        protected override void CopyItem(string path, string copyPath, bool recurse)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::CopyItem(Path = '{0}', CopyPath = '{1}', recurse = '{2}')",
                                       path, copyPath, recurse));

            string xpath = XmlProviderUtils.NormalizePath(path);

            XmlNodeList nodes = GetXmlNodesFromPath(xpath);

            // Now that we have the node(s) to copy we need to figure out where to copy them
            // There are 3 possible scenarios here:
            // 1) there's already an XML node at the place indicated by copyPath
            // 2) There's not a node there but the node indicated by the path minus the childitem name exists
            //    i.e. \root\one\two\three , \root\one\two exists but \root\one\two\three doesn't
            // 3) The path doesn't exist somewhere in the middle, there is no item.
            //    i.e. \root\one\two\three , \root\one exists but not \root\one\two. which means we couldn't copy
            //         to \root\one\two\three without creating the \two\ item inbetween one & three. This is one of
            //         those internal provider details. The typical behavior here is to create any missing inbetween
            //         nodes if the -force flag is specified.
            XmlNode destNode = GetSingleXmlNodeFromPath(copyPath);

            XmlDocument xmldoc = GetXmlDocumentFromCurrentDrive();

            if (xmldoc == null)
            {
                return;
            }

            foreach (XmlNode nd in nodes)
            {
                if (base.ShouldProcess(nd.Name))
                {
                    /*
                     * XmlNode newChildNode = xmldoc.ImportNode(
                     *  nd,
                     *  recurse);
                     * destNode.AppendChild(newChildNode);
                     *
                     * // attributes
                     * destNode.Attributes.RemoveAll();
                     * foreach (XmlAttribute attrib in nd.Attributes)
                     * {
                     *  destNode.Attributes.Append(attrib.Clone());
                     * }
                     */

                    destNode.AppendChild(nd.Clone());
                }
            }
        }
예제 #9
0
        protected override void GetChildNames(string path, ReturnContainers returnContainers)
        {
            Console.WriteLine("XmlNavigationProvider::GetChildNames(Path = '{0}')", path);
            WriteVerbose(string.Format("XmlNavigationProvider::GetChildNames(Path = '{0}', ReturnContainers = '{1}'",
                                       path, returnContainers));

            string xpath = XmlProviderUtils.NormalizePath(path);

            XmlNode node = GetSingleXmlNodeFromPath(xpath);

            foreach (XmlNode nd in node.ChildNodes)
            {
                WriteItemObject(nd, path, IsNodeContainer(nd));
            }
        }
예제 #10
0
        public XmlNode GetSingleXmlNodeFromPath(string path)
        {
            string       npath = XmlProviderUtils.NormalizePath(path);
            string       xpath = XmlProviderUtils.PathNoDrive(npath);
            XmlDriveInfo drive = base.PSDriveInfo as XmlDriveInfo;

            if (drive == null)
            {
                ErrorRecord error = new ErrorRecord(new InvalidProgramException("Unable to retrieve the drive for this path"),
                                                    "drive", ErrorCategory.InvalidData, null);
                ThrowTerminatingError(error);
            }
            XmlDocument xml = drive.XmlDocument;

            return(xml.SelectSingleNode(xpath));
        }
예제 #11
0
        protected override void RemoveItem(string path, bool recurse)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::RemoveItem(Path = '{0}', recurse = '{1}')", path, recurse));
            string      xpath = XmlProviderUtils.NormalizePath(path);
            XmlNodeList nodes = GetXmlNodesFromPath(xpath);

            // NOTE: since we remove nodes, the -recurse flag is kind of assumed. Once a node is removed any of
            // its children are removed also so no need to recurse any further.
            // -------------------------------------------------------------
            foreach (XmlNode node in nodes)
            {
                if (base.ShouldProcess(node.Name))
                {
                    node.ParentNode.RemoveChild(node);
                }
            }
        }
예제 #12
0
        protected override bool HasChildItems(string path)
        {
            Console.WriteLine("XmlNavigationProvider::HasChildItems(Path = '{0}')", path);
            WriteVerbose(string.Format("XmlNavigationProvider::HasChildItems(Path = '{0}')", path));
            string xpath = XmlProviderUtils.NormalizePath(path);

            XmlNode node = GetSingleXmlNodeFromPath(xpath);

            if (node.HasChildNodes)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #13
0
        private XmlNodeList GetXmlNodesFromPath(string path)
        {
            string npath = XmlProviderUtils.NormalizePath(path);
            string xpath = XmlProviderUtils.PathNoDrive(npath);

            XmlDriveInfo drive = XmlProviderUtils.GetDriveFromPath(path, base.ProviderInfo);

            if (drive == null)
            {
                ErrorRecord error = new ErrorRecord(new InvalidProgramException("Unable to retrieve the drive for this path"),
                                                    "drive", ErrorCategory.InvalidData, null);
                WriteError(error);
                return(null);
            }
            XmlDocument xml = drive.XmlDocument;

            return(xml.SelectNodes(xpath));
        }
예제 #14
0
        protected override void RenameItem(string path, string newName)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::RenameItem(Path = '{0}', newname = '{1}')", path, newName));

            // create new node with new name and then copy childnodes and attributes over
            // --------------------------------------------------------------------------
            string      xpath = XmlProviderUtils.NormalizePath(path);
            XmlNodeList nodes = GetXmlNodesFromPath(xpath);

            XmlDriveInfo drive  = base.PSDriveInfo as XmlDriveInfo;
            XmlDocument  xmldoc = drive.XmlDocument;

            foreach (XmlNode nd in nodes)
            {
                if (ShouldProcess(path))
                {
                    XmlNode newNode = xmldoc.CreateNode(nd.NodeType, newName, nd.ParentNode.NamespaceURI);
                    nd.ParentNode.ReplaceChild(newNode, nd);
                }
            }
        }
예제 #15
0
        protected override bool ItemExists(string path)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::ItemExists(Path = '{0}')", path));

            string xpath = XmlProviderUtils.NormalizePath(path);

            XmlDriveInfo drive = base.PSDriveInfo as XmlDriveInfo;

            if (drive == null)
            {
                return(false);
            }
            XmlDocument xml = drive.XmlDocument;

            if (xml.SelectSingleNode(xpath, drive.NamespaceManager) == null)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
예제 #16
0
        /// <summary>
        /// new-item cmdlet callback
        /// </summary>
        /// <param name="path"></param>
        /// <param name="itemTypeName"></param>
        /// <param name="newItemValue"></param>
        protected override void NewItem(string path, string itemTypeName, object newItemValue)
        {
            WriteVerbose(string.Format("XmlContainerProvider::RemoveItemNewItem(Path = '{0}', itemtype = '{1}', newvalue = '{2}')",
                                       path, itemTypeName, newItemValue));

            // first check if item already exists at that path
            // -----------------------------------------------
            string xpath = XmlProviderUtils.NormalizePath(path);

            // we need to get the parent of the new node so we can add to its children
            // we do this by chooping the last item from the path
            // for example: new item path = drive:/root/one/two
            // the parent node would be at drive:/root/one
            // --------------------------------------------
            XmlNode parent = GetParentNodeFromLeaf(xpath);

            string       endName = GetLeafNameFromPath(xpath);
            XmlDriveInfo drive   = base.PSDriveInfo as XmlDriveInfo;
            XmlDocument  xmldoc  = drive.XmlDocument;

            XmlNode newNode = xmldoc.CreateNode(itemTypeName, endName, parent.NamespaceURI);

            parent.AppendChild(newNode);
        }
예제 #17
0
        protected override void GetItem(string path)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::GetItem(Path = '{0}')", path));
            string xpath = XmlProviderUtils.NormalizePath(path);

            // Don't need to remove the drive from the path since container provider infrastructure does that
            // for me automatically
            XmlDriveInfo drive = base.PSDriveInfo as XmlDriveInfo;
            XmlDocument  xml   = drive.XmlDocument;
            XmlNodeList  nodes = xml.SelectNodes(xpath, drive.NamespaceManager);

            // ------------------------------
            // NOTE: We could throw an ItemNotFoundException here if the nodelist returned is null
            // or empty. In this case I decided not to because the fact that get-item returns
            // nothing indicates that case. For other operations such as clear-item or set-item
            // it is a good idea to throw that exception to indicate specifically why you're unable to
            // perform the action.
            // ------------------------------

            foreach (XmlNode node in nodes)
            {
                WriteItemObject(node, path, false);
            }
        }
예제 #18
0
        protected override void NewItem(string path, string itemTypeName, object newItemValue)
        {
            WriteVerbose(string.Format("XmlNavigationProvider::RemoveItemNewItem(Path = '{0}', itemtype = '{1}', newvalue = '{2}')",
                                       path, itemTypeName, newItemValue));

            // first check if item already exists at that path
            // -----------------------------------------------
            string xpath = XmlProviderUtils.NormalizePath(path);

            // we need to get the parent of the new node so we can add to its children
            // we do this by chopping the last item from the path if there isn't already an item
            // at the path. in which case we need to check force flag or error out
            // for example: new item path = drive:/root/one/two
            // the parent node would be at drive:/root/one
            // --------------------------------------------
            XmlNode parent = null;

            XmlNode destNode = GetSingleXmlNodeFromPath(xpath);

            if (destNode != null)
            {
                parent = destNode.ParentNode;
                if (base.Force)
                {
                    destNode.ParentNode.RemoveChild(destNode);
                }
                else
                {
                    // write error
                    ErrorRecord err = new ErrorRecord(new ArgumentException("item already exists!"), "AlreadyExists",
                                                      ErrorCategory.InvalidArgument, path);
                    WriteError(err);
                    return;
                }
            }
            else
            {
                parent = GetParentNodeFromLeaf(xpath);
            }

            if (parent == null)
            {
                // write error
                ErrorRecord err = new ErrorRecord(new ItemNotFoundException("ParentPath doesn't exist"), "ObjectNotFound",
                                                  ErrorCategory.ObjectNotFound, path);
                WriteError(err);
                return;
            }

            string       endName = GetLastPathName(xpath);
            XmlDriveInfo drive   = base.PSDriveInfo as XmlDriveInfo;
            XmlDocument  xmldoc  = drive.XmlDocument;

            XmlNode newNode = xmldoc.CreateNode(itemTypeName, endName, parent.NamespaceURI);

            // lets call shouldprocess
            if (ShouldProcess(path))
            {
                parent.AppendChild(newNode);
            }
        }