📄 nodesubscription.java
字号:
return false; } // Check if published node is a first-level child of the subscribed node if (getDepth() == 1 && !node.isChildNode(leafNode)) { return false; } // Check if published node is a descendant child of the subscribed node if (getDepth() == 0 && !node.isDescendantNode(leafNode)) { return false; } } return true; } /** * Returns true if an event notification can be sent to the subscriber of the collection * node for a newly created node that was associated to the collection node or a child * node that was deleted. The subscription has to be of type {@link Type#nodes}. * * @param originatingNode the node that was added or deleted from the collection node. * @return true if an event notification can be sent to the subscriber of the collection * node. */ boolean canSendChildNodeEvent(Node originatingNode) { // Check that this is a subscriber to a collection node if (!node.isCollectionNode()) { return false; } if (!canSendEvents()) { return false; } // Check that subscriber is using type "nodes" if (Type.nodes != type) { return false; } // Check if added/deleted node is a first-level child of the subscribed node if (getDepth() == 1 && !node.isChildNode(originatingNode)) { return false; } // Check if added/deleted node is a descendant child of the subscribed node if (getDepth() == 0 && !node.isDescendantNode(originatingNode)) { return false; } return true; } /** * Returns true if node events such as configuration changed or node purged can be * sent to the subscriber. * * @return true if node events such as configuration changed or node purged can be * sent to the subscriber. */ boolean canSendNodeEvents() { return canSendEvents(); } /** * Returns true if events in general can be sent. This method checks basic * conditions common to all type of event notifications (e.g. item was published, * node configuration has changed, new child node was added to collection node, etc.). * * @return true if events in general can be sent. */ private boolean canSendEvents() { // Check if the subscription is active if (!isActive()) { return false; } // Check if delivery of notifications is disabled if (!shouldDeliverNotifications()) { return false; } // Check if delivery is subject to presence-based policy if (!getPresenceStates().isEmpty()) { Collection<String> shows = service.getShowPresences(jid); if (shows.isEmpty() || Collections.disjoint(getPresenceStates(), shows)) { return false; } } // Check if node is only sending events when user is online if (node.isPresenceBasedDelivery()) { // Check that user is online if (service.getShowPresences(jid).isEmpty()) { return false; } } return true; } /** * Returns true if the published item matches the keyword filter specified in * the subscription. If no keyword was specified then answer true. * * @param publishedItem the published item to send. * @return true if the published item matches the keyword filter specified in * the subscription. */ boolean isKeywordMatched(PublishedItem publishedItem) { // Check if keyword was defined and it was not matched if (keyword != null && keyword.length() > 0 && !publishedItem.containsKeyword(keyword)) { return false; } return true; } /** * Returns true if the subscription is active. A subscription is considered active if it * has not expired, it has been approved and configured. * * @return true if the subscription is active. */ public boolean isActive() { // Check if subscription is approved and configured (if required) if (state != State.subscribed) { return false; } // Check if the subscription has expired if (expire != null && new Date().after(expire)) { // TODO This checking does not replace the fact that we need to implement expiration. // TODO A thread that checks expired subscriptions and removes them is needed. return false; } return true; } /** * Sends the current subscription status to the user that tried to create a subscription to * the node. The subscription status is sent to the subsciber after the subscription was * created or if the subscriber tries to subscribe many times and the node does not support * multpiple subscriptions. * * @param originalRequest the IQ packet sent by the subscriber to create the subscription. */ void sendSubscriptionState(IQ originalRequest) { IQ result = IQ.createResultIQ(originalRequest); Element child = result.setChildElement("pubsub", "http://jabber.org/protocol/pubsub"); Element entity = child.addElement("subscription"); if (!node.isRootCollectionNode()) { entity.addAttribute("node", node.getNodeID()); } entity.addAttribute("jid", getJID().toString()); if (node.isMultipleSubscriptionsEnabled()) { entity.addAttribute("subid", getID()); } entity.addAttribute("subscription", getState().name()); Element subscribeOptions = entity.addElement("subscribe-options"); if (node.isSubscriptionConfigurationRequired() && isConfigurationPending()) { subscribeOptions.addElement("required"); } // Send the result service.send(result); } /** * Sends an event notification for the last published item to the subscriber. If * the subscription has not yet been authorized or is pending to be configured then * no notification is going to be sent.<p> * * Depending on the subscription configuration the event notification may or may not have * a payload, may not be sent if a keyword (i.e. filter) was defined and it was not matched. * * @param publishedItem the last item that was published to the node. */ void sendLastPublishedItem(PublishedItem publishedItem) { // Check if the published item can be sent to the subscriber if (!canSendPublicationEvent(publishedItem.getNode(), publishedItem)) { return; } // Send event notification to the subscriber Message notification = new Message(); Element event = notification.getElement() .addElement("event", "http://jabber.org/protocol/pubsub#event"); Element items = event.addElement("items"); items.addAttribute("node", node.getNodeID()); Element item = items.addElement("item"); if (((LeafNode) node).isItemRequired()) { item.addAttribute("id", publishedItem.getID()); } if (node.isPayloadDelivered() && publishedItem.getPayload() != null) { item.add(publishedItem.getPayload().createCopy()); } // Add a message body (if required) if (isIncludingBody()) { notification.setBody(LocaleUtils.getLocalizedString("pubsub.notification.message.body")); } // Include date when published item was created notification.getElement().addElement("x", "jabber:x:delay") .addAttribute("stamp", fastDateFormat.format(publishedItem.getCreationDate())); // Send the event notification to the subscriber service.sendNotification(node, notification, jid); } /** * Returns true if the specified user is allowed to modify or cancel the subscription. Users * that are allowed to modify/cancel the subscription are: the entity that is recieving the * notifications, the owner of the subscriptions or sysadmins of the pubsub service. * * @param user the user that is trying to cancel the subscription. * @return true if the specified user is allowed to modify or cancel the subscription. */ boolean canModify(JID user) { return user.equals(getJID()) || user.equals(getOwner()) || service.isServiceAdmin(user); } /** * Returns the {@link NodeAffiliate} that owns this subscription. Users that have a * subscription with the node will ALWAYS have an affiliation even if the * affiliation is of type <tt>none</tt>. * * @return the NodeAffiliate that owns this subscription. */ public NodeAffiliate getAffiliate() { return node.getAffiliate(getOwner()); } public String toString() { return super.toString() + " - JID: " + getJID() + " - State: " + getState().name(); } /** * The subscription has been approved by a node owner. The subscription is now active so * the subscriber is now allowed to get event notifications. */ void approved() { if (state == State.subscribed) { // Do nothing return; } state = State.subscribed; if (savedToDB) { // Update the subscription in the backend store PubSubPersistenceManager.saveSubscription(service, node, this, false); } // Send last published item (if node is leaf node and subscription status is ok) if (node.isSendItemSubscribe() && isActive()) { PublishedItem lastItem = node.getLastPublishedItem(); if (lastItem != null) { sendLastPublishedItem(lastItem); } } } /** * Sends an request to authorize the pending subscription to the specified owner. * * @param owner the JID of the user that will get the authorization request. */ public void sendAuthorizationRequest(JID owner) { Message authRequest = new Message(); authRequest.addExtension(node.getAuthRequestForm(this)); authRequest.setTo(owner); authRequest.setFrom(service.getAddress()); // Send authentication request to node owners service.send(authRequest); } /** * Sends an request to authorize the pending subscription to all owners. The first * answer sent by a owner will be processed. Rest of the answers will be discarded. */ public void sendAuthorizationRequest() { Message authRequest = new Message(); authRequest.addExtension(node.getAuthRequestForm(this)); // Send authentication request to node owners service.broadcast(node, authRequest, node.getOwners()); } /** * Subscriptions to a node may exist in several states. Delivery of event notifications * varies according to the subscription state of the user with the node. */ public static enum State { /** * The node will never send event notifications or payloads to users in this state. Users * with subscription state none and affiliation none are going to be deleted. */ none, /** * An entity has requested to subscribe to a node and the request has not yet been * approved by a node owner. The node will not send event notifications or payloads * to the entity while it is in this state. */ pending, /** * An entity has subscribed but its subscription options have not yet been configured. * The node will send event notifications or payloads to the entity while it is in this * state. Default subscription configuration is going to be assumed. */ unconfigured, /** * An entity is subscribed to a node. The node will send all event notifications * (and, if configured, payloads) to the entity while it is in this state. */ subscribed } public static enum Type { /** * Receive notification of new items only. */ items, /** * Receive notification of new nodes only. */ nodes }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -