mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22:05 +01:00
Refactor PEP to use PubSub API.
Fixes SMACK-416.
This commit is contained in:
parent
0d6f00873f
commit
33e5c37af8
17 changed files with 479 additions and 453 deletions
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2015 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smack.filter.jidtype;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jivesoftware.smack.util.Objects;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for XMPP address type filters.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractJidTypeFilter implements StanzaFilter {
|
||||||
|
|
||||||
|
private final JidType jidType;
|
||||||
|
|
||||||
|
protected AbstractJidTypeFilter(JidType jidType) {
|
||||||
|
this.jidType = Objects.requireNonNull(jidType, "jidType must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(Stanza stanza) {
|
||||||
|
Jid toMatch = getJidToMatchFrom(stanza);
|
||||||
|
if (toMatch == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return jidType.isTypeOf(toMatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Jid getJidToMatchFrom(Stanza stanza);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String toString() {
|
||||||
|
return getClass().getSimpleName() + ": " + jidType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum JidType {
|
||||||
|
BareJid,
|
||||||
|
DomainBareJid,
|
||||||
|
DomainFullJid,
|
||||||
|
DomainJid,
|
||||||
|
EntityBareJid,
|
||||||
|
EntityFullJid,
|
||||||
|
EntityJid,
|
||||||
|
FullJid,
|
||||||
|
;
|
||||||
|
|
||||||
|
public boolean isTypeOf(Jid jid) {
|
||||||
|
if (jid == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (this) {
|
||||||
|
case BareJid:
|
||||||
|
return jid.hasNoResource();
|
||||||
|
case DomainBareJid:
|
||||||
|
return jid.isDomainBareJid();
|
||||||
|
case DomainFullJid:
|
||||||
|
return jid.isDomainFullJid();
|
||||||
|
case EntityBareJid:
|
||||||
|
return jid.isEntityBareJid();
|
||||||
|
case EntityFullJid:
|
||||||
|
return jid.isEntityFullJid();
|
||||||
|
case EntityJid:
|
||||||
|
return jid.isEntityJid();
|
||||||
|
case FullJid:
|
||||||
|
return jid.hasResource();
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2015 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smack.filter.jidtype;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter based on the 'from' XMPP address type.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FromJidTypeFilter extends AbstractJidTypeFilter {
|
||||||
|
|
||||||
|
public FromJidTypeFilter(JidType jidType) {
|
||||||
|
super(jidType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Jid getJidToMatchFrom(Stanza stanza) {
|
||||||
|
return stanza.getFrom();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,6 +16,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO describe me.
|
* Filter based on the type of an XMPP address.
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.pep.packet;
|
package org.jivesoftware.smack.filter.jidtype;
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2015 Florian Schmaus
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.disco;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for Features.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Feature {
|
||||||
|
|
||||||
|
public enum Support {
|
||||||
|
optional,
|
||||||
|
recommended,
|
||||||
|
required,
|
||||||
|
;
|
||||||
|
|
||||||
|
public boolean isRequired() {
|
||||||
|
return this == required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNotRequired() {
|
||||||
|
return !isRequired();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,8 @@ import org.jxmpp.util.cache.Cache;
|
||||||
import org.jxmpp.util.cache.ExpirationCache;
|
import org.jxmpp.util.cache.ExpirationCache;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -659,9 +661,20 @@ public final class ServiceDiscoveryManager extends Manager {
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public boolean serverSupportsFeature(String feature) throws NoResponseException, XMPPErrorException,
|
public boolean serverSupportsFeature(CharSequence feature) throws NoResponseException, XMPPErrorException,
|
||||||
NotConnectedException, InterruptedException {
|
NotConnectedException, InterruptedException {
|
||||||
return supportsFeature(connection().getXMPPServiceDomain(), feature);
|
return serverSupportsFeatures(feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean serverSupportsFeatures(CharSequence... features) throws NoResponseException,
|
||||||
|
XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
return serverSupportsFeatures(Arrays.asList(features));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean serverSupportsFeatures(Collection<? extends CharSequence> features)
|
||||||
|
throws NoResponseException, XMPPErrorException, NotConnectedException,
|
||||||
|
InterruptedException {
|
||||||
|
return supportsFeatures(connection().getXMPPServiceDomain(), features);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -675,9 +688,22 @@ public final class ServiceDiscoveryManager extends Manager {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
public boolean supportsFeature(Jid jid, String feature) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
public boolean supportsFeature(Jid jid, CharSequence feature) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
return supportsFeatures(jid, feature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsFeatures(Jid jid, CharSequence... features) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
return supportsFeatures(jid, Arrays.asList(features));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supportsFeatures(Jid jid, Collection<? extends CharSequence> features) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
DiscoverInfo result = discoverInfo(jid);
|
DiscoverInfo result = discoverInfo(jid);
|
||||||
return result.containsFeature(feature);
|
for (CharSequence feature : features) {
|
||||||
|
if (!result.containsFeature(feature)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -209,7 +209,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable<DiscoverInfo> {
|
||||||
* @param feature the feature to check
|
* @param feature the feature to check
|
||||||
* @return true if the requestes feature has been discovered
|
* @return true if the requestes feature has been discovered
|
||||||
*/
|
*/
|
||||||
public boolean containsFeature(String feature) {
|
public boolean containsFeature(CharSequence feature) {
|
||||||
return features.contains(new Feature(feature));
|
return features.contains(new Feature(feature));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,6 +482,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable<DiscoverInfo> {
|
||||||
this.variable = feature.variable;
|
this.variable = feature.variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Feature(CharSequence variable) {
|
||||||
|
this(variable.toString());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new feature offered by an XMPP entity or item.
|
* Creates a new feature offered by an XMPP entity or item.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2003-2007 Jive Software.
|
* Copyright 2003-2007 Jive Software, 2015 Florian Schmaus.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,8 +17,9 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.pep;
|
package org.jivesoftware.smackx.pep;
|
||||||
|
|
||||||
import org.jivesoftware.smackx.pep.packet.PEPEvent;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jivesoftware.smackx.pubsub.EventElement;
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,6 +27,7 @@ import org.jxmpp.jid.Jid;
|
||||||
* A listener that is fired anytime a PEP event message is received.
|
* A listener that is fired anytime a PEP event message is received.
|
||||||
*
|
*
|
||||||
* @author Jeff Williams
|
* @author Jeff Williams
|
||||||
|
* @author Florian Schmaus
|
||||||
*/
|
*/
|
||||||
public interface PEPListener {
|
public interface PEPListener {
|
||||||
|
|
||||||
|
@ -34,7 +36,8 @@ public interface PEPListener {
|
||||||
*
|
*
|
||||||
* @param from the user that sent the entries.
|
* @param from the user that sent the entries.
|
||||||
* @param event the event contained in the message.
|
* @param event the event contained in the message.
|
||||||
|
* @param message the message stanza containing the PEP event.
|
||||||
*/
|
*/
|
||||||
public void eventReceived(Jid from, PEPEvent event);
|
public void eventReceived(EntityBareJid from, EventElement event, Message message);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2003-2007 Jive Software.
|
* Copyright 2003-2007 Jive Software, 2015 Florian Schmaus
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,21 +17,32 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.pep;
|
package org.jivesoftware.smackx.pep;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Map;
|
||||||
import java.util.List;
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.Manager;
|
||||||
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
import org.jivesoftware.smack.StanzaListener;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
|
import org.jivesoftware.smack.filter.AndFilter;
|
||||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
|
import org.jivesoftware.smack.filter.jidtype.FromJidTypeFilter;
|
||||||
|
import org.jivesoftware.smack.filter.jidtype.AbstractJidTypeFilter.JidType;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
import org.jivesoftware.smack.packet.IQ.Type;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.pep.packet.PEPEvent;
|
import org.jivesoftware.smackx.pubsub.EventElement;
|
||||||
import org.jivesoftware.smackx.pep.packet.PEPItem;
|
import org.jivesoftware.smackx.pubsub.Item;
|
||||||
import org.jivesoftware.smackx.pep.packet.PEPPubSub;
|
import org.jivesoftware.smackx.pubsub.LeafNode;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jivesoftware.smackx.pubsub.PubSubFeature;
|
||||||
|
import org.jivesoftware.smackx.pubsub.PubSubManager;
|
||||||
|
import org.jivesoftware.smackx.pubsub.filter.EventExtensionFilter;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -44,38 +55,55 @@ import org.jxmpp.jid.Jid;
|
||||||
* <pre>
|
* <pre>
|
||||||
* PEPManager pepManager = new PEPManager(smackConnection);
|
* PEPManager pepManager = new PEPManager(smackConnection);
|
||||||
* pepManager.addPEPListener(new PEPListener() {
|
* pepManager.addPEPListener(new PEPListener() {
|
||||||
* public void eventReceived(String inFrom, PEPEvent inEvent) {
|
* public void eventReceived(EntityBareJid from, EventElement event, Message message) {
|
||||||
* LOGGER.debug("Event received: " + inEvent);
|
* LOGGER.debug("Event received: " + event);
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
*
|
|
||||||
* PEPProvider pepProvider = new PEPProvider();
|
|
||||||
* pepProvider.registerPEPParserExtension("http://jabber.org/protocol/tune", new TuneProvider());
|
|
||||||
* ProviderManager.getInstance().addExtensionProvider("event", "http://jabber.org/protocol/pubsub#event", pepProvider);
|
|
||||||
*
|
|
||||||
* Tune tune = new Tune("jeff", "1", "CD", "My Title", "My Track");
|
|
||||||
* pepManager.publish(tune);
|
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Jeff Williams
|
* @author Jeff Williams
|
||||||
|
* @author Florian Schmaus
|
||||||
*/
|
*/
|
||||||
public class PEPManager {
|
public final class PEPManager extends Manager {
|
||||||
|
|
||||||
private List<PEPListener> pepListeners = new ArrayList<PEPListener>();
|
private static final Map<XMPPConnection, PEPManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
|
||||||
private XMPPConnection connection;
|
public static synchronized PEPManager getInstanceFor(XMPPConnection connection) {
|
||||||
|
PEPManager pepManager = INSTANCES.get(connection);
|
||||||
|
if (pepManager == null) {
|
||||||
|
pepManager = new PEPManager(connection);
|
||||||
|
INSTANCES.put(connection, pepManager);
|
||||||
|
}
|
||||||
|
return pepManager;
|
||||||
|
}
|
||||||
|
|
||||||
private StanzaFilter packetFilter = new StanzaExtensionFilter("event", "http://jabber.org/protocol/pubsub#event");
|
private static final StanzaFilter FROM_BARE_JID_WITH_EVENT_EXTENSION_FILTER = new AndFilter(
|
||||||
private StanzaListener packetListener;
|
new FromJidTypeFilter(JidType.BareJid),
|
||||||
|
EventExtensionFilter.INSTANCE);
|
||||||
|
|
||||||
|
private final Set<PEPListener> pepListeners = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new PEP exchange manager.
|
* Creates a new PEP exchange manager.
|
||||||
*
|
*
|
||||||
* @param connection an XMPPConnection which is used to send and receive messages.
|
* @param connection an XMPPConnection which is used to send and receive messages.
|
||||||
*/
|
*/
|
||||||
public PEPManager(XMPPConnection connection) {
|
private PEPManager(XMPPConnection connection) {
|
||||||
this.connection = connection;
|
super(connection);
|
||||||
init();
|
StanzaListener packetListener = new StanzaListener() {
|
||||||
|
public void processPacket(Stanza stanza) {
|
||||||
|
Message message = (Message) stanza;
|
||||||
|
EventElement event = EventElement.from(stanza);
|
||||||
|
assert(event != null);
|
||||||
|
EntityBareJid from = message.getFrom().asEntityBareJidIfPossible();
|
||||||
|
assert(from != null);
|
||||||
|
for (PEPListener listener : pepListeners) {
|
||||||
|
listener.eventReceived(from, event, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// TODO Add filter to check if from supports PubSub as per xep163 2 2.4
|
||||||
|
connection.addSyncStanzaListener(packetListener, FROM_BARE_JID_WITH_EVENT_EXTENSION_FILTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,12 +112,8 @@ public class PEPManager {
|
||||||
*
|
*
|
||||||
* @param pepListener a roster exchange listener.
|
* @param pepListener a roster exchange listener.
|
||||||
*/
|
*/
|
||||||
public void addPEPListener(PEPListener pepListener) {
|
public boolean addPEPListener(PEPListener pepListener) {
|
||||||
synchronized (pepListeners) {
|
return pepListeners.add(pepListener);
|
||||||
if (!pepListeners.contains(pepListener)) {
|
|
||||||
pepListeners.add(pepListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,63 +121,44 @@ public class PEPManager {
|
||||||
*
|
*
|
||||||
* @param pepListener a roster exchange listener.
|
* @param pepListener a roster exchange listener.
|
||||||
*/
|
*/
|
||||||
public void removePEPListener(PEPListener pepListener) {
|
public boolean removePEPListener(PEPListener pepListener) {
|
||||||
synchronized (pepListeners) {
|
return pepListeners.remove(pepListener);
|
||||||
pepListeners.remove(pepListener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Publish an event.
|
* Publish an event.
|
||||||
*
|
*
|
||||||
* @param item the item to publish.
|
* @param item the item to publish.
|
||||||
* @throws NotConnectedException
|
* @param node the node to publish on.
|
||||||
* @throws InterruptedException
|
* @throws NotConnectedException
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @throws XMPPErrorException
|
||||||
|
* @throws NoResponseException
|
||||||
*/
|
*/
|
||||||
public void publish(PEPItem item) throws NotConnectedException, InterruptedException {
|
public void publish(Item item, String node) throws NotConnectedException, InterruptedException,
|
||||||
// Create a new message to publish the event.
|
NoResponseException, XMPPErrorException {
|
||||||
PEPPubSub pubSub = new PEPPubSub(item);
|
XMPPConnection connection = connection();
|
||||||
pubSub.setType(Type.set);
|
PubSubManager pubSubManager = PubSubManager.getInstance(connection, connection.getUser().asEntityBareJid());
|
||||||
//pubSub.setFrom(connection.getUser());
|
LeafNode pubSubNode = pubSubManager.getNode(node);
|
||||||
|
pubSubNode.publish(item);
|
||||||
// Send the message that contains the roster
|
|
||||||
connection.sendStanza(pubSub);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires roster exchange listeners.
|
* XEP-163 5.
|
||||||
*/
|
*/
|
||||||
private void firePEPListeners(Jid from, PEPEvent event) {
|
private static final PubSubFeature[] REQUIRED_FEATURES = new PubSubFeature[] {
|
||||||
PEPListener[] listeners = null;
|
// @formatter:off
|
||||||
synchronized (pepListeners) {
|
PubSubFeature.auto_create,
|
||||||
listeners = new PEPListener[pepListeners.size()];
|
PubSubFeature.auto_subscribe,
|
||||||
pepListeners.toArray(listeners);
|
PubSubFeature.filtered_notifications,
|
||||||
}
|
// @formatter:on
|
||||||
for (int i = 0; i < listeners.length; i++) {
|
};
|
||||||
listeners[i].eventReceived(from, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
public boolean isSupported() throws NoResponseException, XMPPErrorException,
|
||||||
// Listens for all roster exchange packets and fire the roster exchange listeners.
|
NotConnectedException, InterruptedException {
|
||||||
packetListener = new StanzaListener() {
|
XMPPConnection connection = connection();
|
||||||
public void processPacket(Stanza packet) {
|
ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||||
Message message = (Message) packet;
|
BareJid localBareJid = connection.getUser().asBareJid();
|
||||||
PEPEvent event = (PEPEvent) message.getExtension("event", "http://jabber.org/protocol/pubsub#event");
|
return serviceDiscoveryManager.supportsFeatures(localBareJid, REQUIRED_FEATURES);
|
||||||
// Fire event for roster exchange listeners
|
|
||||||
firePEPListeners(message.getFrom(), event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
connection.addSyncStanzaListener(packetListener, packetFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void destroy() {
|
|
||||||
if (connection != null)
|
|
||||||
connection.removeSyncStanzaListener(packetListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void finalize() throws Throwable {
|
|
||||||
destroy();
|
|
||||||
super.finalize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright 2003-2007 Jive Software.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jivesoftware.smackx.pep.packet;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents XMPP Personal Event Protocol packets.<p>
|
|
||||||
*
|
|
||||||
* The 'http://jabber.org/protocol/pubsub#event' namespace is used to publish personal events items from one client
|
|
||||||
* to subscribed clients (See XEP-163).
|
|
||||||
*
|
|
||||||
* @author Jeff Williams
|
|
||||||
*/
|
|
||||||
public class PEPEvent implements ExtensionElement {
|
|
||||||
|
|
||||||
PEPItem item;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new empty roster exchange package.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public PEPEvent() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new empty roster exchange package.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public PEPEvent(PEPItem item) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.item = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPEPItem(PEPItem item) {
|
|
||||||
this.item = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the XML element name of the extension sub-packet root element.
|
|
||||||
* Always returns "x"
|
|
||||||
*
|
|
||||||
* @return the XML element name of the stanza(/packet) extension.
|
|
||||||
*/
|
|
||||||
public String getElementName() {
|
|
||||||
return "event";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the XML namespace of the extension sub-packet root element.
|
|
||||||
* According the specification the namespace is always "jabber:x:roster"
|
|
||||||
* (which is not to be confused with the 'jabber:iq:roster' namespace
|
|
||||||
*
|
|
||||||
* @return the XML namespace of the stanza(/packet) extension.
|
|
||||||
*/
|
|
||||||
public String getNamespace() {
|
|
||||||
return "http://jabber.org/protocol/pubsub";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the XML representation of a Personal Event Publish according the specification.
|
|
||||||
*
|
|
||||||
* Usually the XML representation will be inside of a Message XML representation like
|
|
||||||
* in the following example:
|
|
||||||
* <pre>
|
|
||||||
* <message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack">
|
|
||||||
* <subject>Any subject you want</subject>
|
|
||||||
* <body>This message contains roster items.</body>
|
|
||||||
* <x xmlns="jabber:x:roster">
|
|
||||||
* <item jid="gato1@gato.home"/>
|
|
||||||
* <item jid="gato2@gato.home"/>
|
|
||||||
* </x>
|
|
||||||
* </message>
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public String toXML() {
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
buf.append('<').append(getElementName()).append(" xmlns=\"").append(getNamespace()).append("\">");
|
|
||||||
buf.append(item.toXML());
|
|
||||||
buf.append("</").append(getElementName()).append('>');
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright 2003-2007 Jive Software.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jivesoftware.smackx.pep.packet;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents XMPP Personal Event Protocol packets.<p>
|
|
||||||
*
|
|
||||||
* The 'http://jabber.org/protocol/pubsub#event' namespace is used to publish personal events items from one client
|
|
||||||
* to subscribed clients (See XEP-163).
|
|
||||||
*
|
|
||||||
* @author Jeff Williams
|
|
||||||
*/
|
|
||||||
public abstract class PEPItem implements ExtensionElement {
|
|
||||||
|
|
||||||
String id;
|
|
||||||
public abstract String getNode();
|
|
||||||
public abstract String getItemDetailsXML();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new PEPItem.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public PEPItem(String id) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the XML element name of the extension sub-packet root element.
|
|
||||||
* Always returns "x"
|
|
||||||
*
|
|
||||||
* @return the XML element name of the stanza(/packet) extension.
|
|
||||||
*/
|
|
||||||
public String getElementName() {
|
|
||||||
return "item";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the XML namespace of the extension sub-packet root element.
|
|
||||||
*
|
|
||||||
* @return the XML namespace of the stanza(/packet) extension.
|
|
||||||
*/
|
|
||||||
public String getNamespace() {
|
|
||||||
return "http://jabber.org/protocol/pubsub";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the XML representation of a Personal Event Publish according the specification.
|
|
||||||
*
|
|
||||||
* Usually the XML representation will be inside of a Message XML representation like
|
|
||||||
* in the following example:
|
|
||||||
* <pre>
|
|
||||||
* <message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack">
|
|
||||||
* <subject>Any subject you want</subject>
|
|
||||||
* <body>This message contains roster items.</body>
|
|
||||||
* <x xmlns="jabber:x:roster">
|
|
||||||
* <item jid="gato1@gato.home"/>
|
|
||||||
* <item jid="gato2@gato.home"/>
|
|
||||||
* </x>
|
|
||||||
* </message>
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public String toXML() {
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
buf.append('<').append(getElementName()).append(" id=\"").append(id).append("\">");
|
|
||||||
buf.append(getItemDetailsXML());
|
|
||||||
buf.append("</").append(getElementName()).append('>');
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright 2003-2007 Jive Software.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jivesoftware.smackx.pep.packet;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents XMPP PEP/XEP-163 pubsub packets.<p>
|
|
||||||
*
|
|
||||||
* The 'http://jabber.org/protocol/pubsub' namespace is used to publish personal events items from one client
|
|
||||||
* to subscribed clients (See XEP-163).
|
|
||||||
*
|
|
||||||
* @author Jeff Williams
|
|
||||||
*/
|
|
||||||
public class PEPPubSub extends IQ {
|
|
||||||
|
|
||||||
public static final String ELEMENT = "pubsub";
|
|
||||||
public static final String NAMESPACE = "http://jabber.org/protocol/pubsub";
|
|
||||||
|
|
||||||
private final PEPItem item;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new PubSub.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public PEPPubSub(PEPItem item) {
|
|
||||||
super(ELEMENT, NAMESPACE);
|
|
||||||
this.item = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the XML representation of a Personal Event Publish according the specification.
|
|
||||||
*
|
|
||||||
* Usually the XML representation will be inside of a Message XML representation like
|
|
||||||
* in the following example:
|
|
||||||
* <pre>
|
|
||||||
* <message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack">
|
|
||||||
* <subject>Any subject you want</subject>
|
|
||||||
* <body>This message contains roster items.</body>
|
|
||||||
* <x xmlns="jabber:x:roster">
|
|
||||||
* <item jid="gato1@gato.home"/>
|
|
||||||
* <item jid="gato2@gato.home"/>
|
|
||||||
* </x>
|
|
||||||
* </message>
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) {
|
|
||||||
buf.rightAngleBracket();
|
|
||||||
|
|
||||||
buf.openElement("publish").attribute("node", item.getNode()).rightAngleBracket();
|
|
||||||
buf.append(item.toXML());
|
|
||||||
buf.closeElement("publish");
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright 2003-2007 Jive Software.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jivesoftware.smackx.pep.provider;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
|
||||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* The PEPProvider parses incoming PEPEvent packets.
|
|
||||||
* (XEP-163 has a weird asymmetric deal: outbound PEP are <iq> + <pubsub> and inbound are <message> + <event>.
|
|
||||||
* The provider only deals with inbound, and so it only deals with <message>.
|
|
||||||
*
|
|
||||||
* Anyhoo...
|
|
||||||
*
|
|
||||||
* The way this works is that PEPxxx classes are generic <pubsub> and <message> providers, and anyone who
|
|
||||||
* wants to publish/receive PEPs, such as <tune>, <geoloc>, etc., simply need to extend PEPItem and register (here)
|
|
||||||
* a PacketExtensionProvider that knows how to parse that PEPItem extension.
|
|
||||||
*
|
|
||||||
* @author Jeff Williams
|
|
||||||
*/
|
|
||||||
public class PEPProvider extends ExtensionElementProvider<ExtensionElement> {
|
|
||||||
|
|
||||||
private static final Map<String, ExtensionElementProvider<?>> nodeParsers = new HashMap<String, ExtensionElementProvider<?>>();
|
|
||||||
|
|
||||||
public static void registerPEPParserExtension(String node, ExtensionElementProvider<?> pepItemParser) {
|
|
||||||
nodeParsers.put(node, pepItemParser);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a PEPEvent stanza(/packet) and extracts a PEPItem from it.
|
|
||||||
* (There is only one per <event>.)
|
|
||||||
*
|
|
||||||
* @param parser the XML parser, positioned at the starting element of the extension.
|
|
||||||
* @return a PacketExtension.
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ExtensionElement parse(XmlPullParser parser, int initialDepth)
|
|
||||||
throws Exception {
|
|
||||||
ExtensionElement pepItem = null;
|
|
||||||
boolean done = false;
|
|
||||||
while (!done) {
|
|
||||||
int eventType = parser.next();
|
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
|
||||||
if (parser.getName().equals("event")) {
|
|
||||||
} else if (parser.getName().equals("items")) {
|
|
||||||
// Figure out the node for this event.
|
|
||||||
String node = parser.getAttributeValue("", "node");
|
|
||||||
// Get the parser for this kind of node, and if found then parse the node.
|
|
||||||
ExtensionElementProvider<?> nodeParser = nodeParsers.get(node);
|
|
||||||
if (nodeParser != null) {
|
|
||||||
pepItem = nodeParser.parse(parser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (eventType == XmlPullParser.END_TAG) {
|
|
||||||
if (parser.getName().equals("event")) {
|
|
||||||
done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pepItem;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,6 +20,8 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +34,16 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
||||||
*/
|
*/
|
||||||
public class EventElement implements EmbeddedPacketExtension
|
public class EventElement implements EmbeddedPacketExtension
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The constant String "event".
|
||||||
|
*/
|
||||||
|
public static final String ELEMENT = "event";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constant String "http://jabber.org/protocol/pubsub#event".
|
||||||
|
*/
|
||||||
|
public static final String NAMESPACE = PubSubNamespace.EVENT.getXmlns();
|
||||||
|
|
||||||
private EventElementType type;
|
private EventElementType type;
|
||||||
private NodeExtension ext;
|
private NodeExtension ext;
|
||||||
|
|
||||||
|
@ -66,12 +78,16 @@ public class EventElement implements EmbeddedPacketExtension
|
||||||
return PubSubNamespace.EVENT.getXmlns();
|
return PubSubNamespace.EVENT.getXmlns();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toXML()
|
@Override
|
||||||
{
|
public XmlStringBuilder toXML() {
|
||||||
StringBuilder builder = new StringBuilder("<event xmlns='" + PubSubNamespace.EVENT.getXmlns() + "'>");
|
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||||
|
xml.rightAngleBracket();
|
||||||
|
xml.append(ext.toXML());
|
||||||
|
xml.closeElement(this);
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
builder.append(ext.toXML());
|
public static EventElement from(Stanza stanza) {
|
||||||
builder.append("</event>");
|
return stanza.getExtension(ELEMENT, NAMESPACE);
|
||||||
return builder.toString();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2015 Florian Schmaus
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.pubsub;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.disco.Feature;
|
||||||
|
import org.jivesoftware.smackx.disco.Feature.Support;
|
||||||
|
import org.jivesoftware.smackx.pubsub.packet.PubSub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The features a PubSub service may provides. Some are optional or recommended, while others are required.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
* @see <a href="http://www.xmpp.org/extensions/xep-0060.html#features">XEP-60 § 10</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum PubSubFeature implements CharSequence {
|
||||||
|
|
||||||
|
access_authorize(Support.optional),
|
||||||
|
access_open(Support.optional),
|
||||||
|
access_presence(Support.optional),
|
||||||
|
access_roster(Support.optional),
|
||||||
|
acccess_whitelist(Support.optional),
|
||||||
|
auto_create(Support.optional),
|
||||||
|
auto_subscribe(Support.recommended),
|
||||||
|
collections(Support.optional),
|
||||||
|
config_node(Support.recommended),
|
||||||
|
create_and_configure(Support.recommended),
|
||||||
|
create_nodes(Support.recommended),
|
||||||
|
delete_items(Support.recommended),
|
||||||
|
delete_nodes(Support.recommended),
|
||||||
|
get_pending(Support.optional),
|
||||||
|
item_ids(Support.recommended),
|
||||||
|
last_published(Support.recommended),
|
||||||
|
leased_subscription(Support.optional),
|
||||||
|
manage_subscriptions(Support.optional),
|
||||||
|
member_affiliation(Support.recommended),
|
||||||
|
meta_data(Support.recommended),
|
||||||
|
modify_affiliations(Support.optional),
|
||||||
|
multi_collection(Support.optional),
|
||||||
|
multi_subscribe(Support.optional),
|
||||||
|
outcast_affiliation(Support.recommended),
|
||||||
|
persistent_items(Support.recommended),
|
||||||
|
presence_notifications(Support.optional),
|
||||||
|
presence_subscribe(Support.recommended),
|
||||||
|
publish(Support.required),
|
||||||
|
publish_options(Support.optional),
|
||||||
|
publish_only_affiliation(Support.optional),
|
||||||
|
publisher_affiliation(Support.recommended),
|
||||||
|
purge_nodes(Support.optional),
|
||||||
|
retract_items(Support.optional),
|
||||||
|
retrieve_affiliations(Support.recommended),
|
||||||
|
retrieve_default(Support.recommended),
|
||||||
|
retrieve_default_sub(Support.optional),
|
||||||
|
retrieve_items(Support.recommended),
|
||||||
|
retrieve_subscriptions(Support.recommended),
|
||||||
|
subscribe(Support.required),
|
||||||
|
subscription_options(Support.optional),
|
||||||
|
subscriptions_notifications(Support.optional),
|
||||||
|
instant_nodes(Support.recommended),
|
||||||
|
filtered_notifications(Support.recommended),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String feature;
|
||||||
|
private final String qualifiedFeature;
|
||||||
|
private final Feature.Support support;
|
||||||
|
|
||||||
|
private PubSubFeature(Feature.Support support) {
|
||||||
|
this.feature = name().replace('_', '-');
|
||||||
|
this.qualifiedFeature = PubSub.NAMESPACE + '#' + this.feature;
|
||||||
|
this.support = support;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFeatureName() {
|
||||||
|
return feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return qualifiedFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Feature.Support support() {
|
||||||
|
return support;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int length() {
|
||||||
|
return qualifiedFeature.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char charAt(int index) {
|
||||||
|
return qualifiedFeature.charAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence subSequence(int start, int end) {
|
||||||
|
return qualifiedFeature.subSequence(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
||||||
import org.jivesoftware.smackx.pubsub.util.NodeUtils;
|
import org.jivesoftware.smackx.pubsub.util.NodeUtils;
|
||||||
import org.jivesoftware.smackx.xdata.Form;
|
import org.jivesoftware.smackx.xdata.Form;
|
||||||
import org.jivesoftware.smackx.xdata.FormField;
|
import org.jivesoftware.smackx.xdata.FormField;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.jxmpp.jid.DomainBareJid;
|
import org.jxmpp.jid.DomainBareJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
@ -61,12 +62,12 @@ import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
public final class PubSubManager extends Manager {
|
public final class PubSubManager extends Manager {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(PubSubManager.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(PubSubManager.class.getName());
|
||||||
private static final Map<XMPPConnection, Map<DomainBareJid, PubSubManager>> INSTANCES = new WeakHashMap<>();
|
private static final Map<XMPPConnection, Map<BareJid, PubSubManager>> INSTANCES = new WeakHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JID of the PubSub service this manager manages.
|
* The JID of the PubSub service this manager manages.
|
||||||
*/
|
*/
|
||||||
private final DomainBareJid pubSubService;
|
private final BareJid pubSubService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of node IDs to Nodes, used to cache those Nodes. This does only cache the type of Node,
|
* A map of node IDs to Nodes, used to cache those Nodes. This does only cache the type of Node,
|
||||||
|
@ -112,8 +113,8 @@ public final class PubSubManager extends Manager {
|
||||||
* @param pubSubService the PubSub service.
|
* @param pubSubService the PubSub service.
|
||||||
* @return a PubSub manager for the connection and service.
|
* @return a PubSub manager for the connection and service.
|
||||||
*/
|
*/
|
||||||
public static synchronized PubSubManager getInstance(XMPPConnection connection, DomainBareJid pubSubService) {
|
public static synchronized PubSubManager getInstance(XMPPConnection connection, BareJid pubSubService) {
|
||||||
Map<DomainBareJid, PubSubManager> managers = INSTANCES.get(connection);
|
Map<BareJid, PubSubManager> managers = INSTANCES.get(connection);
|
||||||
if (managers == null) {
|
if (managers == null) {
|
||||||
managers = new HashMap<>();
|
managers = new HashMap<>();
|
||||||
INSTANCES.put(connection, managers);
|
INSTANCES.put(connection, managers);
|
||||||
|
@ -133,7 +134,7 @@ public final class PubSubManager extends Manager {
|
||||||
* @param connection The XMPP connection
|
* @param connection The XMPP connection
|
||||||
* @param toAddress The pubsub specific to address (required for some servers)
|
* @param toAddress The pubsub specific to address (required for some servers)
|
||||||
*/
|
*/
|
||||||
PubSubManager(XMPPConnection connection, DomainBareJid toAddress)
|
PubSubManager(XMPPConnection connection, BareJid toAddress)
|
||||||
{
|
{
|
||||||
super(connection);
|
super(connection);
|
||||||
pubSubService = toAddress;
|
pubSubService = toAddress;
|
||||||
|
@ -356,7 +357,7 @@ public final class PubSubManager extends Manager {
|
||||||
*
|
*
|
||||||
* @return the JID of the PubSub service.
|
* @return the JID of the PubSub service.
|
||||||
*/
|
*/
|
||||||
public DomainBareJid getServiceJid() {
|
public BareJid getServiceJid() {
|
||||||
return pubSubService;
|
return pubSubService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2015 Florian Schmaus.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.pubsub.filter;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||||
|
import org.jivesoftware.smackx.pubsub.EventElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter for stanzas with the PubSub 'event' extension.
|
||||||
|
*
|
||||||
|
* @author Florian Schmaus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class EventExtensionFilter extends StanzaExtensionFilter {
|
||||||
|
|
||||||
|
public static final EventExtensionFilter INSTANCE = new EventExtensionFilter();
|
||||||
|
|
||||||
|
private EventExtensionFilter() {
|
||||||
|
super(EventElement.ELEMENT, EventElement.NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,6 +16,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO describe me.
|
* Filters for Publish-Subscribe (XEP-60).
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.pep.provider;
|
package org.jivesoftware.smackx.pubsub.filter;
|
Loading…
Reference in a new issue