mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-22 20:47:57 +01:00
Add MucBookmarkAutojoinManager
Also add MucConfigFormManager and improve the MUC API (SMACK-648). Bump to jxmpp 0.5.0-alpha3. Improve and extend PrivateDataManager and BookmarkManager.
This commit is contained in:
parent
265e5c69d5
commit
f274581c27
15 changed files with 690 additions and 102 deletions
|
@ -38,8 +38,8 @@ the _**MultiUserChat**_ instance where nickname is the nickname to use when
|
|||
joining the room.
|
||||
|
||||
Depending on the type of room that you want to create you will have to use
|
||||
different configuration forms. In order to create an Instant room just send
|
||||
**sendConfigurationForm(Form form)** where form is an empty form. But if you
|
||||
different configuration forms. In order to create an Instant room just use
|
||||
`MucCreateConfigFormHandle.makeInstant()`. But if you
|
||||
want to create a Reserved room then you should first get the room's
|
||||
configuration form, complete the form and finally send it back to the server.
|
||||
|
||||
|
@ -54,12 +54,8 @@ MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
|
|||
// Get a MultiUserChat using MultiUserChatManager
|
||||
MultiUserChat muc = manager.getMultiUserChat("myroom@conference.jabber.org");
|
||||
|
||||
// Create the room
|
||||
muc.create("testbot");
|
||||
|
||||
// Send an empty room configuration form which indicates that we want
|
||||
// an instant room
|
||||
muc.sendConfigurationForm(new Form(DataForm.Type.submit));
|
||||
// Create the room and send an empty configuration form to make this an instant room
|
||||
muc.create("testbot").makeInstant();
|
||||
```
|
||||
|
||||
In this example we can see how to create a reserved room. The form is
|
||||
|
@ -72,27 +68,14 @@ MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
|
|||
// Create a MultiUserChat using an XMPPConnection for a room
|
||||
MultiUserChat muc = = manager.getMultiUserChat("myroom@conference.jabber.org");
|
||||
|
||||
// Create the room
|
||||
muc.create("testbot");
|
||||
// Prepare a list of owners of the new room
|
||||
Set<Jid> owners = JidUtil.jidSetFrom(new String[] { "me@example.org", "juliet@example.org" });
|
||||
|
||||
// Get the the room's configuration form
|
||||
Form form = muc.getConfigurationForm();
|
||||
// Create a new form to submit based on the original form
|
||||
Form submitForm = form.createAnswerForm();
|
||||
// Add default answers to the form to submit
|
||||
for (Iterator fields = form.getFields(); fields.hasNext();) {
|
||||
FormField field = (FormField) fields.next();
|
||||
if (!FormField.type.hidden.equals(field.getType()) && field.getVariable() != null) {
|
||||
// Sets the default value as the answer
|
||||
submitForm.setDefaultAnswer(field.getVariable());
|
||||
}
|
||||
}
|
||||
// Sets the new owner of the room
|
||||
List owners = new ArrayList();
|
||||
owners.add("johndoe@jabber.org");
|
||||
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
|
||||
// Send the completed form (with default values) to the server to configure the room
|
||||
muc.sendConfigurationForm(submitForm);
|
||||
// Create the room
|
||||
muc.create("testbot")
|
||||
.getConfigFormManger()
|
||||
.setRoomOwners(owners)
|
||||
.submitConfigurationForm();
|
||||
```
|
||||
|
||||
Join a room
|
||||
|
|
|
@ -28,6 +28,8 @@ import org.jivesoftware.smack.SmackException.NotConnectedException;
|
|||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smackx.iqprivate.PrivateDataManager;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -109,8 +111,8 @@ public final class BookmarkManager {
|
|||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void addBookmarkedConference(String name, String jid, boolean isAutoJoin,
|
||||
String nickname, String password) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
public void addBookmarkedConference(String name, BareJid jid, boolean isAutoJoin,
|
||||
Resourcepart nickname, String password) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
|
||||
{
|
||||
retrieveBookmarks();
|
||||
BookmarkedConference bookmark
|
||||
|
@ -144,12 +146,12 @@ public final class BookmarkManager {
|
|||
* @throws IllegalArgumentException thrown when the conference being removed is a shared
|
||||
* conference
|
||||
*/
|
||||
public void removeBookmarkedConference(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
public void removeBookmarkedConference(BareJid jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
retrieveBookmarks();
|
||||
Iterator<BookmarkedConference> it = bookmarks.getBookmarkedConferences().iterator();
|
||||
while(it.hasNext()) {
|
||||
BookmarkedConference conference = it.next();
|
||||
if(conference.getJid().equalsIgnoreCase(jid)) {
|
||||
if(conference.getJid().equals(jid)) {
|
||||
if(conference.isShared()) {
|
||||
throw new IllegalArgumentException("Conference is shared and can't be removed");
|
||||
}
|
||||
|
@ -230,6 +232,22 @@ public final class BookmarkManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the service supports bookmarks using private data.
|
||||
*
|
||||
* @return true if the service supports private data, false otherwise.
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws XMPPErrorException
|
||||
* @see PrivateDataManager#isSupported()
|
||||
* @since 4.2
|
||||
*/
|
||||
public boolean isSupported() throws NoResponseException, NotConnectedException,
|
||||
XMPPErrorException, InterruptedException {
|
||||
return privateDataManager.isSupported();
|
||||
}
|
||||
|
||||
private Bookmarks retrieveBookmarks() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
synchronized(bookmarkLock) {
|
||||
if(bookmarks == null) {
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
|
||||
package org.jivesoftware.smackx.bookmarks;
|
||||
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
|
||||
/**
|
||||
* Respresents a Conference Room bookmarked on the server using XEP-0048 Bookmark Storage XEP.
|
||||
*
|
||||
|
@ -26,17 +29,17 @@ public class BookmarkedConference implements SharedBookmark {
|
|||
|
||||
private String name;
|
||||
private boolean autoJoin;
|
||||
private final String jid;
|
||||
private final BareJid jid;
|
||||
|
||||
private String nickname;
|
||||
private Resourcepart nickname;
|
||||
private String password;
|
||||
private boolean isShared;
|
||||
|
||||
protected BookmarkedConference(String jid) {
|
||||
protected BookmarkedConference(BareJid jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
|
||||
protected BookmarkedConference(String name, String jid, boolean autoJoin, String nickname,
|
||||
protected BookmarkedConference(String name, BareJid jid, boolean autoJoin, Resourcepart nickname,
|
||||
String password)
|
||||
{
|
||||
this.name = name;
|
||||
|
@ -78,7 +81,7 @@ public class BookmarkedConference implements SharedBookmark {
|
|||
*
|
||||
* @return the full JID of this conference room.
|
||||
*/
|
||||
public String getJid() {
|
||||
public BareJid getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
|
@ -88,11 +91,11 @@ public class BookmarkedConference implements SharedBookmark {
|
|||
*
|
||||
* @return the nickname to use when joining, null may be returned.
|
||||
*/
|
||||
public String getNickname() {
|
||||
public Resourcepart getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
protected void setNickname(String nickname) {
|
||||
protected void setNickname(Resourcepart nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
|
@ -116,7 +119,7 @@ public class BookmarkedConference implements SharedBookmark {
|
|||
return false;
|
||||
}
|
||||
BookmarkedConference conference = (BookmarkedConference)obj;
|
||||
return conference.getJid().equalsIgnoreCase(jid);
|
||||
return conference.getJid().equals(jid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.bookmarks;
|
||||
|
||||
import org.jivesoftware.smack.util.ParserUtils;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jivesoftware.smackx.iqprivate.packet.PrivateData;
|
||||
import org.jivesoftware.smackx.iqprivate.provider.PrivateDataProvider;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
|
@ -268,7 +271,7 @@ public class Bookmarks implements PrivateData {
|
|||
private static BookmarkedConference getConferenceStorage(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
String name = parser.getAttributeValue("", "name");
|
||||
String autojoin = parser.getAttributeValue("", "autojoin");
|
||||
String jid = parser.getAttributeValue("", "jid");
|
||||
BareJid jid = ParserUtils.getBareJidAttribute(parser);
|
||||
|
||||
BookmarkedConference conf = new BookmarkedConference(jid);
|
||||
conf.setName(name);
|
||||
|
@ -279,7 +282,8 @@ public class Bookmarks implements PrivateData {
|
|||
while (!done) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG && "nick".equals(parser.getName())) {
|
||||
conf.setNickname(parser.nextText());
|
||||
String nickString = parser.nextText();
|
||||
conf.setNickname(Resourcepart.from(nickString));
|
||||
}
|
||||
else if (eventType == XmlPullParser.START_TAG && "password".equals(parser.getName())) {
|
||||
conf.setPassword(parser.nextText());
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException;
|
|||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.XMPPError.Condition;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.iqprivate.packet.DefaultPrivateData;
|
||||
import org.jivesoftware.smackx.iqprivate.packet.PrivateData;
|
||||
|
@ -184,6 +185,51 @@ public final class PrivateDataManager extends Manager {
|
|||
connection().createPacketCollectorAndSend(privateDataSet).nextResultOrThrow();
|
||||
}
|
||||
|
||||
private static final PrivateData DUMMY_PRIVATE_DATA = new PrivateData() {
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return "smackDummyPrivateData";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNamespace() {
|
||||
return "https://igniterealtime.org/projects/smack/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML() {
|
||||
return '<' + getElementName() + " xmlns='" + getNamespace() + "'/>";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the service supports private data.
|
||||
*
|
||||
* @return true if the service supports private data, false otherwise.
|
||||
* @throws NoResponseException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws XMPPErrorException
|
||||
* @since 4.2
|
||||
*/
|
||||
public boolean isSupported() throws NoResponseException, NotConnectedException,
|
||||
InterruptedException, XMPPErrorException {
|
||||
// This is just a primitive hack, since XEP-49 does not specify a way to determine if the
|
||||
// service supports it
|
||||
try {
|
||||
setPrivateData(DUMMY_PRIVATE_DATA);
|
||||
return true;
|
||||
}
|
||||
catch (XMPPErrorException e) {
|
||||
if (e.getXMPPError().getCondition() == Condition.service_unavailable) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An IQ provider to parse IQ results containing private data.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2015 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MucConfigurationNotSupported;
|
||||
import org.jivesoftware.smackx.xdata.Form;
|
||||
import org.jivesoftware.smackx.xdata.FormField;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.util.JidUtil;
|
||||
|
||||
/**
|
||||
* Multi-User Chat configuration form manager is used to fill out and submit a {@link Form} used to
|
||||
* configure rooms.
|
||||
* <p>
|
||||
* Room configuration needs either be done right after the room is created and still locked. Or at
|
||||
* any later point (see <a href="http://xmpp.org/extensions/xep-0045.html#roomconfig">XEP-45 § 10.2
|
||||
* Subsequent Room Configuration</a>). When done with the configuration, call
|
||||
* {@link #submitConfigurationForm()}.
|
||||
* </p>
|
||||
* <p>
|
||||
* The manager may not provide all possible configuration options. If you want direct access to the
|
||||
* configuraiton form, use {@link MultiUserChat#getConfigurationForm()} and
|
||||
* {@link MultiUserChat#sendConfigurationForm(Form)}.
|
||||
* </p>
|
||||
*/
|
||||
public class MucConfigFormManager {
|
||||
public static final String MUC_ROOMCONFIG_ROOMOWNERS = "muc#roomconfig_roomowners";
|
||||
|
||||
private final MultiUserChat multiUserChat;
|
||||
private final Form answerForm;
|
||||
private final List<Jid> owners;
|
||||
|
||||
/**
|
||||
* Create a new MUC config form manager.
|
||||
* <p>
|
||||
* Note that the answerForm needs to be filled out with the defaults.
|
||||
* </p>
|
||||
*
|
||||
* @param multiUserChat the MUC for this configuration form.
|
||||
* @throws InterruptedException
|
||||
* @throws NotConnectedException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
*/
|
||||
MucConfigFormManager(MultiUserChat multiUserChat) throws NoResponseException,
|
||||
XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
this.multiUserChat = multiUserChat;
|
||||
|
||||
// Set the answer form
|
||||
Form configForm = multiUserChat.getConfigurationForm();
|
||||
this.answerForm = configForm.createAnswerForm();
|
||||
// Add the default answers to the form to submit
|
||||
for (FormField field : configForm.getFields()) {
|
||||
if (field.getType() == FormField.Type.hidden
|
||||
|| StringUtils.isNullOrEmpty(field.getVariable())) {
|
||||
continue;
|
||||
}
|
||||
answerForm.setDefaultAnswer(field.getVariable());
|
||||
}
|
||||
|
||||
// Set the local variables according to the fields found in the answer form
|
||||
if (answerForm.hasField(MUC_ROOMCONFIG_ROOMOWNERS)) {
|
||||
// Set 'owners' to the currently configured owners
|
||||
List<String> ownerStrings = answerForm.getField(MUC_ROOMCONFIG_ROOMOWNERS).getValues();
|
||||
owners = new ArrayList<>(ownerStrings.size());
|
||||
JidUtil.jidsFrom(ownerStrings, owners, null);
|
||||
}
|
||||
else {
|
||||
// roomowners not supported, this should barely be the case
|
||||
owners = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supportsRoomOwners() {
|
||||
return owners != null;
|
||||
}
|
||||
|
||||
public MucConfigFormManager setRoomOwners(Collection<? extends Jid> newOwners) throws MucConfigurationNotSupported {
|
||||
if (!supportsRoomOwners()) {
|
||||
throw new MucConfigurationNotSupported(MUC_ROOMCONFIG_ROOMOWNERS);
|
||||
}
|
||||
owners.clear();
|
||||
owners.addAll(newOwners);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void submitConfigurationForm() throws NoResponseException, XMPPErrorException, NotConnectedException,
|
||||
InterruptedException {
|
||||
if (owners != null) {
|
||||
answerForm.setAnswer(MUC_ROOMCONFIG_ROOMOWNERS, JidUtil.toStringList(owners));
|
||||
}
|
||||
multiUserChat.sendConfigurationForm(answerForm);
|
||||
}
|
||||
}
|
|
@ -57,6 +57,9 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
||||
import org.jivesoftware.smackx.iqregister.packet.Registration;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MucNotJoinedException;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException;
|
||||
import org.jivesoftware.smackx.muc.packet.Destroy;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCAdmin;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
|
||||
|
@ -354,25 +357,30 @@ public class MultiUserChat {
|
|||
* the room. {@link #sendConfigurationForm(Form)}
|
||||
*
|
||||
* @param nickname the nickname to use.
|
||||
* @return a handle to the MUC create configuration form API.
|
||||
* @throws XMPPErrorException if the room couldn't be created for some reason (e.g. 405 error if
|
||||
* the user is not allowed to create the room)
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws SmackException If the creation failed because of a missing acknowledge from the
|
||||
* server, e.g. because the room already existed.
|
||||
* @throws InterruptedException
|
||||
* @throws NotConnectedException
|
||||
* @throws MucAlreadyJoinedException
|
||||
* @throws MissingMucCreationAcknowledgeException
|
||||
*/
|
||||
public synchronized void create(Resourcepart nickname) throws NoResponseException, XMPPErrorException, SmackException, InterruptedException {
|
||||
public synchronized MucCreateConfigFormHandle create(Resourcepart nickname) throws NoResponseException,
|
||||
XMPPErrorException, InterruptedException, MucAlreadyJoinedException,
|
||||
NotConnectedException, MissingMucCreationAcknowledgeException {
|
||||
if (joined) {
|
||||
throw new IllegalStateException("Creation failed - User already joined the room.");
|
||||
throw new MucAlreadyJoinedException();
|
||||
}
|
||||
|
||||
if (createOrJoin(nickname)) {
|
||||
MucCreateConfigFormHandle mucCreateConfigFormHandle = createOrJoin(nickname);
|
||||
if (mucCreateConfigFormHandle != null) {
|
||||
// We successfully created a new room
|
||||
return;
|
||||
return mucCreateConfigFormHandle;
|
||||
}
|
||||
// We need to leave the room since it seems that the room already existed
|
||||
leave();
|
||||
throw new SmackException("Creation failed - Missing acknowledge of room creation.");
|
||||
throw new MissingMucCreationAcknowledgeException();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -380,15 +388,16 @@ public class MultiUserChat {
|
|||
* discussion history and using the connections default reply timeout.
|
||||
*
|
||||
* @param nickname
|
||||
* @return true if the room creation was acknowledged by the service, false otherwise.
|
||||
* @return A {@link MucCreateConfigFormHandle} if the room was created, or {code null} if the room was joined.
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws SmackException
|
||||
* @throws InterruptedException
|
||||
* @throws NotConnectedException
|
||||
* @throws MucAlreadyJoinedException
|
||||
* @see #createOrJoin(Resourcepart, String, DiscussionHistory, long)
|
||||
*/
|
||||
public synchronized boolean createOrJoin(Resourcepart nickname) throws NoResponseException, XMPPErrorException,
|
||||
SmackException, InterruptedException {
|
||||
public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname) throws NoResponseException, XMPPErrorException,
|
||||
InterruptedException, MucAlreadyJoinedException, NotConnectedException {
|
||||
return createOrJoin(nickname, null, null, connection.getPacketReplyTimeout());
|
||||
}
|
||||
|
||||
|
@ -402,16 +411,18 @@ public class MultiUserChat {
|
|||
* @param password the password to use.
|
||||
* @param history the amount of discussion history to receive while joining a room.
|
||||
* @param timeout the amount of time to wait for a reply from the MUC service(in milliseconds).
|
||||
* @return true if the room creation was acknowledged by the service, false otherwise.
|
||||
* @return A {@link MucCreateConfigFormHandle} if the room was created, or {code null} if the room was joined.
|
||||
* @throws XMPPErrorException if the room couldn't be created for some reason (e.g. 405 error if
|
||||
* the user is not allowed to create the room)
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws InterruptedException
|
||||
* @throws MucAlreadyJoinedException if the MUC is already joined
|
||||
* @throws NotConnectedException
|
||||
*/
|
||||
public synchronized boolean createOrJoin(Resourcepart nickname, String password, DiscussionHistory history, long timeout)
|
||||
throws NoResponseException, XMPPErrorException, SmackException, InterruptedException {
|
||||
public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname, String password, DiscussionHistory history, long timeout)
|
||||
throws NoResponseException, XMPPErrorException, InterruptedException, MucAlreadyJoinedException, NotConnectedException {
|
||||
if (joined) {
|
||||
throw new IllegalStateException("Creation failed - User already joined the room.");
|
||||
throw new MucAlreadyJoinedException();
|
||||
}
|
||||
|
||||
Presence presence = enter(nickname, password, history, timeout);
|
||||
|
@ -420,9 +431,78 @@ public class MultiUserChat {
|
|||
MUCUser mucUser = MUCUser.from(presence);
|
||||
if (mucUser != null && mucUser.getStatus().contains(Status.ROOM_CREATED_201)) {
|
||||
// Room was created and the user has joined the room
|
||||
return true;
|
||||
return new MucCreateConfigFormHandle();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A handle used to configure a newly created room. As long as the room is not configured it will be locked, which
|
||||
* means that no one is able to join. The room will become unlocked as soon it got configured. In order to create an
|
||||
* instant room, use {@link #makeInstant()}.
|
||||
* <p>
|
||||
* For advanced configuration options, use {@link MultiUserChat#getConfigurationForm()}, get the answer form with
|
||||
* {@link Form#createAnswerForm()}, fill it out and send it back to the room with
|
||||
* {@link MultiUserChat#sendConfigurationForm(Form)}.
|
||||
* </p>
|
||||
*/
|
||||
public class MucCreateConfigFormHandle {
|
||||
|
||||
/**
|
||||
* Create an instant room. The default configuration will be accepted and the room will become unlocked, i.e.
|
||||
* other users are able to join.
|
||||
*
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @see <a href="http://www.xmpp.org/extensions/xep-0045.html#createroom-instant">XEP-45 § 10.1.2 Creating an
|
||||
* Instant Room</a>
|
||||
*/
|
||||
public void makeInstant() throws NoResponseException, XMPPErrorException, NotConnectedException,
|
||||
InterruptedException {
|
||||
sendConfigurationForm(new Form(DataForm.Type.submit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for {@link MultiUserChat#getConfigFormManager()}.
|
||||
*
|
||||
* @return a MUC configuration form manager for this room.
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @see MultiUserChat#getConfigFormManager()
|
||||
*/
|
||||
public MucConfigFormManager getConfigFormManager() throws NoResponseException,
|
||||
XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
return MultiUserChat.this.getConfigFormManager();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or join a MUC if it is necessary, i.e. if not the MUC is not already joined.
|
||||
*
|
||||
* @param nickname the required nickname to use.
|
||||
* @param password the optional password required to join
|
||||
* @return A {@link MucCreateConfigFormHandle} if the room was created, or {code null} if the room was joined.
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public MucCreateConfigFormHandle createOrJoinIfNecessary(Resourcepart nickname, String password) throws NoResponseException,
|
||||
XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
if (isJoined()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return createOrJoin(nickname, password, null, connection.getPacketReplyTimeout());
|
||||
}
|
||||
catch (MucAlreadyJoinedException e) {
|
||||
return null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -466,10 +546,11 @@ public class MultiUserChat {
|
|||
* 404 error can occur if the room does not exist or is locked; or a
|
||||
* 407 error can occur if user is not on the member list; or a
|
||||
* 409 error can occur if someone is already in the group chat with the same nickname.
|
||||
* @throws SmackException if there was no response from the server.
|
||||
* @throws InterruptedException
|
||||
* @throws NotConnectedException
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
*/
|
||||
public void join(Resourcepart nickname, String password) throws XMPPErrorException, SmackException, InterruptedException {
|
||||
public void join(Resourcepart nickname, String password) throws XMPPErrorException, InterruptedException, NoResponseException, NotConnectedException {
|
||||
join(nickname, password, null, connection.getPacketReplyTimeout());
|
||||
}
|
||||
|
||||
|
@ -547,6 +628,25 @@ public class MultiUserChat {
|
|||
userHasLeft();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link MucConfigFormManager} to configure this room.
|
||||
* <p>
|
||||
* Only room owners are able to configure a room.
|
||||
* </p>
|
||||
*
|
||||
* @return a MUC configuration form manager for this room.
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0045.html#roomconfig">XEP-45 § 10.2 Subsequent Room Configuration</a>
|
||||
* @since 4.2
|
||||
*/
|
||||
public MucConfigFormManager getConfigFormManager() throws NoResponseException,
|
||||
XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
return new MucConfigFormManager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the room's configuration form that the room's owner can use or <tt>null</tt> if
|
||||
* no configuration is possible. The configuration form allows to set the room's language,
|
||||
|
@ -570,14 +670,13 @@ public class MultiUserChat {
|
|||
|
||||
/**
|
||||
* Sends the completed configuration form to the server. The room will be configured
|
||||
* with the new settings defined in the form. If the form is empty then the server
|
||||
* will create an instant room (will use default configuration).
|
||||
* with the new settings defined in the form.
|
||||
*
|
||||
* @param form the form with the new settings.
|
||||
* @throws XMPPErrorException if an error occurs setting the new rooms' configuration.
|
||||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public void sendConfigurationForm(Form form) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
MUCOwner iq = new MUCOwner();
|
||||
|
@ -868,13 +967,14 @@ public class MultiUserChat {
|
|||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws MucNotJoinedException
|
||||
*/
|
||||
public void changeNickname(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
public void changeNickname(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, MucNotJoinedException {
|
||||
StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank.");
|
||||
// Check that we already have joined the room before attempting to change the
|
||||
// nickname.
|
||||
if (!joined) {
|
||||
throw new IllegalStateException("Must be logged into the room to change nickname.");
|
||||
throw new MucNotJoinedException(this);
|
||||
}
|
||||
final FullJid jid = JidCreate.fullFrom(room, nickname);
|
||||
// We change the nickname by sending a presence packet where the "to"
|
||||
|
@ -905,14 +1005,14 @@ public class MultiUserChat {
|
|||
* @param mode the mode type for the presence update.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws MucNotJoinedException
|
||||
*/
|
||||
public void changeAvailabilityStatus(String status, Presence.Mode mode) throws NotConnectedException, InterruptedException {
|
||||
public void changeAvailabilityStatus(String status, Presence.Mode mode) throws NotConnectedException, InterruptedException, MucNotJoinedException {
|
||||
StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank.");
|
||||
// Check that we already have joined the room before attempting to change the
|
||||
// availability status.
|
||||
if (!joined) {
|
||||
throw new IllegalStateException(
|
||||
"Must be logged into the room to change the " + "availability status.");
|
||||
throw new MucNotJoinedException(this);
|
||||
}
|
||||
// We change the availability status by sending a presence packet to the room with the
|
||||
// new presence status and mode
|
||||
|
@ -1689,11 +1789,11 @@ public class MultiUserChat {
|
|||
*
|
||||
* @return the next message if one is immediately available and
|
||||
* <tt>null</tt> otherwise.
|
||||
* @throws MUCNotJoinedException
|
||||
* @throws MucNotJoinedException
|
||||
*/
|
||||
public Message pollMessage() throws MUCNotJoinedException {
|
||||
public Message pollMessage() throws MucNotJoinedException {
|
||||
if (messageCollector == null) {
|
||||
throw new MUCNotJoinedException(this);
|
||||
throw new MucNotJoinedException(this);
|
||||
}
|
||||
return messageCollector.pollResult();
|
||||
}
|
||||
|
@ -1703,12 +1803,12 @@ public class MultiUserChat {
|
|||
* (not return) until a message is available.
|
||||
*
|
||||
* @return the next message.
|
||||
* @throws MUCNotJoinedException
|
||||
* @throws MucNotJoinedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Message nextMessage() throws MUCNotJoinedException, InterruptedException {
|
||||
public Message nextMessage() throws MucNotJoinedException, InterruptedException {
|
||||
if (messageCollector == null) {
|
||||
throw new MUCNotJoinedException(this);
|
||||
throw new MucNotJoinedException(this);
|
||||
}
|
||||
return messageCollector.nextResult();
|
||||
}
|
||||
|
@ -1721,12 +1821,12 @@ public class MultiUserChat {
|
|||
* @param timeout the maximum amount of time to wait for the next message.
|
||||
* @return the next message, or <tt>null</tt> if the timeout elapses without a
|
||||
* message becoming available.
|
||||
* @throws MUCNotJoinedException
|
||||
* @throws MucNotJoinedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public Message nextMessage(long timeout) throws MUCNotJoinedException, InterruptedException {
|
||||
public Message nextMessage(long timeout) throws MucNotJoinedException, InterruptedException {
|
||||
if (messageCollector == null) {
|
||||
throw new MUCNotJoinedException(this);
|
||||
throw new MucNotJoinedException(this);
|
||||
}
|
||||
return messageCollector.nextResult(timeout);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2014-2015 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
|
||||
public abstract class MultiUserChatException extends SmackException {
|
||||
|
||||
protected MultiUserChatException() {
|
||||
}
|
||||
|
||||
protected MultiUserChatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// This could eventually become an unchecked exception. But be aware that it's required in the
|
||||
// control flow of MultiUserChat.createOrJoinIfNecessary
|
||||
public static class MucAlreadyJoinedException extends MultiUserChatException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if the requested operation required the MUC to be joined by the
|
||||
* client, while the client is currently joined.
|
||||
*
|
||||
*/
|
||||
public static class MucNotJoinedException extends MultiUserChatException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MucNotJoinedException(MultiUserChat multiUserChat) {
|
||||
super("Client not currently joined " + multiUserChat.getRoom());
|
||||
}
|
||||
}
|
||||
|
||||
public static class MissingMucCreationAcknowledgeException extends MultiUserChatException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if the MUC room does not support the requested configuration option.
|
||||
*/
|
||||
public static class MucConfigurationNotSupported extends MultiUserChatException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MucConfigurationNotSupported(String configString) {
|
||||
super("The MUC configuration '" + configString + "' is not supported by the MUC service");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2015 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.muc.bookmarkautojoin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.AbstractConnectionListener;
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smackx.bookmarks.BookmarkManager;
|
||||
import org.jivesoftware.smackx.bookmarks.BookmarkedConference;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatManager;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
|
||||
/**
|
||||
* Autojoin bookmarked Multi-User Chat conferences.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0048.html">XEP-48: Bookmarks</a>
|
||||
*
|
||||
*/
|
||||
public final class MucBookmarkAutojoinManager extends Manager {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(MucBookmarkAutojoinManager.class.getName());
|
||||
|
||||
private static final Map<XMPPConnection, MucBookmarkAutojoinManager> INSTANCES = new WeakHashMap<>();
|
||||
|
||||
private static boolean autojoinEnabledDefault = false;
|
||||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void setAutojoinPerDefault(boolean autojoin) {
|
||||
autojoinEnabledDefault = autojoin;
|
||||
}
|
||||
|
||||
public static synchronized MucBookmarkAutojoinManager getInstanceFor(XMPPConnection connection) {
|
||||
MucBookmarkAutojoinManager mbam = INSTANCES.get(connection);
|
||||
if (mbam == null) {
|
||||
mbam = new MucBookmarkAutojoinManager(connection);
|
||||
INSTANCES.put(connection, mbam);
|
||||
}
|
||||
return mbam;
|
||||
}
|
||||
|
||||
private final MultiUserChatManager multiUserChatManager;
|
||||
private final BookmarkManager bookmarkManager;
|
||||
|
||||
private boolean autojoinEnabled = autojoinEnabledDefault;
|
||||
|
||||
private MucBookmarkAutojoinManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
|
||||
bookmarkManager = BookmarkManager.getBookmarkManager(connection);
|
||||
connection.addConnectionListener(new AbstractConnectionListener() {
|
||||
@Override
|
||||
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||
if (!autojoinEnabled) {
|
||||
return;
|
||||
}
|
||||
// TODO handle resumed case?
|
||||
autojoinBookmarkedConferences();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setAutojoinEnabled(boolean autojoin) {
|
||||
autojoinEnabled = autojoin;
|
||||
}
|
||||
|
||||
public void autojoinBookmarkedConferences() {
|
||||
List<BookmarkedConference> bookmarkedConferences;
|
||||
try {
|
||||
bookmarkedConferences = bookmarkManager.getBookmarkedConferences();
|
||||
}
|
||||
catch (NotConnectedException | InterruptedException e) {
|
||||
LOGGER.log(Level.FINER, "Could not get MUC bookmarks", e);
|
||||
return;
|
||||
}
|
||||
catch (NoResponseException | XMPPErrorException e) {
|
||||
LOGGER.log(Level.WARNING, "Could not get MUC bookmarks", e);
|
||||
return;
|
||||
}
|
||||
|
||||
final XMPPConnection connection = connection();
|
||||
Resourcepart defaultNick = connection.getUser().getResourcepart();
|
||||
|
||||
for (BookmarkedConference bookmarkedConference : bookmarkedConferences) {
|
||||
if (!bookmarkedConference.isAutoJoin()) {
|
||||
continue;
|
||||
}
|
||||
Resourcepart nick = bookmarkedConference.getNickname();
|
||||
if (nick == null) {
|
||||
nick = defaultNick;
|
||||
}
|
||||
String password = bookmarkedConference.getPassword();
|
||||
MultiUserChat muc = multiUserChatManager.getMultiUserChat(bookmarkedConference.getJid());
|
||||
try {
|
||||
MucCreateConfigFormHandle handle = muc.createOrJoinIfNecessary(nick, password);
|
||||
if (handle != null) {
|
||||
handle.makeInstant();
|
||||
}
|
||||
}
|
||||
catch (NotConnectedException | InterruptedException e) {
|
||||
LOGGER.log(Level.FINER, "Could not autojoin bookmarked MUC", e);
|
||||
// abort here
|
||||
break;
|
||||
}
|
||||
catch (NoResponseException | XMPPErrorException e) {
|
||||
// Do no abort, just log,
|
||||
LOGGER.log(Level.WARNING, "Could not autojoin bookmarked MUC", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2014 Florian Schmaus
|
||||
* Copyright 2015 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,23 +14,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
|
||||
/**
|
||||
* Thrown if the requested operation required the MUC to be joined by the
|
||||
* client, while the client is currently joined.
|
||||
*
|
||||
* Manager to autojoin bookmarked Multi-User Chat conferences.
|
||||
*/
|
||||
public class MUCNotJoinedException extends SmackException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5204934585663465576L;
|
||||
|
||||
public MUCNotJoinedException(MultiUserChat multiUserChat) {
|
||||
super("Client not currently joined " + multiUserChat.getRoom());
|
||||
}
|
||||
}
|
||||
package org.jivesoftware.smackx.muc.bookmarkautojoin;
|
|
@ -353,6 +353,17 @@ public class Form {
|
|||
return dataForm.getField(variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a field with the given variable exists.
|
||||
*
|
||||
* @param variable the variable to check for.
|
||||
* @return true if a field with the variable exists, false otherwise.
|
||||
* @since 4.2
|
||||
*/
|
||||
public boolean hasField(String variable) {
|
||||
return dataForm.hasField(variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instructions that explain how to fill out the form and what the form is about.
|
||||
*
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<className>org.jivesoftware.smackx.disco.ServiceDiscoveryManager</className>
|
||||
<className>org.jivesoftware.smackx.xhtmlim.XHTMLManager</className>
|
||||
<className>org.jivesoftware.smackx.muc.MultiUserChatManager</className>
|
||||
<className>org.jivesoftware.smackx.muc.bookmarkautojoin.MucBookmarkAutojoinManager</className>
|
||||
<className>org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager</className>
|
||||
<className>org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager</className>
|
||||
<className>org.jivesoftware.smackx.filetransfer.FileTransferManager</className>
|
||||
|
|
|
@ -30,8 +30,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException;
|
|||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smackx.xdata.Form;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.DomainBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
@ -82,9 +81,9 @@ public class MultiUserChatIntegrationTest extends AbstractSmackIntegrationTest {
|
|||
}
|
||||
});
|
||||
|
||||
boolean newlyCreated = mucAsSeenByOne.createOrJoin(Resourcepart.from("one-" + randomString));
|
||||
if (newlyCreated) {
|
||||
mucAsSeenByOne.sendConfigurationForm(new Form(DataForm.Type.submit));
|
||||
MucCreateConfigFormHandle handle = mucAsSeenByOne.createOrJoin(Resourcepart.from("one-" + randomString));
|
||||
if (handle != null) {
|
||||
handle.makeInstant();
|
||||
}
|
||||
mucAsSeenByTwo.join(Resourcepart.from("two-" + randomString));
|
||||
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2015 Florian Schmaus
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smackx.muc;
|
||||
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.igniterealtime.smack.inttest.AbstractSmackLowLevelIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.Configuration;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.jivesoftware.smack.SmackException;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smackx.bookmarks.BookmarkManager;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle;
|
||||
import org.jivesoftware.smackx.muc.bookmarkautojoin.MucBookmarkAutojoinManager;
|
||||
import org.jxmpp.jid.DomainBareJid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.jid.parts.Localpart;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
|
||||
public class MultiUserChatLowLevelIntegrationTest extends AbstractSmackLowLevelIntegrationTest {
|
||||
|
||||
public MultiUserChatLowLevelIntegrationTest(Configuration configuration, String testRunId) throws Exception {
|
||||
super(configuration, testRunId);
|
||||
performCheck(new ConnectionCallback() {
|
||||
@Override
|
||||
public void connectionCallback(XMPPTCPConnection connection) throws Exception {
|
||||
if (MultiUserChatManager.getInstanceFor(connection).getServiceNames().isEmpty()) {
|
||||
throw new TestNotPossibleException("MUC component not offered by service");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SmackIntegrationTest
|
||||
public void testMucBookmarksAutojoin(XMPPTCPConnection connection) throws InterruptedException,
|
||||
TestNotPossibleException, XMPPException, SmackException, IOException {
|
||||
final BookmarkManager bookmarkManager = BookmarkManager.getBookmarkManager(connection);
|
||||
if (!bookmarkManager.isSupported()) {
|
||||
throw new TestNotPossibleException("Private data storage not supported");
|
||||
}
|
||||
final MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
|
||||
final Resourcepart mucNickname = Resourcepart.from("Nick-" + StringUtils.randomString(6));
|
||||
final String randomMucName = StringUtils.randomString(6);
|
||||
final DomainBareJid mucComponent = multiUserChatManager.getServiceNames().get(0);
|
||||
final MultiUserChat muc = multiUserChatManager.getMultiUserChat(JidCreate.bareFrom(
|
||||
Localpart.from(randomMucName), mucComponent));
|
||||
|
||||
MucCreateConfigFormHandle handle = muc.createOrJoin(mucNickname);
|
||||
if (handle != null) {
|
||||
handle.makeInstant();
|
||||
}
|
||||
muc.leave();
|
||||
|
||||
bookmarkManager.addBookmarkedConference("Smack Inttest: " + testRunId, muc.getRoom(), true,
|
||||
mucNickname, null);
|
||||
|
||||
connection.disconnect();
|
||||
connection.connect().login();
|
||||
|
||||
// MucBookmarkAutojoinManager is also able to do its task automatically
|
||||
// after every login, it's not determinstic when this will be finished.
|
||||
// So we trigger it manually here.
|
||||
MucBookmarkAutojoinManager.getInstanceFor(connection).autojoinBookmarkedConferences();
|
||||
|
||||
assertTrue(muc.isJoined());
|
||||
|
||||
// If the test went well, leave the MUC
|
||||
muc.leave();
|
||||
}
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@ allprojects {
|
|||
ext {
|
||||
shortVersion = '4.2.0-alpha2'
|
||||
isSnapshot = true
|
||||
jxmppVersion = '0.5.0-alpha2'
|
||||
jxmppVersion = '0.5.0-alpha3'
|
||||
smackMinAndroidSdk = 8
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue