⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smarttree.java

📁 JAVA开源LDAP浏览器jxplorer的源码!
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            {
                clearTree();
                setRoot(dn);
                addCutting(rootDNBase, en);
            }
        }
        catch (NamingException e)
        {
            CBUtility.error(CBIntText.get("threaded broker error: "), e);
        } // XXXTHREAD
    }


    /**
     * removes a SmartNode and its children from the tree.
     * Only affects the GUI tree - does nothing to the underlying data.
     *
     * @param apex the root of the subtree to be deleted (may be a leaf).
     */

    protected void deleteTreeNode(SmartNode apex)
    {
        treeModel.removeNodeFromParent(apex);
    }

    /**
     * changes the RDN of a tree node to the lowest level
     * RDN of the supplied DN.
     * (usually to mirror a change  in the underlying DIT)
     *
     * @param node  the node to modify
     * @param newDN the DN providing the new lowest level RDN
     *              to modify the node RDN to.
     */

    public void renameTreeNode(SmartNode node, DN newDN)
    {
        node.update(newDN.getLowestRDN());
    }

    /**
     * moves a subtree (may be a leaf) to a
     * new position.  This only modifies the
     * tree, it <i>does not</i> modify the
     * underlying directory.
     *
     * @param node the node to move.
     * @param to   the DN of the position to move it to.
     */

    public void moveTreeNode(SmartNode node, DN to)
    {
        DN from = treeModel.getDNForNode(node);
        if (from.sharesParent(to))    // we may only need to do a rename...
        {
            renameTreeNode(node, to);
        }
        else
        {
            // step 1; remove node from old position
            SmartNode parent = (SmartNode) node.getParent();
            treeModel.removeNodeFromParent(node);
            treeModel.nodeStructureChanged(parent);

            // step 2: modify the nodes RDN
            node.update(to.getLowestRDN());

            // step 3: add it to new position
            parent = treeModel.getNodeForDN(to.parentDN());

            if (parent.getChildCount() == 1 && ((SmartNode) parent.getChildAt(0)).isDummy())
            {
                return;  // tree hasn't been read from the directory yet - wait until it is before adding anything
            }

            parent.add(node);
            parent.sort();
            treeModel.nodeStructureChanged(parent);
        }
    }

    /**
     * This copies a tree node and its children to a newly
     * created tree node with the given name, <i>without affecting
     * the underlying directory</i>.
     *
     * @param node the tree node to copy data from
     * @param to   the name of the new tree node to create and, if
     *             necessary, populate.
     */

    public void copyTreeNode(SmartNode node, DN to)
    {
        // find the parent corresponding to the target DN
        SmartNode parent = treeModel.getNodeForDN(to.parentDN());

        // sanity check
        if (parent == null)
        {
            CBUtility.error(this, CBIntText.get("unable to copy node {0}.", new String[]{node.toString()}), null);
            return;
        }

        // copy the node (and children) and note the resulting node created
        SmartNode newCopy = copyTreeNodes(node, parent);

        // see if the newly created node has the right RDN
        // (it may not if it has been changed to avoid a 'copy'ing
        // name collision.


        if (newCopy.getRDN().equals(to.getLowestRDN()) == false)
        {
            // we must be doing a 'copy' with a naming problem, so
            // update the newCopy node with it's new, unique RDN.
            newCopy.update(to.getLowestRDN());
        }

        parent.sort();
        // signal a change to the tree for a display update...
        treeModel.nodeStructureChanged(parent);
    }

    /**
     * Copies the node 'from' (creating a new node to hold the copy),
     * adding it as a child to 'toParent',
     * and recursively copies all the children held by 'from' into
     * the newly created copy.
     * This only affects the tree, <i>not</i> the directory.
     *
     * @param from     the node to copy.
     * @param toParent the node which receives the from node as a child.
     * @return the copy of from that is added to toParent
     */

    public SmartNode copyTreeNodes(SmartNode from, SmartNode toParent)
    {
        SmartNode fromCopy = new SmartNode(from); // make copy of 'from' called 'fromCopy
        
        /*
         *    Time saver/Bug Fix - don't bother updating the tree
         *    if the parent hasn't had its children read yet.
         */
         
        if (toParent.hasDummy())
            return fromCopy;

        toParent.add(fromCopy);                   // add 'fromCopy' to 'toParent'

        Enumeration children = from.children();  // find children of 'from'
        while (children.hasMoreElements())
        {
            SmartNode child = (SmartNode) children.nextElement();
            copyTreeNodes(child, fromCopy);       // and add them recursively to 'fromCopy'
        }
        fromCopy.sort();
        return fromCopy;
    }

    /**
     * fully expands all nodes of the tree.
     * (Mainly used for debugging; this could take an
     * unreasonable time if used on a large production
     * directory.)
     */

    public void expandAll()
    {
        int rows = 0;
        while (rows != getRowCount()) // i.e. tree is still expanding...
        {
            rows = getRowCount();
            for (int i = 0; i < rows; i++)
                expandRow(i);
        }

    }

    /**
     * This makes the internal tree object available, in case
     * different cell editors/renderers and so on need to be
     * registered.
     *
     * @return the internal tree object
     */

    public JTree getTree()
    {
        return this;
    }

    /**
     * Starts the process of making a new entry.  As an aid to the user,
     * it tries to find any children of the current node, and if it can
     * find such, it uses them as a template for the new object.
     */

    public void makeNewEntry(DN parentDN)
    {
        if (treeDataSource.getSchemaOps() == null)
        {
            JOptionPane.showMessageDialog(owner, CBIntText.get("Because there is no schema currently published by the\ndirectory, adding a new entry is unavailable."), CBIntText.get("No Schema"), JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        else
        {
            // step 1: find a child to use as a template

            SmartNode parent = treeModel.getNodeForDN(parentDN);
            DN childDN = null;
            if (parent == null)
            {
                log.warning("unable to find " + parentDN + " in tree!");
                return;
            }

            if (parent.getChildCount() > 0)
            {
                SmartNode child = (SmartNode) parent.getChildAt(0);
                if ((child != null) && (child.isDummy() == false))
                {
                    RDN childRDN = child.getRDN();
                    childDN = new DN(parentDN);
                    try
                    {
                        childDN.addChildRDN(childRDN);
                    }
                    catch (InvalidNameException e)
                    {
                        log.log(Level.WARNING, "ERROR: makeNewEntry(DN parentDN) " + parentDN, e);
                    }
                }
                else  // children are not currently displayed - send of a query to get them...
                {
                    refresh(parentDN);
                }

            }

// step 2: find a datasink that can handle a partially created entry

            DataSink editor = null;
            for (int i = 0; i < treeDataSinks.size(); i++)
            {
                if (((DataSink) treeDataSinks.get(i)).canCreateEntry())
                    editor = (DataSink) treeDataSinks.get(i);
            }

            if (editor == null)
            {
                CBUtility.error("Unable to create a new entry!", new Exception("No available entry editors"));
                return;
            }

// step 3: open a NewEntryWin (see) and pass the found child to it.


            NewEntryWin userData = new NewEntryWin(parentDN, childDN, treeDataSource, editor, owner);

            userData.setSize(400, 300);
            CBUtility.center(userData, owner);    // TE: centres window.
            userData.setVisible(true);
        }
    }

/*
    public boolean exists(DN nodeDN)
    {
        if (nodeDN == null) return false;
        try
        {
            return treeDataSource.exists(nodeDN).getStatus();
        } catch (NamingException e) {CBUtility.error("threaded broker error: ", e); } // XXXTHREAD
        return false;
    }
*/

    /**
     * Returns the current popup tool.
     * This is used by the menu bar and others to trigger edits
     * etc, since all that functionality lives in SmartPopupTool.
     */

    public SmartPopupTool getPopupTool()
    {
        return popupTreeTool;
    }

    public void registerEventPublisher(JXplorerEventGenerator gen)
    {
        eventPublisher = gen;
    }

    public void fireJXplorerEvent(JXplorerEvent e)
    {
        if (eventPublisher != null)
            eventPublisher.fireJXplorerEvent(e);
    }


    public boolean isModifiable()
    {
        return treeDataSource.isModifiable();
    }

    public DirContext getDirContext()
    {
        return (treeDataSource == null) ? null : treeDataSource.getDirContext();

    }

    /**
     * This files a request with the directory broker to modify (move / delete / add)
     * an entry.  If oldEntry is null this is an add, if newEntry is null it is a
     * delete, otherwise it is (when called by the tree) usually a rename.
     */

    public void modifyEntry(DXEntry oldEntry, DXEntry newEntry)
    {
        if (oldEntry == null && newEntry == null) return; // nothing to do.

        treeDataSource.modifyEntry(oldEntry, newEntry);  // queue directory request
    }


    /**
     * This files a request with the directory broker to copy a node or subtree.
     */

    //XXX This should be done in the thread that actually does the operation - it is
    //XXX possible for the user to 'beat' this method by quickly copying multiples of
    //XXX the same entry.  Also, it produces extra naming attributes.

    public void copyTree(DN oldNodeDN, DN newNodeDN)
    {

        // 'copy'ing a tree means placing the old tree *under*
        // the newly selected tree... hence deepen 'activeDN' by
        // one new level.  (i.e. copying ou=eng,o=uni,c=au moved
        // to o=biz,c=au requires activeDN extended to ou=eng,o=biz,c=au before move

        // * first check name is not already there; if it is, create a
        //   unique name of the form "copy [(n)] of ..." first.
        // * if adding this to the *display* tree fails display error message.
        // * if directory mod fails, clean up display tree...

        String uniqueRDN = treeModel.getUniqueCopyRDN(newNodeDN, oldNodeDN);

        // check not recursively pasting
        try
        {
            newNodeDN.addChildRDN(uniqueRDN);
        }
        catch (javax.naming.InvalidNameException e)
        {
            CBUtility.error(this, CBIntText.get("Unable to add {0} due to bad name", new String[]{newNodeDN.toString()}), e);
            return;
        }

        treeDataSource.copyTree(oldNodeDN, newNodeDN);  // queue directory request
    }


    /**
     * Displays the result of a expand result, triggered from the data listener.
     * This (should) run from the directory connection thread.
     *
     * @param result the directory read result
     */

    protected void displayExpandedNodeResult(DataQuery result)
    {
        // 1) Find node for result

        SmartNode node = treeModel.getNodeForDN(result.requestDN());

        if (node == null)
        {
            node = addNode(result.requestDN());
        }

        try
        {
            // XXX EXTREME HACKINESS AS WE TRY TO SIMULTANEOUSLY SATISFY RICK AND SCOTT'S CONFLICTING REQUIREMENTS
            // 1b) Special Hack for structural nodes to make work nicely for both x500 and ldap...
            /**
             *  What a debacle.  If null prefix router has knowledge of democorp (o=democorp,c=au) then a list of 'root' fails
             *  horribly, because no-one has the node 'c=au'.  So we hack it to not delete root nodes even if it gets zero
             *  results from a list.  Whoo hoo.  *But*, we still need to keep it all clear in the circumstance that it is

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -