mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-11 01:59:38 +02:00
Merge branch '4.2'
This commit is contained in:
commit
ca54f65b3e
346 changed files with 7037 additions and 5593 deletions
|
@ -53,6 +53,7 @@ import org.jxmpp.jid.Jid;
|
|||
*
|
||||
* @see <a href="https://xmpp.org/extensions/xep-0296.html">XEP-0296: Best Practices for Resource Locking</a>
|
||||
*/
|
||||
@SuppressWarnings("FunctionalInterfaceClash")
|
||||
public final class ChatManager extends Manager {
|
||||
|
||||
private static final Map<XMPPConnection, ChatManager> INSTANCES = new WeakHashMap<>();
|
||||
|
@ -69,7 +70,7 @@ public final class ChatManager extends Manager {
|
|||
// @FORMATTER:OFF
|
||||
private static final StanzaFilter MESSAGE_FILTER = new AndFilter(
|
||||
MessageTypeFilter.NORMAL_OR_CHAT,
|
||||
new OrFilter(MessageWithBodiesFilter.INSTANCE), new StanzaExtensionFilter(XHTMLExtension.ELEMENT, XHTMLExtension.NAMESPACE)
|
||||
new OrFilter(MessageWithBodiesFilter.INSTANCE, new StanzaExtensionFilter(XHTMLExtension.ELEMENT, XHTMLExtension.NAMESPACE))
|
||||
);
|
||||
|
||||
private static final StanzaFilter OUTGOING_MESSAGE_FILTER = new AndFilter(
|
||||
|
@ -188,22 +189,84 @@ public final class ChatManager extends Manager {
|
|||
return true;
|
||||
}
|
||||
|
||||
public boolean addListener(IncomingChatMessageListener listener) {
|
||||
/**
|
||||
* Add a new listener for incoming chat messages.
|
||||
*
|
||||
* @param listener the listener to add.
|
||||
* @return <code>true</code> if the listener was not already added.
|
||||
*/
|
||||
public boolean addIncomingListener(IncomingChatMessageListener listener) {
|
||||
return incomingListeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new listener for incoming chat messages.
|
||||
*
|
||||
* @param listener the listener to add.
|
||||
* @return <code>true</code> if the listener was not already added.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("FunctionalInterfaceClash")
|
||||
public boolean addListener(IncomingChatMessageListener listener) {
|
||||
return addIncomingListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an incoming chat message listener.
|
||||
*
|
||||
* @param listener the listener to remove.
|
||||
* @return <code>true</code> if the listener was active and got removed.
|
||||
*/
|
||||
@SuppressWarnings("FunctionalInterfaceClash")
|
||||
public boolean removeListener(IncomingChatMessageListener listener) {
|
||||
return incomingListeners.remove(listener);
|
||||
}
|
||||
|
||||
public boolean addListener(OutgoingChatMessageListener listener) {
|
||||
/**
|
||||
* Add a new listener for outgoing chat messages.
|
||||
*
|
||||
* @param listener the listener to add.
|
||||
* @return <code>true</code> if the listener was not already added.
|
||||
*/
|
||||
public boolean addOutgoingListener(OutgoingChatMessageListener listener) {
|
||||
return outgoingListeners.add(listener);
|
||||
}
|
||||
|
||||
public boolean removeOutoingLIstener(OutgoingChatMessageListener listener) {
|
||||
/**
|
||||
* Add a new listener for incoming chat messages.
|
||||
*
|
||||
* @param listener the listener to add.
|
||||
* @return <code>true</code> if the listener was not already added.
|
||||
* @deprecated use {@link #addOutgoingListener(OutgoingChatMessageListener)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("FunctionalInterfaceClash")
|
||||
public boolean addListener(OutgoingChatMessageListener listener) {
|
||||
return addOutgoingListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an outgoing chat message listener.
|
||||
*
|
||||
* @param listener the listener to remove.
|
||||
* @return <code>true</code> if the listener was active and got removed.
|
||||
*/
|
||||
public boolean removeListener(OutgoingChatMessageListener listener) {
|
||||
return outgoingListeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an outgoing chat message listener.
|
||||
*
|
||||
* @param listener the listener to remove.
|
||||
* @return <code>true</code> if the listener was active and got removed.
|
||||
* @deprecated use {@link #removeListener(OutgoingChatMessageListener)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean removeOutoingLIstener(OutgoingChatMessageListener listener) {
|
||||
return removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a new or retrieve the existing chat with <code>jid</code>.
|
||||
*
|
||||
|
|
|
@ -40,6 +40,7 @@ public class AMPManager {
|
|||
// The ServiceDiscoveryManager class should have been already initialized
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
AMPManager.setServiceEnabled(connection, true);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ public class AttentionExtension implements ExtensionElement {
|
|||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
|
||||
*/
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT_NAME;
|
||||
}
|
||||
|
@ -56,6 +57,7 @@ public class AttentionExtension implements ExtensionElement {
|
|||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
|
||||
*/
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
@ -65,6 +67,7 @@ public class AttentionExtension implements ExtensionElement {
|
|||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#toXML()
|
||||
*/
|
||||
@Override
|
||||
public String toXML() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append('<').append(getElementName()).append(" xmlns=\"").append(
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 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.blocking;
|
||||
|
||||
public interface AllJidsUnblockedListener {
|
||||
|
||||
void onAllJidsUnblocked();
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez, Florian Schmaus
|
||||
* Copyright 2016-2017 Fernando Ramirez, Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -20,7 +20,9 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.jivesoftware.smack.AbstractConnectionListener;
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
|
@ -82,6 +84,12 @@ public final class BlockingCommandManager extends Manager {
|
|||
return blockingCommandManager;
|
||||
}
|
||||
|
||||
private final Set<AllJidsUnblockedListener> allJidsUnblockedListeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
private final Set<JidsBlockedListener> jidsBlockedListeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
private final Set<JidsUnblockedListener> jidsUnblockedListeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
private BlockingCommandManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
|
||||
|
@ -99,6 +107,10 @@ public final class BlockingCommandManager extends Manager {
|
|||
List<Jid> blockedJids = blockContactIQ.getJids();
|
||||
blockListCached.addAll(blockedJids);
|
||||
|
||||
for (JidsBlockedListener listener : jidsBlockedListeners) {
|
||||
listener.onJidsBlocked(blockedJids);
|
||||
}
|
||||
|
||||
return IQ.createResultIQ(blockContactIQ);
|
||||
}
|
||||
});
|
||||
|
@ -117,8 +129,14 @@ public final class BlockingCommandManager extends Manager {
|
|||
List<Jid> unblockedJids = unblockContactIQ.getJids();
|
||||
if (unblockedJids == null) { // remove all
|
||||
blockListCached.clear();
|
||||
for (AllJidsUnblockedListener listener : allJidsUnblockedListeners) {
|
||||
listener.onAllJidsUnblocked();
|
||||
}
|
||||
} else { // remove only some
|
||||
blockListCached.removeAll(unblockedJids);
|
||||
for (JidsUnblockedListener listener : jidsUnblockedListeners) {
|
||||
listener.onJidsUnblocked(unblockedJids);
|
||||
}
|
||||
}
|
||||
|
||||
return IQ.createResultIQ(unblockContactIQ);
|
||||
|
@ -216,4 +234,27 @@ public final class BlockingCommandManager extends Manager {
|
|||
connection().createStanzaCollectorAndSend(unblockContactIQ).nextResultOrThrow();
|
||||
}
|
||||
|
||||
public void addJidsBlockedListener(JidsBlockedListener jidsBlockedListener) {
|
||||
jidsBlockedListeners.add(jidsBlockedListener);
|
||||
}
|
||||
|
||||
public void removeJidsBlockedListener(JidsBlockedListener jidsBlockedListener) {
|
||||
jidsBlockedListeners.remove(jidsBlockedListener);
|
||||
}
|
||||
|
||||
public void addJidsUnblockedListener(JidsUnblockedListener jidsUnblockedListener) {
|
||||
jidsUnblockedListeners.add(jidsUnblockedListener);
|
||||
}
|
||||
|
||||
public void removeJidsUnblockedListener(JidsUnblockedListener jidsUnblockedListener) {
|
||||
jidsUnblockedListeners.remove(jidsUnblockedListener);
|
||||
}
|
||||
|
||||
public void addAllJidsUnblockedListener(AllJidsUnblockedListener allJidsUnblockedListener) {
|
||||
allJidsUnblockedListeners.add(allJidsUnblockedListener);
|
||||
}
|
||||
|
||||
public void removeAllJidsUnblockedListener(AllJidsUnblockedListener allJidsUnblockedListener) {
|
||||
allJidsUnblockedListeners.remove(allJidsUnblockedListener);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 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.blocking;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
public interface JidsBlockedListener {
|
||||
|
||||
void onJidsBlocked(List<Jid> blockedJids);
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 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.blocking;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
public interface JidsUnblockedListener {
|
||||
|
||||
void onJidsUnblocked(List<Jid> unblockedJids);
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.blocking.element;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
@ -51,7 +52,7 @@ public class BlockContactsIQ extends IQ {
|
|||
public BlockContactsIQ(List<Jid> jids) {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
this.setType(Type.set);
|
||||
this.jids = jids;
|
||||
this.jids = Collections.unmodifiableList(jids);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez, Florian Schmaus
|
||||
* Copyright 2016-2017 Fernando Ramirez, Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.blocking.element;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
@ -52,7 +53,11 @@ public class UnblockContactsIQ extends IQ {
|
|||
public UnblockContactsIQ(List<Jid> jids) {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
this.setType(Type.set);
|
||||
this.jids = jids;
|
||||
if (jids != null) {
|
||||
this.jids = Collections.unmodifiableList(jids);
|
||||
} else {
|
||||
this.jids = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,9 +68,9 @@ public class UnblockContactsIQ extends IQ {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the JIDs.
|
||||
* Get the JIDs. This may return null, which means that all JIDs should be or where unblocked.
|
||||
*
|
||||
* @return the list of JIDs
|
||||
* @return the list of JIDs or <code>null</code>.
|
||||
*/
|
||||
public List<Jid> getJids() {
|
||||
return jids;
|
||||
|
@ -73,14 +78,16 @@ public class UnblockContactsIQ extends IQ {
|
|||
|
||||
@Override
|
||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||
xml.rightAngleBracket();
|
||||
if (jids == null) {
|
||||
xml.setEmptyElement();
|
||||
return xml;
|
||||
}
|
||||
|
||||
if (jids != null) {
|
||||
for (Jid jid : jids) {
|
||||
xml.halfOpenElement("item");
|
||||
xml.attribute("jid", jid);
|
||||
xml.closeEmptyElement();
|
||||
}
|
||||
xml.rightAngleBracket();
|
||||
for (Jid jid : jids) {
|
||||
xml.halfOpenElement("item");
|
||||
xml.attribute("jid", jid);
|
||||
xml.closeEmptyElement();
|
||||
}
|
||||
|
||||
return xml;
|
||||
|
|
|
@ -20,9 +20,9 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smack.util.ParserUtils;
|
||||
import org.jivesoftware.smackx.blocking.element.BlockContactsIQ;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ public class BlockContactsIQProvider extends IQProvider<BlockContactsIQ> {
|
|||
|
||||
@Override
|
||||
public BlockContactsIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
List<Jid> jids = null;
|
||||
List<Jid> jids = new ArrayList<>();
|
||||
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
|
@ -45,10 +45,8 @@ public class BlockContactsIQProvider extends IQProvider<BlockContactsIQ> {
|
|||
|
||||
case XmlPullParser.START_TAG:
|
||||
if (parser.getName().equals("item")) {
|
||||
if (jids == null) {
|
||||
jids = new ArrayList<>();
|
||||
}
|
||||
jids.add(JidCreate.from(parser.getAttributeValue("", "jid")));
|
||||
Jid jid = ParserUtils.getJidAttribute(parser);
|
||||
jids.add(jid);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ public class BookmarkedConference implements SharedBookmark {
|
|||
this.isShared = isShared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShared() {
|
||||
return isShared;
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ public class BookmarkedURL implements SharedBookmark {
|
|||
this.isShared = shared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShared() {
|
||||
return isShared;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,7 @@ public class Bookmarks implements PrivateData {
|
|||
*
|
||||
* @return the element name.
|
||||
*/
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
@ -160,6 +161,7 @@ public class Bookmarks implements PrivateData {
|
|||
*
|
||||
* @return the namespace.
|
||||
*/
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
@ -218,6 +220,7 @@ public class Bookmarks implements PrivateData {
|
|||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateData parsePrivateData(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
Bookmarks storage = new Bookmarks();
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ public abstract class InBandBytestreamListener implements BytestreamListener {
|
|||
|
||||
|
||||
|
||||
@Override
|
||||
public void incomingBytestreamRequest(BytestreamRequest request) {
|
||||
incomingBytestreamRequest((InBandBytestreamRequest) request);
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
*/
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(final XMPPConnection connection) {
|
||||
// create the manager for this connection
|
||||
InBandBytestreamManager.getByteStreamManager(connection);
|
||||
|
@ -236,6 +237,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
*
|
||||
* @param listener the listener to register
|
||||
*/
|
||||
@Override
|
||||
public void addIncomingBytestreamListener(BytestreamListener listener) {
|
||||
this.allRequestListeners.add(listener);
|
||||
}
|
||||
|
@ -246,6 +248,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
*
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
@Override
|
||||
public void removeIncomingBytestreamListener(BytestreamListener listener) {
|
||||
this.allRequestListeners.remove(listener);
|
||||
}
|
||||
|
@ -268,6 +271,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
* @param listener the listener to register
|
||||
* @param initiatorJID the JID of the user that wants to establish an In-Band Bytestream
|
||||
*/
|
||||
@Override
|
||||
public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
|
||||
this.userListeners.put(initiatorJID, listener);
|
||||
}
|
||||
|
@ -277,6 +281,9 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
*
|
||||
* @param initiatorJID the JID of the user the listener should be removed
|
||||
*/
|
||||
@Override
|
||||
// TODO: Change argument to Jid in Smack 4.3.
|
||||
@SuppressWarnings("CollectionIncompatibleType")
|
||||
public void removeIncomingBytestreamListener(String initiatorJID) {
|
||||
this.userListeners.remove(initiatorJID);
|
||||
}
|
||||
|
@ -402,6 +409,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
* @throws SmackException if there was no response from the server.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public InBandBytestreamSession establishSession(Jid targetJID) throws XMPPException, SmackException, InterruptedException {
|
||||
String sessionID = getNextSessionID();
|
||||
return establishSession(targetJID, sessionID);
|
||||
|
@ -420,6 +428,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
|||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public InBandBytestreamSession establishSession(Jid targetJID, String sessionID)
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
|
||||
|
|
|
@ -50,6 +50,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
|||
*
|
||||
* @return the sender of the In-Band Bytestream open request
|
||||
*/
|
||||
@Override
|
||||
public Jid getFrom() {
|
||||
return this.byteStreamRequest.getFrom();
|
||||
}
|
||||
|
@ -59,6 +60,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
|||
*
|
||||
* @return the session ID of the In-Band Bytestream open request
|
||||
*/
|
||||
@Override
|
||||
public String getSessionID() {
|
||||
return this.byteStreamRequest.getSessionID();
|
||||
}
|
||||
|
@ -71,6 +73,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
|||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public InBandBytestreamSession accept() throws NotConnectedException, InterruptedException {
|
||||
XMPPConnection connection = this.manager.getConnection();
|
||||
|
||||
|
@ -92,6 +95,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
|||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public void reject() throws NotConnectedException, InterruptedException {
|
||||
this.manager.replyRejectPacket(this.byteStreamRequest);
|
||||
}
|
||||
|
|
|
@ -109,18 +109,22 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return this.inputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() {
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadTimeout() {
|
||||
return this.inputStream.readTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadTimeout(int timeout) {
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("Timeout must be >= 0");
|
||||
|
@ -151,6 +155,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
this.closeBothStreamsEnabled = closeBothStreamsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
closeByLocal(true); // close input stream
|
||||
closeByLocal(false); // close output stream
|
||||
|
@ -224,7 +229,9 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
this.inputStream.cleanup();
|
||||
|
||||
// remove session from manager
|
||||
InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(this);
|
||||
// Thanks Google Error Prone for finding the bug where remove() was called with 'this' as argument. Changed
|
||||
// now to remove(byteStreamRequest.getSessionID).
|
||||
InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(byteStreamRequest.getSessionID());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -283,6 +290,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
*/
|
||||
protected abstract StanzaFilter getDataPacketFilter();
|
||||
|
||||
@Override
|
||||
public synchronized int read() throws IOException {
|
||||
checkClosed();
|
||||
|
||||
|
@ -298,6 +306,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
return buffer[bufferPointer++] & 0xff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int read(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
|
@ -331,6 +340,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
return len;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int read(byte[] b) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
@ -405,10 +415,12 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (closeInvoked) {
|
||||
return;
|
||||
|
@ -444,11 +456,13 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
*/
|
||||
private class IQIBBInputStream extends IBBInputStream {
|
||||
|
||||
@Override
|
||||
protected StanzaListener getDataPacketListener() {
|
||||
return new StanzaListener() {
|
||||
|
||||
private long lastSequence = -1;
|
||||
|
||||
@Override
|
||||
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
|
||||
// get data packet extension
|
||||
DataPacketExtension data = ((Data) packet).getDataPacketExtension();
|
||||
|
@ -491,6 +505,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StanzaFilter getDataPacketFilter() {
|
||||
/*
|
||||
* filter all IQ stanzas having type 'SET' (represented by Data class), containing a
|
||||
|
@ -507,9 +522,11 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
*/
|
||||
private class MessageIBBInputStream extends IBBInputStream {
|
||||
|
||||
@Override
|
||||
protected StanzaListener getDataPacketListener() {
|
||||
return new StanzaListener() {
|
||||
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
// get data packet extension
|
||||
DataPacketExtension data = (DataPacketExtension) packet.getExtension(
|
||||
|
@ -555,6 +572,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
*/
|
||||
private class IBBDataPacketFilter implements StanzaFilter {
|
||||
|
||||
@Override
|
||||
public boolean accept(Stanza packet) {
|
||||
// sender equals remote peer
|
||||
if (!packet.getFrom().equals(remoteJID)) {
|
||||
|
@ -619,6 +637,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
*/
|
||||
protected abstract void writeToXML(DataPacketExtension data) throws IOException, NotConnectedException, InterruptedException;
|
||||
|
||||
@Override
|
||||
public synchronized void write(int b) throws IOException {
|
||||
if (this.isClosed) {
|
||||
throw new IOException("Stream is closed");
|
||||
|
@ -632,6 +651,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
buffer[bufferPointer++] = (byte) b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(byte[] b, int off, int len) throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException();
|
||||
|
@ -662,6 +682,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void write(byte[] b) throws IOException {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
@ -698,6 +719,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
bufferPointer += len - available;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void flush() throws IOException {
|
||||
if (this.isClosed) {
|
||||
throw new IOException("Stream is closed");
|
||||
|
@ -735,6 +757,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (isClosed) {
|
||||
return;
|
||||
|
|
|
@ -66,6 +66,7 @@ class InitiationListener extends AbstractIqRequestHandler {
|
|||
public IQ handleIQRequest(final IQ packet) {
|
||||
initiationListenerExecutor.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
processRequest(packet);
|
||||
|
|
|
@ -126,10 +126,12 @@ public class DataPacketExtension implements ExtensionElement {
|
|||
return this.decodedData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ final class InitiationListener extends AbstractIqRequestHandler {
|
|||
public IQ handleIQRequest(final IQ packet) {
|
||||
initiationListenerExecutor.execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
processRequest(packet);
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
|
|||
*/
|
||||
public abstract class Socks5BytestreamListener implements BytestreamListener {
|
||||
|
||||
@Override
|
||||
public void incomingBytestreamRequest(BytestreamRequest request) {
|
||||
incomingBytestreamRequest((Socks5BytestreamRequest) request);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
|
||||
@Override
|
||||
public void connectionCreated(final XMPPConnection connection) {
|
||||
// create the manager for this connection
|
||||
Socks5BytestreamManager.getBytestreamManager(connection);
|
||||
|
@ -198,6 +199,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
*
|
||||
* @param listener the listener to register
|
||||
*/
|
||||
@Override
|
||||
public void addIncomingBytestreamListener(BytestreamListener listener) {
|
||||
this.allRequestListeners.add(listener);
|
||||
}
|
||||
|
@ -208,6 +210,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
*
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
@Override
|
||||
public void removeIncomingBytestreamListener(BytestreamListener listener) {
|
||||
this.allRequestListeners.remove(listener);
|
||||
}
|
||||
|
@ -230,6 +233,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
* @param listener the listener to register
|
||||
* @param initiatorJID the JID of the user that wants to establish a SOCKS5 Bytestream
|
||||
*/
|
||||
@Override
|
||||
public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
|
||||
this.userListeners.put(initiatorJID, listener);
|
||||
}
|
||||
|
@ -239,6 +243,9 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
*
|
||||
* @param initiatorJID the JID of the user the listener should be removed
|
||||
*/
|
||||
// TODO: Change parameter to Jid in Smack 4.3.
|
||||
@Override
|
||||
@SuppressWarnings("CollectionIncompatibleType")
|
||||
public void removeIncomingBytestreamListener(String initiatorJID) {
|
||||
this.userListeners.remove(initiatorJID);
|
||||
}
|
||||
|
@ -386,6 +393,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
* @throws InterruptedException if the current thread was interrupted while waiting
|
||||
* @throws SmackException if there was no response from the server.
|
||||
*/
|
||||
@Override
|
||||
public Socks5BytestreamSession establishSession(Jid targetJID) throws XMPPException,
|
||||
IOException, InterruptedException, SmackException {
|
||||
String sessionID = getNextSessionID();
|
||||
|
@ -405,6 +413,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
* @throws SmackException if the target does not support SOCKS5.
|
||||
* @throws XMPPException
|
||||
*/
|
||||
@Override
|
||||
public Socks5BytestreamSession establishSession(Jid targetJID, String sessionID)
|
||||
throws IOException, InterruptedException, NoResponseException, SmackException, XMPPException{
|
||||
XMPPConnection connection = connection();
|
||||
|
|
|
@ -170,6 +170,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
|||
*
|
||||
* @return the sender of the SOCKS5 Bytestream initialization request.
|
||||
*/
|
||||
@Override
|
||||
public Jid getFrom() {
|
||||
return this.bytestreamRequest.getFrom();
|
||||
}
|
||||
|
@ -179,6 +180,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
|||
*
|
||||
* @return the session ID of the SOCKS5 Bytestream initialization request.
|
||||
*/
|
||||
@Override
|
||||
public String getSessionID() {
|
||||
return this.bytestreamRequest.getSessionID();
|
||||
}
|
||||
|
@ -195,6 +197,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
|||
* @throws XMPPErrorException
|
||||
* @throws SmackException
|
||||
*/
|
||||
@Override
|
||||
public Socks5BytestreamSession accept() throws InterruptedException, XMPPErrorException, SmackException {
|
||||
Collection<StreamHost> streamHosts = this.bytestreamRequest.getStreamHosts();
|
||||
|
||||
|
@ -264,6 +267,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
|||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Override
|
||||
public void reject() throws NotConnectedException, InterruptedException {
|
||||
this.manager.replyRejectPacket(this.bytestreamRequest);
|
||||
}
|
||||
|
|
|
@ -64,14 +64,17 @@ public class Socks5BytestreamSession implements BytestreamSession {
|
|||
return !this.isDirect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return this.socket.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return this.socket.getOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReadTimeout() throws IOException {
|
||||
try {
|
||||
return this.socket.getSoTimeout();
|
||||
|
@ -81,6 +84,7 @@ public class Socks5BytestreamSession implements BytestreamSession {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadTimeout(int timeout) throws IOException {
|
||||
try {
|
||||
this.socket.setSoTimeout(timeout);
|
||||
|
@ -90,6 +94,7 @@ public class Socks5BytestreamSession implements BytestreamSession {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.socket.close();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.bytestreams.socks5;
|
|||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
|
@ -34,6 +35,7 @@ import java.util.logging.Logger;
|
|||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
|
||||
|
||||
/**
|
||||
|
@ -82,6 +84,7 @@ class Socks5Client {
|
|||
// wrap connecting in future for timeout
|
||||
FutureTask<Socket> futureTask = new FutureTask<Socket>(new Callable<Socket>() {
|
||||
|
||||
@Override
|
||||
public Socket call() throws IOException, SmackException {
|
||||
|
||||
// initialize socket
|
||||
|
@ -199,7 +202,13 @@ class Socks5Client {
|
|||
* @return SOCKS5 connection request message
|
||||
*/
|
||||
private byte[] createSocks5ConnectRequest() {
|
||||
byte[] addr = this.digest.getBytes();
|
||||
byte[] addr;
|
||||
try {
|
||||
addr = digest.getBytes(StringUtils.UTF8);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
byte[] data = new byte[7 + addr.length];
|
||||
data[0] = (byte) 0x05; // version (SOCKS5)
|
||||
|
|
|
@ -69,6 +69,7 @@ class Socks5ClientForInitiator extends Socks5Client {
|
|||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket getSocket(int timeout) throws IOException, InterruptedException,
|
||||
TimeoutException, XMPPException, SmackException {
|
||||
Socket socket = null;
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.util.logging.Level;
|
|||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
/**
|
||||
* The Socks5Proxy class represents a local SOCKS5 proxy server. It can be enabled/disabled by
|
||||
|
@ -381,6 +382,7 @@ public final class Socks5Proxy {
|
|||
*/
|
||||
private class Socks5ServerProcess implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
Socket socket = null;
|
||||
|
@ -470,7 +472,7 @@ public final class Socks5Proxy {
|
|||
byte[] connectionRequest = Socks5Utils.receiveSocks5Message(in);
|
||||
|
||||
// extract digest
|
||||
String responseDigest = new String(connectionRequest, 5, connectionRequest[4]);
|
||||
String responseDigest = new String(connectionRequest, 5, connectionRequest[4], StringUtils.UTF8);
|
||||
|
||||
// return error if digest is not allowed
|
||||
if (!Socks5Proxy.this.allowedConnections.contains(responseDigest)) {
|
||||
|
|
|
@ -317,6 +317,7 @@ public class Bytestream extends IQ {
|
|||
return port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENTNAME;
|
||||
}
|
||||
|
@ -366,6 +367,7 @@ public class Bytestream extends IQ {
|
|||
return JID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENTNAME;
|
||||
}
|
||||
|
@ -408,6 +410,7 @@ public class Bytestream extends IQ {
|
|||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENTNAME;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ import java.util.WeakHashMap;
|
|||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
|
@ -113,6 +114,7 @@ public final class EntityCapsManager extends Manager {
|
|||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
|
@ -346,6 +348,7 @@ public final class EntityCapsManager extends Manager {
|
|||
// XEP-0115 specifies that a client SHOULD include entity capabilities
|
||||
// with every presence notification it sends.
|
||||
StanzaListener packetInterceptor = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
if (!entityCapsEnabled) {
|
||||
// Be sure to not send stanzas with the caps extension if it's not enabled
|
||||
|
@ -403,7 +406,11 @@ public final class EntityCapsManager extends Manager {
|
|||
* @param user
|
||||
* the user (Full JID)
|
||||
*/
|
||||
// TODO: Change parameter type to Jid in Smack 4.3.
|
||||
@SuppressWarnings("CollectionIncompatibleType")
|
||||
public static void removeUserCapsNode(String user) {
|
||||
// While JID_TO_NODEVER_CHACHE has the generic types <Jid, NodeVerHash>, it is ok to call remove with String
|
||||
// arguments, since the same Jid and String representations would be equal and have the same hash code.
|
||||
JID_TO_NODEVER_CACHE.remove(user);
|
||||
}
|
||||
|
||||
|
@ -658,6 +665,7 @@ public final class EntityCapsManager extends Manager {
|
|||
// XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e.,
|
||||
// by the XML character data of the <value/> element).
|
||||
SortedSet<FormField> fs = new TreeSet<FormField>(new Comparator<FormField>() {
|
||||
@Override
|
||||
public int compare(FormField f1, FormField f2) {
|
||||
return f1.getVariable().compareTo(f2.getVariable());
|
||||
}
|
||||
|
@ -701,9 +709,16 @@ public final class EntityCapsManager extends Manager {
|
|||
// encoded using Base64 as specified in Section 4 of RFC 4648
|
||||
// (note: the Base64 output MUST NOT include whitespace and MUST set
|
||||
// padding bits to zero).
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = sb.toString().getBytes(StringUtils.UTF8);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
byte[] digest;
|
||||
synchronized(md) {
|
||||
digest = md.digest(sb.toString().getBytes());
|
||||
digest = md.digest(bytes);
|
||||
}
|
||||
String version = Base64.encodeToString(digest);
|
||||
return new CapsVersionAndHash(version, hash);
|
||||
|
|
|
@ -35,10 +35,12 @@ public class CapsExtension implements ExtensionElement {
|
|||
this.hash = hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||
|
||||
public class CapsExtensionProvider extends ExtensionElementProvider<CapsExtension> {
|
||||
|
||||
@Override
|
||||
public CapsExtension parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException,
|
||||
SmackException {
|
||||
String hash = null;
|
||||
|
|
|
@ -119,6 +119,7 @@ public final class ChatStateManager extends Manager {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
@ -129,6 +130,7 @@ public final class ChatStateManager extends Manager {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return connection().hashCode();
|
||||
}
|
||||
|
@ -164,12 +166,14 @@ public final class ChatStateManager extends Manager {
|
|||
}
|
||||
}
|
||||
|
||||
private class IncomingMessageInterceptor implements ChatManagerListener, ChatMessageListener {
|
||||
private static class IncomingMessageInterceptor implements ChatManagerListener, ChatMessageListener {
|
||||
|
||||
@Override
|
||||
public void chatCreated(final org.jivesoftware.smack.chat.Chat chat, boolean createdLocally) {
|
||||
chat.addMessageListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMessage(org.jivesoftware.smack.chat.Chat chat, Message message) {
|
||||
ExtensionElement extension = message.getExtension(NAMESPACE);
|
||||
if (extension == null) {
|
||||
|
|
|
@ -19,9 +19,7 @@ package org.jivesoftware.smackx.chatstates.packet;
|
|||
|
||||
import org.jivesoftware.smackx.chatstates.ChatState;
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* Represents a chat state which is an extension to message packets which is used to indicate
|
||||
|
@ -66,18 +64,4 @@ public class ChatStateExtension implements ExtensionElement {
|
|||
return xml;
|
||||
}
|
||||
|
||||
public static class Provider extends ExtensionElementProvider<ChatStateExtension> {
|
||||
|
||||
@Override
|
||||
public ChatStateExtension parse(XmlPullParser parser, int initialDepth) {
|
||||
ChatState state;
|
||||
try {
|
||||
state = ChatState.valueOf(parser.getName());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
state = ChatState.active;
|
||||
}
|
||||
return new ChatStateExtension(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 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.chatstates.provider;
|
||||
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smackx.chatstates.ChatState;
|
||||
import org.jivesoftware.smackx.chatstates.packet.ChatStateExtension;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class ChatStateExtensionProvider extends ExtensionElementProvider<ChatStateExtension> {
|
||||
|
||||
@Override
|
||||
public ChatStateExtension parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
String chatStateString = parser.getName();
|
||||
ChatState state = ChatState.valueOf(chatStateString);
|
||||
|
||||
return new ChatStateExtension(state);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provider classes for Chat State Notifications (XEP-0085).
|
||||
*/
|
||||
package org.jivesoftware.smackx.chatstates.provider;
|
|
@ -457,12 +457,13 @@ public abstract class AdHocCommand {
|
|||
*/
|
||||
sessionExpired("session-expired");
|
||||
|
||||
private String value;
|
||||
private final String value;
|
||||
|
||||
SpecificErrorCondition(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.jivesoftware.smackx.commands;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -83,6 +84,7 @@ public final class AdHocCommandManager extends Manager {
|
|||
*/
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getAddHocCommandsManager(connection);
|
||||
}
|
||||
|
@ -200,8 +202,16 @@ public final class AdHocCommandManager extends Manager {
|
|||
*/
|
||||
public void registerCommand(String node, String name, final Class<? extends LocalCommand> clazz) {
|
||||
registerCommand(node, name, new LocalCommandFactory() {
|
||||
@Override
|
||||
public LocalCommand getInstance() throws InstantiationException, IllegalAccessException {
|
||||
return clazz.newInstance();
|
||||
try {
|
||||
return clazz.getConstructor().newInstance();
|
||||
}
|
||||
catch (IllegalArgumentException | InvocationTargetException | NoSuchMethodException
|
||||
| SecurityException e) {
|
||||
// TODO: Throw those method in Smack 4.3.
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -393,6 +403,7 @@ public final class AdHocCommandManager extends Manager {
|
|||
// See if the session reaping thread is started. If not, start it.
|
||||
if (sessionsSweeper == null) {
|
||||
sessionsSweeper = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
for (String sessionId : executingCommands.keySet()) {
|
||||
|
|
|
@ -248,9 +248,11 @@ public class AdHocCommandData extends IQ {
|
|||
this.condition = condition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return condition.toString();
|
||||
}
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
@ -259,6 +261,7 @@ public class AdHocCommandData extends IQ {
|
|||
return condition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('<').append(getElementName());
|
||||
|
|
|
@ -88,10 +88,12 @@ public class DelayInformation implements ExtensionElement {
|
|||
return reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
|
|
@ -25,18 +25,22 @@ import java.util.List;
|
|||
|
||||
public abstract class AbstractNodeInformationProvider implements NodeInformationProvider {
|
||||
|
||||
@Override
|
||||
public List<DiscoverItems.Item> getNodeItems() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNodeFeatures() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiscoverInfo.Identity> getNodeIdentities() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionElement> getNodePacketExtensions() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ public final class ServiceDiscoveryManager extends Manager {
|
|||
// Create a new ServiceDiscoveryManager on every established connection
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
|
|
|
@ -394,6 +394,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable<DiscoverInfo> {
|
|||
* <a href="http://xmpp.org/extensions/xep-0115.html#ver-proc">XEP-0015 5.4 Processing Method (Step 3.3)</a>.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
@ -437,6 +438,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable<DiscoverInfo> {
|
|||
* @return a negative integer, zero, or a positive integer as this object is less than,
|
||||
* equal to, or greater than the specified object.
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(DiscoverInfo.Identity other) {
|
||||
String otherLang = other.lang == null ? "" : other.lang;
|
||||
String thisLang = lang == null ? "" : lang;
|
||||
|
@ -512,6 +514,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable<DiscoverInfo> {
|
|||
return xml;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
|
|
@ -55,11 +55,13 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
|
|||
secondaryNegotiator.newStreamInitiation(from, streamID);
|
||||
}
|
||||
|
||||
@Override
|
||||
InputStream negotiateIncomingStream(Stanza streamInitiation) {
|
||||
throw new UnsupportedOperationException("Negotiation only handled by create incoming " +
|
||||
"stream method.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream createIncomingStream(final StreamInitiation initiation) throws SmackException, XMPPErrorException, InterruptedException {
|
||||
// This could be either an xep47 ibb 'open' iq or an xep65 streamhost iq
|
||||
IQ initationSet = initiateIncomingStream(connection, initiation);
|
||||
|
@ -79,6 +81,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream createOutgoingStream(String streamID, Jid initiator, Jid target)
|
||||
throws SmackException, XMPPException, InterruptedException {
|
||||
OutputStream stream;
|
||||
|
@ -92,6 +95,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
|
|||
return stream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNamespaces() {
|
||||
String[] primary = primaryNegotiator.getNamespaces();
|
||||
String[] secondary = secondaryNegotiator.getNamespaces();
|
||||
|
|
|
@ -31,27 +31,27 @@ import org.jxmpp.jid.Jid;
|
|||
*/
|
||||
public abstract class FileTransfer {
|
||||
|
||||
private String fileName;
|
||||
private String fileName;
|
||||
|
||||
private String filePath;
|
||||
private String filePath;
|
||||
|
||||
private long fileSize;
|
||||
private long fileSize;
|
||||
|
||||
private Jid peer;
|
||||
private Jid peer;
|
||||
|
||||
private Status status = Status.initial;
|
||||
private Status status = Status.initial;
|
||||
|
||||
private final Object statusMonitor = new Object();
|
||||
|
||||
protected FileTransferNegotiator negotiator;
|
||||
protected FileTransferNegotiator negotiator;
|
||||
|
||||
protected String streamID;
|
||||
protected String streamID;
|
||||
|
||||
protected long amountWritten = -1;
|
||||
protected long amountWritten = -1;
|
||||
|
||||
private Error error;
|
||||
private Error error;
|
||||
|
||||
private Exception exception;
|
||||
private Exception exception;
|
||||
|
||||
/**
|
||||
* Buffer size between input and output
|
||||
|
@ -59,137 +59,137 @@ public abstract class FileTransfer {
|
|||
private static final int BUFFER_SIZE = 8192;
|
||||
|
||||
protected FileTransfer(Jid peer, String streamID,
|
||||
FileTransferNegotiator negotiator) {
|
||||
this.peer = peer;
|
||||
this.streamID = streamID;
|
||||
this.negotiator = negotiator;
|
||||
}
|
||||
FileTransferNegotiator negotiator) {
|
||||
this.peer = peer;
|
||||
this.streamID = streamID;
|
||||
this.negotiator = negotiator;
|
||||
}
|
||||
|
||||
protected void setFileInfo(String fileName, long fileSize) {
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
protected void setFileInfo(String fileName, long fileSize) {
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
protected void setFileInfo(String path, String fileName, long fileSize) {
|
||||
this.filePath = path;
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
protected void setFileInfo(String path, String fileName, long fileSize) {
|
||||
this.filePath = path;
|
||||
this.fileName = fileName;
|
||||
this.fileSize = fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the file being transfered.
|
||||
*
|
||||
* @return Returns the size of the file being transfered.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
/**
|
||||
* Returns the size of the file being transfered.
|
||||
*
|
||||
* @return Returns the size of the file being transfered.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the file being transfered.
|
||||
*
|
||||
* @return Returns the name of the file being transfered.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
/**
|
||||
* Returns the name of the file being transfered.
|
||||
*
|
||||
* @return Returns the name of the file being transfered.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local path of the file.
|
||||
*
|
||||
* @return Returns the local path of the file.
|
||||
*/
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
/**
|
||||
* Returns the local path of the file.
|
||||
*
|
||||
* @return Returns the local path of the file.
|
||||
*/
|
||||
public String getFilePath() {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JID of the peer for this file transfer.
|
||||
*
|
||||
* @return Returns the JID of the peer for this file transfer.
|
||||
*/
|
||||
public Jid getPeer() {
|
||||
return peer;
|
||||
}
|
||||
/**
|
||||
* Returns the JID of the peer for this file transfer.
|
||||
*
|
||||
* @return Returns the JID of the peer for this file transfer.
|
||||
*/
|
||||
public Jid getPeer() {
|
||||
return peer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the progress of the file transfer as a number between 0 and 1.
|
||||
*
|
||||
* @return Returns the progress of the file transfer as a number between 0
|
||||
* and 1.
|
||||
*/
|
||||
public double getProgress() {
|
||||
/**
|
||||
* Returns the progress of the file transfer as a number between 0 and 1.
|
||||
*
|
||||
* @return Returns the progress of the file transfer as a number between 0
|
||||
* and 1.
|
||||
*/
|
||||
public double getProgress() {
|
||||
if (amountWritten <= 0 || fileSize <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return (double) amountWritten / (double) fileSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the transfer has been cancelled, if it has stopped because
|
||||
* of a an error, or the transfer completed successfully.
|
||||
*
|
||||
* @return Returns true if the transfer has been cancelled, if it has stopped
|
||||
* because of a an error, or the transfer completed successfully.
|
||||
*/
|
||||
public boolean isDone() {
|
||||
return status == Status.cancelled || status == Status.error
|
||||
|| status == Status.complete || status == Status.refused;
|
||||
}
|
||||
/**
|
||||
* Returns true if the transfer has been cancelled, if it has stopped because
|
||||
* of a an error, or the transfer completed successfully.
|
||||
*
|
||||
* @return Returns true if the transfer has been cancelled, if it has stopped
|
||||
* because of a an error, or the transfer completed successfully.
|
||||
*/
|
||||
public boolean isDone() {
|
||||
return status == Status.cancelled || status == Status.error
|
||||
|| status == Status.complete || status == Status.refused;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current status of the file transfer.
|
||||
*
|
||||
* @return Returns the current status of the file transfer.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* Returns the current status of the file transfer.
|
||||
*
|
||||
* @return Returns the current status of the file transfer.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
protected void setError(Error type) {
|
||||
this.error = type;
|
||||
}
|
||||
protected void setError(Error type) {
|
||||
this.error = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* When {@link #getStatus()} returns that there was an {@link Status#error}
|
||||
* during the transfer, the type of error can be retrieved through this
|
||||
* method.
|
||||
*
|
||||
* @return Returns the type of error that occurred if one has occurred.
|
||||
*/
|
||||
public Error getError() {
|
||||
return error;
|
||||
}
|
||||
/**
|
||||
* When {@link #getStatus()} returns that there was an {@link Status#error}
|
||||
* during the transfer, the type of error can be retrieved through this
|
||||
* method.
|
||||
*
|
||||
* @return Returns the type of error that occurred if one has occurred.
|
||||
*/
|
||||
public Error getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* If an exception occurs asynchronously it will be stored for later
|
||||
* retrieval. If there is an error there maybe an exception set.
|
||||
*
|
||||
* @return The exception that occurred or null if there was no exception.
|
||||
* @see #getError()
|
||||
*/
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
/**
|
||||
* If an exception occurs asynchronously it will be stored for later
|
||||
* retrieval. If there is an error there maybe an exception set.
|
||||
*
|
||||
* @return The exception that occurred or null if there was no exception.
|
||||
* @see #getError()
|
||||
*/
|
||||
public Exception getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public String getStreamID() {
|
||||
return streamID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the file transfer.
|
||||
*/
|
||||
public abstract void cancel();
|
||||
/**
|
||||
* Cancels the file transfer.
|
||||
*/
|
||||
public abstract void cancel();
|
||||
|
||||
protected void setException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
protected void setException(Exception exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
protected void setStatus(Status status) {
|
||||
protected void setStatus(Status status) {
|
||||
synchronized (statusMonitor) {
|
||||
// CHECKSTYLE:OFF
|
||||
this.status = status;
|
||||
}
|
||||
this.status = status;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
|
@ -206,98 +206,99 @@ public abstract class FileTransfer {
|
|||
protected void writeToStream(final InputStream in, final OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
final byte[] b = new byte[BUFFER_SIZE];
|
||||
int count = 0;
|
||||
amountWritten = 0;
|
||||
final byte[] b = new byte[BUFFER_SIZE];
|
||||
int count = 0;
|
||||
amountWritten = 0;
|
||||
|
||||
while ((count = in.read(b)) > 0 && !getStatus().equals(Status.cancelled)) {
|
||||
out.write(b, 0, count);
|
||||
amountWritten += count;
|
||||
}
|
||||
|
||||
// the connection was likely terminated abruptly if these are not equal
|
||||
if (!getStatus().equals(Status.cancelled) && getError() == Error.none
|
||||
&& amountWritten != fileSize) {
|
||||
// the connection was likely terminated abruptly if these are not equal
|
||||
if (!getStatus().equals(Status.cancelled) && getError() == Error.none
|
||||
&& amountWritten != fileSize) {
|
||||
setStatus(Status.error);
|
||||
this.error = Error.connection;
|
||||
}
|
||||
}
|
||||
this.error = Error.connection;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to represent the current status of the file transfer.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public enum Status {
|
||||
/**
|
||||
* A class to represent the current status of the file transfer.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public enum Status {
|
||||
|
||||
/**
|
||||
* An error occurred during the transfer.
|
||||
*
|
||||
* @see FileTransfer#getError()
|
||||
*/
|
||||
error("Error"),
|
||||
/**
|
||||
* An error occurred during the transfer.
|
||||
*
|
||||
* @see FileTransfer#getError()
|
||||
*/
|
||||
error("Error"),
|
||||
|
||||
/**
|
||||
/**
|
||||
* The initial status of the file transfer.
|
||||
*/
|
||||
initial("Initial"),
|
||||
|
||||
/**
|
||||
* The file transfer is being negotiated with the peer. The party
|
||||
* Receiving the file has the option to accept or refuse a file transfer
|
||||
* request. If they accept, then the process of stream negotiation will
|
||||
* begin. If they refuse the file will not be transfered.
|
||||
*
|
||||
* @see #negotiating_stream
|
||||
*/
|
||||
negotiating_transfer("Negotiating Transfer"),
|
||||
* The file transfer is being negotiated with the peer. The party
|
||||
* Receiving the file has the option to accept or refuse a file transfer
|
||||
* request. If they accept, then the process of stream negotiation will
|
||||
* begin. If they refuse the file will not be transfered.
|
||||
*
|
||||
* @see #negotiating_stream
|
||||
*/
|
||||
negotiating_transfer("Negotiating Transfer"),
|
||||
|
||||
/**
|
||||
* The peer has refused the file transfer request halting the file
|
||||
* transfer negotiation process.
|
||||
*/
|
||||
refused("Refused"),
|
||||
/**
|
||||
* The peer has refused the file transfer request halting the file
|
||||
* transfer negotiation process.
|
||||
*/
|
||||
refused("Refused"),
|
||||
|
||||
/**
|
||||
* The stream to transfer the file is being negotiated over the chosen
|
||||
* stream type. After the stream negotiating process is complete the
|
||||
* status becomes negotiated.
|
||||
*
|
||||
* @see #negotiated
|
||||
*/
|
||||
negotiating_stream("Negotiating Stream"),
|
||||
/**
|
||||
* The stream to transfer the file is being negotiated over the chosen
|
||||
* stream type. After the stream negotiating process is complete the
|
||||
* status becomes negotiated.
|
||||
*
|
||||
* @see #negotiated
|
||||
*/
|
||||
negotiating_stream("Negotiating Stream"),
|
||||
|
||||
/**
|
||||
* After the stream negotiation has completed the intermediate state
|
||||
* between the time when the negotiation is finished and the actual
|
||||
* transfer begins.
|
||||
*/
|
||||
negotiated("Negotiated"),
|
||||
/**
|
||||
* After the stream negotiation has completed the intermediate state
|
||||
* between the time when the negotiation is finished and the actual
|
||||
* transfer begins.
|
||||
*/
|
||||
negotiated("Negotiated"),
|
||||
|
||||
/**
|
||||
* The transfer is in progress.
|
||||
*
|
||||
* @see FileTransfer#getProgress()
|
||||
*/
|
||||
in_progress("In Progress"),
|
||||
/**
|
||||
* The transfer is in progress.
|
||||
*
|
||||
* @see FileTransfer#getProgress()
|
||||
*/
|
||||
in_progress("In Progress"),
|
||||
|
||||
/**
|
||||
* The transfer has completed successfully.
|
||||
*/
|
||||
complete("Complete"),
|
||||
/**
|
||||
* The transfer has completed successfully.
|
||||
*/
|
||||
complete("Complete"),
|
||||
|
||||
/**
|
||||
* The file transfer was cancelled.
|
||||
*/
|
||||
cancelled("Cancelled");
|
||||
/**
|
||||
* The file transfer was cancelled.
|
||||
*/
|
||||
cancelled("Cancelled");
|
||||
|
||||
private String status;
|
||||
private final String status;
|
||||
|
||||
private Status(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return status;
|
||||
}
|
||||
|
@ -312,55 +313,56 @@ public abstract class FileTransfer {
|
|||
}
|
||||
|
||||
public enum Error {
|
||||
/**
|
||||
* No error.
|
||||
*/
|
||||
none("No error"),
|
||||
/**
|
||||
* No error.
|
||||
*/
|
||||
none("No error"),
|
||||
|
||||
/**
|
||||
* The peer did not find any of the provided stream mechanisms
|
||||
* acceptable.
|
||||
*/
|
||||
not_acceptable("The peer did not find any of the provided stream mechanisms acceptable."),
|
||||
/**
|
||||
* The peer did not find any of the provided stream mechanisms
|
||||
* acceptable.
|
||||
*/
|
||||
not_acceptable("The peer did not find any of the provided stream mechanisms acceptable."),
|
||||
|
||||
/**
|
||||
* The provided file to transfer does not exist or could not be read.
|
||||
*/
|
||||
bad_file("The provided file to transfer does not exist or could not be read."),
|
||||
/**
|
||||
* The provided file to transfer does not exist or could not be read.
|
||||
*/
|
||||
bad_file("The provided file to transfer does not exist or could not be read."),
|
||||
|
||||
/**
|
||||
* The remote user did not respond or the connection timed out.
|
||||
*/
|
||||
no_response("The remote user did not respond or the connection timed out."),
|
||||
/**
|
||||
* The remote user did not respond or the connection timed out.
|
||||
*/
|
||||
no_response("The remote user did not respond or the connection timed out."),
|
||||
|
||||
/**
|
||||
* An error occurred over the socket connected to send the file.
|
||||
*/
|
||||
connection("An error occured over the socket connected to send the file."),
|
||||
/**
|
||||
* An error occurred over the socket connected to send the file.
|
||||
*/
|
||||
connection("An error occured over the socket connected to send the file."),
|
||||
|
||||
/**
|
||||
* An error occurred while sending or receiving the file.
|
||||
*/
|
||||
stream("An error occured while sending or recieving the file.");
|
||||
/**
|
||||
* An error occurred while sending or receiving the file.
|
||||
*/
|
||||
stream("An error occured while sending or recieving the file.");
|
||||
|
||||
private final String msg;
|
||||
private final String msg;
|
||||
|
||||
private Error(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
private Error(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a String representation of this error.
|
||||
*
|
||||
* @return Returns a String representation of this error.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
/**
|
||||
* Returns a String representation of this error.
|
||||
*
|
||||
* @return Returns a String representation of this error.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ package org.jivesoftware.smackx.filetransfer;
|
|||
* @author Alexander Wenckus
|
||||
*/
|
||||
public interface FileTransferListener {
|
||||
/**
|
||||
* A request to send a file has been recieved from another user.
|
||||
*
|
||||
* @param request
|
||||
* The request from the other user.
|
||||
*/
|
||||
public void fileTransferRequest(final FileTransferRequest request);
|
||||
/**
|
||||
* A request to send a file has been recieved from another user.
|
||||
*
|
||||
* @param request
|
||||
* The request from the other user.
|
||||
*/
|
||||
public void fileTransferRequest(final FileTransferRequest request);
|
||||
}
|
||||
|
|
|
@ -56,20 +56,20 @@ public final class FileTransferManager extends Manager {
|
|||
return fileTransferManager;
|
||||
}
|
||||
|
||||
private final FileTransferNegotiator fileTransferNegotiator;
|
||||
private final FileTransferNegotiator fileTransferNegotiator;
|
||||
|
||||
private final List<FileTransferListener> listeners = new CopyOnWriteArrayList<FileTransferListener>();
|
||||
private final List<FileTransferListener> listeners = new CopyOnWriteArrayList<FileTransferListener>();
|
||||
|
||||
/**
|
||||
* Creates a file transfer manager to initiate and receive file transfers.
|
||||
*
|
||||
* @param connection
|
||||
* The XMPPConnection that the file transfers will use.
|
||||
*/
|
||||
private FileTransferManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
this.fileTransferNegotiator = FileTransferNegotiator
|
||||
.getInstanceFor(connection);
|
||||
/**
|
||||
* Creates a file transfer manager to initiate and receive file transfers.
|
||||
*
|
||||
* @param connection
|
||||
* The XMPPConnection that the file transfers will use.
|
||||
*/
|
||||
private FileTransferManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
this.fileTransferNegotiator = FileTransferNegotiator
|
||||
.getInstanceFor(connection);
|
||||
connection.registerIQRequestHandler(new AbstractIqRequestHandler(StreamInitiation.ELEMENT,
|
||||
StreamInitiation.NAMESPACE, IQ.Type.set, Mode.async) {
|
||||
@Override
|
||||
|
@ -82,42 +82,42 @@ public final class FileTransferManager extends Manager {
|
|||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a file transfer listener to listen to incoming file transfer
|
||||
* requests.
|
||||
*
|
||||
* @param li
|
||||
* The listener
|
||||
* @see #removeFileTransferListener(FileTransferListener)
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void addFileTransferListener(final FileTransferListener li) {
|
||||
listeners.add(li);
|
||||
}
|
||||
/**
|
||||
* Add a file transfer listener to listen to incoming file transfer
|
||||
* requests.
|
||||
*
|
||||
* @param li
|
||||
* The listener
|
||||
* @see #removeFileTransferListener(FileTransferListener)
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void addFileTransferListener(final FileTransferListener li) {
|
||||
listeners.add(li);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a file transfer listener.
|
||||
*
|
||||
* @param li
|
||||
* The file transfer listener to be removed
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void removeFileTransferListener(final FileTransferListener li) {
|
||||
listeners.remove(li);
|
||||
}
|
||||
/**
|
||||
* Removes a file transfer listener.
|
||||
*
|
||||
* @param li
|
||||
* The file transfer listener to be removed
|
||||
* @see FileTransferListener
|
||||
*/
|
||||
public void removeFileTransferListener(final FileTransferListener li) {
|
||||
listeners.remove(li);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an OutgoingFileTransfer to send a file to another user.
|
||||
*
|
||||
* @param userID
|
||||
* The fully qualified jabber ID (i.e. full JID) with resource of the user to
|
||||
* send the file to.
|
||||
* @return The send file object on which the negotiated transfer can be run.
|
||||
* @exception IllegalArgumentException if userID is null or not a full JID
|
||||
*/
|
||||
public OutgoingFileTransfer createOutgoingFileTransfer(EntityFullJid userID) {
|
||||
/**
|
||||
* Creates an OutgoingFileTransfer to send a file to another user.
|
||||
*
|
||||
* @param userID
|
||||
* The fully qualified jabber ID (i.e. full JID) with resource of the user to
|
||||
* send the file to.
|
||||
* @return The send file object on which the negotiated transfer can be run.
|
||||
* @exception IllegalArgumentException if userID is null or not a full JID
|
||||
*/
|
||||
public OutgoingFileTransfer createOutgoingFileTransfer(EntityFullJid userID) {
|
||||
// We need to create outgoing file transfers with a full JID since this method will later
|
||||
// use XEP-0095 to negotiate the stream. This is done with IQ stanzas that need to be addressed to a full JID
|
||||
// in order to reach an client entity.
|
||||
|
@ -125,45 +125,45 @@ public final class FileTransferManager extends Manager {
|
|||
throw new IllegalArgumentException("userID was null");
|
||||
}
|
||||
|
||||
return new OutgoingFileTransfer(connection().getUser(), userID,
|
||||
FileTransferNegotiator.getNextStreamID(),
|
||||
fileTransferNegotiator);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the file transfer request is acceptable, this method should be
|
||||
* invoked. It will create an IncomingFileTransfer which allows the
|
||||
* transmission of the file to procede.
|
||||
*
|
||||
* @param request
|
||||
* The remote request that is being accepted.
|
||||
* @return The IncomingFileTransfer which manages the download of the file
|
||||
* from the transfer initiator.
|
||||
*/
|
||||
protected IncomingFileTransfer createIncomingFileTransfer(
|
||||
FileTransferRequest request) {
|
||||
if (request == null) {
|
||||
throw new NullPointerException("RecieveRequest cannot be null");
|
||||
}
|
||||
|
||||
IncomingFileTransfer transfer = new IncomingFileTransfer(request,
|
||||
return new OutgoingFileTransfer(connection().getUser(), userID,
|
||||
FileTransferNegotiator.getNextStreamID(),
|
||||
fileTransferNegotiator);
|
||||
transfer.setFileInfo(request.getFileName(), request.getFileSize());
|
||||
}
|
||||
|
||||
return transfer;
|
||||
}
|
||||
/**
|
||||
* When the file transfer request is acceptable, this method should be
|
||||
* invoked. It will create an IncomingFileTransfer which allows the
|
||||
* transmission of the file to procede.
|
||||
*
|
||||
* @param request
|
||||
* The remote request that is being accepted.
|
||||
* @return The IncomingFileTransfer which manages the download of the file
|
||||
* from the transfer initiator.
|
||||
*/
|
||||
protected IncomingFileTransfer createIncomingFileTransfer(
|
||||
FileTransferRequest request) {
|
||||
if (request == null) {
|
||||
throw new NullPointerException("RecieveRequest cannot be null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject an incoming file transfer.
|
||||
* <p>
|
||||
* Specified in XEP-95 4.2 and 3.2 Example 8
|
||||
* </p>
|
||||
* @param request
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected void rejectIncomingFileTransfer(FileTransferRequest request) throws NotConnectedException, InterruptedException {
|
||||
StreamInitiation initiation = request.getStreamInitiation();
|
||||
IncomingFileTransfer transfer = new IncomingFileTransfer(request,
|
||||
fileTransferNegotiator);
|
||||
transfer.setFileInfo(request.getFileName(), request.getFileSize());
|
||||
|
||||
return transfer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject an incoming file transfer.
|
||||
* <p>
|
||||
* Specified in XEP-95 4.2 and 3.2 Example 8
|
||||
* </p>
|
||||
* @param request
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
protected void rejectIncomingFileTransfer(FileTransferRequest request) throws NotConnectedException, InterruptedException {
|
||||
StreamInitiation initiation = request.getStreamInitiation();
|
||||
|
||||
// Reject as specified in XEP-95 4.2. Note that this is not to be confused with the Socks 5
|
||||
// Bytestream rejection as specified in XEP-65 5.3.1 Example 13, which says that
|
||||
|
@ -172,5 +172,5 @@ public final class FileTransferManager extends Manager {
|
|||
IQ rejection = IQ.createErrorResponse(initiation, XMPPError.getBuilder(
|
||||
XMPPError.Condition.forbidden));
|
||||
connection().sendStanza(rejection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,113 +27,113 @@ import org.jxmpp.jid.Jid;
|
|||
*
|
||||
*/
|
||||
public class FileTransferRequest {
|
||||
private final StreamInitiation streamInitiation;
|
||||
private final StreamInitiation streamInitiation;
|
||||
|
||||
private final FileTransferManager manager;
|
||||
private final FileTransferManager manager;
|
||||
|
||||
/**
|
||||
* A recieve request is constructed from the Stream Initiation request
|
||||
* received from the initator.
|
||||
*
|
||||
* @param manager
|
||||
* The manager handling this file transfer
|
||||
*
|
||||
* @param si
|
||||
* The Stream initiaton recieved from the initiator.
|
||||
*/
|
||||
public FileTransferRequest(FileTransferManager manager, StreamInitiation si) {
|
||||
this.streamInitiation = si;
|
||||
this.manager = manager;
|
||||
}
|
||||
/**
|
||||
* A recieve request is constructed from the Stream Initiation request
|
||||
* received from the initator.
|
||||
*
|
||||
* @param manager
|
||||
* The manager handling this file transfer
|
||||
*
|
||||
* @param si
|
||||
* The Stream initiaton recieved from the initiator.
|
||||
*/
|
||||
public FileTransferRequest(FileTransferManager manager, StreamInitiation si) {
|
||||
this.streamInitiation = si;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the file.
|
||||
*
|
||||
* @return Returns the name of the file.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return streamInitiation.getFile().getName();
|
||||
}
|
||||
/**
|
||||
* Returns the name of the file.
|
||||
*
|
||||
* @return Returns the name of the file.
|
||||
*/
|
||||
public String getFileName() {
|
||||
return streamInitiation.getFile().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size in bytes of the file.
|
||||
*
|
||||
* @return Returns the size in bytes of the file.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return streamInitiation.getFile().getSize();
|
||||
}
|
||||
/**
|
||||
* Returns the size in bytes of the file.
|
||||
*
|
||||
* @return Returns the size in bytes of the file.
|
||||
*/
|
||||
public long getFileSize() {
|
||||
return streamInitiation.getFile().getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the description of the file provided by the requestor.
|
||||
*
|
||||
* @return Returns the description of the file provided by the requestor.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return streamInitiation.getFile().getDesc();
|
||||
}
|
||||
/**
|
||||
* Returns the description of the file provided by the requestor.
|
||||
*
|
||||
* @return Returns the description of the file provided by the requestor.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return streamInitiation.getFile().getDesc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime-type of the file.
|
||||
*
|
||||
* @return Returns the mime-type of the file.
|
||||
*/
|
||||
public String getMimeType() {
|
||||
return streamInitiation.getMimeType();
|
||||
}
|
||||
/**
|
||||
* Returns the mime-type of the file.
|
||||
*
|
||||
* @return Returns the mime-type of the file.
|
||||
*/
|
||||
public String getMimeType() {
|
||||
return streamInitiation.getMimeType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fully-qualified jabber ID of the user that requested this
|
||||
* file transfer.
|
||||
*
|
||||
* @return Returns the fully-qualified jabber ID of the user that requested
|
||||
* this file transfer.
|
||||
*/
|
||||
public Jid getRequestor() {
|
||||
return streamInitiation.getFrom();
|
||||
}
|
||||
/**
|
||||
* Returns the fully-qualified jabber ID of the user that requested this
|
||||
* file transfer.
|
||||
*
|
||||
* @return Returns the fully-qualified jabber ID of the user that requested
|
||||
* this file transfer.
|
||||
*/
|
||||
public Jid getRequestor() {
|
||||
return streamInitiation.getFrom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream ID that uniquely identifies this file transfer.
|
||||
*
|
||||
* @return Returns the stream ID that uniquely identifies this file
|
||||
* transfer.
|
||||
*/
|
||||
public String getStreamID() {
|
||||
return streamInitiation.getSessionID();
|
||||
}
|
||||
/**
|
||||
* Returns the stream ID that uniquely identifies this file transfer.
|
||||
*
|
||||
* @return Returns the stream ID that uniquely identifies this file
|
||||
* transfer.
|
||||
*/
|
||||
public String getStreamID() {
|
||||
return streamInitiation.getSessionID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream initiation stanza(/packet) that was sent by the requestor which
|
||||
* contains the parameters of the file transfer being transfer and also the
|
||||
* methods available to transfer the file.
|
||||
*
|
||||
* @return Returns the stream initiation stanza(/packet) that was sent by the
|
||||
* requestor which contains the parameters of the file transfer
|
||||
* being transfer and also the methods available to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected StreamInitiation getStreamInitiation() {
|
||||
return streamInitiation;
|
||||
}
|
||||
/**
|
||||
* Returns the stream initiation stanza(/packet) that was sent by the requestor which
|
||||
* contains the parameters of the file transfer being transfer and also the
|
||||
* methods available to transfer the file.
|
||||
*
|
||||
* @return Returns the stream initiation stanza(/packet) that was sent by the
|
||||
* requestor which contains the parameters of the file transfer
|
||||
* being transfer and also the methods available to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected StreamInitiation getStreamInitiation() {
|
||||
return streamInitiation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts this file transfer and creates the incoming file transfer.
|
||||
*
|
||||
* @return Returns the <b><i>IncomingFileTransfer</b></i> on which the
|
||||
* file transfer can be carried out.
|
||||
*/
|
||||
public IncomingFileTransfer accept() {
|
||||
return manager.createIncomingFileTransfer(this);
|
||||
}
|
||||
/**
|
||||
* Accepts this file transfer and creates the incoming file transfer.
|
||||
*
|
||||
* @return Returns the <b><i>IncomingFileTransfer</b></i> on which the
|
||||
* file transfer can be carried out.
|
||||
*/
|
||||
public IncomingFileTransfer accept() {
|
||||
return manager.createIncomingFileTransfer(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects the file transfer request.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void reject() throws NotConnectedException, InterruptedException {
|
||||
manager.rejectIncomingFileTransfer(this);
|
||||
}
|
||||
/**
|
||||
* Rejects the file transfer request.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void reject() throws NotConnectedException, InterruptedException {
|
||||
manager.rejectIncomingFileTransfer(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
|
|||
this.manager = InBandBytestreamManager.getByteStreamManager(connection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream createOutgoingStream(String streamID, Jid initiator,
|
||||
Jid target) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
InBandBytestreamSession session = this.manager.establishSession(target, streamID);
|
||||
|
@ -65,6 +66,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
|
|||
return session.getOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream createIncomingStream(StreamInitiation initiation)
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
/*
|
||||
|
@ -87,10 +89,12 @@ public class IBBTransferNegotiator extends StreamNegotiator {
|
|||
this.manager.ignoreBytestreamRequestOnce(streamID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNamespaces() {
|
||||
return new String[] { DataPacketExtension.NAMESPACE };
|
||||
}
|
||||
|
||||
@Override
|
||||
InputStream negotiateIncomingStream(Stanza streamInitiation) throws NotConnectedException, InterruptedException {
|
||||
// build In-Band Bytestream request
|
||||
InBandBytestreamRequest request = new ByteStreamRequest(this.manager,
|
||||
|
|
|
@ -126,6 +126,7 @@ public class IncomingFileTransfer extends FileTransfer {
|
|||
}
|
||||
|
||||
Thread transferThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
inputStream = negotiateStream();
|
||||
|
@ -184,6 +185,7 @@ public class IncomingFileTransfer extends FileTransfer {
|
|||
FutureTask<InputStream> streamNegotiatorTask = new FutureTask<InputStream>(
|
||||
new Callable<InputStream>() {
|
||||
|
||||
@Override
|
||||
public InputStream call() throws Exception {
|
||||
return streamNegotiator
|
||||
.createIncomingStream(recieveRequest.getStreamInitiation());
|
||||
|
@ -220,6 +222,7 @@ public class IncomingFileTransfer extends FileTransfer {
|
|||
return inputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
setStatus(Status.cancelled);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ import org.jxmpp.jid.Jid;
|
|||
public class OutgoingFileTransfer extends FileTransfer {
|
||||
private static final Logger LOGGER = Logger.getLogger(OutgoingFileTransfer.class.getName());
|
||||
|
||||
private static int RESPONSE_TIMEOUT = 60 * 1000;
|
||||
private static int RESPONSE_TIMEOUT = 60 * 1000;
|
||||
private NegotiationProgress callback;
|
||||
|
||||
/**
|
||||
|
@ -58,349 +58,353 @@ public class OutgoingFileTransfer extends FileTransfer {
|
|||
return RESPONSE_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time in milliseconds after which the file transfer negotiation
|
||||
* process will timeout if the other user has not responded.
|
||||
*
|
||||
* @param responseTimeout
|
||||
* The timeout time in milliseconds.
|
||||
*/
|
||||
public static void setResponseTimeout(int responseTimeout) {
|
||||
RESPONSE_TIMEOUT = responseTimeout;
|
||||
}
|
||||
/**
|
||||
* Sets the time in milliseconds after which the file transfer negotiation
|
||||
* process will timeout if the other user has not responded.
|
||||
*
|
||||
* @param responseTimeout
|
||||
* The timeout time in milliseconds.
|
||||
*/
|
||||
public static void setResponseTimeout(int responseTimeout) {
|
||||
RESPONSE_TIMEOUT = responseTimeout;
|
||||
}
|
||||
|
||||
private OutputStream outputStream;
|
||||
private OutputStream outputStream;
|
||||
|
||||
private Jid initiator;
|
||||
private Jid initiator;
|
||||
|
||||
private Thread transferThread;
|
||||
private Thread transferThread;
|
||||
|
||||
protected OutgoingFileTransfer(Jid initiator, Jid target,
|
||||
String streamID, FileTransferNegotiator transferNegotiator) {
|
||||
super(target, streamID, transferNegotiator);
|
||||
this.initiator = initiator;
|
||||
}
|
||||
protected OutgoingFileTransfer(Jid initiator, Jid target,
|
||||
String streamID, FileTransferNegotiator transferNegotiator) {
|
||||
super(target, streamID, transferNegotiator);
|
||||
this.initiator = initiator;
|
||||
}
|
||||
|
||||
protected void setOutputStream(OutputStream stream) {
|
||||
if (outputStream == null) {
|
||||
this.outputStream = stream;
|
||||
}
|
||||
}
|
||||
protected void setOutputStream(OutputStream stream) {
|
||||
if (outputStream == null) {
|
||||
this.outputStream = stream;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output stream connected to the peer to transfer the file. It
|
||||
* is only available after it has been successfully negotiated by the
|
||||
* {@link StreamNegotiator}.
|
||||
*
|
||||
* @return Returns the output stream connected to the peer to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected OutputStream getOutputStream() {
|
||||
if (getStatus().equals(FileTransfer.Status.negotiated)) {
|
||||
return outputStream;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the output stream connected to the peer to transfer the file. It
|
||||
* is only available after it has been successfully negotiated by the
|
||||
* {@link StreamNegotiator}.
|
||||
*
|
||||
* @return Returns the output stream connected to the peer to transfer the
|
||||
* file.
|
||||
*/
|
||||
protected OutputStream getOutputStream() {
|
||||
if (getStatus().equals(FileTransfer.Status.negotiated)) {
|
||||
return outputStream;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles the negotiation of the file transfer and the stream,
|
||||
* it only returns the created stream after the negotiation has been completed.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @return The OutputStream that is connected to the peer to transmit the
|
||||
* file.
|
||||
* @throws XMPPException
|
||||
* Thrown if an error occurs during the file transfer
|
||||
* negotiation process.
|
||||
* @throws SmackException if there was no response from the server.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public synchronized OutputStream sendFile(String fileName, long fileSize,
|
||||
String description) throws XMPPException, SmackException, InterruptedException {
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted on this file transfer");
|
||||
}
|
||||
try {
|
||||
setFileInfo(fileName, fileSize);
|
||||
this.outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
throw e;
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
/**
|
||||
* This method handles the negotiation of the file transfer and the stream,
|
||||
* it only returns the created stream after the negotiation has been completed.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @return The OutputStream that is connected to the peer to transmit the
|
||||
* file.
|
||||
* @throws XMPPException
|
||||
* Thrown if an error occurs during the file transfer
|
||||
* negotiation process.
|
||||
* @throws SmackException if there was no response from the server.
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public synchronized OutputStream sendFile(String fileName, long fileSize,
|
||||
String description) throws XMPPException, SmackException, InterruptedException {
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted on this file transfer");
|
||||
}
|
||||
try {
|
||||
setFileInfo(fileName, fileSize);
|
||||
this.outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
throw e;
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods handles the transfer and stream negotiation process. It
|
||||
* returns immediately and its progress will be updated through the
|
||||
* {@link NegotiationProgress} callback.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @param progress
|
||||
* A callback to monitor the progress of the file transfer
|
||||
* negotiation process and to retrieve the OutputStream when it
|
||||
* is complete.
|
||||
*/
|
||||
public synchronized void sendFile(final String fileName,
|
||||
final long fileSize, final String description,
|
||||
final NegotiationProgress progress)
|
||||
/**
|
||||
* This methods handles the transfer and stream negotiation process. It
|
||||
* returns immediately and its progress will be updated through the
|
||||
* {@link NegotiationProgress} callback.
|
||||
*
|
||||
* @param fileName
|
||||
* The name of the file that will be transmitted. It is
|
||||
* preferable for this name to have an extension as it will be
|
||||
* used to determine the type of file it is.
|
||||
* @param fileSize
|
||||
* The size in bytes of the file that will be transmitted.
|
||||
* @param description
|
||||
* A description of the file that will be transmitted.
|
||||
* @param progress
|
||||
* A callback to monitor the progress of the file transfer
|
||||
* negotiation process and to retrieve the OutputStream when it
|
||||
* is complete.
|
||||
*/
|
||||
public synchronized void sendFile(final String fileName,
|
||||
final long fileSize, final String description,
|
||||
final NegotiationProgress progress)
|
||||
{
|
||||
if(progress == null) {
|
||||
throw new IllegalArgumentException("Callback progress cannot be null.");
|
||||
}
|
||||
checkTransferThread();
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted for this file transfer");
|
||||
}
|
||||
if (isDone() || outputStream != null) {
|
||||
throw new IllegalStateException(
|
||||
"The negotation process has already"
|
||||
+ " been attempted for this file transfer");
|
||||
}
|
||||
setFileInfo(fileName, fileSize);
|
||||
this.callback = progress;
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
OutgoingFileTransfer.this.outputStream = negotiateStream(
|
||||
fileName, fileSize, description);
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
OutgoingFileTransfer.this.outputStream = negotiateStream(
|
||||
fileName, fileSize, description);
|
||||
progress.outputStreamEstablished(OutgoingFileTransfer.this.outputStream);
|
||||
}
|
||||
catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
}
|
||||
handleXMPPException(e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
}
|
||||
}, "File Transfer Negotiation " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
}
|
||||
}, "File Transfer Negotiation " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
|
||||
private void checkTransferThread() {
|
||||
if (transferThread != null && transferThread.isAlive() || isDone()) {
|
||||
throw new IllegalStateException(
|
||||
"File transfer in progress or has already completed.");
|
||||
}
|
||||
}
|
||||
private void checkTransferThread() {
|
||||
if ((transferThread != null && transferThread.isAlive()) || isDone()) {
|
||||
throw new IllegalStateException(
|
||||
"File transfer in progress or has already completed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* @param file the file to transfer to the remote entity.
|
||||
* @param description a description for the file to transfer.
|
||||
* @throws SmackException
|
||||
* If there is an error during the negotiation process or the
|
||||
* sending of the file.
|
||||
*/
|
||||
public synchronized void sendFile(final File file, final String description)
|
||||
throws SmackException {
|
||||
checkTransferThread();
|
||||
if (file == null || !file.exists() || !file.canRead()) {
|
||||
throw new IllegalArgumentException("Could not read file");
|
||||
} else {
|
||||
setFileInfo(file.getAbsolutePath(), file.getName(), file.length());
|
||||
}
|
||||
* @throws SmackException
|
||||
* If there is an error during the negotiation process or the
|
||||
* sending of the file.
|
||||
*/
|
||||
public synchronized void sendFile(final File file, final String description)
|
||||
throws SmackException {
|
||||
checkTransferThread();
|
||||
if (file == null || !file.exists() || !file.canRead()) {
|
||||
throw new IllegalArgumentException("Could not read file");
|
||||
} else {
|
||||
setFileInfo(file.getAbsolutePath(), file.getName(), file.length());
|
||||
}
|
||||
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
outputStream = negotiateStream(file.getName(), file
|
||||
.length(), description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
transferThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
outputStream = negotiateStream(file.getName(), file
|
||||
.length(), description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!updateStatus(Status.negotiated, Status.in_progress)) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
writeToStream(inputStream, outputStream);
|
||||
} catch (FileNotFoundException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setError(Error.bad_file);
|
||||
setException(e);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(file);
|
||||
writeToStream(inputStream, outputStream);
|
||||
} catch (FileNotFoundException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setError(Error.bad_file);
|
||||
setException(e);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.WARNING, "Closing input stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.WARNING, "Closing output stream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
updateStatus(Status.in_progress, FileTransfer.Status.complete);
|
||||
}
|
||||
}
|
||||
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* This method handles the stream negotiation process and transmits the file
|
||||
* to the remote user. It returns immediately and the progress of the file
|
||||
* transfer can be monitored through several methods:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>{@link FileTransfer#getStatus()}
|
||||
* <LI>{@link FileTransfer#getProgress()}
|
||||
* <LI>{@link FileTransfer#isDone()}
|
||||
* </UL>
|
||||
*
|
||||
* @param in the stream to transfer to the remote entity.
|
||||
* @param fileName the name of the file that is transferred
|
||||
* @param fileSize the size of the file that is transferred
|
||||
* @param description a description for the file to transfer.
|
||||
*/
|
||||
public synchronized void sendStream(final InputStream in, final String fileName, final long fileSize, final String description){
|
||||
checkTransferThread();
|
||||
*/
|
||||
public synchronized void sendStream(final InputStream in, final String fileName, final long fileSize, final String description){
|
||||
checkTransferThread();
|
||||
|
||||
setFileInfo(fileName, fileSize);
|
||||
transferThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
setFileInfo(fileName, fileSize);
|
||||
transferThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Create packet filter
|
||||
try {
|
||||
outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
outputStream = negotiateStream(fileName, fileSize, description);
|
||||
} catch (XMPPErrorException e) {
|
||||
handleXMPPException(e);
|
||||
return;
|
||||
}
|
||||
catch (Exception e) {
|
||||
setException(e);
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
if (outputStream == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!updateStatus(Status.negotiated, Status.in_progress)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
writeToStream(in, outputStream);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
writeToStream(in, outputStream);
|
||||
} catch (IOException e) {
|
||||
setStatus(FileTransfer.Status.error);
|
||||
setException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
/* Do Nothing */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
updateStatus(Status.in_progress, FileTransfer.Status.complete);
|
||||
}
|
||||
}
|
||||
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
}, "File Transfer " + streamID);
|
||||
transferThread.start();
|
||||
}
|
||||
|
||||
private void handleXMPPException(XMPPErrorException e) {
|
||||
XMPPError error = e.getXMPPError();
|
||||
if (error != null) {
|
||||
switch (error.getCondition()) {
|
||||
case forbidden:
|
||||
setStatus(Status.refused);
|
||||
return;
|
||||
case bad_request:
|
||||
setStatus(Status.error);
|
||||
setError(Error.not_acceptable);
|
||||
break;
|
||||
private void handleXMPPException(XMPPErrorException e) {
|
||||
XMPPError error = e.getXMPPError();
|
||||
if (error != null) {
|
||||
switch (error.getCondition()) {
|
||||
case forbidden:
|
||||
setStatus(Status.refused);
|
||||
return;
|
||||
case bad_request:
|
||||
setStatus(Status.error);
|
||||
setError(Error.not_acceptable);
|
||||
break;
|
||||
default:
|
||||
setStatus(FileTransfer.Status.error);
|
||||
}
|
||||
}
|
||||
|
||||
setException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of bytes that have been sent for the file transfer. Or
|
||||
* -1 if the file transfer has not started.
|
||||
* <p>
|
||||
* Note: This method is only useful when the {@link #sendFile(File, String)}
|
||||
* method is called, as it is the only method that actually transmits the
|
||||
* file.
|
||||
*
|
||||
* @return Returns the amount of bytes that have been sent for the file
|
||||
* transfer. Or -1 if the file transfer has not started.
|
||||
*/
|
||||
public long getBytesSent() {
|
||||
return amountWritten;
|
||||
}
|
||||
/**
|
||||
* Returns the amount of bytes that have been sent for the file transfer. Or
|
||||
* -1 if the file transfer has not started.
|
||||
* <p>
|
||||
* Note: This method is only useful when the {@link #sendFile(File, String)}
|
||||
* method is called, as it is the only method that actually transmits the
|
||||
* file.
|
||||
*
|
||||
* @return Returns the amount of bytes that have been sent for the file
|
||||
* transfer. Or -1 if the file transfer has not started.
|
||||
*/
|
||||
public long getBytesSent() {
|
||||
return amountWritten;
|
||||
}
|
||||
|
||||
private OutputStream negotiateStream(String fileName, long fileSize,
|
||||
String description) throws SmackException, XMPPException, InterruptedException {
|
||||
// Negotiate the file transfer profile
|
||||
private OutputStream negotiateStream(String fileName, long fileSize,
|
||||
String description) throws SmackException, XMPPException, InterruptedException {
|
||||
// Negotiate the file transfer profile
|
||||
|
||||
if (!updateStatus(Status.initial, Status.negotiating_transfer)) {
|
||||
throw new IllegalStateChangeException();
|
||||
}
|
||||
StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer(
|
||||
getPeer(), streamID, fileName, fileSize, description,
|
||||
RESPONSE_TIMEOUT);
|
||||
StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer(
|
||||
getPeer(), streamID, fileName, fileSize, description,
|
||||
RESPONSE_TIMEOUT);
|
||||
|
||||
// Negotiate the stream
|
||||
if (!updateStatus(Status.negotiating_transfer, Status.negotiating_stream)) {
|
||||
throw new IllegalStateChangeException();
|
||||
}
|
||||
outputStream = streamNegotiator.createOutgoingStream(streamID,
|
||||
outputStream = streamNegotiator.createOutgoingStream(streamID,
|
||||
initiator, getPeer());
|
||||
|
||||
if (!updateStatus(Status.negotiating_stream, Status.negotiated)) {
|
||||
throw new IllegalStateChangeException();
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setStatus(Status.cancelled);
|
||||
}
|
||||
@Override
|
||||
public void cancel() {
|
||||
setStatus(Status.cancelled);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateStatus(Status oldStatus, Status newStatus) {
|
||||
|
@ -429,30 +433,30 @@ public class OutgoingFileTransfer extends FileTransfer {
|
|||
}
|
||||
|
||||
/**
|
||||
* A callback class to retrieve the status of an outgoing transfer
|
||||
* negotiation process.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public interface NegotiationProgress {
|
||||
* A callback class to retrieve the status of an outgoing transfer
|
||||
* negotiation process.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public interface NegotiationProgress {
|
||||
|
||||
/**
|
||||
* Called when the status changes.
|
||||
/**
|
||||
* Called when the status changes.
|
||||
*
|
||||
* @param oldStatus the previous status of the file transfer.
|
||||
* @param newStatus the new status of the file transfer.
|
||||
*/
|
||||
void statusUpdated(Status oldStatus, Status newStatus);
|
||||
void statusUpdated(Status oldStatus, Status newStatus);
|
||||
|
||||
/**
|
||||
* Once the negotiation process is completed the output stream can be
|
||||
* retrieved.
|
||||
/**
|
||||
* Once the negotiation process is completed the output stream can be
|
||||
* retrieved.
|
||||
*
|
||||
* @param stream the established stream which can be used to transfer the file to the remote
|
||||
* entity
|
||||
*/
|
||||
void outputStreamEstablished(OutputStream stream);
|
||||
*/
|
||||
void outputStreamEstablished(OutputStream stream);
|
||||
|
||||
/**
|
||||
* Called when an exception occurs during the negotiation progress.
|
||||
|
|
|
@ -34,6 +34,7 @@ public final class GeoLocationManager extends Manager {
|
|||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
|
|
|
@ -108,6 +108,7 @@ public final class LastActivityManager extends Manager {
|
|||
// Enable the LastActivity support on every established connection
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
LastActivityManager.getInstanceFor(connection);
|
||||
}
|
||||
|
@ -135,6 +136,7 @@ public final class LastActivityManager extends Manager {
|
|||
|
||||
// Listen to all the sent messages to reset the idle time on each one
|
||||
connection.addPacketSendingListener(new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
Presence presence = (Presence) packet;
|
||||
Presence.Mode mode = presence.getMode();
|
||||
|
|
|
@ -66,6 +66,7 @@ public class DefaultPrivateData implements PrivateData {
|
|||
*
|
||||
* @return the XML element name of the stanza(/packet) extension.
|
||||
*/
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return elementName;
|
||||
}
|
||||
|
@ -75,10 +76,12 @@ public class DefaultPrivateData implements PrivateData {
|
|||
*
|
||||
* @return the XML namespace of the stanza(/packet) extension.
|
||||
*/
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('<').append(elementName).append(" xmlns=\"").append(namespace).append("\">");
|
||||
|
|
|
@ -71,6 +71,6 @@ public class RegistrationProvider extends IQProvider<Registration> {
|
|||
Registration registration = new Registration(instruction, fields);
|
||||
registration.addExtensions(packetExtensions);
|
||||
return registration;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ public final class VersionManager extends Manager {
|
|||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
VersionManager.getInstanceFor(connection);
|
||||
}
|
||||
|
|
|
@ -32,48 +32,63 @@ import org.jxmpp.jid.parts.Resourcepart;
|
|||
*/
|
||||
public class DefaultParticipantStatusListener implements ParticipantStatusListener {
|
||||
|
||||
@Override
|
||||
public void joined(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void left(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kicked(EntityFullJid participant, Jid actor, String reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voiceGranted(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voiceRevoked(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void banned(EntityFullJid participant, Jid actor, String reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipGranted(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipRevoked(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorGranted(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorRevoked(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipGranted(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipRevoked(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminGranted(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminRevoked(EntityFullJid participant) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nicknameChanged(EntityFullJid participant, Resourcepart newNickname) {
|
||||
}
|
||||
|
||||
|
|
|
@ -30,42 +30,55 @@ import org.jxmpp.jid.Jid;
|
|||
*/
|
||||
public class DefaultUserStatusListener implements UserStatusListener {
|
||||
|
||||
@Override
|
||||
public void kicked(Jid actor, String reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voiceGranted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void voiceRevoked() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void banned(Jid actor, String reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipGranted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void membershipRevoked() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorGranted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moderatorRevoked() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipGranted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ownershipRevoked() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminGranted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adminRevoked() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void roomDestroyed(MultiUserChat alternateMUC, String reason) {
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.jivesoftware.smackx.muc;
|
|||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCUser;
|
||||
import org.jxmpp.jid.EntityFullJid;
|
||||
import org.jxmpp.jid.EntityJid;
|
||||
|
||||
/**
|
||||
* A listener that is fired anytime an invitation to join a MUC room is received.
|
||||
|
@ -43,7 +43,7 @@ public interface InvitationListener {
|
|||
* @param message the message used by the inviter to send the invitation.
|
||||
* @param invitation the raw invitation received with the message.
|
||||
*/
|
||||
public abstract void invitationReceived(XMPPConnection conn, MultiUserChat room, EntityFullJid inviter, String reason,
|
||||
public abstract void invitationReceived(XMPPConnection conn, MultiUserChat room, EntityJid inviter, String reason,
|
||||
String password, Message message, MUCUser.Invite invitation);
|
||||
|
||||
}
|
||||
|
|
|
@ -95,15 +95,16 @@ public final class MucEnterConfiguration {
|
|||
/**
|
||||
* Set the presence used to join the MUC room.
|
||||
* <p>
|
||||
* The 'to' value of the given presence will be overridden.
|
||||
* The 'to' value of the given presence will be overridden and the given presence must be of type
|
||||
* 'available', otherwise an {@link IllegalArgumentException} will be thrown.
|
||||
* <p>
|
||||
*
|
||||
* @param presence
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public Builder withPresence(Presence presence) {
|
||||
if (presence.getType() == Presence.Type.available) {
|
||||
throw new IllegalArgumentException();
|
||||
if (presence.getType() != Presence.Type.available) {
|
||||
throw new IllegalArgumentException("Presence must be of type 'available'");
|
||||
}
|
||||
|
||||
joinPresence = presence;
|
||||
|
|
|
@ -46,7 +46,7 @@ import org.jivesoftware.smack.filter.NotFilter;
|
|||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
||||
import org.jivesoftware.smack.filter.ToFilter;
|
||||
import org.jivesoftware.smack.filter.ToMatchesFilter;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
|
@ -163,6 +163,7 @@ public class MultiUserChat {
|
|||
|
||||
// Create a listener for subject updates.
|
||||
subjectListener = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
Message msg = (Message) packet;
|
||||
EntityFullJid from = msg.getFrom().asEntityFullJidIfPossible();
|
||||
|
@ -181,6 +182,7 @@ public class MultiUserChat {
|
|||
|
||||
// Create a listener for all presence updates.
|
||||
presenceListener = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
Presence presence = (Presence) packet;
|
||||
final EntityFullJid from = presence.getFrom().asEntityFullJidIfPossible();
|
||||
|
@ -251,6 +253,7 @@ public class MultiUserChat {
|
|||
// Listens for all messages that include a MUCUser extension and fire the invitation
|
||||
// rejection listeners if the message includes an invitation rejection.
|
||||
declinesListener = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
Message message = (Message) packet;
|
||||
// Get the MUC User extension
|
||||
|
@ -319,7 +322,7 @@ public class MultiUserChat {
|
|||
connection.addSyncStanzaListener(subjectListener, new AndFilter(fromRoomFilter,
|
||||
MessageWithSubjectFilter.INSTANCE, new NotFilter(MessageTypeFilter.ERROR)));
|
||||
connection.addSyncStanzaListener(declinesListener, DECLINE_FILTER);
|
||||
connection.addPacketInterceptor(presenceInterceptor, new AndFilter(new ToFilter(room),
|
||||
connection.addPacketInterceptor(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room),
|
||||
StanzaTypeFilter.PRESENCE));
|
||||
messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter);
|
||||
|
||||
|
@ -331,7 +334,7 @@ public class MultiUserChat {
|
|||
try {
|
||||
presence = connection.createStanzaCollectorAndSend(responseFilter, joinPresence).nextResultOrThrow(conf.getTimeout());
|
||||
}
|
||||
catch (InterruptedException | NoResponseException | XMPPErrorException e) {
|
||||
catch (NotConnectedException | InterruptedException | NoResponseException | XMPPErrorException e) {
|
||||
// Ensure that all callbacks are removed if there is an exception
|
||||
removeConnectionCallbacks();
|
||||
throw e;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2014-2016 Florian Schmaus
|
||||
* Copyright © 2014-2017 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -55,7 +55,6 @@ import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceExceptio
|
|||
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCUser;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.EntityFullJid;
|
||||
import org.jxmpp.jid.DomainBareJid;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
|
@ -83,6 +82,7 @@ public final class MultiUserChatManager extends Manager {
|
|||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(final XMPPConnection connection) {
|
||||
// Set on every established connection that this client supports the Multi-User
|
||||
// Chat protocol. This information will be used when another client tries to
|
||||
|
@ -150,6 +150,7 @@ public final class MultiUserChatManager extends Manager {
|
|||
// Listens for all messages that include a MUCUser extension and fire the invitation
|
||||
// listeners if the message includes an invitation.
|
||||
StanzaListener invitationPacketListener = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
final Message message = (Message) packet;
|
||||
// Get the MUCUser extension
|
||||
|
@ -165,7 +166,7 @@ public final class MultiUserChatManager extends Manager {
|
|||
final MultiUserChat muc = getMultiUserChat(mucJid);
|
||||
final XMPPConnection connection = connection();
|
||||
final MUCUser.Invite invite = mucUser.getInvite();
|
||||
final EntityFullJid from = invite.getFrom();
|
||||
final EntityJid from = invite.getFrom();
|
||||
final String reason = invite.getReason();
|
||||
final String password = mucUser.getPassword();
|
||||
for (final InvitationListener listener : invitationsListeners) {
|
||||
|
|
|
@ -110,6 +110,7 @@ public class Occupant {
|
|||
return nick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof Occupant)) {
|
||||
return false;
|
||||
|
@ -118,6 +119,7 @@ public class Occupant {
|
|||
return jid.equals(occupant.jid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = affiliation.hashCode();
|
||||
|
|
|
@ -92,10 +92,12 @@ public class GroupChatInvitation implements ExtensionElement {
|
|||
return roomAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
|
|
@ -72,10 +72,12 @@ public class MUCInitialPresence implements ExtensionElement {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
@ -282,6 +284,7 @@ public class MUCInitialPresence implements ExtensionElement {
|
|||
this.since = since;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||
xml.optIntAttribute("maxchars", getMaxChars());
|
||||
|
|
|
@ -158,6 +158,7 @@ public class MUCItem implements NamedElement {
|
|||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||
xml.optAttribute("affiliation", getAffiliation());
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.jivesoftware.smack.packet.ExtensionElement;
|
|||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.EntityFullJid;
|
||||
import org.jxmpp.jid.EntityJid;
|
||||
|
||||
/**
|
||||
* Represents extended presence information about roles, affiliations, full JIDs,
|
||||
|
@ -49,10 +50,12 @@ public class MUCUser implements ExtensionElement {
|
|||
private String password;
|
||||
private Destroy destroy;
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
@ -247,7 +250,12 @@ public class MUCUser implements ExtensionElement {
|
|||
public static final String ELEMENT ="invite";
|
||||
|
||||
private final String reason;
|
||||
private final EntityFullJid from;
|
||||
|
||||
/**
|
||||
* From XEP-0045 § 7.8.2: "… whose value is the bare JID, full JID, or occupant JID of the inviter …"
|
||||
*/
|
||||
private final EntityJid from;
|
||||
|
||||
private final EntityBareJid to;
|
||||
|
||||
public Invite(String reason, EntityFullJid from) {
|
||||
|
@ -258,7 +266,7 @@ public class MUCUser implements ExtensionElement {
|
|||
this(reason, null, to);
|
||||
}
|
||||
|
||||
public Invite(String reason, EntityFullJid from, EntityBareJid to) {
|
||||
public Invite(String reason, EntityJid from, EntityBareJid to) {
|
||||
this.reason = reason;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
|
@ -270,7 +278,7 @@ public class MUCUser implements ExtensionElement {
|
|||
*
|
||||
* @return the room's occupant that sent the invitation.
|
||||
*/
|
||||
public EntityFullJid getFrom() {
|
||||
public EntityJid getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
|||
import org.jivesoftware.smack.util.ParserUtils;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCUser;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.EntityFullJid;
|
||||
import org.jxmpp.jid.EntityJid;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
|
@ -86,7 +86,7 @@ public class MUCUserProvider extends ExtensionElementProvider<MUCUser> {
|
|||
private static MUCUser.Invite parseInvite(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
String reason = null;
|
||||
EntityBareJid to = ParserUtils.getBareJidAttribute(parser, "to");
|
||||
EntityFullJid from = ParserUtils.getFullJidAttribute(parser, "from");
|
||||
EntityJid from = ParserUtils.getEntityJidAttribute(parser, "from");
|
||||
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
|
|
|
@ -31,77 +31,80 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||
*/
|
||||
public class Nick implements ExtensionElement {
|
||||
|
||||
public static final String NAMESPACE = "http://jabber.org/protocol/nick";
|
||||
public static final String NAMESPACE = "http://jabber.org/protocol/nick";
|
||||
|
||||
public static final String ELEMENT_NAME = "nick";
|
||||
public static final String ELEMENT_NAME = "nick";
|
||||
|
||||
private String name = null;
|
||||
private String name = null;
|
||||
|
||||
public Nick(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public Nick(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of this nickname.
|
||||
*
|
||||
* @return the nickname
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* The value of this nickname.
|
||||
*
|
||||
* @return the nickname
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this nickname.
|
||||
*
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* Sets the value of this nickname.
|
||||
*
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
|
||||
*/
|
||||
public String getElementName() {
|
||||
return ELEMENT_NAME;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
|
||||
*/
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT_NAME;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
|
||||
*/
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
|
||||
*/
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#toXML()
|
||||
*/
|
||||
public String toXML() {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.packet.PacketExtension#toXML()
|
||||
*/
|
||||
@Override
|
||||
public String toXML() {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
|
||||
buf.append('<').append(ELEMENT_NAME).append(" xmlns=\"").append(
|
||||
NAMESPACE).append("\">");
|
||||
buf.append(getName());
|
||||
buf.append("</").append(ELEMENT_NAME).append('>');
|
||||
buf.append('<').append(ELEMENT_NAME).append(" xmlns=\"").append(
|
||||
NAMESPACE).append("\">");
|
||||
buf.append(getName());
|
||||
buf.append("</").append(ELEMENT_NAME).append('>');
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static class Provider extends ExtensionElementProvider<Nick> {
|
||||
public static class Provider extends ExtensionElementProvider<Nick> {
|
||||
|
||||
@Override
|
||||
public Nick parse(XmlPullParser parser, int initialDepth)
|
||||
throws XmlPullParserException, IOException {
|
||||
final String name = parser.nextText();
|
||||
final String name = parser.nextText();
|
||||
|
||||
return new Nick(name);
|
||||
}
|
||||
}
|
||||
return new Nick(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,6 +152,7 @@ public class OfflineMessageManager {
|
|||
}
|
||||
// Filter offline messages that were requested by this request
|
||||
StanzaFilter messageFilter = new AndFilter(PACKET_FILTER, new StanzaFilter() {
|
||||
@Override
|
||||
public boolean accept(Stanza packet) {
|
||||
OfflineMessageInfo info = (OfflineMessageInfo) packet.getExtension("offline",
|
||||
namespace);
|
||||
|
|
|
@ -42,6 +42,7 @@ public class OfflineMessageInfo implements ExtensionElement {
|
|||
*
|
||||
* @return the XML element name of the stanza(/packet) extension.
|
||||
*/
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return "offline";
|
||||
}
|
||||
|
@ -52,6 +53,7 @@ public class OfflineMessageInfo implements ExtensionElement {
|
|||
*
|
||||
* @return the XML namespace of the stanza(/packet) extension.
|
||||
*/
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return "http://jabber.org/protocol/offline";
|
||||
}
|
||||
|
@ -78,6 +80,7 @@ public class OfflineMessageInfo implements ExtensionElement {
|
|||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append('<').append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
|
||||
|
|
|
@ -91,6 +91,7 @@ public final class PEPManager extends Manager {
|
|||
private PEPManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
StanzaListener packetListener = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza stanza) {
|
||||
Message message = (Message) stanza;
|
||||
EventElement event = EventElement.from(stanza);
|
||||
|
|
|
@ -67,6 +67,7 @@ public final class PingManager extends Manager {
|
|||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
|
@ -402,6 +403,7 @@ public final class PingManager extends Manager {
|
|||
}
|
||||
|
||||
private final Runnable pingServerRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOGGER.fine("ServerPingTask run()");
|
||||
pingServerIfNecessary();
|
||||
|
|
|
@ -78,6 +78,7 @@ public final class PrivacyListManager extends Manager {
|
|||
static {
|
||||
// Create a new PrivacyListManager on every established connection.
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
|
@ -95,7 +96,7 @@ public final class PrivacyListManager extends Manager {
|
|||
*
|
||||
* @param connection the XMPP connection.
|
||||
*/
|
||||
private PrivacyListManager(XMPPConnection connection) {
|
||||
private PrivacyListManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
|
||||
connection.registerIQRequestHandler(new AbstractIqRequestHandler(Privacy.ELEMENT, Privacy.NAMESPACE,
|
||||
|
@ -215,24 +216,24 @@ public final class PrivacyListManager extends Manager {
|
|||
return plm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the {@link Privacy} stanza(/packet) to the server in order to know some privacy content and then
|
||||
* waits for the answer.
|
||||
*
|
||||
* @param requestPrivacy is the {@link Privacy} stanza(/packet) configured properly whose XML
|
||||
/**
|
||||
* Send the {@link Privacy} stanza(/packet) to the server in order to know some privacy content and then
|
||||
* waits for the answer.
|
||||
*
|
||||
* @param requestPrivacy is the {@link Privacy} stanza(/packet) configured properly whose XML
|
||||
* will be sent to the server.
|
||||
* @return a new {@link Privacy} with the data received from the server.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getRequest(Privacy requestPrivacy) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request is a get iq type
|
||||
requestPrivacy.setType(Privacy.Type.get);
|
||||
* @return a new {@link Privacy} with the data received from the server.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getRequest(Privacy requestPrivacy) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request is a get iq type
|
||||
requestPrivacy.setType(Privacy.Type.get);
|
||||
|
||||
return connection().createStanzaCollectorAndSend(requestPrivacy).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the {@link Privacy} stanza(/packet) to the server in order to modify the server privacy and waits
|
||||
|
@ -253,22 +254,22 @@ public final class PrivacyListManager extends Manager {
|
|||
return connection().createStanzaCollectorAndSend(requestPrivacy).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer a privacy containing the list structure without {@link PrivacyItem}.
|
||||
*
|
||||
* @return a Privacy with the list names.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getPrivacyWithListNames() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an empty privacy message
|
||||
Privacy request = new Privacy();
|
||||
/**
|
||||
* Answer a privacy containing the list structure without {@link PrivacyItem}.
|
||||
*
|
||||
* @return a Privacy with the list names.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private Privacy getPrivacyWithListNames() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an empty privacy message
|
||||
Privacy request = new Privacy();
|
||||
|
||||
// Send the package to the server and get the answer
|
||||
return getRequest(request);
|
||||
}
|
||||
// Send the package to the server and get the answer
|
||||
return getRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer the active privacy list. Returns <code>null</code> if there is no active list.
|
||||
|
@ -386,20 +387,20 @@ public final class PrivacyListManager extends Manager {
|
|||
return privacyAnswer.getPrivacyList(listName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer the privacy list items under listName with the allowed and blocked permissions.
|
||||
*
|
||||
* @param listName the name of the list to get the allowed and blocked permissions.
|
||||
* @return a privacy list under the list listName.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public PrivacyList getPrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
/**
|
||||
* Answer the privacy list items under listName with the allowed and blocked permissions.
|
||||
*
|
||||
* @param listName the name of the list to get the allowed and blocked permissions.
|
||||
* @return a privacy list under the list listName.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public PrivacyList getPrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
listName = StringUtils.requireNotNullOrEmpty(listName, "List name must not be null");
|
||||
return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer every privacy list with the allowed and blocked permissions.
|
||||
|
@ -423,87 +424,87 @@ public final class PrivacyListManager extends Manager {
|
|||
return lists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or change the active list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the active one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setActiveListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setActiveName(listName);
|
||||
/**
|
||||
* Set or change the active list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the active one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setActiveListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setActiveName(listName);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client declines the use of active lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineActiveList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineActiveList(true);
|
||||
/**
|
||||
* Client declines the use of active lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineActiveList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineActiveList(true);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or change the default list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the default one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setDefaultListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDefaultName(listName);
|
||||
/**
|
||||
* Set or change the default list to listName.
|
||||
*
|
||||
* @param listName the list name to set as the default one.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void setDefaultListName(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDefaultName(listName);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client declines the use of default lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineDefaultList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineDefaultList(true);
|
||||
/**
|
||||
* Client declines the use of default lists.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void declineDefaultList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setDeclineDefaultList(true);
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* The client has created a new list. It send the new one to the server.
|
||||
*
|
||||
/**
|
||||
* The client has created a new list. It send the new one to the server.
|
||||
*
|
||||
* @param listName the list that has changed its content.
|
||||
* @param privacyItems a List with every privacy item in the list.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
updatePrivacyList(listName, privacyItems);
|
||||
}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void createPrivacyList(String listName, List<PrivacyItem> privacyItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
updatePrivacyList(listName, privacyItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* The client has edited an existing list. It updates the server content with the resulting
|
||||
|
@ -526,23 +527,23 @@ public final class PrivacyListManager extends Manager {
|
|||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a privacy list.
|
||||
*
|
||||
/**
|
||||
* Remove a privacy list.
|
||||
*
|
||||
* @param listName the list that has changed its content.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deletePrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deletePrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// The request of the list is an privacy message with an empty list
|
||||
Privacy request = new Privacy();
|
||||
request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
|
||||
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
// Send the package to the server
|
||||
setRequest(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a privacy list listener that will be notified of any new update in the user
|
||||
|
|
|
@ -45,17 +45,17 @@ public class Privacy extends IQ {
|
|||
public static final String ELEMENT = QUERY_ELEMENT;
|
||||
public static final String NAMESPACE = "jabber:iq:privacy";
|
||||
|
||||
/** declineActiveList is true when the user declines the use of the active list **/
|
||||
private boolean declineActiveList=false;
|
||||
/** activeName is the name associated with the active list set for the session **/
|
||||
private String activeName;
|
||||
/** declineDefaultList is true when the user declines the use of the default list **/
|
||||
private boolean declineDefaultList=false;
|
||||
/** defaultName is the name of the default list that applies to the user as a whole **/
|
||||
private String defaultName;
|
||||
/** itemLists holds the set of privacy items classified in lists. It is a map where the
|
||||
* key is the name of the list and the value a collection with privacy items. **/
|
||||
private Map<String, List<PrivacyItem>> itemLists = new HashMap<String, List<PrivacyItem>>();
|
||||
/** declineActiveList is true when the user declines the use of the active list **/
|
||||
private boolean declineActiveList=false;
|
||||
/** activeName is the name associated with the active list set for the session **/
|
||||
private String activeName;
|
||||
/** declineDefaultList is true when the user declines the use of the default list **/
|
||||
private boolean declineDefaultList=false;
|
||||
/** defaultName is the name of the default list that applies to the user as a whole **/
|
||||
private String defaultName;
|
||||
/** itemLists holds the set of privacy items classified in lists. It is a map where the
|
||||
* key is the name of the list and the value a collection with privacy items. **/
|
||||
private Map<String, List<PrivacyItem>> itemLists = new HashMap<String, List<PrivacyItem>>();
|
||||
|
||||
public Privacy() {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
|
@ -94,13 +94,13 @@ public class Privacy extends IQ {
|
|||
public void deletePrivacyList(String listName) {
|
||||
// Remove the list from the cache
|
||||
// CHECKSTYLE:OFF
|
||||
this.getItemLists().remove(listName);
|
||||
this.getItemLists().remove(listName);
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
// Check if deleted list was the default list
|
||||
if (this.getDefaultName() != null && listName.equals(this.getDefaultName())) {
|
||||
// CHECKSTYLE:OFF
|
||||
this.setDefaultName(null);
|
||||
this.setDefaultName(null);
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
|
@ -114,9 +114,9 @@ public class Privacy extends IQ {
|
|||
// Check if we have the default list
|
||||
// CHECKSTYLE:OFF
|
||||
if (this.getActiveName() == null) {
|
||||
return null;
|
||||
return null;
|
||||
} else {
|
||||
return this.getItemLists().get(this.getActiveName());
|
||||
return this.getItemLists().get(this.getActiveName());
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
@ -130,9 +130,9 @@ public class Privacy extends IQ {
|
|||
// Check if we have the default list
|
||||
// CHECKSTYLE:OFF
|
||||
if (this.getDefaultName() == null) {
|
||||
return null;
|
||||
return null;
|
||||
} else {
|
||||
return this.getItemLists().get(this.getDefaultName());
|
||||
return this.getItemLists().get(this.getDefaultName());
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
@ -156,15 +156,15 @@ public class Privacy extends IQ {
|
|||
*/
|
||||
public PrivacyItem getItem(String listName, int order) {
|
||||
// CHECKSTYLE:OFF
|
||||
Iterator<PrivacyItem> values = getPrivacyList(listName).iterator();
|
||||
PrivacyItem itemFound = null;
|
||||
while (itemFound == null && values.hasNext()) {
|
||||
PrivacyItem element = values.next();
|
||||
if (element.getOrder() == order) {
|
||||
itemFound = element;
|
||||
}
|
||||
}
|
||||
return itemFound;
|
||||
Iterator<PrivacyItem> values = getPrivacyList(listName).iterator();
|
||||
PrivacyItem itemFound = null;
|
||||
while (itemFound == null && values.hasNext()) {
|
||||
PrivacyItem element = values.next();
|
||||
if (element.getOrder() == order) {
|
||||
itemFound = element;
|
||||
}
|
||||
}
|
||||
return itemFound;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ public class Privacy extends IQ {
|
|||
return true;
|
||||
} else {
|
||||
// CHECKSTYLE:OFF
|
||||
return false;
|
||||
return false;
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public class Privacy extends IQ {
|
|||
*/
|
||||
public void deleteList(String listName) {
|
||||
// CHECKSTYLE:OFF
|
||||
this.getItemLists().remove(listName);
|
||||
this.getItemLists().remove(listName);
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
|
||||
|
@ -203,9 +203,9 @@ public class Privacy extends IQ {
|
|||
* @return the name of the active list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public String getActiveName() {
|
||||
return activeName;
|
||||
}
|
||||
public String getActiveName() {
|
||||
return activeName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -215,9 +215,9 @@ public class Privacy extends IQ {
|
|||
* @param activeName is the name of the active list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setActiveName(String activeName) {
|
||||
this.activeName = activeName;
|
||||
}
|
||||
public void setActiveName(String activeName) {
|
||||
this.activeName = activeName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -228,9 +228,9 @@ public class Privacy extends IQ {
|
|||
* @return the name of the default list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public String getDefaultName() {
|
||||
return defaultName;
|
||||
}
|
||||
public String getDefaultName() {
|
||||
return defaultName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -243,9 +243,9 @@ public class Privacy extends IQ {
|
|||
* @param defaultName is the name of the default list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setDefaultName(String defaultName) {
|
||||
this.defaultName = defaultName;
|
||||
}
|
||||
public void setDefaultName(String defaultName) {
|
||||
this.defaultName = defaultName;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -257,9 +257,9 @@ public class Privacy extends IQ {
|
|||
* collection of privacy items.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public Map<String, List<PrivacyItem>> getItemLists() {
|
||||
return itemLists;
|
||||
}
|
||||
public Map<String, List<PrivacyItem>> getItemLists() {
|
||||
return itemLists;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -268,9 +268,9 @@ public class Privacy extends IQ {
|
|||
* @return the decline status of the list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public boolean isDeclineActiveList() {
|
||||
return declineActiveList;
|
||||
}
|
||||
public boolean isDeclineActiveList() {
|
||||
return declineActiveList;
|
||||
}
|
||||
// CHECKSYTLE:ON
|
||||
|
||||
/**
|
||||
|
@ -279,9 +279,9 @@ public class Privacy extends IQ {
|
|||
* @param declineActiveList indicates if the receiver declines the use of an active list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setDeclineActiveList(boolean declineActiveList) {
|
||||
this.declineActiveList = declineActiveList;
|
||||
}
|
||||
public void setDeclineActiveList(boolean declineActiveList) {
|
||||
this.declineActiveList = declineActiveList;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -290,9 +290,9 @@ public class Privacy extends IQ {
|
|||
* @return the decline status of the list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public boolean isDeclineDefaultList() {
|
||||
return declineDefaultList;
|
||||
}
|
||||
public boolean isDeclineDefaultList() {
|
||||
return declineDefaultList;
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
/**
|
||||
|
@ -301,18 +301,18 @@ public class Privacy extends IQ {
|
|||
* @param declineDefaultList indicates if the receiver declines the use of a default list.
|
||||
*/
|
||||
// CHECKSTYLE:OFF
|
||||
public void setDeclineDefaultList(boolean declineDefaultList) {
|
||||
this.declineDefaultList = declineDefaultList;
|
||||
}
|
||||
public void setDeclineDefaultList(boolean declineDefaultList) {
|
||||
this.declineDefaultList = declineDefaultList;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns all the list names the user has defined to group restrictions.
|
||||
*
|
||||
* @return a Set with Strings containing every list names.
|
||||
*/
|
||||
public Set<String> getPrivacyListNames() {
|
||||
return this.itemLists.keySet();
|
||||
}
|
||||
public Set<String> getPrivacyListNames() {
|
||||
return this.itemLists.keySet();
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
@Override
|
||||
|
@ -322,40 +322,40 @@ public class Privacy extends IQ {
|
|||
|
||||
// Add the active tag
|
||||
if (this.isDeclineActiveList()) {
|
||||
buf.append("<active/>");
|
||||
buf.append("<active/>");
|
||||
} else {
|
||||
if (this.getActiveName() != null) {
|
||||
if (this.getActiveName() != null) {
|
||||
buf.append("<active name=\"").escape(getActiveName()).append("\"/>");
|
||||
}
|
||||
}
|
||||
// Add the default tag
|
||||
if (this.isDeclineDefaultList()) {
|
||||
buf.append("<default/>");
|
||||
buf.append("<default/>");
|
||||
} else {
|
||||
if (this.getDefaultName() != null) {
|
||||
if (this.getDefaultName() != null) {
|
||||
buf.append("<default name=\"").escape(getDefaultName()).append("\"/>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the list with their privacy items
|
||||
for (Map.Entry<String, List<PrivacyItem>> entry : this.getItemLists().entrySet()) {
|
||||
String listName = entry.getKey();
|
||||
List<PrivacyItem> items = entry.getValue();
|
||||
// Begin the list tag
|
||||
if (items.isEmpty()) {
|
||||
// Begin the list tag
|
||||
if (items.isEmpty()) {
|
||||
buf.append("<list name=\"").escape(listName).append("\"/>");
|
||||
} else {
|
||||
} else {
|
||||
buf.append("<list name=\"").escape(listName).append("\">");
|
||||
}
|
||||
for (PrivacyItem item : items) {
|
||||
// Append the item xml representation
|
||||
buf.append(item.toXML());
|
||||
}
|
||||
// Close the list tag
|
||||
if (!items.isEmpty()) {
|
||||
buf.append("</list>");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PrivacyItem item : items) {
|
||||
// Append the item xml representation
|
||||
buf.append(item.toXML());
|
||||
}
|
||||
// Close the list tag
|
||||
if (!items.isEmpty()) {
|
||||
buf.append("</list>");
|
||||
}
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -47,20 +47,20 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
if (eventType == XmlPullParser.START_TAG) {
|
||||
// CHECKSTYLE:OFF
|
||||
if (parser.getName().equals("active")) {
|
||||
String activeName = parser.getAttributeValue("", "name");
|
||||
if (activeName == null) {
|
||||
privacy.setDeclineActiveList(true);
|
||||
} else {
|
||||
privacy.setActiveName(activeName);
|
||||
}
|
||||
String activeName = parser.getAttributeValue("", "name");
|
||||
if (activeName == null) {
|
||||
privacy.setDeclineActiveList(true);
|
||||
} else {
|
||||
privacy.setActiveName(activeName);
|
||||
}
|
||||
}
|
||||
else if (parser.getName().equals("default")) {
|
||||
String defaultName = parser.getAttributeValue("", "name");
|
||||
if (defaultName == null) {
|
||||
privacy.setDeclineDefaultList(true);
|
||||
} else {
|
||||
privacy.setDefaultName(defaultName);
|
||||
}
|
||||
String defaultName = parser.getAttributeValue("", "name");
|
||||
if (defaultName == null) {
|
||||
privacy.setDeclineDefaultList(true);
|
||||
} else {
|
||||
privacy.setDefaultName(defaultName);
|
||||
}
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
else if (parser.getName().equals("list")) {
|
||||
|
@ -75,10 +75,10 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
}
|
||||
|
||||
return privacy;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the list complex type
|
||||
private static void parseList(XmlPullParser parser, Privacy privacy) throws XmlPullParserException, IOException, SmackException {
|
||||
// Parse the list complex type
|
||||
private static void parseList(XmlPullParser parser, Privacy privacy) throws XmlPullParserException, IOException, SmackException {
|
||||
boolean done = false;
|
||||
String listName = parser.getAttributeValue("", "name");
|
||||
ArrayList<PrivacyItem> items = new ArrayList<PrivacyItem>();
|
||||
|
@ -87,7 +87,7 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("item")) {
|
||||
// CHECKSTYLE:OFF
|
||||
items.add(parseItem(parser));
|
||||
items.add(parseItem(parser));
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
|
@ -100,10 +100,10 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
|
||||
privacy.setPrivacyList(listName, items);
|
||||
// CHECKSTYLE:OFF
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the list complex type
|
||||
private static PrivacyItem parseItem(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException {
|
||||
// Parse the list complex type
|
||||
private static PrivacyItem parseItem(XmlPullParser parser) throws XmlPullParserException, IOException, SmackException {
|
||||
// CHECKSTYLE:ON
|
||||
// Retrieves the required attributes
|
||||
String actionValue = parser.getAttributeValue("", "action");
|
||||
|
@ -142,7 +142,7 @@ public class PrivacyProvider extends IQProvider<Privacy> {
|
|||
parseItemChildElements(parser, item);
|
||||
return item;
|
||||
// CHECKSTYLE:OFF
|
||||
}
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
|
||||
private static void parseItemChildElements(XmlPullParser parser, PrivacyItem privacyItem) throws XmlPullParserException, IOException {
|
||||
|
|
|
@ -24,18 +24,18 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum AccessModel
|
||||
{
|
||||
/** Anyone may subscribe and retrieve items. */
|
||||
open,
|
||||
/** Anyone may subscribe and retrieve items. */
|
||||
open,
|
||||
|
||||
/** Subscription request must be approved and only subscribers may retrieve items. */
|
||||
authorize,
|
||||
/** Subscription request must be approved and only subscribers may retrieve items. */
|
||||
authorize,
|
||||
|
||||
/** Anyone with a presence subscription of both or from may subscribe and retrieve items. */
|
||||
presence,
|
||||
/** Anyone with a presence subscription of both or from may subscribe and retrieve items. */
|
||||
presence,
|
||||
|
||||
/** Anyone in the specified roster group(s) may subscribe and retrieve items. */
|
||||
roster,
|
||||
/** Anyone in the specified roster group(s) may subscribe and retrieve items. */
|
||||
roster,
|
||||
|
||||
/** Only those on a whitelist may subscribe and retrieve items. */
|
||||
whitelist;
|
||||
/** Only those on a whitelist may subscribe and retrieve items. */
|
||||
whitelist;
|
||||
}
|
||||
|
|
|
@ -42,17 +42,17 @@ public class Affiliation implements ExtensionElement
|
|||
private final Type affiliation;
|
||||
private final PubSubNamespace namespace;
|
||||
|
||||
public enum Type
|
||||
{
|
||||
member, none, outcast, owner, publisher
|
||||
}
|
||||
public enum Type
|
||||
{
|
||||
member, none, outcast, owner, publisher
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an affiliation.
|
||||
*
|
||||
* @param node The node the user is affiliated with.
|
||||
* @param affiliation the optional affiliation.
|
||||
*/
|
||||
/**
|
||||
* Constructs an affiliation.
|
||||
*
|
||||
* @param node The node the user is affiliated with.
|
||||
* @param affiliation the optional affiliation.
|
||||
*/
|
||||
public Affiliation(String node, Type affiliation) {
|
||||
this.node = StringUtils.requireNotNullOrEmpty(node, "node must not be null or empty");
|
||||
this.affiliation = affiliation;
|
||||
|
@ -122,6 +122,7 @@ public class Affiliation implements ExtensionElement
|
|||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return namespace.getXmlns();
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
|||
*/
|
||||
public class AffiliationsExtension extends NodeExtension
|
||||
{
|
||||
protected List<Affiliation> items = Collections.emptyList();
|
||||
private final String node;
|
||||
protected List<Affiliation> items = Collections.emptyList();
|
||||
private final String node;
|
||||
|
||||
public AffiliationsExtension() {
|
||||
this(null, null);
|
||||
|
@ -47,20 +47,20 @@ public class AffiliationsExtension extends NodeExtension
|
|||
this.node = node;
|
||||
}
|
||||
|
||||
public List<Affiliation> getAffiliations()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
public List<Affiliation> getAffiliations()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't use XmlStringBuilder(this), because we don't want the namespace to be included
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.openElement(getElementName());
|
||||
|
@ -69,6 +69,6 @@ public class AffiliationsExtension extends NodeExtension
|
|||
xml.append(items);
|
||||
xml.closeElement(this);
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum ChildrenAssociationPolicy
|
||||
{
|
||||
/** Anyone may associate leaf nodes with the collection. */
|
||||
all,
|
||||
/** Anyone may associate leaf nodes with the collection. */
|
||||
all,
|
||||
|
||||
/** Only collection node owners may associate leaf nodes with the collection. */
|
||||
owners,
|
||||
/** Only collection node owners may associate leaf nodes with the collection. */
|
||||
owners,
|
||||
|
||||
/** Only those on a whitelist may associate leaf nodes with the collection. */
|
||||
whitelist;
|
||||
/** Only those on a whitelist may associate leaf nodes with the collection. */
|
||||
whitelist;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ package org.jivesoftware.smackx.pubsub;
|
|||
|
||||
public class CollectionNode extends Node
|
||||
{
|
||||
CollectionNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
CollectionNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,29 +31,30 @@ import org.jivesoftware.smack.packet.ExtensionElement;
|
|||
*/
|
||||
public class ConfigurationEvent extends NodeExtension implements EmbeddedPacketExtension
|
||||
{
|
||||
private ConfigureForm form;
|
||||
private ConfigureForm form;
|
||||
|
||||
public ConfigurationEvent(String nodeId)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
}
|
||||
public ConfigurationEvent(String nodeId)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
}
|
||||
|
||||
public ConfigurationEvent(String nodeId, ConfigureForm configForm)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
form = configForm;
|
||||
}
|
||||
public ConfigurationEvent(String nodeId, ConfigureForm configForm)
|
||||
{
|
||||
super(PubSubElementType.CONFIGURATION, nodeId);
|
||||
form = configForm;
|
||||
}
|
||||
|
||||
public ConfigureForm getConfiguration()
|
||||
{
|
||||
return form;
|
||||
}
|
||||
public ConfigureForm getConfiguration()
|
||||
{
|
||||
return form;
|
||||
}
|
||||
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
if (getConfiguration() == null)
|
||||
return Collections.emptyList();
|
||||
else
|
||||
return Arrays.asList(((ExtensionElement)getConfiguration().getDataFormToSend()));
|
||||
}
|
||||
@Override
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
if (getConfiguration() == null)
|
||||
return Collections.emptyList();
|
||||
else
|
||||
return Arrays.asList(((ExtensionElement)getConfiguration().getDataFormToSend()));
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -29,193 +29,193 @@ import org.jivesoftware.smackx.xdata.Form;
|
|||
*/
|
||||
public enum ConfigureNodeFields
|
||||
{
|
||||
/**
|
||||
* Determines who may subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: {@link AccessModel}</b></p>
|
||||
*/
|
||||
access_model,
|
||||
/**
|
||||
* Determines who may subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: {@link AccessModel}</b></p>
|
||||
*/
|
||||
access_model,
|
||||
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payloads in order to generate an appropriate message
|
||||
* body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
body_xslt,
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payloads in order to generate an appropriate message
|
||||
* body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
body_xslt,
|
||||
|
||||
/**
|
||||
* The collection with which a node is affiliated.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
collection,
|
||||
/**
|
||||
* The collection with which a node is affiliated.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
collection,
|
||||
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payload format in order to generate a valid Data Forms result
|
||||
* that the client could display using a generic Data Forms
|
||||
* rendering engine body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
dataform_xslt,
|
||||
/**
|
||||
* The URL of an XSL transformation which can be applied to
|
||||
* payload format in order to generate a valid Data Forms result
|
||||
* that the client could display using a generic Data Forms
|
||||
* rendering engine body element.
|
||||
*
|
||||
* <p><b>Value: {@link URL}</b></p>
|
||||
*/
|
||||
dataform_xslt,
|
||||
|
||||
/**
|
||||
* Whether to deliver payloads with event notifications.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
deliver_payloads,
|
||||
/**
|
||||
* Whether to deliver payloads with event notifications.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
deliver_payloads,
|
||||
|
||||
/**
|
||||
* Whether owners or publisher should receive replies to items.
|
||||
*
|
||||
* <p><b>Value: {@link ItemReply}</b></p>
|
||||
*/
|
||||
itemreply,
|
||||
/**
|
||||
* Whether owners or publisher should receive replies to items.
|
||||
*
|
||||
* <p><b>Value: {@link ItemReply}</b></p>
|
||||
*/
|
||||
itemreply,
|
||||
|
||||
/**
|
||||
* Who may associate leaf nodes with a collection.
|
||||
*
|
||||
* <p><b>Value: {@link ChildrenAssociationPolicy}</b></p>
|
||||
*/
|
||||
children_association_policy,
|
||||
/**
|
||||
* Who may associate leaf nodes with a collection.
|
||||
*
|
||||
* <p><b>Value: {@link ChildrenAssociationPolicy}</b></p>
|
||||
*/
|
||||
children_association_policy,
|
||||
|
||||
/**
|
||||
* The list of JIDs that may associate leaf nodes with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
children_association_whitelist,
|
||||
/**
|
||||
* The list of JIDs that may associate leaf nodes with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
children_association_whitelist,
|
||||
|
||||
/**
|
||||
* The child nodes (leaf or collection) associated with a collection.
|
||||
*
|
||||
* <p><b>Value: List of Strings</b></p>
|
||||
*/
|
||||
children,
|
||||
/**
|
||||
* The child nodes (leaf or collection) associated with a collection.
|
||||
*
|
||||
* <p><b>Value: List of Strings</b></p>
|
||||
*/
|
||||
children,
|
||||
|
||||
/**
|
||||
* The maximum number of child nodes that can be associated with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
children_max,
|
||||
/**
|
||||
* The maximum number of child nodes that can be associated with a
|
||||
* collection.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
children_max,
|
||||
|
||||
/**
|
||||
* The maximum number of items to persist.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_items,
|
||||
/**
|
||||
* The maximum number of items to persist.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_items,
|
||||
|
||||
/**
|
||||
* The maximum payload size in bytes.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_payload_size,
|
||||
/**
|
||||
* The maximum payload size in bytes.
|
||||
*
|
||||
* <p><b>Value: int</b></p>
|
||||
*/
|
||||
max_payload_size,
|
||||
|
||||
/**
|
||||
* Whether the node is a leaf (default) or collection.
|
||||
*
|
||||
* <p><b>Value: {@link NodeType}</b></p>
|
||||
*/
|
||||
node_type,
|
||||
/**
|
||||
* Whether the node is a leaf (default) or collection.
|
||||
*
|
||||
* <p><b>Value: {@link NodeType}</b></p>
|
||||
*/
|
||||
node_type,
|
||||
|
||||
/**
|
||||
* Whether to notify subscribers when the node configuration changes.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_config,
|
||||
/**
|
||||
* Whether to notify subscribers when the node configuration changes.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_config,
|
||||
|
||||
/**
|
||||
* Whether to notify subscribers when the node is deleted.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_delete,
|
||||
/**
|
||||
* Whether to notify subscribers when the node is deleted.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_delete,
|
||||
|
||||
/**
|
||||
* Whether to notify subscribers when items are removed from the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_retract,
|
||||
/**
|
||||
* Whether to notify subscribers when items are removed from the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
notify_retract,
|
||||
|
||||
/**
|
||||
* Whether to persist items to storage. This is required to have. multiple
|
||||
* items in the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
persist_items,
|
||||
/**
|
||||
* Whether to persist items to storage. This is required to have. multiple
|
||||
* items in the node.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
persist_items,
|
||||
|
||||
/**
|
||||
* Whether to deliver notifications to available users only.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
presence_based_delivery,
|
||||
/**
|
||||
* Whether to deliver notifications to available users only.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
presence_based_delivery,
|
||||
|
||||
/**
|
||||
* Defines who can publish to the node.
|
||||
*
|
||||
* <p><b>Value: {@link PublishModel}</b></p>
|
||||
*/
|
||||
publish_model,
|
||||
/**
|
||||
* Defines who can publish to the node.
|
||||
*
|
||||
* <p><b>Value: {@link PublishModel}</b></p>
|
||||
*/
|
||||
publish_model,
|
||||
|
||||
/**
|
||||
* The specific multi-user chat rooms to specify for replyroom.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyroom,
|
||||
/**
|
||||
* The specific multi-user chat rooms to specify for replyroom.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyroom,
|
||||
|
||||
/**
|
||||
* The specific JID(s) to specify for replyto.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyto,
|
||||
/**
|
||||
* The specific JID(s) to specify for replyto.
|
||||
*
|
||||
* <p><b>Value: List of JIDs as Strings</b></p>
|
||||
*/
|
||||
replyto,
|
||||
|
||||
/**
|
||||
* The roster group(s) allowed to subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: List of strings</b></p>
|
||||
*/
|
||||
roster_groups_allowed,
|
||||
/**
|
||||
* The roster group(s) allowed to subscribe and retrieve items.
|
||||
*
|
||||
* <p><b>Value: List of strings</b></p>
|
||||
*/
|
||||
roster_groups_allowed,
|
||||
|
||||
/**
|
||||
* Whether to allow subscriptions.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
subscribe,
|
||||
/**
|
||||
* Whether to allow subscriptions.
|
||||
*
|
||||
* <p><b>Value: boolean</b></p>
|
||||
*/
|
||||
subscribe,
|
||||
|
||||
/**
|
||||
* A friendly name for the node.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
title,
|
||||
/**
|
||||
* A friendly name for the node.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
title,
|
||||
|
||||
/**
|
||||
* The type of node data, ussually specified by the namespace
|
||||
* of the payload(if any);MAY be a list-single rather than a
|
||||
* text single.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
type;
|
||||
/**
|
||||
* The type of node data, ussually specified by the namespace
|
||||
* of the payload(if any);MAY be a list-single rather than a
|
||||
* text single.
|
||||
*
|
||||
* <p><b>Value: String</b></p>
|
||||
*/
|
||||
type;
|
||||
|
||||
public String getFieldName()
|
||||
{
|
||||
return "pubsub#" + toString();
|
||||
}
|
||||
public String getFieldName()
|
||||
{
|
||||
return "pubsub#" + toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,10 +39,10 @@ import org.jivesoftware.smack.util.PacketParserUtils;
|
|||
*/
|
||||
public interface EmbeddedPacketExtension extends ExtensionElement
|
||||
{
|
||||
/**
|
||||
* Get the list of embedded {@link ExtensionElement} objects.
|
||||
*
|
||||
* @return List of embedded {@link ExtensionElement}
|
||||
*/
|
||||
List<ExtensionElement> getExtensions();
|
||||
/**
|
||||
* Get the list of embedded {@link ExtensionElement} objects.
|
||||
*
|
||||
* @return List of embedded {@link ExtensionElement}
|
||||
*/
|
||||
List<ExtensionElement> getExtensions();
|
||||
}
|
||||
|
|
|
@ -44,39 +44,42 @@ public class EventElement implements EmbeddedPacketExtension
|
|||
*/
|
||||
public static final String NAMESPACE = PubSubNamespace.EVENT.getXmlns();
|
||||
|
||||
private EventElementType type;
|
||||
private NodeExtension ext;
|
||||
private EventElementType type;
|
||||
private NodeExtension ext;
|
||||
|
||||
public EventElement(EventElementType eventType, NodeExtension eventExt)
|
||||
{
|
||||
type = eventType;
|
||||
ext = eventExt;
|
||||
}
|
||||
public EventElement(EventElementType eventType, NodeExtension eventExt)
|
||||
{
|
||||
type = eventType;
|
||||
ext = eventExt;
|
||||
}
|
||||
|
||||
public EventElementType getEventType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
public EventElementType getEventType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return Arrays.asList(new ExtensionElement[]{getEvent()});
|
||||
}
|
||||
@Override
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return Arrays.asList(new ExtensionElement[]{getEvent()});
|
||||
}
|
||||
|
||||
public NodeExtension getEvent()
|
||||
{
|
||||
return ext;
|
||||
}
|
||||
public NodeExtension getEvent()
|
||||
{
|
||||
return ext;
|
||||
}
|
||||
|
||||
public String getElementName()
|
||||
{
|
||||
return "event";
|
||||
}
|
||||
@Override
|
||||
public String getElementName()
|
||||
{
|
||||
return "event";
|
||||
}
|
||||
|
||||
public String getNamespace()
|
||||
{
|
||||
return PubSubNamespace.EVENT.getXmlns();
|
||||
}
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return PubSubNamespace.EVENT.getXmlns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
|
|
|
@ -24,21 +24,21 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum EventElementType
|
||||
{
|
||||
/** A node has been associated or dissassociated with a collection node. */
|
||||
collection,
|
||||
/** A node has been associated or dissassociated with a collection node. */
|
||||
collection,
|
||||
|
||||
/** A node has had its configuration changed. */
|
||||
configuration,
|
||||
/** A node has had its configuration changed. */
|
||||
configuration,
|
||||
|
||||
/** A node has been deleted. */
|
||||
delete,
|
||||
/** A node has been deleted. */
|
||||
delete,
|
||||
|
||||
/** Items have been published to a node. */
|
||||
items,
|
||||
/** Items have been published to a node. */
|
||||
items,
|
||||
|
||||
/** All items have been purged from a node. */
|
||||
purge,
|
||||
/** All items have been purged from a node. */
|
||||
purge,
|
||||
|
||||
/** A node has been subscribed to. */
|
||||
subscription
|
||||
/** A node has been subscribed to. */
|
||||
subscription
|
||||
}
|
||||
|
|
|
@ -28,75 +28,75 @@ import org.jivesoftware.smackx.xdata.Form;
|
|||
*/
|
||||
public class FormNode extends NodeExtension
|
||||
{
|
||||
private Form configForm;
|
||||
private Form configForm;
|
||||
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement());
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement());
|
||||
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form, which is
|
||||
* associated with the specified node.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param nodeId The node the form is associated with
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, String nodeId, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement(), nodeId);
|
||||
/**
|
||||
* Create a {@link FormNode} which contains the specified form, which is
|
||||
* associated with the specified node.
|
||||
*
|
||||
* @param formType The type of form being sent
|
||||
* @param nodeId The node the form is associated with
|
||||
* @param submitForm The form
|
||||
*/
|
||||
public FormNode(FormNodeType formType, String nodeId, Form submitForm)
|
||||
{
|
||||
super(formType.getNodeElement(), nodeId);
|
||||
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
if (submitForm == null)
|
||||
throw new IllegalArgumentException("Submit form cannot be null");
|
||||
configForm = submitForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Form that is to be sent, or was retrieved from the server.
|
||||
*
|
||||
* @return The form
|
||||
*/
|
||||
public Form getForm()
|
||||
{
|
||||
return configForm;
|
||||
}
|
||||
/**
|
||||
* Get the Form that is to be sent, or was retrieved from the server.
|
||||
*
|
||||
* @return The form
|
||||
*/
|
||||
public Form getForm()
|
||||
{
|
||||
return configForm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if (configForm == null)
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if (configForm == null)
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
|
||||
if (getNode() != null)
|
||||
{
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
builder.append('>');
|
||||
builder.append(configForm.getDataFormToSend().toXML());
|
||||
builder.append("</");
|
||||
builder.append(getElementName() + '>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
if (getNode() != null)
|
||||
{
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
builder.append('>');
|
||||
builder.append(configForm.getDataFormToSend().toXML());
|
||||
builder.append("</");
|
||||
builder.append(getElementName() + '>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,29 +27,29 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
|||
*/
|
||||
public enum FormNodeType
|
||||
{
|
||||
/** Form for configuring an existing node. */
|
||||
CONFIGURE_OWNER,
|
||||
/** Form for configuring an existing node. */
|
||||
CONFIGURE_OWNER,
|
||||
|
||||
/** Form for configuring a node during creation. */
|
||||
CONFIGURE,
|
||||
/** Form for configuring a node during creation. */
|
||||
CONFIGURE,
|
||||
|
||||
/** Form for configuring subscription options. */
|
||||
OPTIONS,
|
||||
/** Form for configuring subscription options. */
|
||||
OPTIONS,
|
||||
|
||||
/** Form which represents the default node configuration options. */
|
||||
DEFAULT;
|
||||
/** Form which represents the default node configuration options. */
|
||||
DEFAULT;
|
||||
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return PubSubElementType.valueOf(toString());
|
||||
}
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return PubSubElementType.valueOf(toString());
|
||||
}
|
||||
|
||||
public static FormNodeType valueOfFromElementName(String elem, String configNamespace)
|
||||
{
|
||||
if ("configure".equals(elem) && PubSubNamespace.OWNER.getXmlns().equals(configNamespace))
|
||||
{
|
||||
return CONFIGURE_OWNER;
|
||||
}
|
||||
return valueOf(elem.toUpperCase(Locale.US));
|
||||
}
|
||||
public static FormNodeType valueOfFromElementName(String elem, String configNamespace)
|
||||
{
|
||||
if ("configure".equals(elem) && PubSubNamespace.OWNER.getXmlns().equals(configNamespace))
|
||||
{
|
||||
return CONFIGURE_OWNER;
|
||||
}
|
||||
return valueOf(elem.toUpperCase(Locale.US));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,42 +25,42 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
|||
*/
|
||||
public class GetItemsRequest extends NodeExtension
|
||||
{
|
||||
protected final String subId;
|
||||
protected final int maxItems;
|
||||
protected final String subId;
|
||||
protected final int maxItems;
|
||||
|
||||
public GetItemsRequest(String nodeId)
|
||||
{
|
||||
this(nodeId, null, -1);
|
||||
}
|
||||
public GetItemsRequest(String nodeId)
|
||||
{
|
||||
this(nodeId, null, -1);
|
||||
}
|
||||
|
||||
public GetItemsRequest(String nodeId, String subscriptionId)
|
||||
{
|
||||
public GetItemsRequest(String nodeId, String subscriptionId)
|
||||
{
|
||||
this(nodeId, subscriptionId, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public GetItemsRequest(String nodeId, int maxItemsToReturn)
|
||||
{
|
||||
public GetItemsRequest(String nodeId, int maxItemsToReturn)
|
||||
{
|
||||
this(nodeId, null, maxItemsToReturn);
|
||||
}
|
||||
}
|
||||
|
||||
public GetItemsRequest(String nodeId, String subscriptionId, int maxItemsToReturn)
|
||||
{
|
||||
public GetItemsRequest(String nodeId, String subscriptionId, int maxItemsToReturn)
|
||||
{
|
||||
super(PubSubElementType.ITEMS, nodeId);
|
||||
maxItems = maxItemsToReturn;
|
||||
subId = subscriptionId;
|
||||
}
|
||||
subId = subscriptionId;
|
||||
}
|
||||
|
||||
public String getSubscriptionId()
|
||||
{
|
||||
return subId;
|
||||
}
|
||||
public String getSubscriptionId()
|
||||
{
|
||||
return subId;
|
||||
}
|
||||
|
||||
public int getMaxItems()
|
||||
{
|
||||
return maxItems;
|
||||
}
|
||||
public int getMaxItems()
|
||||
{
|
||||
return maxItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(getElementName());
|
||||
|
|
|
@ -50,94 +50,92 @@ import org.jivesoftware.smackx.pubsub.provider.ItemProvider;
|
|||
*/
|
||||
public class Item extends NodeExtension
|
||||
{
|
||||
private String id;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Create an empty <tt>Item</tt> with no id. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false. In most cases an id will be generated by the server.
|
||||
* For nodes configured with {@link ConfigureForm#isDeliverPayloads()} and {@link ConfigureForm#isPersistItems()}
|
||||
* set to false, no <tt>Item</tt> is sent to the node, you have to use {@link LeafNode#send()} or {@link LeafNode#publish()}
|
||||
* methods in this case.
|
||||
*/
|
||||
public Item()
|
||||
{
|
||||
super(PubSubElementType.ITEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id but no payload. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false.
|
||||
*
|
||||
* @param itemId The id if the item. It must be unique within the node unless overwriting and existing item.
|
||||
* Passing null is the equivalent of calling {@link #Item()}.
|
||||
*/
|
||||
public Item(String itemId)
|
||||
{
|
||||
// The element type is actually irrelevant since we override getNamespace() to return null
|
||||
super(PubSubElementType.ITEM);
|
||||
id = itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id and a node id.
|
||||
* <p>
|
||||
* <b>Note:</b> This is not valid for publishing an item to a node, only receiving from
|
||||
* one as part of {@link Message}. If used to create an Item to publish
|
||||
* (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
|
||||
* error for an invalid packet.
|
||||
*
|
||||
* @param itemId The id of the item.
|
||||
* @param nodeId The id of the node which the item was published to.
|
||||
*/
|
||||
public Item(String itemId, String nodeId)
|
||||
/**
|
||||
* Create an empty <tt>Item</tt> with no id. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false. In most cases an id will be generated by the server.
|
||||
* For nodes configured with {@link ConfigureForm#isDeliverPayloads()} and {@link ConfigureForm#isPersistItems()}
|
||||
* set to false, no <tt>Item</tt> is sent to the node, you have to use {@link LeafNode#send()} or {@link LeafNode#publish()}
|
||||
* methods in this case.
|
||||
*/
|
||||
public Item()
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
super(PubSubElementType.ITEM_EVENT, nodeId);
|
||||
// CHECKSTYLE:ON
|
||||
super(PubSubElementType.ITEM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id but no payload. This is a valid item for nodes which are configured
|
||||
* so that {@link ConfigureForm#isDeliverPayloads()} is false.
|
||||
*
|
||||
* @param itemId The id if the item. It must be unique within the node unless overwriting and existing item.
|
||||
* Passing null is the equivalent of calling {@link #Item()}.
|
||||
*/
|
||||
public Item(String itemId)
|
||||
{
|
||||
// The element type is actually irrelevant since we override getNamespace() to return null
|
||||
super(PubSubElementType.ITEM);
|
||||
id = itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item id. Unique to the node it is associated with.
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Create an <tt>Item</tt> with an id and a node id.
|
||||
* <p>
|
||||
* <b>Note:</b> This is not valid for publishing an item to a node, only receiving from
|
||||
* one as part of {@link Message}. If used to create an Item to publish
|
||||
* (via {@link LeafNode#publish(Item)}, the server <i>may</i> return an
|
||||
* error for an invalid packet.
|
||||
*
|
||||
* @param itemId The id of the item.
|
||||
* @param nodeId The id of the node which the item was published to.
|
||||
*/
|
||||
public Item(String itemId, String nodeId)
|
||||
{
|
||||
super(PubSubElementType.ITEM_EVENT, nodeId);
|
||||
id = itemId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Get the item id. Unique to the node it is associated with.
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<item");
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
builder.append(" id='");
|
||||
builder.append(id);
|
||||
builder.append('\'');
|
||||
}
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<item");
|
||||
|
||||
if (id != null)
|
||||
{
|
||||
builder.append(" id='");
|
||||
builder.append(id);
|
||||
builder.append('\'');
|
||||
}
|
||||
|
||||
if (getNode() != null) {
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
builder.append('\'');
|
||||
}
|
||||
builder.append("/>");
|
||||
builder.append("/>");
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " | Content [" + toXML() + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " | Content [" + toXML() + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,40 +26,40 @@ import java.util.List;
|
|||
*/
|
||||
public class ItemDeleteEvent extends SubscriptionEvent
|
||||
{
|
||||
private List<String> itemIds = Collections.emptyList();
|
||||
private List<String> itemIds = Collections.emptyList();
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemDeleteEvent</tt> that indicates the the supplied
|
||||
* items (by id) have been deleted, and that the event matches the listed
|
||||
* subscriptions. The subscriptions would have been created by calling
|
||||
* {@link LeafNode#subscribe(String)}.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param deletedItemIds The item ids of the items that were deleted.
|
||||
* @param subscriptionIds The subscriptions that match the event.
|
||||
*/
|
||||
public ItemDeleteEvent(String nodeId, List<String> deletedItemIds, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
/**
|
||||
* Constructs an <tt>ItemDeleteEvent</tt> that indicates the the supplied
|
||||
* items (by id) have been deleted, and that the event matches the listed
|
||||
* subscriptions. The subscriptions would have been created by calling
|
||||
* {@link LeafNode#subscribe(String)}.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param deletedItemIds The item ids of the items that were deleted.
|
||||
* @param subscriptionIds The subscriptions that match the event.
|
||||
*/
|
||||
public ItemDeleteEvent(String nodeId, List<String> deletedItemIds, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
|
||||
if (deletedItemIds == null)
|
||||
throw new IllegalArgumentException("deletedItemIds cannot be null");
|
||||
itemIds = deletedItemIds;
|
||||
}
|
||||
if (deletedItemIds == null)
|
||||
throw new IllegalArgumentException("deletedItemIds cannot be null");
|
||||
itemIds = deletedItemIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item id's of the items that have been deleted.
|
||||
*
|
||||
* @return List of item id's
|
||||
*/
|
||||
public List<String> getItemIds()
|
||||
{
|
||||
return Collections.unmodifiableList(itemIds);
|
||||
}
|
||||
/**
|
||||
* Get the item id's of the items that have been deleted.
|
||||
*
|
||||
* @return List of item id's
|
||||
*/
|
||||
public List<String> getItemIds()
|
||||
{
|
||||
return Collections.unmodifiableList(itemIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Deleted Items: " + itemIds + ']';
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Deleted Items: " + itemIds + ']';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,98 +27,98 @@ import java.util.List;
|
|||
*/
|
||||
public class ItemPublishEvent<T extends Item> extends SubscriptionEvent
|
||||
{
|
||||
private List<T> items;
|
||||
private Date originalDate;
|
||||
private List<T> items;
|
||||
private Date originalDate;
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems)
|
||||
{
|
||||
super(nodeId);
|
||||
items = eventItems;
|
||||
}
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems)
|
||||
{
|
||||
super(nodeId);
|
||||
items = eventItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
}
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published in the past. The published
|
||||
* date signifies that this is delayed event. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds, Date publishedDate)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
/**
|
||||
* Constructs an <tt>ItemPublishEvent</tt> with the provided list
|
||||
* of {@link Item} that were published in the past. The published
|
||||
* date signifies that this is delayed event. The list of subscription ids
|
||||
* represents the subscriptions that matched the event, in the case
|
||||
* of the user having multiple subscriptions.
|
||||
*
|
||||
* @param nodeId The id of the node the event came from
|
||||
* @param eventItems The list of {@link Item} that were published
|
||||
* @param subscriptionIds The list of subscriptionIds
|
||||
*/
|
||||
public ItemPublishEvent(String nodeId, List<T> eventItems, List<String> subscriptionIds, Date publishedDate)
|
||||
{
|
||||
super(nodeId, subscriptionIds);
|
||||
items = eventItems;
|
||||
|
||||
if (publishedDate != null)
|
||||
originalDate = publishedDate;
|
||||
}
|
||||
if (publishedDate != null)
|
||||
originalDate = publishedDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of {@link Item} that were published.
|
||||
*
|
||||
* @return The list of published {@link Item}
|
||||
*/
|
||||
public List<T> getItems()
|
||||
{
|
||||
return Collections.unmodifiableList(items);
|
||||
}
|
||||
/**
|
||||
* Get the list of {@link Item} that were published.
|
||||
*
|
||||
* @return The list of published {@link Item}
|
||||
*/
|
||||
public List<T> getItems()
|
||||
{
|
||||
return Collections.unmodifiableList(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this event was delayed. That is, the items
|
||||
* were published to the node at some time in the past. This will
|
||||
* typically happen if there is an item already published to the node
|
||||
* before a user subscribes to it. In this case, when the user
|
||||
* subscribes, the server may send the last item published to the node
|
||||
* with a delay date showing its time of original publication.
|
||||
*
|
||||
* @return true if the items are delayed, false otherwise.
|
||||
*/
|
||||
public boolean isDelayed()
|
||||
{
|
||||
return (originalDate != null);
|
||||
}
|
||||
/**
|
||||
* Indicates whether this event was delayed. That is, the items
|
||||
* were published to the node at some time in the past. This will
|
||||
* typically happen if there is an item already published to the node
|
||||
* before a user subscribes to it. In this case, when the user
|
||||
* subscribes, the server may send the last item published to the node
|
||||
* with a delay date showing its time of original publication.
|
||||
*
|
||||
* @return true if the items are delayed, false otherwise.
|
||||
*/
|
||||
public boolean isDelayed()
|
||||
{
|
||||
return (originalDate != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original date the items were published. This is only
|
||||
* valid if {@link #isDelayed()} is true.
|
||||
*
|
||||
*/
|
||||
public Date getPublishedDate()
|
||||
{
|
||||
return originalDate;
|
||||
}
|
||||
/**
|
||||
* Gets the original date the items were published. This is only
|
||||
* valid if {@link #isDelayed()} is true.
|
||||
*
|
||||
*/
|
||||
public Date getPublishedDate()
|
||||
{
|
||||
return originalDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Delayed: " +
|
||||
(isDelayed() ? originalDate.toString() : "false") + ']';
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " [subscriptions: " + getSubscriptions() + "], [Delayed: " +
|
||||
(isDelayed() ? originalDate.toString() : "false") + ']';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum ItemReply
|
||||
{
|
||||
/** The node owner. */
|
||||
owner,
|
||||
/** The node owner. */
|
||||
owner,
|
||||
|
||||
/** The item publisher. */
|
||||
publisher;
|
||||
/** The item publisher. */
|
||||
publisher;
|
||||
}
|
||||
|
|
|
@ -36,168 +36,169 @@ import org.jivesoftware.smack.packet.ExtensionElement;
|
|||
*/
|
||||
public class ItemsExtension extends NodeExtension implements EmbeddedPacketExtension
|
||||
{
|
||||
protected ItemsElementType type;
|
||||
protected Boolean notify;
|
||||
protected List<? extends ExtensionElement> items;
|
||||
protected ItemsElementType type;
|
||||
protected Boolean notify;
|
||||
protected List<? extends ExtensionElement> items;
|
||||
|
||||
public enum ItemsElementType
|
||||
{
|
||||
/** An items element, which has an optional <b>max_items</b> attribute when requesting items. */
|
||||
items(PubSubElementType.ITEMS, "max_items"),
|
||||
public enum ItemsElementType
|
||||
{
|
||||
/** An items element, which has an optional <b>max_items</b> attribute when requesting items. */
|
||||
items(PubSubElementType.ITEMS, "max_items"),
|
||||
|
||||
/** A retract element, which has an optional <b>notify</b> attribute when publishing deletions. */
|
||||
retract(PubSubElementType.RETRACT, "notify");
|
||||
/** A retract element, which has an optional <b>notify</b> attribute when publishing deletions. */
|
||||
retract(PubSubElementType.RETRACT, "notify");
|
||||
|
||||
private PubSubElementType elem;
|
||||
private String att;
|
||||
private final PubSubElementType elem;
|
||||
private final String att;
|
||||
|
||||
private ItemsElementType(PubSubElementType nodeElement, String attribute)
|
||||
{
|
||||
elem = nodeElement;
|
||||
att = attribute;
|
||||
}
|
||||
private ItemsElementType(PubSubElementType nodeElement, String attribute)
|
||||
{
|
||||
elem = nodeElement;
|
||||
att = attribute;
|
||||
}
|
||||
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return elem;
|
||||
}
|
||||
public PubSubElementType getNodeElement()
|
||||
{
|
||||
return elem;
|
||||
}
|
||||
|
||||
public String getElementAttribute()
|
||||
{
|
||||
return att;
|
||||
}
|
||||
}
|
||||
public String getElementAttribute()
|
||||
{
|
||||
return att;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param itemsType Type of representation
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(ItemsElementType itemsType, String nodeId, List<? extends ExtensionElement> items)
|
||||
{
|
||||
super(itemsType.getNodeElement(), nodeId);
|
||||
type = itemsType;
|
||||
this.items = items;
|
||||
}
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param itemsType Type of representation
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(ItemsElementType itemsType, String nodeId, List<? extends ExtensionElement> items)
|
||||
{
|
||||
super(itemsType.getNodeElement(), nodeId);
|
||||
type = itemsType;
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(String nodeId, List<? extends ExtensionElement> items, boolean notify)
|
||||
{
|
||||
super(ItemsElementType.retract.getNodeElement(), nodeId);
|
||||
type = ItemsElementType.retract;
|
||||
this.items = items;
|
||||
this.notify = notify;
|
||||
}
|
||||
/**
|
||||
* Construct an instance with a list representing items that have been published or deleted.
|
||||
*
|
||||
* <p>Valid scenarios are:</p>
|
||||
* <ul>
|
||||
* <li>Request items from node - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and an
|
||||
* optional value for the <b>max_items</b> attribute.
|
||||
* <li>Request to delete items - itemsType = {@link ItemsElementType#retract}, items = list of {@link Item} containing
|
||||
* only id's and an optional value for the <b>notify</b> attribute.
|
||||
* <li>Items published event - itemsType = {@link ItemsElementType#items}, items = list of {@link Item} and
|
||||
* attributeValue = <code>null</code>
|
||||
* <li>Items deleted event - itemsType = {@link ItemsElementType#items}, items = list of {@link RetractItem} and
|
||||
* attributeValue = <code>null</code>
|
||||
* </ul>
|
||||
*
|
||||
* @param nodeId The node to which the items are being sent or deleted
|
||||
* @param items The list of {@link Item} or {@link RetractItem}
|
||||
*/
|
||||
public ItemsExtension(String nodeId, List<? extends ExtensionElement> items, boolean notify)
|
||||
{
|
||||
super(ItemsElementType.retract.getNodeElement(), nodeId);
|
||||
type = ItemsElementType.retract;
|
||||
this.items = items;
|
||||
this.notify = notify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of element.
|
||||
*
|
||||
* @return The element type
|
||||
*/
|
||||
public ItemsElementType getItemsElementType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* Get the type of element.
|
||||
*
|
||||
* @return The element type
|
||||
*/
|
||||
public ItemsElementType getItemsElementType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return (List<ExtensionElement>)getItems();
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<ExtensionElement> getExtensions()
|
||||
{
|
||||
return (List<ExtensionElement>)getItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the items related to the type of request or event.
|
||||
*
|
||||
* return List of {@link Item}, {@link RetractItem}, or null
|
||||
*/
|
||||
public List<? extends ExtensionElement> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
/**
|
||||
* Gets the items related to the type of request or event.
|
||||
*
|
||||
* return List of {@link Item}, {@link RetractItem}, or null
|
||||
*/
|
||||
public List<? extends ExtensionElement> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of the optional attribute related to the {@link ItemsElementType}.
|
||||
*
|
||||
* @return The attribute value
|
||||
*/
|
||||
public boolean getNotify()
|
||||
{
|
||||
return notify;
|
||||
}
|
||||
/**
|
||||
* Gets the value of the optional attribute related to the {@link ItemsElementType}.
|
||||
*
|
||||
* @return The attribute value
|
||||
*/
|
||||
public boolean getNotify()
|
||||
{
|
||||
return notify;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
if ((items == null) || (items.size() == 0))
|
||||
{
|
||||
return super.toXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder builder = new StringBuilder("<");
|
||||
builder.append(getElementName());
|
||||
builder.append(" node='");
|
||||
builder.append(getNode());
|
||||
|
||||
if (notify != null)
|
||||
{
|
||||
builder.append("' ");
|
||||
builder.append(type.getElementAttribute());
|
||||
builder.append("='");
|
||||
builder.append(notify.equals(Boolean.TRUE) ? 1 : 0);
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append("'>");
|
||||
for (ExtensionElement item : items)
|
||||
{
|
||||
builder.append(item.toXML());
|
||||
}
|
||||
}
|
||||
if (notify != null)
|
||||
{
|
||||
builder.append("' ");
|
||||
builder.append(type.getElementAttribute());
|
||||
builder.append("='");
|
||||
builder.append(notify.equals(Boolean.TRUE) ? 1 : 0);
|
||||
builder.append("'>");
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.append("'>");
|
||||
for (ExtensionElement item : items)
|
||||
{
|
||||
builder.append(item.toXML());
|
||||
}
|
||||
}
|
||||
|
||||
builder.append("</");
|
||||
builder.append(getElementName());
|
||||
builder.append('>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
builder.append("</");
|
||||
builder.append(getElementName());
|
||||
builder.append('>');
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + "Content [" + toXML() + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + "Content [" + toXML() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,125 +38,125 @@ import org.jivesoftware.smackx.pubsub.packet.PubSub;
|
|||
*/
|
||||
public class LeafNode extends Node
|
||||
{
|
||||
LeafNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
LeafNode(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
super(pubSubManager, nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information on the items in the node in standard
|
||||
* {@link DiscoverItems} format.
|
||||
*
|
||||
* @return The item details in {@link DiscoverItems} format
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverItems discoverItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverItems items = new DiscoverItems();
|
||||
items.setTo(pubSubManager.getServiceJid());
|
||||
items.setNode(getId());
|
||||
/**
|
||||
* Get information on the items in the node in standard
|
||||
* {@link DiscoverItems} format.
|
||||
*
|
||||
* @return The item details in {@link DiscoverItems} format
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverItems discoverItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverItems items = new DiscoverItems();
|
||||
items.setTo(pubSubManager.getServiceJid());
|
||||
items.setNode(getId());
|
||||
return pubSubManager.getConnection().createStanzaCollectorAndSend(items).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current items stored in the node.
|
||||
*
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Get the current items stored in the node.
|
||||
*
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getItems((List<ExtensionElement>) null, (List<ExtensionElement>) null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current items stored in the node based
|
||||
* on the subscription associated with the provided
|
||||
* subscription id.
|
||||
*
|
||||
* @param subscriptionId - The subscription id for the
|
||||
* associated subscription.
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId));
|
||||
/**
|
||||
* Get the current items stored in the node based
|
||||
* on the subscription associated with the provided
|
||||
* subscription id.
|
||||
*
|
||||
* @param subscriptionId - The subscription id for the
|
||||
* associated subscription.
|
||||
* @return List of {@link Item} in the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the items specified from the node. This would typically be
|
||||
* used when the server does not return the payload due to size
|
||||
* constraints. The user would be required to retrieve the payload
|
||||
* after the items have been retrieved via {@link #getItems()} or an
|
||||
* event, that did not include the payload.
|
||||
*
|
||||
* @param ids Item ids of the items to retrieve
|
||||
*
|
||||
* @return The list of {@link Item} with payload
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(Collection<String> ids) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> itemList = new ArrayList<Item>(ids.size());
|
||||
/**
|
||||
* Get the items specified from the node. This would typically be
|
||||
* used when the server does not return the payload due to size
|
||||
* constraints. The user would be required to retrieve the payload
|
||||
* after the items have been retrieved via {@link #getItems()} or an
|
||||
* event, that did not include the payload.
|
||||
*
|
||||
* @param ids Item ids of the items to retrieve
|
||||
*
|
||||
* @return The list of {@link Item} with payload
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(Collection<String> ids) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> itemList = new ArrayList<Item>(ids.size());
|
||||
|
||||
for (String id : ids)
|
||||
{
|
||||
itemList.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.get, new ItemsExtension(ItemsExtension.ItemsElementType.items, getId(), itemList));
|
||||
for (String id : ids)
|
||||
{
|
||||
itemList.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.get, new ItemsExtension(ItemsExtension.ItemsElementType.items, getId(), itemList));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), maxItems));
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), maxItems));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number
|
||||
* based on the subscription associated with the provided subscriptionId.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
* @param subscriptionId The subscription which the retrieval is based
|
||||
* on.
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId, maxItems));
|
||||
/**
|
||||
* Get items persisted on the node, limited to the specified number
|
||||
* based on the subscription associated with the provided subscriptionId.
|
||||
*
|
||||
* @param maxItems Maximum number of items to return
|
||||
* @param subscriptionId The subscription which the retrieval is based
|
||||
* on.
|
||||
*
|
||||
* @return List of {@link Item}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> List<T> getItems(int maxItems, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.get, new GetItemsRequest(getId(), subscriptionId, maxItems));
|
||||
return getItems(request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items persisted on the node.
|
||||
|
@ -200,206 +200,206 @@ public class LeafNode extends Node
|
|||
return (List<T>) itemsElem.getItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send() send()}.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void publish() throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send() send()}.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void publish() throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This is a simple item
|
||||
* with no payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Item) send(Item))}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void publish(T item) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((T)(item == null ? new Item() : item));
|
||||
publish(items);
|
||||
}
|
||||
/**
|
||||
* Publishes an event to the node. This is a simple item
|
||||
* with no payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Item) send(Item))}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void publish(T item) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((T)(item == null ? new Item() : item));
|
||||
publish(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #publish(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Collection) send(Collection))}.
|
||||
*
|
||||
* @param items - The collection of items being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> void publish(Collection<T> items) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #publish(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is an asynchronous call which returns as soon as the
|
||||
* stanza(/packet) has been sent.
|
||||
*
|
||||
* For synchronous calls use {@link #send(Collection) send(Collection))}.
|
||||
*
|
||||
* @param items - The collection of items being sent
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public <T extends Item> void publish(Collection<T> items) throws NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
pubSubManager.getConnection().sendStanza(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish() publish()}.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void send() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
/**
|
||||
* Publishes an event to the node. This is an empty event
|
||||
* with no item.
|
||||
*
|
||||
* This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
|
||||
* and {@link ConfigureForm#isDeliverPayloads()}=false.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish() publish()}.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void send() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PUBLISH, getId()));
|
||||
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event to the node. This can be either a simple item
|
||||
* with no payload, or one with it. This is determined by the Node
|
||||
* configuration.
|
||||
*
|
||||
* If the node has <b>deliver_payload=false</b>, the Item must not
|
||||
* have a payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Item) publish(Item)}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void send(T item) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((item == null ? (T)new Item() : item));
|
||||
send(items);
|
||||
}
|
||||
/**
|
||||
* Publishes an event to the node. This can be either a simple item
|
||||
* with no payload, or one with it. This is determined by the Node
|
||||
* configuration.
|
||||
*
|
||||
* If the node has <b>deliver_payload=false</b>, the Item must not
|
||||
* have a payload.
|
||||
*
|
||||
* If the id is null, an empty item (one without an id) will be sent.
|
||||
* Please note that this is not the same as {@link #send()}, which
|
||||
* publishes an event with NO item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Item) publish(Item)}.
|
||||
*
|
||||
* @param item - The item being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Item> void send(T item) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<T> items = new ArrayList<T>(1);
|
||||
items.add((item == null ? (T)new Item() : item));
|
||||
send(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #send(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Collection) publish(Collection))}.
|
||||
*
|
||||
* @param items - The collection of {@link Item} objects being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public <T extends Item> void send(Collection<T> items) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
/**
|
||||
* Publishes multiple events to the node. Same rules apply as in {@link #send(Item)}.
|
||||
*
|
||||
* In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
|
||||
* list will get stored on the node, assuming it stores the last sent item.
|
||||
*
|
||||
* This is a synchronous call which will throw an exception
|
||||
* on failure.
|
||||
*
|
||||
* For asynchronous calls, use {@link #publish(Collection) publish(Collection))}.
|
||||
*
|
||||
* @param items - The collection of {@link Item} objects being sent
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public <T extends Item> void send(Collection<T> items) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new PublishItem<T>(getId(), items));
|
||||
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges the node of all items.
|
||||
*
|
||||
* <p>Note: Some implementations may keep the last item
|
||||
* sent.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteAllItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace());
|
||||
/**
|
||||
* Purges the node of all items.
|
||||
*
|
||||
* <p>Note: Some implementations may keep the last item
|
||||
* sent.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteAllItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace());
|
||||
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the item with the specified id from the node.
|
||||
*
|
||||
* @param itemId The id of the item
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(String itemId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<String> items = new ArrayList<String>(1);
|
||||
items.add(itemId);
|
||||
deleteItem(items);
|
||||
}
|
||||
/**
|
||||
* Delete the item with the specified id from the node.
|
||||
*
|
||||
* @param itemId The id of the item
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(String itemId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
Collection<String> items = new ArrayList<String>(1);
|
||||
items.add(itemId);
|
||||
deleteItem(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the items with the specified id's from the node.
|
||||
*
|
||||
* @param itemIds The list of id's of items to delete
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(Collection<String> itemIds) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> items = new ArrayList<Item>(itemIds.size());
|
||||
/**
|
||||
* Delete the items with the specified id's from the node.
|
||||
*
|
||||
* @param itemIds The list of id's of items to delete
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void deleteItem(Collection<String> itemIds) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
List<Item> items = new ArrayList<Item>(itemIds.size());
|
||||
|
||||
for (String id : itemIds)
|
||||
{
|
||||
items.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.set, new ItemsExtension(ItemsExtension.ItemsElementType.retract, getId(), items));
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
for (String id : itemIds)
|
||||
{
|
||||
items.add(new Item(id));
|
||||
}
|
||||
PubSub request = createPubsubPacket(Type.set, new ItemsExtension(ItemsExtension.ItemsElementType.retract, getId(), items));
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,97 +48,97 @@ abstract public class Node
|
|||
protected final PubSubManager pubSubManager;
|
||||
protected final String id;
|
||||
|
||||
protected ConcurrentHashMap<ItemEventListener<Item>, StanzaListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, StanzaListener>();
|
||||
protected ConcurrentHashMap<ItemDeleteListener, StanzaListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, StanzaListener>();
|
||||
protected ConcurrentHashMap<NodeConfigListener, StanzaListener> configEventToListenerMap = new ConcurrentHashMap<NodeConfigListener, StanzaListener>();
|
||||
protected ConcurrentHashMap<ItemEventListener<Item>, StanzaListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, StanzaListener>();
|
||||
protected ConcurrentHashMap<ItemDeleteListener, StanzaListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, StanzaListener>();
|
||||
protected ConcurrentHashMap<NodeConfigListener, StanzaListener> configEventToListenerMap = new ConcurrentHashMap<NodeConfigListener, StanzaListener>();
|
||||
|
||||
/**
|
||||
* Construct a node associated to the supplied connection with the specified
|
||||
* node id.
|
||||
*
|
||||
* @param connection The connection the node is associated with
|
||||
* @param nodeName The node id
|
||||
*/
|
||||
Node(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
this.pubSubManager = pubSubManager;
|
||||
id = nodeId;
|
||||
}
|
||||
/**
|
||||
* Construct a node associated to the supplied connection with the specified
|
||||
* node id.
|
||||
*
|
||||
* @param connection The connection the node is associated with
|
||||
* @param nodeName The node id
|
||||
*/
|
||||
Node(PubSubManager pubSubManager, String nodeId)
|
||||
{
|
||||
this.pubSubManager = pubSubManager;
|
||||
id = nodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeId.
|
||||
*
|
||||
* @return the node id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Returns a configuration form, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return the configuration form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public ConfigureForm getNodeConfiguration() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Get the NodeId.
|
||||
*
|
||||
* @return the node id
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Returns a configuration form, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return the configuration form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public ConfigureForm getNodeConfiguration() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(
|
||||
PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER);
|
||||
Stanza reply = sendPubsubPacket(pubSub);
|
||||
return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER);
|
||||
}
|
||||
Stanza reply = sendPubsubPacket(pubSub);
|
||||
return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the configuration with the contents of the new {@link Form}.
|
||||
*
|
||||
* @param submitForm
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void sendConfigurationForm(Form submitForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Update the configuration with the contents of the new {@link Form}.
|
||||
*
|
||||
* @param submitForm
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void sendConfigurationForm(Form submitForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = createPubsubPacket(Type.set, new FormNode(FormNodeType.CONFIGURE_OWNER,
|
||||
getId(), submitForm), PubSubNamespace.OWNER);
|
||||
pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover node information in standard {@link DiscoverInfo} format.
|
||||
*
|
||||
* @return The discovery information about the node.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverInfo info = new DiscoverInfo();
|
||||
info.setTo(pubSubManager.getServiceJid());
|
||||
info.setNode(getId());
|
||||
return pubSubManager.getConnection().createStanzaCollectorAndSend(info).nextResultOrThrow();
|
||||
}
|
||||
/**
|
||||
* Discover node information in standard {@link DiscoverInfo} format.
|
||||
*
|
||||
* @return The discovery information about the node.
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
DiscoverInfo info = new DiscoverInfo();
|
||||
info.setTo(pubSubManager.getServiceJid());
|
||||
info.setNode(getId());
|
||||
return pubSubManager.getConnection().createStanzaCollectorAndSend(info).nextResultOrThrow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subscriptions currently associated with this node.
|
||||
*
|
||||
* @return List of {@link Subscription}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public List<Subscription> getSubscriptions() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
/**
|
||||
* Get the subscriptions currently associated with this node.
|
||||
*
|
||||
* @return List of {@link Subscription}
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public List<Subscription> getSubscriptions() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getSubscriptions(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subscriptions currently associated with this node.
|
||||
|
@ -223,15 +223,15 @@ abstract public class Node
|
|||
return subElem.getSubscriptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the affiliations of this node.
|
||||
*
|
||||
* @return List of {@link Affiliation}
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
/**
|
||||
* Get the affiliations of this node.
|
||||
*
|
||||
* @return List of {@link Affiliation}
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public List<Affiliation> getAffiliations() throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException {
|
||||
return getAffiliations(null, null);
|
||||
|
@ -346,398 +346,396 @@ abstract public class Node
|
|||
return sendPubsubPacket(pubSub);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid. The
|
||||
* bare jid portion of this one must match the jid for the connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
PubSub pubSub = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
// CHECKSTYLE:ON
|
||||
PubSub reply = sendPubsubPacket(pubSub);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid. The
|
||||
* bare jid portion of this one must match the jid for the connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub pubSub = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
PubSub reply = sendPubsubPacket(pubSub);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid and subscription
|
||||
* options. The bare jid portion of this one must match the jid for the
|
||||
* connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid, SubscribeForm subForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
PubSub request = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
// CHECKSTYLE:ON
|
||||
request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm));
|
||||
PubSub reply = sendPubsubPacket(request);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
/**
|
||||
* The user subscribes to the node using the supplied jid and subscription
|
||||
* options. The bare jid portion of this one must match the jid for the
|
||||
* connection.
|
||||
*
|
||||
* Please note that the {@link Subscription.State} should be checked
|
||||
* on return since more actions may be required by the caller.
|
||||
* {@link Subscription.State#pending} - The owner must approve the subscription
|
||||
* request before messages will be received.
|
||||
* {@link Subscription.State#unconfigured} - If the {@link Subscription#isConfigRequired()} is true,
|
||||
* the caller must configure the subscription before messages will be received. If it is false
|
||||
* the caller can configure it but is not required to do so.
|
||||
* @param jid The jid to subscribe as.
|
||||
* @return The subscription
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Subscription subscribe(String jid, SubscribeForm subForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub request = createPubsubPacket(Type.set, new SubscribeExtension(jid, getId()));
|
||||
request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm));
|
||||
PubSub reply = sendPubsubPacket(request);
|
||||
return reply.getExtension(PubSubElementType.SUBSCRIPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the subscription related to the specified JID. This will only
|
||||
* work if there is only 1 subscription. If there are multiple subscriptions,
|
||||
* use {@link #unsubscribe(String, String)}.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void unsubscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
unsubscribe(jid, null);
|
||||
}
|
||||
/**
|
||||
* Remove the subscription related to the specified JID. This will only
|
||||
* work if there is only 1 subscription. If there are multiple subscriptions,
|
||||
* use {@link #unsubscribe(String, String)}.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public void unsubscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
unsubscribe(jid, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specific subscription related to the specified JID.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @param subscriptionId The id of the subscription being removed
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void unsubscribe(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
sendPubsubPacket(createPubsubPacket(Type.set, new UnsubscribeExtension(jid, getId(), subscriptionId)));
|
||||
}
|
||||
/**
|
||||
* Remove the specific subscription related to the specified JID.
|
||||
*
|
||||
* @param jid The JID used to subscribe to the node
|
||||
* @param subscriptionId The id of the subscription being removed
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void unsubscribe(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
sendPubsubPacket(createPubsubPacket(Type.set, new UnsubscribeExtension(jid, getId(), subscriptionId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SubscribeForm for subscriptions, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return A subscription options form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getSubscriptionOptions(jid, null);
|
||||
}
|
||||
/**
|
||||
* Returns a SubscribeForm for subscriptions, from which you can create an answer form to be submitted
|
||||
* via the {@link #sendConfigurationForm(Form)}.
|
||||
*
|
||||
* @return A subscription options form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return getSubscriptionOptions(jid, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the options for configuring the specified subscription.
|
||||
*
|
||||
* @param jid JID the subscription is registered under
|
||||
* @param subscriptionId The subscription id
|
||||
*
|
||||
* @return The subscription option form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = sendPubsubPacket(createPubsubPacket(Type.get, new OptionsExtension(jid, getId(), subscriptionId)));
|
||||
FormNode ext = packet.getExtension(PubSubElementType.OPTIONS);
|
||||
return new SubscribeForm(ext.getForm());
|
||||
}
|
||||
/**
|
||||
* Get the options for configuring the specified subscription.
|
||||
*
|
||||
* @param jid JID the subscription is registered under
|
||||
* @param subscriptionId The subscription id
|
||||
*
|
||||
* @return The subscription option form
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*
|
||||
*/
|
||||
public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
PubSub packet = sendPubsubPacket(createPubsubPacket(Type.get, new OptionsExtension(jid, getId(), subscriptionId)));
|
||||
FormNode ext = packet.getExtension(PubSubElementType.OPTIONS);
|
||||
return new SubscribeForm(ext.getForm());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener for item publication events. This
|
||||
* listener will get called whenever an item is published to
|
||||
* this node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
/**
|
||||
* Register a listener for item publication events. This
|
||||
* listener will get called whenever an item is published to
|
||||
* this node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addItemEventListener(@SuppressWarnings("rawtypes") ItemEventListener listener)
|
||||
{
|
||||
StanzaListener conListener = new ItemEventTranslator(listener);
|
||||
itemEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item"));
|
||||
}
|
||||
{
|
||||
StanzaListener conListener = new ItemEventTranslator(listener);
|
||||
itemEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener for publication events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemEventListener(@SuppressWarnings("rawtypes") ItemEventListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemEventToListenerMap.remove(listener);
|
||||
/**
|
||||
* Unregister a listener for publication events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemEventListener(@SuppressWarnings("rawtypes") ItemEventListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemEventToListenerMap.remove(listener);
|
||||
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a listener for configuration events. This listener
|
||||
* will get called whenever the node's configuration changes.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = new NodeConfigTranslator(listener);
|
||||
configEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.configuration.toString()));
|
||||
}
|
||||
/**
|
||||
* Register a listener for configuration events. This listener
|
||||
* will get called whenever the node's configuration changes.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = new NodeConfigTranslator(listener);
|
||||
configEventToListenerMap.put(listener, conListener);
|
||||
pubSubManager.getConnection().addSyncStanzaListener(conListener, new EventContentFilter(EventElementType.configuration.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener for configuration events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = configEventToListenerMap .remove(listener);
|
||||
/**
|
||||
* Unregister a listener for configuration events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeConfigurationListener(NodeConfigListener listener)
|
||||
{
|
||||
StanzaListener conListener = configEventToListenerMap .remove(listener);
|
||||
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an listener for item delete events. This listener
|
||||
* gets called whenever an item is deleted from the node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener delListener = new ItemDeleteTranslator(listener);
|
||||
itemDeleteToListenerMap.put(listener, delListener);
|
||||
EventContentFilter deleteItem = new EventContentFilter(EventElementType.items.toString(), "retract");
|
||||
EventContentFilter purge = new EventContentFilter(EventElementType.purge.toString());
|
||||
/**
|
||||
* Register an listener for item delete events. This listener
|
||||
* gets called whenever an item is deleted from the node.
|
||||
*
|
||||
* @param listener The handler for the event
|
||||
*/
|
||||
public void addItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener delListener = new ItemDeleteTranslator(listener);
|
||||
itemDeleteToListenerMap.put(listener, delListener);
|
||||
EventContentFilter deleteItem = new EventContentFilter(EventElementType.items.toString(), "retract");
|
||||
EventContentFilter purge = new EventContentFilter(EventElementType.purge.toString());
|
||||
|
||||
pubSubManager.getConnection().addSyncStanzaListener(delListener, new OrFilter(deleteItem, purge));
|
||||
}
|
||||
pubSubManager.getConnection().addSyncStanzaListener(delListener, new OrFilter(deleteItem, purge));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a listener for item delete events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemDeleteToListenerMap .remove(listener);
|
||||
/**
|
||||
* Unregister a listener for item delete events.
|
||||
*
|
||||
* @param listener The handler to unregister
|
||||
*/
|
||||
public void removeItemDeleteListener(ItemDeleteListener listener)
|
||||
{
|
||||
StanzaListener conListener = itemDeleteToListenerMap .remove(listener);
|
||||
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
if (conListener != null)
|
||||
pubSubManager.getConnection().removeSyncStanzaListener(conListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return super.toString() + " " + getClass().getName() + " id: " + id;
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return super.toString() + " " + getClass().getName() + " id: " + id;
|
||||
}
|
||||
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext)
|
||||
{
|
||||
return createPubsubPacket(type, ext, null);
|
||||
}
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext)
|
||||
{
|
||||
return createPubsubPacket(type, ext, null);
|
||||
}
|
||||
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext, PubSubNamespace ns)
|
||||
{
|
||||
protected PubSub createPubsubPacket(Type type, ExtensionElement ext, PubSubNamespace ns)
|
||||
{
|
||||
return PubSub.createPubsubPacket(pubSubManager.getServiceJid(), type, ext, ns);
|
||||
}
|
||||
}
|
||||
|
||||
protected PubSub sendPubsubPacket(PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return pubSubManager.sendPubsubPacket(packet);
|
||||
}
|
||||
protected PubSub sendPubsubPacket(PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
return pubSubManager.sendPubsubPacket(packet);
|
||||
}
|
||||
|
||||
|
||||
private static List<String> getSubscriptionIds(Stanza packet)
|
||||
{
|
||||
HeadersExtension headers = (HeadersExtension)packet.getExtension("headers", "http://jabber.org/protocol/shim");
|
||||
List<String> values = null;
|
||||
private static List<String> getSubscriptionIds(Stanza packet)
|
||||
{
|
||||
HeadersExtension headers = (HeadersExtension)packet.getExtension("headers", "http://jabber.org/protocol/shim");
|
||||
List<String> values = null;
|
||||
|
||||
if (headers != null)
|
||||
{
|
||||
values = new ArrayList<String>(headers.getHeaders().size());
|
||||
if (headers != null)
|
||||
{
|
||||
values = new ArrayList<String>(headers.getHeaders().size());
|
||||
|
||||
for (Header header : headers.getHeaders())
|
||||
{
|
||||
values.add(header.getValue());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
for (Header header : headers.getHeaders())
|
||||
{
|
||||
values.add(header.getValue());
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class translates low level item publication events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemEventTranslator implements StanzaListener
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
/**
|
||||
* This class translates low level item publication events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemEventTranslator implements StanzaListener
|
||||
{
|
||||
@SuppressWarnings("rawtypes")
|
||||
private ItemEventListener listener;
|
||||
|
||||
public ItemEventTranslator(@SuppressWarnings("rawtypes") ItemEventListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
public ItemEventTranslator(@SuppressWarnings("rawtypes") ItemEventListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public void processStanza(Stanza packet)
|
||||
{
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
// CHECKSTYLE:ON
|
||||
ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
|
||||
ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
|
||||
ItemPublishEvent eventItems = new ItemPublishEvent(itemsElem.getNode(), itemsElem.getItems(), getSubscriptionIds(packet), DelayInformationManager.getDelayTimestamp(packet));
|
||||
listener.handlePublishedItems(eventItems);
|
||||
}
|
||||
}
|
||||
listener.handlePublishedItems(eventItems);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class translates low level item deletion events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemDeleteTranslator implements StanzaListener
|
||||
{
|
||||
private ItemDeleteListener listener;
|
||||
/**
|
||||
* This class translates low level item deletion events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class ItemDeleteTranslator implements StanzaListener
|
||||
{
|
||||
private ItemDeleteListener listener;
|
||||
|
||||
public ItemDeleteTranslator(ItemDeleteListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
public ItemDeleteTranslator(ItemDeleteListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
|
||||
public void processStanza(Stanza packet)
|
||||
{
|
||||
@Override
|
||||
public void processStanza(Stanza packet)
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
|
||||
List<ExtensionElement> extList = event.getExtensions();
|
||||
List<ExtensionElement> extList = event.getExtensions();
|
||||
|
||||
if (extList.get(0).getElementName().equals(PubSubElementType.PURGE_EVENT.getElementName()))
|
||||
{
|
||||
listener.handlePurge();
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
|
||||
@SuppressWarnings("unchecked")
|
||||
if (extList.get(0).getElementName().equals(PubSubElementType.PURGE_EVENT.getElementName()))
|
||||
{
|
||||
listener.handlePurge();
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemsExtension itemsElem = (ItemsExtension)event.getEvent();
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<RetractItem> pubItems = (Collection<RetractItem>) itemsElem.getItems();
|
||||
List<String> items = new ArrayList<String>(pubItems.size());
|
||||
List<String> items = new ArrayList<String>(pubItems.size());
|
||||
|
||||
for (RetractItem item : pubItems)
|
||||
{
|
||||
items.add(item.getId());
|
||||
}
|
||||
for (RetractItem item : pubItems)
|
||||
{
|
||||
items.add(item.getId());
|
||||
}
|
||||
|
||||
ItemDeleteEvent eventItems = new ItemDeleteEvent(itemsElem.getNode(), items, getSubscriptionIds(packet));
|
||||
listener.handleDeletedItems(eventItems);
|
||||
}
|
||||
ItemDeleteEvent eventItems = new ItemDeleteEvent(itemsElem.getNode(), items, getSubscriptionIds(packet));
|
||||
listener.handleDeletedItems(eventItems);
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class translates low level node configuration events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public class NodeConfigTranslator implements StanzaListener
|
||||
{
|
||||
private NodeConfigListener listener;
|
||||
/**
|
||||
* This class translates low level node configuration events into api level objects for
|
||||
* user consumption.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public static class NodeConfigTranslator implements StanzaListener
|
||||
{
|
||||
private NodeConfigListener listener;
|
||||
|
||||
public NodeConfigTranslator(NodeConfigListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
public NodeConfigTranslator(NodeConfigListener eventListener)
|
||||
{
|
||||
listener = eventListener;
|
||||
}
|
||||
|
||||
public void processStanza(Stanza packet)
|
||||
{
|
||||
// CHECKSTYLE:OFF
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
ConfigurationEvent config = (ConfigurationEvent)event.getEvent();
|
||||
// CHECKSTYLE:ON
|
||||
@Override
|
||||
public void processStanza(Stanza packet)
|
||||
{
|
||||
EventElement event = (EventElement)packet.getExtension("event", PubSubNamespace.EVENT.getXmlns());
|
||||
ConfigurationEvent config = (ConfigurationEvent)event.getEvent();
|
||||
|
||||
listener.handleNodeConfiguration(config);
|
||||
}
|
||||
}
|
||||
listener.handleNodeConfiguration(config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for {@link StanzaListener} to filter out events not specific to the
|
||||
* event type expected for this node.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
class EventContentFilter extends FlexibleStanzaTypeFilter<Message>
|
||||
{
|
||||
/**
|
||||
* Filter for {@link StanzaListener} to filter out events not specific to the
|
||||
* event type expected for this node.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
class EventContentFilter extends FlexibleStanzaTypeFilter<Message>
|
||||
{
|
||||
private final String firstElement;
|
||||
private final String secondElement;
|
||||
private final boolean allowEmpty;
|
||||
|
||||
EventContentFilter(String elementName)
|
||||
{
|
||||
EventContentFilter(String elementName)
|
||||
{
|
||||
this(elementName, null);
|
||||
}
|
||||
}
|
||||
|
||||
EventContentFilter(String firstLevelEelement, String secondLevelElement)
|
||||
{
|
||||
firstElement = firstLevelEelement;
|
||||
secondElement = secondLevelElement;
|
||||
EventContentFilter(String firstLevelEelement, String secondLevelElement)
|
||||
{
|
||||
firstElement = firstLevelEelement;
|
||||
secondElement = secondLevelElement;
|
||||
allowEmpty = firstElement.equals(EventElementType.items.toString())
|
||||
&& "item".equals(secondLevelElement);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptSpecific(Message message) {
|
||||
EventElement event = EventElement.from(message);
|
||||
|
||||
if (event == null)
|
||||
return false;
|
||||
if (event == null)
|
||||
return false;
|
||||
|
||||
NodeExtension embedEvent = event.getEvent();
|
||||
NodeExtension embedEvent = event.getEvent();
|
||||
|
||||
if (embedEvent == null)
|
||||
return false;
|
||||
if (embedEvent == null)
|
||||
return false;
|
||||
|
||||
if (embedEvent.getElementName().equals(firstElement))
|
||||
{
|
||||
if (!embedEvent.getNode().equals(getId()))
|
||||
return false;
|
||||
if (embedEvent.getElementName().equals(firstElement))
|
||||
{
|
||||
if (!embedEvent.getNode().equals(getId()))
|
||||
return false;
|
||||
|
||||
if (secondElement == null)
|
||||
return true;
|
||||
if (secondElement == null)
|
||||
return true;
|
||||
|
||||
if (embedEvent instanceof EmbeddedPacketExtension)
|
||||
{
|
||||
List<ExtensionElement> secondLevelList = ((EmbeddedPacketExtension)embedEvent).getExtensions();
|
||||
if (embedEvent instanceof EmbeddedPacketExtension)
|
||||
{
|
||||
List<ExtensionElement> secondLevelList = ((EmbeddedPacketExtension)embedEvent).getExtensions();
|
||||
|
||||
// XEP-0060 allows no elements on second level for notifications. See schema or
|
||||
// for example § 4.3:
|
||||
|
@ -746,11 +744,11 @@ abstract public class Node
|
|||
return true;
|
||||
}
|
||||
|
||||
if (secondLevelList.size() > 0 && secondLevelList.get(0).getElementName().equals(secondElement))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (secondLevelList.size() > 0 && secondLevelList.get(0).getElementName().equals(secondElement))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,15 @@ package org.jivesoftware.smackx.pubsub;
|
|||
|
||||
abstract public class NodeEvent
|
||||
{
|
||||
private String nodeId;
|
||||
private String nodeId;
|
||||
|
||||
protected NodeEvent(String id)
|
||||
{
|
||||
nodeId = id;
|
||||
}
|
||||
protected NodeEvent(String id)
|
||||
{
|
||||
nodeId = id;
|
||||
}
|
||||
|
||||
public String getNodeId()
|
||||
{
|
||||
return nodeId;
|
||||
}
|
||||
public String getNodeId()
|
||||
{
|
||||
return nodeId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,61 +28,64 @@ import org.jivesoftware.smack.packet.ExtensionElement;
|
|||
*/
|
||||
public class NodeExtension implements ExtensionElement
|
||||
{
|
||||
private final PubSubElementType element;
|
||||
private final String node;
|
||||
private final PubSubElementType element;
|
||||
private final String node;
|
||||
|
||||
/**
|
||||
* Constructs a <tt>NodeExtension</tt> with an element name specified
|
||||
* by {@link PubSubElementType} and the specified node id.
|
||||
*
|
||||
* @param elem Defines the element name and namespace
|
||||
* @param nodeId Specifies the id of the node
|
||||
*/
|
||||
public NodeExtension(PubSubElementType elem, String nodeId)
|
||||
{
|
||||
element = elem;
|
||||
this.node = nodeId;
|
||||
}
|
||||
/**
|
||||
* Constructs a <tt>NodeExtension</tt> with an element name specified
|
||||
* by {@link PubSubElementType} and the specified node id.
|
||||
*
|
||||
* @param elem Defines the element name and namespace
|
||||
* @param nodeId Specifies the id of the node
|
||||
*/
|
||||
public NodeExtension(PubSubElementType elem, String nodeId)
|
||||
{
|
||||
element = elem;
|
||||
this.node = nodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <tt>NodeExtension</tt> with an element name specified
|
||||
* by {@link PubSubElementType}.
|
||||
*
|
||||
* @param elem Defines the element name and namespace
|
||||
*/
|
||||
public NodeExtension(PubSubElementType elem)
|
||||
{
|
||||
this(elem, null);
|
||||
}
|
||||
/**
|
||||
* Constructs a <tt>NodeExtension</tt> with an element name specified
|
||||
* by {@link PubSubElementType}.
|
||||
*
|
||||
* @param elem Defines the element name and namespace
|
||||
*/
|
||||
public NodeExtension(PubSubElementType elem)
|
||||
{
|
||||
this(elem, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node id.
|
||||
*
|
||||
* @return The node id
|
||||
*/
|
||||
public String getNode()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
/**
|
||||
* Gets the node id.
|
||||
*
|
||||
* @return The node id
|
||||
*/
|
||||
public String getNode()
|
||||
{
|
||||
return node;
|
||||
}
|
||||
|
||||
public String getElementName()
|
||||
{
|
||||
return element.getElementName();
|
||||
}
|
||||
@Override
|
||||
public String getElementName()
|
||||
{
|
||||
return element.getElementName();
|
||||
}
|
||||
|
||||
public String getNamespace()
|
||||
{
|
||||
return element.getNamespace().getXmlns();
|
||||
}
|
||||
@Override
|
||||
public String getNamespace()
|
||||
{
|
||||
return element.getNamespace().getXmlns();
|
||||
}
|
||||
|
||||
public CharSequence toXML()
|
||||
{
|
||||
return '<' + getElementName() + (node == null ? "" : " node='" + node + '\'') + "/>";
|
||||
}
|
||||
@Override
|
||||
public CharSequence toXML()
|
||||
{
|
||||
return '<' + getElementName() + (node == null ? "" : " node='" + node + '\'') + "/>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " - content [" + toXML() + "]";
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getName() + " - content [" + toXML() + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,6 @@ package org.jivesoftware.smackx.pubsub;
|
|||
*/
|
||||
public enum NodeType
|
||||
{
|
||||
leaf,
|
||||
collection;
|
||||
leaf,
|
||||
collection;
|
||||
}
|
||||
|
|
|
@ -25,35 +25,35 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
|||
*/
|
||||
public class OptionsExtension extends NodeExtension
|
||||
{
|
||||
protected String jid;
|
||||
protected String id;
|
||||
protected String jid;
|
||||
protected String id;
|
||||
|
||||
public OptionsExtension(String subscriptionJid)
|
||||
{
|
||||
this(subscriptionJid, null, null);
|
||||
}
|
||||
public OptionsExtension(String subscriptionJid)
|
||||
{
|
||||
this(subscriptionJid, null, null);
|
||||
}
|
||||
|
||||
public OptionsExtension(String subscriptionJid, String nodeId)
|
||||
{
|
||||
this(subscriptionJid, nodeId, null);
|
||||
}
|
||||
public OptionsExtension(String subscriptionJid, String nodeId)
|
||||
{
|
||||
this(subscriptionJid, nodeId, null);
|
||||
}
|
||||
|
||||
public OptionsExtension(String jid, String nodeId, String subscriptionId)
|
||||
{
|
||||
super(PubSubElementType.OPTIONS, nodeId);
|
||||
this.jid = jid;
|
||||
id = subscriptionId;
|
||||
}
|
||||
public OptionsExtension(String jid, String nodeId, String subscriptionId)
|
||||
{
|
||||
super(PubSubElementType.OPTIONS, nodeId);
|
||||
this.jid = jid;
|
||||
id = subscriptionId;
|
||||
}
|
||||
|
||||
public String getJid()
|
||||
{
|
||||
return jid;
|
||||
}
|
||||
public String getJid()
|
||||
{
|
||||
return jid;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlStringBuilder toXML() {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue