📄 node.java
字号:
/** * $RCSfile: $ * $Revision: $ * $Date: $ * * Copyright (C) 2008 Jive Software. All rights reserved. * * This software is published under the terms of the GNU Public License (GPL), * a copy of which is included in this distribution, or a commercial license * agreement with Jive. */package org.jivesoftware.openfire.pubsub;import org.dom4j.Element;import org.jivesoftware.openfire.pubsub.models.AccessModel;import org.jivesoftware.openfire.pubsub.models.PublisherModel;import org.jivesoftware.util.LocaleUtils;import org.jivesoftware.util.StringUtils;import org.xmpp.forms.DataForm;import org.xmpp.forms.FormField;import org.xmpp.packet.IQ;import org.xmpp.packet.JID;import org.xmpp.packet.Message;import java.util.*;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.CopyOnWriteArrayList;/** * A virtual location to which information can be published and from which event * notifications and/or payloads can be received (in other pubsub systems, this may * be labelled a "topic"). * * @author Matt Tucker */public abstract class Node { /** * Reference to the publish and subscribe service. */ protected PubSubService service; /** * Keeps the Node that is containing this node. */ protected CollectionNode parent; /** * The unique identifier for a node within the context of a pubsub service. */ protected String nodeID; /** * Flag that indicates whether to deliver payloads with event notifications. */ protected boolean deliverPayloads; /** * Policy that defines whether owners or publisher should receive replies to items. */ protected ItemReplyPolicy replyPolicy; /** * Flag that indicates whether to notify subscribers when the node configuration changes. */ protected boolean notifyConfigChanges; /** * Flag that indicates whether to notify subscribers when the node is deleted. */ protected boolean notifyDelete; /** * Flag that indicates whether to notify subscribers when items are removed from the node. */ protected boolean notifyRetract; /** * Flag that indicates whether to deliver notifications to available users only. */ protected boolean presenceBasedDelivery; /** * Publisher model that specifies who is allowed to publish items to the node. */ protected PublisherModel publisherModel = PublisherModel.open; /** * Flag that indicates that subscribing and unsubscribing are enabled. */ protected boolean subscriptionEnabled; /** * Access model that specifies who is allowed to subscribe and retrieve items. */ protected AccessModel accessModel = AccessModel.open; /** * The roster group(s) allowed to subscribe and retrieve items. */ protected Collection<String> rosterGroupsAllowed = new ArrayList<String>(); /** * List of multi-user chat rooms to specify for replyroom. */ protected Collection<JID> replyRooms = new ArrayList<JID>(); /** * List of JID(s) to specify for replyto. */ protected Collection<JID> replyTo = new ArrayList<JID>(); /** * The type of payload data to be provided at the node. Usually specified by the * namespace of the payload (if any). */ protected String payloadType = ""; /** * The URL of an XSL transformation which can be applied to payloads in order * to generate an appropriate message body element. */ protected String bodyXSLT = ""; /** * The URL of an XSL transformation which can be applied to the payload format * in order to generate a valid Data Forms result that the client could display * using a generic Data Forms rendering engine. */ protected String dataformXSLT = ""; /** * Indicates if the node is present in the database. */ private boolean savedToDB = false; /** * The datetime when the node was created. */ protected Date creationDate; /** * The last date when the ndoe's configuration was modified. */ private Date modificationDate; /** * The JID of the node creator. */ protected JID creator; /** * A description of the node. */ protected String description = ""; /** * The default language of the node. */ protected String language = ""; /** * The JIDs of those to contact with questions. */ protected Collection<JID> contacts = new ArrayList<JID>(); /** * The name of the node. */ protected String name = ""; /** * Flag that indicates whether new subscriptions should be configured to be active. */ protected boolean subscriptionConfigurationRequired = false; /** * The JIDs of those who have an affiliation with this node. When subscriptionModel is * whitelist then this collection acts as the white list (unless user is an outcast) */ protected Collection<NodeAffiliate> affiliates = new CopyOnWriteArrayList<NodeAffiliate>(); /** * Map that contains the current subscriptions to the node. A user may have more than one * subscription. Each subscription is uniquely identified by its ID. * Key: Subscription ID, Value: the subscription. */ protected Map<String, NodeSubscription> subscriptionsByID = new ConcurrentHashMap<String, NodeSubscription>(); /** * Map that contains the current subscriptions to the node. This map should be used only * when node is not configured to allow multiple subscriptions. When multiple subscriptions * is not allowed the subscriptions can be searched by the subscriber JID. Otherwise searches * should be done using the subscription ID. * Key: Subscriber full JID, Value: the subscription. */ protected Map<String, NodeSubscription> subscriptionsByJID = new ConcurrentHashMap<String, NodeSubscription>(); Node(PubSubService service, CollectionNode parent, String nodeID, JID creator) { this.service = service; this.parent = parent; this.nodeID = nodeID; this.creator = creator; long startTime = System.currentTimeMillis(); this.creationDate = new Date(startTime); this.modificationDate = new Date(startTime); // Configure node with default values (get them from the pubsub service) DefaultNodeConfiguration defaultConfiguration = service.getDefaultNodeConfiguration(!isCollectionNode()); this.subscriptionEnabled = defaultConfiguration.isSubscriptionEnabled(); this.deliverPayloads = defaultConfiguration.isDeliverPayloads(); this.notifyConfigChanges = defaultConfiguration.isNotifyConfigChanges(); this.notifyDelete = defaultConfiguration.isNotifyDelete(); this.notifyRetract = defaultConfiguration.isNotifyRetract(); this.presenceBasedDelivery = defaultConfiguration.isPresenceBasedDelivery(); this.accessModel = defaultConfiguration.getAccessModel(); this.publisherModel = defaultConfiguration.getPublisherModel(); this.language = defaultConfiguration.getLanguage(); this.replyPolicy = defaultConfiguration.getReplyPolicy(); } /** * Adds a new affiliation or updates an existing affiliation of the specified entity JID * to become a node owner. * * @param jid the JID of the user being added as a node owner. * @return the newly created or modified affiliation to the node. */ public NodeAffiliate addOwner(JID jid) { NodeAffiliate nodeAffiliate = addAffiliation(jid, NodeAffiliate.Affiliation.owner); Collection<NodeSubscription> subscriptions = getSubscriptions(jid); if (subscriptions.isEmpty()) { // User does not have a subscription with the node so create a default one createSubscription(null, jid, jid, false, null); } else { // Approve any pending subscription for (NodeSubscription subscription : getSubscriptions(jid)) { if (subscription.isAuthorizationPending()) { subscription.approved(); } } } return nodeAffiliate; } /** * Removes the owner affiliation of the specified entity JID. If the user that is * no longer an owner was subscribed to the node then his affiliation will be of * type {@link NodeAffiliate.Affiliation#none}. * * @param jid the JID of the user being removed as a node owner. */ public void removeOwner(JID jid) { // Get the current affiliation of the specified JID NodeAffiliate affiliate = getAffiliate(jid); if (affiliate.getSubscriptions().isEmpty()) { removeAffiliation(jid, NodeAffiliate.Affiliation.owner); removeSubscriptions(jid); } else { // The user has subscriptions so change affiliation to NONE addNoneAffiliation(jid); } } /** * Adds a new affiliation or updates an existing affiliation of the specified entity JID * to become a node publisher. * * @param jid the JID of the user being added as a node publisher. * @return the newly created or modified affiliation to the node. */ public NodeAffiliate addPublisher(JID jid) { NodeAffiliate nodeAffiliate = addAffiliation(jid, NodeAffiliate.Affiliation.publisher); Collection<NodeSubscription> subscriptions = getSubscriptions(jid); if (subscriptions.isEmpty()) { // User does not have a subscription with the node so create a default one createSubscription(null, jid, jid, false, null); } else { // Approve any pending subscription for (NodeSubscription subscription : getSubscriptions(jid)) { if (subscription.isAuthorizationPending()) { subscription.approved(); } } } return nodeAffiliate; } /** * Removes the publisher affiliation of the specified entity JID. If the user that is * no longer a publisher was subscribed to the node then his affiliation will be of * type {@link NodeAffiliate.Affiliation#none}. * * @param jid the JID of the user being removed as a node publisher. */ public void removePublisher(JID jid) { // Get the current affiliation of the specified JID NodeAffiliate affiliate = getAffiliate(jid); if (affiliate.getSubscriptions().isEmpty()) { removeAffiliation(jid, NodeAffiliate.Affiliation.publisher); removeSubscriptions(jid); } else { // The user has subscriptions so change affiliation to NONE addNoneAffiliation(jid); } } /** * Adds a new affiliation or updates an existing affiliation of the specified entity JID * to become a none affiliate. Affiliates of type none are allowed to subscribe to the node. * * @param jid the JID of the user with affiliation "none". * @return the newly created or modified affiliation to the node. */ public NodeAffiliate addNoneAffiliation(JID jid) { return addAffiliation(jid, NodeAffiliate.Affiliation.none); } /** * Sets that the specified entity is an outcast of the node. Outcast entities are not * able to publish or subscribe to the node. Existing subscriptions will be deleted. * * @param jid the JID of the user that is no longer able to publish or subscribe to the node. * @return the newly created or modified affiliation to the node. */ public NodeAffiliate addOutcast(JID jid) { NodeAffiliate nodeAffiliate = addAffiliation(jid, NodeAffiliate.Affiliation.outcast); // Delete existing subscriptions removeSubscriptions(jid); return nodeAffiliate; } /** * Removes the banning to subscribe to the node for the specified entity. * * @param jid the JID of the user that is no longer an outcast. */ public void removeOutcast(JID jid) { removeAffiliation(jid, NodeAffiliate.Affiliation.outcast); } private NodeAffiliate addAffiliation(JID jid, NodeAffiliate.Affiliation affiliation) { boolean created = false; // Get the current affiliation of the specified JID NodeAffiliate affiliate = getAffiliate(jid); // Check if the user already has the same affiliation if (affiliate != null && affiliation == affiliate.getAffiliation()) { // Do nothing since the user already has the expected affiliation return affiliate; } else if (affiliate != null) { // Update existing affiliation with new affiliation type affiliate.setAffiliation(affiliation); } else { // User did not have any affiliation with the node so create a new one affiliate = new NodeAffiliate(this, jid); affiliate.setAffiliation(affiliation); addAffiliate(affiliate);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -