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

📄 iqdiscoitemshandler.java

📁 openfire 服务器源码下载
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    /**
     * Sets the DiscoItemsProvider to use when a disco#items packet is sent to the server itself
     * and the specified node. For instance, if node matches "http://jabber.org/protocol/offline"
     * then a special DiscoItemsProvider should be use to return information about offline messages.
     *
     * @param node the node that the provider will handle.
     * @param provider the DiscoItemsProvider that will handle disco#items packets sent with the
     *        specified node.
     */
    public void setServerNodeInfoProvider(String node, DiscoItemsProvider provider) {
        serverNodeProviders.put(node, provider);
    }

    /**
     * Removes the DiscoItemsProvider to use when a disco#items packet is sent to the server itself
     * and the specified node.
     *
     * @param node the node that the provider was handling.
     */
    public void removeServerNodeInfoProvider(String node) {
        serverNodeProviders.remove(node);
    }

    /**
     * Registers a new disco item for a component. The jid attribute of the item will match the jid
     * of the component and the name should be the name of the component discovered using disco.
     *
     * @param jid the jid of the component.
     * @param name the discovered name of the component.
     */
    public void addComponentItem(String jid, String name) {
        addComponentItem(jid, null, name);
    }

    /**
     * Registers a new disco item for a component. The jid attribute of the item will match the jid
     * of the component and the name should be the name of the component discovered using disco.
     *
     * @param jid the jid of the component.
     * @param node the node that complements the jid address.
     * @param name the discovered name of the component.
     */
    public void addComponentItem(String jid, String node, String name) {
        Lock lock = CacheFactory.getLock(jid, serverItems);
        try {
            lock.lock();
            ClusteredServerItem item = serverItems.get(jid);
            if (item == null) {
                // First time a node registers a server item for this component
                item = new ClusteredServerItem();

                Element element = DocumentHelper.createElement("item");
                element.addAttribute("jid", jid);
                element.addAttribute("node", node);
                element.addAttribute("name", name);
                item.element = element;
            }
            if (item.nodes.add(XMPPServer.getInstance().getNodeID())) {
                // Update the cache with latest info
                serverItems.put(jid, item);
            }
            // Keep track of the new server item added by this JVM
            localServerItems.put(jid, item.element);
        }
        finally {
            lock.unlock();
        }
    }

    /**
     * Removes a disco item for a component that has been removed from the server.
     *
     * @param jid the jid of the component being removed.
     */
    public void removeComponentItem(String jid) {
        if (serverItems == null) {
            // Safety check
            return;
        }
        Lock lock = CacheFactory.getLock(jid, serverItems);
        try {
            lock.lock();
            ClusteredServerItem item = serverItems.get(jid);
            if (item != null && item.nodes.remove(XMPPServer.getInstance().getNodeID())) {
                // Update the cache with latest info
                if (item.nodes.isEmpty()) {
                    serverItems.remove(jid);
                }
                else {
                    serverItems.put(jid, item);
                }
            }
        }
        finally {
            lock.unlock();
        }
        // Remove locally added server item
        localServerItems.remove(jid);
    }

    public void initialize(XMPPServer server) {
        super.initialize(server);
        serverItems = CacheFactory.createCache("Disco Server Items");
        // Track the implementors of ServerItemsProvider so that we can collect the items
        // provided by the server
        infoHandler = server.getIQDiscoInfoHandler();
        setProvider(server.getServerInfo().getXMPPDomain(), getServerItemsProvider());
        // Listen to cluster events
        ClusterManager.addListener(this);
    }

    public void start() throws IllegalStateException {
        super.start();
        for (ServerItemsProvider provider : XMPPServer.getInstance().getServerItemsProviders()) {
            addServerItemsProvider(provider);
        }
    }

    public Iterator<String> getFeatures() {
        List<String> features = new ArrayList<String>();
        features.add("http://jabber.org/protocol/disco#items");
        // TODO Comment out this line when publishing of client items is implemented
        //features.add("http://jabber.org/protocol/disco#publish");
        return features.iterator();
    }

    public void joinedCluster() {
        restoreCacheContent();
    }

    public void joinedCluster(byte[] nodeID) {
        // Do nothing
    }

    public void leftCluster() {
        if (!XMPPServer.getInstance().isShuttingDown()) {
            restoreCacheContent();
        }
    }

    public void leftCluster(byte[] nodeID) {
        if (ClusterManager.isSeniorClusterMember()) {
            NodeID leftNode = NodeID.getInstance(nodeID);
            for (Map.Entry<String, ClusteredServerItem> entry : serverItems.entrySet()) {
                String jid = entry.getKey();
                Lock lock = CacheFactory.getLock(jid, serverItems);
                try {
                    lock.lock();
                    ClusteredServerItem item = entry.getValue();
                    if (item.nodes.remove(leftNode)) {
                        // Update the cache with latest info
                        if (item.nodes.isEmpty()) {
                            serverItems.remove(jid);
                        }
                        else {
                            serverItems.put(jid, item);
                        }
                    }
                }
                finally {
                    lock.unlock();
                }
            }
        }
    }

    public void markedAsSeniorClusterMember() {
        // Do nothing
    }
    private void restoreCacheContent() {
        for (Map.Entry<String, Element> entry : localServerItems.entrySet()) {
            String jid = entry.getKey();
            Element element = entry.getValue();
            Lock lock = CacheFactory.getLock(jid, serverItems);
            try {
                lock.lock();
                ClusteredServerItem item = serverItems.get(jid);
                if (item == null) {
                    // First time a node registers a server item for this component
                    item = new ClusteredServerItem();
                    item.element = element;
                }
                if (item.nodes.add(XMPPServer.getInstance().getNodeID())) {
                    // Update the cache with latest info
                    serverItems.put(jid, item);
                }
            }
            finally {
                lock.unlock();
            }
        }
    }

    private DiscoItemsProvider getServerItemsProvider() {
        return new DiscoItemsProvider() {
            public Iterator<DiscoItem> getItems(String name, String node, JID senderJID) {
                if (node != null) {
                    // Check if there is a provider for the requested node
                    if (serverNodeProviders.get(node) != null) {
                        return serverNodeProviders.get(node).getItems(name, node, senderJID);
                    }
                    return null;
                }
                if (name == null) {
                    List<DiscoItem> answer = new ArrayList<DiscoItem>();
                    for (ClusteredServerItem item : serverItems.values()) {
                        answer.add(new DiscoItem(item.element));
                    }
                    return answer.iterator();
                }
                else {
                    // If addressed to user@domain, add items from UserItemsProviders to
                    // the reply.
                    List<UserItemsProvider> itemsProviders = XMPPServer.getInstance().getUserItemsProviders();
                    if (itemsProviders.isEmpty()) {
                        // If we didn't find any UserItemsProviders, then answer a not found error
                        return null;
                    }
                    List<DiscoItem> answer = new ArrayList<DiscoItem>();
                    for (UserItemsProvider itemsProvider : itemsProviders) {
                        // Check if we have items associated with the requested name
                        Iterator<Element> itemsItr = itemsProvider.getUserItems(name, senderJID);
                        if (itemsItr != null) {
                            // Add to the reply all the items provided by the UserItemsProvider
                            Element item;
                            while (itemsItr.hasNext()) {
                                item = itemsItr.next();
                                JID itemJid = new JID(item.attributeValue("jid"));
                                String itemName = item.attributeValue("name");
                                String itemNode = item.attributeValue("node");
                                String itemAction = item.attributeValue("action");
                                answer.add(new DiscoItem(itemJid, itemName, itemNode, itemAction));
                            }
                        }
                    }
                    return answer.iterator();
                }
            }
        };
    }

    private static class ClusteredServerItem implements Externalizable {
        private Element element;
        private Set<NodeID> nodes = new HashSet<NodeID>();

        public ClusteredServerItem() {
        }

        public void writeExternal(ObjectOutput out) throws IOException {
            ExternalizableUtil.getInstance().writeSerializable(out, (DefaultElement) element);
            ExternalizableUtil.getInstance().writeExternalizableCollection(out, nodes);
        }

        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            element = (Element) ExternalizableUtil.getInstance().readSerializable(in);
            ExternalizableUtil.getInstance().readExternalizableCollection(in, nodes, getClass().getClassLoader());
        }
    }

    public Iterator<Element> getUserItems(String name, JID senderJID) {
        List<Element> answer = new ArrayList<Element>();
        try {
            User user = UserManager.getInstance().getUser(name);
            RosterItem item = user.getRoster().getRosterItem(senderJID);
            // If the requesting entity is subscribed to the account's presence then
            // answer the user's "available resources"
            if (item.getSubStatus() == RosterItem.SUB_FROM ||
                    item.getSubStatus() == RosterItem.SUB_BOTH) {
                for (Session session : SessionManager.getInstance().getSessions(name)) {
                    Element element = DocumentHelper.createElement("item");
                    element.addAttribute("jid", session.getAddress().toString());
                    answer.add(element);
                }
            }
            return answer.iterator();
        }
        catch (UserNotFoundException e) {
            return answer.iterator();
        }
    }
}

⌨️ 快捷键说明

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