mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-04-18 04:18:38 +02:00
Normalize newlines to '\n'
Change all \r\n into unix style newlines. Add missing newlines at the end of a file and activate the newline checkstyle module, that enforces '\n' as newline and a newline at the end of every file.
This commit is contained in:
parent
1e57f1c659
commit
d069e1be64
364 changed files with 50349 additions and 50346 deletions
|
@ -11,6 +11,9 @@
|
|||
<property name="ignoreLines" value="3"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
</module>
|
||||
<module name="NewlineAtEndOfFile">
|
||||
<property name="lineSeparator" value="lf"/>
|
||||
</module>
|
||||
<module name="TreeWalker">
|
||||
<module name="UnusedImports">
|
||||
<property name="processJavadoc" value="true"/>
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2009 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
/**
|
||||
* The AbstractConnectionListener class provides an empty implementation for all
|
||||
* methods defined by the {@link ConnectionListener} interface. This is a
|
||||
* convenience class which should be used in case you do not need to implement
|
||||
* all methods.
|
||||
*
|
||||
* @author Henning Staib
|
||||
*/
|
||||
public class AbstractConnectionListener implements ConnectionListener {
|
||||
|
||||
public void connectionClosed() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void reconnectingIn(int seconds) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void reconnectionFailed(Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void reconnectionSuccessful() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2009 the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
/**
|
||||
* The AbstractConnectionListener class provides an empty implementation for all
|
||||
* methods defined by the {@link ConnectionListener} interface. This is a
|
||||
* convenience class which should be used in case you do not need to implement
|
||||
* all methods.
|
||||
*
|
||||
* @author Henning Staib
|
||||
*/
|
||||
public class AbstractConnectionListener implements ConnectionListener {
|
||||
|
||||
public void connectionClosed() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void reconnectingIn(int seconds) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void reconnectionFailed(Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void reconnectionSuccessful() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -332,4 +332,4 @@ public class AccountManager {
|
|||
info = (Registration)result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,4 +186,4 @@ public class Chat {
|
|||
&& threadID.equals(((Chat)obj).getThreadID())
|
||||
&& participant.equals(((Chat)obj).getParticipant());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,4 +63,4 @@ public interface ConnectionListener {
|
|||
* @param e the exception that caused the reconnection to fail.
|
||||
*/
|
||||
public void reconnectionFailed(Exception e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,140 +1,140 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||
import org.jivesoftware.smack.packet.Authentication;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.Callback;
|
||||
|
||||
/**
|
||||
* Implementation of JEP-0078: Non-SASL Authentication. Follow the following
|
||||
* <a href=http://www.jabber.org/jeps/jep-0078.html>link</a> to obtain more
|
||||
* information about the JEP.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
class NonSASLAuthentication implements UserAuthentication {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
public NonSASLAuthentication(Connection connection) {
|
||||
super();
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public String authenticate(String username, String resource, CallbackHandler cbh) throws XMPPException {
|
||||
//Use the callback handler to determine the password, and continue on.
|
||||
PasswordCallback pcb = new PasswordCallback("Password: ",false);
|
||||
try {
|
||||
cbh.handle(new Callback[]{pcb});
|
||||
return authenticate(username, String.valueOf(pcb.getPassword()),resource);
|
||||
} catch (Exception e) {
|
||||
throw new XMPPException("Unable to determine password.",e);
|
||||
}
|
||||
}
|
||||
|
||||
public String authenticate(String username, String password, String resource) throws
|
||||
XMPPException {
|
||||
// If we send an authentication packet in "get" mode with just the username,
|
||||
// the server will return the list of authentication protocols it supports.
|
||||
Authentication discoveryAuth = new Authentication();
|
||||
discoveryAuth.setType(IQ.Type.GET);
|
||||
discoveryAuth.setUsername(username);
|
||||
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(discoveryAuth.getPacketID()));
|
||||
// Send the packet
|
||||
connection.sendPacket(discoveryAuth);
|
||||
// Wait up to a certain number of seconds for a response from the server.
|
||||
IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
if (response == null) {
|
||||
throw new XMPPException("No response from the server.");
|
||||
}
|
||||
// If the server replied with an error, throw an exception.
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
// Otherwise, no error so continue processing.
|
||||
Authentication authTypes = (Authentication) response;
|
||||
collector.cancel();
|
||||
|
||||
// Now, create the authentication packet we'll send to the server.
|
||||
Authentication auth = new Authentication();
|
||||
auth.setUsername(username);
|
||||
|
||||
// Figure out if we should use digest or plain text authentication.
|
||||
if (authTypes.getDigest() != null) {
|
||||
auth.setDigest(connection.getConnectionID(), password);
|
||||
}
|
||||
else if (authTypes.getPassword() != null) {
|
||||
auth.setPassword(password);
|
||||
}
|
||||
else {
|
||||
throw new XMPPException("Server does not support compatible authentication mechanism.");
|
||||
}
|
||||
|
||||
auth.setResource(resource);
|
||||
|
||||
collector = connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
|
||||
// Send the packet.
|
||||
connection.sendPacket(auth);
|
||||
// Wait up to a certain number of seconds for a response from the server.
|
||||
response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
if (response == null) {
|
||||
throw new XMPPException("Authentication failed.");
|
||||
}
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
// We're done with the collector, so explicitly cancel it.
|
||||
collector.cancel();
|
||||
|
||||
return response.getTo();
|
||||
}
|
||||
|
||||
public String authenticateAnonymously() throws XMPPException {
|
||||
// Create the authentication packet we'll send to the server.
|
||||
Authentication auth = new Authentication();
|
||||
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
|
||||
// Send the packet.
|
||||
connection.sendPacket(auth);
|
||||
// Wait up to a certain number of seconds for a response from the server.
|
||||
IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
if (response == null) {
|
||||
throw new XMPPException("Anonymous login failed.");
|
||||
}
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
// We're done with the collector, so explicitly cancel it.
|
||||
collector.cancel();
|
||||
|
||||
if (response.getTo() != null) {
|
||||
return response.getTo();
|
||||
}
|
||||
else {
|
||||
return connection.getServiceName() + "/" + ((Authentication) response).getResource();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||
import org.jivesoftware.smack.packet.Authentication;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.Callback;
|
||||
|
||||
/**
|
||||
* Implementation of JEP-0078: Non-SASL Authentication. Follow the following
|
||||
* <a href=http://www.jabber.org/jeps/jep-0078.html>link</a> to obtain more
|
||||
* information about the JEP.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
class NonSASLAuthentication implements UserAuthentication {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
public NonSASLAuthentication(Connection connection) {
|
||||
super();
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public String authenticate(String username, String resource, CallbackHandler cbh) throws XMPPException {
|
||||
//Use the callback handler to determine the password, and continue on.
|
||||
PasswordCallback pcb = new PasswordCallback("Password: ",false);
|
||||
try {
|
||||
cbh.handle(new Callback[]{pcb});
|
||||
return authenticate(username, String.valueOf(pcb.getPassword()),resource);
|
||||
} catch (Exception e) {
|
||||
throw new XMPPException("Unable to determine password.",e);
|
||||
}
|
||||
}
|
||||
|
||||
public String authenticate(String username, String password, String resource) throws
|
||||
XMPPException {
|
||||
// If we send an authentication packet in "get" mode with just the username,
|
||||
// the server will return the list of authentication protocols it supports.
|
||||
Authentication discoveryAuth = new Authentication();
|
||||
discoveryAuth.setType(IQ.Type.GET);
|
||||
discoveryAuth.setUsername(username);
|
||||
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(discoveryAuth.getPacketID()));
|
||||
// Send the packet
|
||||
connection.sendPacket(discoveryAuth);
|
||||
// Wait up to a certain number of seconds for a response from the server.
|
||||
IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
if (response == null) {
|
||||
throw new XMPPException("No response from the server.");
|
||||
}
|
||||
// If the server replied with an error, throw an exception.
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
// Otherwise, no error so continue processing.
|
||||
Authentication authTypes = (Authentication) response;
|
||||
collector.cancel();
|
||||
|
||||
// Now, create the authentication packet we'll send to the server.
|
||||
Authentication auth = new Authentication();
|
||||
auth.setUsername(username);
|
||||
|
||||
// Figure out if we should use digest or plain text authentication.
|
||||
if (authTypes.getDigest() != null) {
|
||||
auth.setDigest(connection.getConnectionID(), password);
|
||||
}
|
||||
else if (authTypes.getPassword() != null) {
|
||||
auth.setPassword(password);
|
||||
}
|
||||
else {
|
||||
throw new XMPPException("Server does not support compatible authentication mechanism.");
|
||||
}
|
||||
|
||||
auth.setResource(resource);
|
||||
|
||||
collector = connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
|
||||
// Send the packet.
|
||||
connection.sendPacket(auth);
|
||||
// Wait up to a certain number of seconds for a response from the server.
|
||||
response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
if (response == null) {
|
||||
throw new XMPPException("Authentication failed.");
|
||||
}
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
// We're done with the collector, so explicitly cancel it.
|
||||
collector.cancel();
|
||||
|
||||
return response.getTo();
|
||||
}
|
||||
|
||||
public String authenticateAnonymously() throws XMPPException {
|
||||
// Create the authentication packet we'll send to the server.
|
||||
Authentication auth = new Authentication();
|
||||
|
||||
PacketCollector collector =
|
||||
connection.createPacketCollector(new PacketIDFilter(auth.getPacketID()));
|
||||
// Send the packet.
|
||||
connection.sendPacket(auth);
|
||||
// Wait up to a certain number of seconds for a response from the server.
|
||||
IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
|
||||
if (response == null) {
|
||||
throw new XMPPException("Anonymous login failed.");
|
||||
}
|
||||
else if (response.getType() == IQ.Type.ERROR) {
|
||||
throw new XMPPException(response.getError());
|
||||
}
|
||||
// We're done with the collector, so explicitly cancel it.
|
||||
collector.cancel();
|
||||
|
||||
if (response.getTo() != null) {
|
||||
return response.getTo();
|
||||
}
|
||||
else {
|
||||
return connection.getServiceName() + "/" + ((Authentication) response).getResource();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* Dummy trust manager that trust all certificates presented by the server. This class
|
||||
* is used during old SSL connections.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
class OpenTrustManager implements X509TrustManager {
|
||||
|
||||
public OpenTrustManager() {
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
|
||||
throws CertificateException {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
|
||||
throws CertificateException {
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* Dummy trust manager that trust all certificates presented by the server. This class
|
||||
* is used during old SSL connections.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
class OpenTrustManager implements X509TrustManager {
|
||||
|
||||
public OpenTrustManager() {
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
|
||||
throws CertificateException {
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
|
||||
throws CertificateException {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2005 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
||||
/**
|
||||
* Provides a mechanism to intercept and modify packets that are going to be
|
||||
* sent to the server. PacketInterceptors are added to the {@link Connection}
|
||||
* together with a {@link org.jivesoftware.smack.filter.PacketFilter} so that only
|
||||
* certain packets are intercepted and processed by the interceptor.<p>
|
||||
*
|
||||
* This allows event-style programming -- every time a new packet is found,
|
||||
* the {@link #interceptPacket(Packet)} method will be called.
|
||||
*
|
||||
* @see Connection#addPacketInterceptor(PacketInterceptor, org.jivesoftware.smack.filter.PacketFilter)
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface PacketInterceptor {
|
||||
|
||||
/**
|
||||
* Process the packet that is about to be sent to the server. The intercepted
|
||||
* packet can be modified by the interceptor.<p>
|
||||
*
|
||||
* Interceptors are invoked using the same thread that requested the packet
|
||||
* to be sent, so it's very important that implementations of this method
|
||||
* not block for any extended period of time.
|
||||
*
|
||||
* @param packet the packet to is going to be sent to the server.
|
||||
*/
|
||||
public void interceptPacket(Packet packet);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2005 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
||||
/**
|
||||
* Provides a mechanism to intercept and modify packets that are going to be
|
||||
* sent to the server. PacketInterceptors are added to the {@link Connection}
|
||||
* together with a {@link org.jivesoftware.smack.filter.PacketFilter} so that only
|
||||
* certain packets are intercepted and processed by the interceptor.<p>
|
||||
*
|
||||
* This allows event-style programming -- every time a new packet is found,
|
||||
* the {@link #interceptPacket(Packet)} method will be called.
|
||||
*
|
||||
* @see Connection#addPacketInterceptor(PacketInterceptor, org.jivesoftware.smack.filter.PacketFilter)
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public interface PacketInterceptor {
|
||||
|
||||
/**
|
||||
* Process the packet that is about to be sent to the server. The intercepted
|
||||
* packet can be modified by the interceptor.<p>
|
||||
*
|
||||
* Interceptors are invoked using the same thread that requested the packet
|
||||
* to be sent, so it's very important that implementations of this method
|
||||
* not block for any extended period of time.
|
||||
*
|
||||
* @param packet the packet to is going to be sent to the server.
|
||||
*/
|
||||
public void interceptPacket(Packet packet);
|
||||
}
|
||||
|
|
|
@ -14,215 +14,215 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
import java.util.Random;
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Logger;
|
||||
/**
|
||||
* Handles the automatic reconnection process. Every time a connection is dropped without
|
||||
* the application explictly closing it, the manager automatically tries to reconnect to
|
||||
* the server.<p>
|
||||
*
|
||||
* The reconnection mechanism will try to reconnect periodically:
|
||||
* <ol>
|
||||
* <li>For the first minute it will attempt to connect once every ten seconds.
|
||||
* <li>For the next five minutes it will attempt to connect once a minute.
|
||||
* <li>If that fails it will indefinitely try to connect once every five minutes.
|
||||
* </ol>
|
||||
*
|
||||
* @author Francisco Vives
|
||||
*/
|
||||
public class ReconnectionManager implements ConnectionListener {
|
||||
/**
|
||||
* Handles the automatic reconnection process. Every time a connection is dropped without
|
||||
* the application explictly closing it, the manager automatically tries to reconnect to
|
||||
* the server.<p>
|
||||
*
|
||||
* The reconnection mechanism will try to reconnect periodically:
|
||||
* <ol>
|
||||
* <li>For the first minute it will attempt to connect once every ten seconds.
|
||||
* <li>For the next five minutes it will attempt to connect once a minute.
|
||||
* <li>If that fails it will indefinitely try to connect once every five minutes.
|
||||
* </ol>
|
||||
*
|
||||
* @author Francisco Vives
|
||||
*/
|
||||
public class ReconnectionManager implements ConnectionListener {
|
||||
private static Logger log = Logger.getLogger(ReconnectionManager.class.getName());
|
||||
|
||||
// Holds the connection to the server
|
||||
private Connection connection;
|
||||
private Thread reconnectionThread;
|
||||
private int randomBase = new Random().nextInt(11) + 5; // between 5 and 15 seconds
|
||||
|
||||
// Holds the state of the reconnection
|
||||
boolean done = false;
|
||||
|
||||
static {
|
||||
// Create a new PrivacyListManager on every established connection. In the init()
|
||||
// method of PrivacyListManager, we'll add a listener that will delete the
|
||||
// instance when the connection is closed.
|
||||
Connection.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
public void connectionCreated(Connection connection) {
|
||||
connection.addConnectionListener(new ReconnectionManager(connection));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ReconnectionManager(Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the reconnection mechanism is enabled.
|
||||
*
|
||||
* @return true if automatic reconnections are allowed.
|
||||
*/
|
||||
private boolean isReconnectionAllowed() {
|
||||
|
||||
// Holds the connection to the server
|
||||
private Connection connection;
|
||||
private Thread reconnectionThread;
|
||||
private int randomBase = new Random().nextInt(11) + 5; // between 5 and 15 seconds
|
||||
|
||||
// Holds the state of the reconnection
|
||||
boolean done = false;
|
||||
|
||||
static {
|
||||
// Create a new PrivacyListManager on every established connection. In the init()
|
||||
// method of PrivacyListManager, we'll add a listener that will delete the
|
||||
// instance when the connection is closed.
|
||||
Connection.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
public void connectionCreated(Connection connection) {
|
||||
connection.addConnectionListener(new ReconnectionManager(connection));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ReconnectionManager(Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the reconnection mechanism is enabled.
|
||||
*
|
||||
* @return true if automatic reconnections are allowed.
|
||||
*/
|
||||
private boolean isReconnectionAllowed() {
|
||||
return !done && !connection.isConnected()
|
||||
&& connection.isReconnectionAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reconnection mechanism if it was configured to do that.
|
||||
* The algorithm is been executed when the first connection error is detected.
|
||||
* <p/>
|
||||
* The reconnection mechanism will try to reconnect periodically in this way:
|
||||
* <ol>
|
||||
* <li>First it will try 6 times every 10 seconds.
|
||||
* <li>Then it will try 10 times every 1 minute.
|
||||
* <li>Finally it will try indefinitely every 5 minutes.
|
||||
* </ol>
|
||||
*/
|
||||
synchronized protected void reconnect() {
|
||||
if (this.isReconnectionAllowed()) {
|
||||
// Since there is no thread running, creates a new one to attempt
|
||||
// the reconnection.
|
||||
// avoid to run duplicated reconnectionThread -- fd: 16/09/2010
|
||||
if (reconnectionThread!=null && reconnectionThread.isAlive()) return;
|
||||
|
||||
reconnectionThread = new Thread() {
|
||||
|
||||
/**
|
||||
* Holds the current number of reconnection attempts
|
||||
*/
|
||||
private int attempts = 0;
|
||||
|
||||
/**
|
||||
* Returns the number of seconds until the next reconnection attempt.
|
||||
*
|
||||
* @return the number of seconds until the next reconnection attempt.
|
||||
*/
|
||||
private int timeDelay() {
|
||||
attempts++;
|
||||
if (attempts > 13) {
|
||||
return randomBase*6*5; // between 2.5 and 7.5 minutes (~5 minutes)
|
||||
}
|
||||
if (attempts > 7) {
|
||||
return randomBase*6; // between 30 and 90 seconds (~1 minutes)
|
||||
}
|
||||
return randomBase; // 10 seconds
|
||||
}
|
||||
|
||||
/**
|
||||
* The process will try the reconnection until the connection succeed or the user
|
||||
* cancell it
|
||||
*/
|
||||
public void run() {
|
||||
// The process will try to reconnect until the connection is established or
|
||||
// the user cancel the reconnection process {@link Connection#disconnect()}
|
||||
while (ReconnectionManager.this.isReconnectionAllowed()) {
|
||||
// Find how much time we should wait until the next reconnection
|
||||
int remainingSeconds = timeDelay();
|
||||
// Sleep until we're ready for the next reconnection attempt. Notify
|
||||
// listeners once per second about how much time remains before the next
|
||||
// reconnection attempt.
|
||||
while (ReconnectionManager.this.isReconnectionAllowed() &&
|
||||
remainingSeconds > 0)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
remainingSeconds--;
|
||||
ReconnectionManager.this
|
||||
.notifyAttemptToReconnectIn(remainingSeconds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reconnection mechanism if it was configured to do that.
|
||||
* The algorithm is been executed when the first connection error is detected.
|
||||
* <p/>
|
||||
* The reconnection mechanism will try to reconnect periodically in this way:
|
||||
* <ol>
|
||||
* <li>First it will try 6 times every 10 seconds.
|
||||
* <li>Then it will try 10 times every 1 minute.
|
||||
* <li>Finally it will try indefinitely every 5 minutes.
|
||||
* </ol>
|
||||
*/
|
||||
synchronized protected void reconnect() {
|
||||
if (this.isReconnectionAllowed()) {
|
||||
// Since there is no thread running, creates a new one to attempt
|
||||
// the reconnection.
|
||||
// avoid to run duplicated reconnectionThread -- fd: 16/09/2010
|
||||
if (reconnectionThread!=null && reconnectionThread.isAlive()) return;
|
||||
|
||||
reconnectionThread = new Thread() {
|
||||
|
||||
/**
|
||||
* Holds the current number of reconnection attempts
|
||||
*/
|
||||
private int attempts = 0;
|
||||
|
||||
/**
|
||||
* Returns the number of seconds until the next reconnection attempt.
|
||||
*
|
||||
* @return the number of seconds until the next reconnection attempt.
|
||||
*/
|
||||
private int timeDelay() {
|
||||
attempts++;
|
||||
if (attempts > 13) {
|
||||
return randomBase*6*5; // between 2.5 and 7.5 minutes (~5 minutes)
|
||||
}
|
||||
if (attempts > 7) {
|
||||
return randomBase*6; // between 30 and 90 seconds (~1 minutes)
|
||||
}
|
||||
return randomBase; // 10 seconds
|
||||
}
|
||||
|
||||
/**
|
||||
* The process will try the reconnection until the connection succeed or the user
|
||||
* cancell it
|
||||
*/
|
||||
public void run() {
|
||||
// The process will try to reconnect until the connection is established or
|
||||
// the user cancel the reconnection process {@link Connection#disconnect()}
|
||||
while (ReconnectionManager.this.isReconnectionAllowed()) {
|
||||
// Find how much time we should wait until the next reconnection
|
||||
int remainingSeconds = timeDelay();
|
||||
// Sleep until we're ready for the next reconnection attempt. Notify
|
||||
// listeners once per second about how much time remains before the next
|
||||
// reconnection attempt.
|
||||
while (ReconnectionManager.this.isReconnectionAllowed() &&
|
||||
remainingSeconds > 0)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
remainingSeconds--;
|
||||
ReconnectionManager.this
|
||||
.notifyAttemptToReconnectIn(remainingSeconds);
|
||||
}
|
||||
catch (InterruptedException e1) {
|
||||
log.warning("Sleeping thread interrupted");
|
||||
// Notify the reconnection has failed
|
||||
ReconnectionManager.this.notifyReconnectionFailed(e1);
|
||||
}
|
||||
}
|
||||
|
||||
// Makes a reconnection attempt
|
||||
try {
|
||||
if (ReconnectionManager.this.isReconnectionAllowed()) {
|
||||
connection.connect();
|
||||
}
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
// Fires the failed reconnection notification
|
||||
ReconnectionManager.this.notifyReconnectionFailed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
reconnectionThread.setName("Smack Reconnection Manager");
|
||||
reconnectionThread.setDaemon(true);
|
||||
reconnectionThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires listeners when a reconnection attempt has failed.
|
||||
*
|
||||
* @param exception the exception that occured.
|
||||
*/
|
||||
protected void notifyReconnectionFailed(Exception exception) {
|
||||
log.warning("Sleeping thread interrupted");
|
||||
// Notify the reconnection has failed
|
||||
ReconnectionManager.this.notifyReconnectionFailed(e1);
|
||||
}
|
||||
}
|
||||
|
||||
// Makes a reconnection attempt
|
||||
try {
|
||||
if (ReconnectionManager.this.isReconnectionAllowed()) {
|
||||
connection.connect();
|
||||
}
|
||||
}
|
||||
catch (XMPPException e) {
|
||||
// Fires the failed reconnection notification
|
||||
ReconnectionManager.this.notifyReconnectionFailed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
reconnectionThread.setName("Smack Reconnection Manager");
|
||||
reconnectionThread.setDaemon(true);
|
||||
reconnectionThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires listeners when a reconnection attempt has failed.
|
||||
*
|
||||
* @param exception the exception that occured.
|
||||
*/
|
||||
protected void notifyReconnectionFailed(Exception exception) {
|
||||
if (isReconnectionAllowed()) {
|
||||
for (ConnectionListener listener : connection.connectionListeners) {
|
||||
listener.reconnectionFailed(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires listeners when The Connection will retry a reconnection. Expressed in seconds.
|
||||
*
|
||||
* @param seconds the number of seconds that a reconnection will be attempted in.
|
||||
*/
|
||||
protected void notifyAttemptToReconnectIn(int seconds) {
|
||||
listener.reconnectionFailed(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires listeners when The Connection will retry a reconnection. Expressed in seconds.
|
||||
*
|
||||
* @param seconds the number of seconds that a reconnection will be attempted in.
|
||||
*/
|
||||
protected void notifyAttemptToReconnectIn(int seconds) {
|
||||
if (isReconnectionAllowed()) {
|
||||
for (ConnectionListener listener : connection.connectionListeners) {
|
||||
listener.reconnectingIn(seconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void connectionClosed() {
|
||||
done = true;
|
||||
}
|
||||
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
done = false;
|
||||
if (e instanceof XMPPException) {
|
||||
XMPPException xmppEx = (XMPPException) e;
|
||||
StreamError error = xmppEx.getStreamError();
|
||||
|
||||
// Make sure the error is not null
|
||||
if (error != null) {
|
||||
String reason = error.getCode();
|
||||
|
||||
if ("conflict".equals(reason)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isReconnectionAllowed()) {
|
||||
this.reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void reconnectingIn(int seconds) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
public void reconnectionFailed(Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* The connection has successfull gotten connected.
|
||||
*/
|
||||
public void reconnectionSuccessful() {
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
||||
listener.reconnectingIn(seconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void connectionClosed() {
|
||||
done = true;
|
||||
}
|
||||
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
done = false;
|
||||
if (e instanceof XMPPException) {
|
||||
XMPPException xmppEx = (XMPPException) e;
|
||||
StreamError error = xmppEx.getStreamError();
|
||||
|
||||
// Make sure the error is not null
|
||||
if (error != null) {
|
||||
String reason = error.getCode();
|
||||
|
||||
if ("conflict".equals(reason)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isReconnectionAllowed()) {
|
||||
this.reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void reconnectingIn(int seconds) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
public void reconnectionFailed(Exception e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* The connection has successfull gotten connected.
|
||||
*/
|
||||
public void reconnectionSuccessful() {
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -238,4 +238,4 @@ public class RosterEntry {
|
|||
return item;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,4 +248,4 @@ public class RosterGroup {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,4 +77,4 @@ public interface RosterListener {
|
|||
* @see Roster#getPresence(String)
|
||||
*/
|
||||
public void presenceChanged(Presence presence);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,40 +1,40 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
public enum SmackError {
|
||||
NO_RESPONSE_FROM_SERVER("No response from server.");
|
||||
|
||||
private String message;
|
||||
|
||||
private SmackError(String errMessage) {
|
||||
message = errMessage;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static SmackError getErrorCode(String message) {
|
||||
for (SmackError code : values()) {
|
||||
if (code.message.equals(message)) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
public enum SmackError {
|
||||
NO_RESPONSE_FROM_SERVER("No response from server.");
|
||||
|
||||
private String message;
|
||||
|
||||
private SmackError(String errMessage) {
|
||||
message = errMessage;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public static SmackError getErrorCode(String message) {
|
||||
for (SmackError code : values()) {
|
||||
if (code.message.equals(message)) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,76 +1,76 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
/**
|
||||
* There are two ways to authenticate a user with a server. Using SASL or Non-SASL
|
||||
* authentication. This interface makes {@link SASLAuthentication} and
|
||||
* {@link NonSASLAuthentication} polyphormic.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
* @author Jay Kline
|
||||
*/
|
||||
interface UserAuthentication {
|
||||
|
||||
/**
|
||||
* Authenticates the user with the server. This method will return the full JID provided by
|
||||
* the server. The server may assign a full JID with a username and resource different than
|
||||
* requested by this method.
|
||||
*
|
||||
* Note that using callbacks is the prefered method of authenticating users since it allows
|
||||
* more flexability in the mechanisms used.
|
||||
*
|
||||
* @param username the requested username (authorization ID) for authenticating to the server
|
||||
* @param resource the requested resource.
|
||||
* @param cbh the CallbackHandler used to obtain authentication ID, password, or other
|
||||
* information
|
||||
* @return the full JID provided by the server while binding a resource for the connection.
|
||||
* @throws XMPPException if an error occurs while authenticating.
|
||||
*/
|
||||
String authenticate(String username, String resource, CallbackHandler cbh) throws
|
||||
XMPPException;
|
||||
|
||||
/**
|
||||
* Authenticates the user with the server. This method will return the full JID provided by
|
||||
* the server. The server may assign a full JID with a username and resource different than
|
||||
* the requested by this method.
|
||||
*
|
||||
* It is recommended that @{link #authenticate(String, String, CallbackHandler)} be used instead
|
||||
* since it provides greater flexability in authenticaiton and authorization.
|
||||
*
|
||||
* @param username the username that is authenticating with the server.
|
||||
* @param password the password to send to the server.
|
||||
* @param resource the desired resource.
|
||||
* @return the full JID provided by the server while binding a resource for the connection.
|
||||
* @throws XMPPException if an error occures while authenticating.
|
||||
*/
|
||||
String authenticate(String username, String password, String resource) throws
|
||||
XMPPException;
|
||||
|
||||
/**
|
||||
* Performs an anonymous authentication with the server. The server will created a new full JID
|
||||
* for this connection. An exception will be thrown if the server does not support anonymous
|
||||
* authentication.
|
||||
*
|
||||
* @return the full JID provided by the server while binding a resource for the connection.
|
||||
* @throws XMPPException if an error occures while authenticating.
|
||||
*/
|
||||
String authenticateAnonymously() throws XMPPException;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
/**
|
||||
* There are two ways to authenticate a user with a server. Using SASL or Non-SASL
|
||||
* authentication. This interface makes {@link SASLAuthentication} and
|
||||
* {@link NonSASLAuthentication} polyphormic.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
* @author Jay Kline
|
||||
*/
|
||||
interface UserAuthentication {
|
||||
|
||||
/**
|
||||
* Authenticates the user with the server. This method will return the full JID provided by
|
||||
* the server. The server may assign a full JID with a username and resource different than
|
||||
* requested by this method.
|
||||
*
|
||||
* Note that using callbacks is the prefered method of authenticating users since it allows
|
||||
* more flexability in the mechanisms used.
|
||||
*
|
||||
* @param username the requested username (authorization ID) for authenticating to the server
|
||||
* @param resource the requested resource.
|
||||
* @param cbh the CallbackHandler used to obtain authentication ID, password, or other
|
||||
* information
|
||||
* @return the full JID provided by the server while binding a resource for the connection.
|
||||
* @throws XMPPException if an error occurs while authenticating.
|
||||
*/
|
||||
String authenticate(String username, String resource, CallbackHandler cbh) throws
|
||||
XMPPException;
|
||||
|
||||
/**
|
||||
* Authenticates the user with the server. This method will return the full JID provided by
|
||||
* the server. The server may assign a full JID with a username and resource different than
|
||||
* the requested by this method.
|
||||
*
|
||||
* It is recommended that @{link #authenticate(String, String, CallbackHandler)} be used instead
|
||||
* since it provides greater flexability in authenticaiton and authorization.
|
||||
*
|
||||
* @param username the username that is authenticating with the server.
|
||||
* @param password the password to send to the server.
|
||||
* @param resource the desired resource.
|
||||
* @return the full JID provided by the server while binding a resource for the connection.
|
||||
* @throws XMPPException if an error occures while authenticating.
|
||||
*/
|
||||
String authenticate(String username, String password, String resource) throws
|
||||
XMPPException;
|
||||
|
||||
/**
|
||||
* Performs an anonymous authentication with the server. The server will created a new full JID
|
||||
* for this connection. An exception will be thrown if the server does not support anonymous
|
||||
* authentication.
|
||||
*
|
||||
* @return the full JID provided by the server while binding a resource for the connection.
|
||||
* @throws XMPPException if an error occures while authenticating.
|
||||
*/
|
||||
String authenticateAnonymously() throws XMPPException;
|
||||
}
|
||||
|
|
|
@ -235,4 +235,4 @@ public class XMPPException extends Exception {
|
|||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,4 +92,4 @@ public interface SmackDebugger {
|
|||
* the GUI
|
||||
*/
|
||||
public abstract PacketListener getWriterListener();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,4 +48,4 @@ public class FromContainsFilter implements PacketFilter {
|
|||
return packet.getFrom().toLowerCase().indexOf(from) != -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2006 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.filter;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
||||
/**
|
||||
* A filter for IQ packet types. Returns true only if the packet is an IQ packet
|
||||
* and it matches the type provided in the constructor.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public class IQTypeFilter implements PacketFilter {
|
||||
|
||||
private IQ.Type type;
|
||||
|
||||
public IQTypeFilter(IQ.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.filter.PacketFilter#accept(org.jivesoftware.smack.packet.Packet)
|
||||
*/
|
||||
public boolean accept(Packet packet) {
|
||||
return (packet instanceof IQ && ((IQ) packet).getType().equals(type));
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2006 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.filter;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
||||
/**
|
||||
* A filter for IQ packet types. Returns true only if the packet is an IQ packet
|
||||
* and it matches the type provided in the constructor.
|
||||
*
|
||||
* @author Alexander Wenckus
|
||||
*
|
||||
*/
|
||||
public class IQTypeFilter implements PacketFilter {
|
||||
|
||||
private IQ.Type type;
|
||||
|
||||
public IQTypeFilter(IQ.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.jivesoftware.smack.filter.PacketFilter#accept(org.jivesoftware.smack.packet.Packet)
|
||||
*/
|
||||
public boolean accept(Packet packet) {
|
||||
return (packet instanceof IQ && ((IQ) packet).getType().equals(type));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,4 +97,4 @@ public class OrFilter implements PacketFilter {
|
|||
public String toString() {
|
||||
return filters.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,4 +49,4 @@ public class ToContainsFilter implements PacketFilter {
|
|||
return packet.getTo().toLowerCase().indexOf(to) != -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Initializes the Java logging system.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public class LoggingInitializer implements SmackInitializer {
|
||||
|
||||
private static Logger log = Logger.getLogger(LoggingInitializer.class.getName());
|
||||
|
||||
private List<Exception> exceptions = new LinkedList<Exception>();
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
try {
|
||||
LogManager.getLogManager().readConfiguration(FileUtils.getStreamForUrl("classpath:org.jivesofware.smack/jul.properties", null));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log .log(Level.WARNING, "Could not initialize Java Logging from default file.", e);
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Exception> getExceptions() {
|
||||
return Collections.unmodifiableList(exceptions);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogManager;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Initializes the Java logging system.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public class LoggingInitializer implements SmackInitializer {
|
||||
|
||||
private static Logger log = Logger.getLogger(LoggingInitializer.class.getName());
|
||||
|
||||
private List<Exception> exceptions = new LinkedList<Exception>();
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
try {
|
||||
LogManager.getLogManager().readConfiguration(FileUtils.getStreamForUrl("classpath:org.jivesofware.smack/jul.properties", null));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log .log(Level.WARNING, "Could not initialize Java Logging from default file.", e);
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Exception> getExceptions() {
|
||||
return Collections.unmodifiableList(exceptions);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
|
||||
/**
|
||||
* Defines an initialization class that will be instantiated and invoked by the {@link SmackConfiguration} class during initialization.
|
||||
*
|
||||
* <p>
|
||||
* Any implementation of this class MUST have a default constructor.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public interface SmackInitializer {
|
||||
void initialize();
|
||||
List<Exception> getExceptions();
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
|
||||
/**
|
||||
* Defines an initialization class that will be instantiated and invoked by the {@link SmackConfiguration} class during initialization.
|
||||
*
|
||||
* <p>
|
||||
* Any implementation of this class MUST have a default constructor.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public interface SmackInitializer {
|
||||
void initialize();
|
||||
List<Exception> getExceptions();
|
||||
}
|
||||
|
|
|
@ -1,81 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.provider.ProviderFileLoader;
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
import org.jivesoftware.smack.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Loads the provider file defined by the URL returned by {@link #getFilePath()}. This file will be loaded on Smack initialization.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public abstract class UrlProviderFileInitializer implements SmackInitializer {
|
||||
private static final Logger log = Logger.getLogger(UrlProviderFileInitializer.class.getName());
|
||||
|
||||
private List<Exception> exceptions = new LinkedList<Exception>();
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
String filePath = getFilePath();
|
||||
|
||||
try {
|
||||
InputStream is = FileUtils.getStreamForUrl(filePath, getClassLoader());
|
||||
|
||||
if (is != null) {
|
||||
log.log(Level.INFO, "Loading providers for file [" + filePath + "]");
|
||||
ProviderFileLoader pfl = new ProviderFileLoader(is);
|
||||
ProviderManager.getInstance().addLoader(pfl);
|
||||
exceptions.addAll(pfl.getLoadingExceptions());
|
||||
}
|
||||
else {
|
||||
log.log(Level.WARNING, "No input stream created for " + filePath);
|
||||
exceptions.add(new IOException("No input stream created for " + filePath));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.log(Level.SEVERE, "Error trying to load provider file " + filePath, e);
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Exception> getExceptions() {
|
||||
return Collections.unmodifiableList(exceptions);
|
||||
}
|
||||
|
||||
protected abstract String getFilePath();
|
||||
|
||||
/**
|
||||
* Returns an array of class loaders to load resources from.
|
||||
*
|
||||
* @return an array of ClassLoader instances.
|
||||
*/
|
||||
protected ClassLoader getClassLoader() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.provider.ProviderFileLoader;
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
import org.jivesoftware.smack.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Loads the provider file defined by the URL returned by {@link #getFilePath()}. This file will be loaded on Smack initialization.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public abstract class UrlProviderFileInitializer implements SmackInitializer {
|
||||
private static final Logger log = Logger.getLogger(UrlProviderFileInitializer.class.getName());
|
||||
|
||||
private List<Exception> exceptions = new LinkedList<Exception>();
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
String filePath = getFilePath();
|
||||
|
||||
try {
|
||||
InputStream is = FileUtils.getStreamForUrl(filePath, getClassLoader());
|
||||
|
||||
if (is != null) {
|
||||
log.log(Level.INFO, "Loading providers for file [" + filePath + "]");
|
||||
ProviderFileLoader pfl = new ProviderFileLoader(is);
|
||||
ProviderManager.getInstance().addLoader(pfl);
|
||||
exceptions.addAll(pfl.getLoadingExceptions());
|
||||
}
|
||||
else {
|
||||
log.log(Level.WARNING, "No input stream created for " + filePath);
|
||||
exceptions.add(new IOException("No input stream created for " + filePath));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.log(Level.SEVERE, "Error trying to load provider file " + filePath, e);
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Exception> getExceptions() {
|
||||
return Collections.unmodifiableList(exceptions);
|
||||
}
|
||||
|
||||
protected abstract String getFilePath();
|
||||
|
||||
/**
|
||||
* Returns an array of class loaders to load resources from.
|
||||
*
|
||||
* @return an array of ClassLoader instances.
|
||||
*/
|
||||
protected ClassLoader getClassLoader() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
|
||||
|
||||
/**
|
||||
* Looks for a provider file location based on the VM argument <i>smack.provider.file</>. If it is supplied, its value will
|
||||
* be used as a file location for a providers file and loaded into the {@link ProviderManager} on Smack initialization.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public class VmArgInitializer extends UrlProviderFileInitializer {
|
||||
|
||||
protected String getFilePath() {
|
||||
return System.getProperty("smack.provider.file");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
if (getFilePath() != null) {
|
||||
super.initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.initializer;
|
||||
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
|
||||
|
||||
/**
|
||||
* Looks for a provider file location based on the VM argument <i>smack.provider.file</>. If it is supplied, its value will
|
||||
* be used as a file location for a providers file and loaded into the {@link ProviderManager} on Smack initialization.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public class VmArgInitializer extends UrlProviderFileInitializer {
|
||||
|
||||
protected String getFilePath() {
|
||||
return System.getProperty("smack.provider.file");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
if (getFilePath() != null) {
|
||||
super.initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,68 +1,68 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack.packet;
|
||||
|
||||
/**
|
||||
* IQ packet used by Smack to bind a resource and to obtain the jid assigned by the server.
|
||||
* There are two ways to bind a resource. One is simply sending an empty Bind packet where the
|
||||
* server will assign a new resource for this connection. The other option is to set a desired
|
||||
* resource but the server may return a modified version of the sent resource.<p>
|
||||
*
|
||||
* For more information refer to the following
|
||||
* <a href=http://www.xmpp.org/specs/rfc3920.html#bind>link</a>.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Bind extends IQ {
|
||||
|
||||
private String resource = null;
|
||||
private String jid = null;
|
||||
|
||||
public Bind() {
|
||||
setType(IQ.Type.SET);
|
||||
}
|
||||
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
public void setJid(String jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">");
|
||||
if (resource != null) {
|
||||
buf.append("<resource>").append(resource).append("</resource>");
|
||||
}
|
||||
if (jid != null) {
|
||||
buf.append("<jid>").append(jid).append("</jid>");
|
||||
}
|
||||
buf.append("</bind>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack.packet;
|
||||
|
||||
/**
|
||||
* IQ packet used by Smack to bind a resource and to obtain the jid assigned by the server.
|
||||
* There are two ways to bind a resource. One is simply sending an empty Bind packet where the
|
||||
* server will assign a new resource for this connection. The other option is to set a desired
|
||||
* resource but the server may return a modified version of the sent resource.<p>
|
||||
*
|
||||
* For more information refer to the following
|
||||
* <a href=http://www.xmpp.org/specs/rfc3920.html#bind>link</a>.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Bind extends IQ {
|
||||
|
||||
private String resource = null;
|
||||
private String jid = null;
|
||||
|
||||
public Bind() {
|
||||
setType(IQ.Type.SET);
|
||||
}
|
||||
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
public void setJid(String jid) {
|
||||
this.jid = jid;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">");
|
||||
if (resource != null) {
|
||||
buf.append("<resource>").append(resource).append("</resource>");
|
||||
}
|
||||
if (jid != null) {
|
||||
buf.append("<jid>").append(jid).append("</jid>");
|
||||
}
|
||||
buf.append("</bind>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,4 +127,4 @@ public class DefaultPacketExtension implements PacketExtension {
|
|||
}
|
||||
map.put(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -669,4 +669,4 @@ public class Message extends Packet {
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -352,4 +352,4 @@ public class Presence extends Packet {
|
|||
*/
|
||||
dnd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,4 +104,4 @@ public class Registration extends IQ {
|
|||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack.packet;
|
||||
|
||||
/**
|
||||
* IQ packet that will be sent to the server to establish a session.<p>
|
||||
*
|
||||
* If a server supports sessions, it MUST include a <i>session</i> element in the
|
||||
* stream features it advertises to a client after the completion of stream authentication.
|
||||
* Upon being informed that session establishment is required by the server the client MUST
|
||||
* establish a session if it desires to engage in instant messaging and presence functionality.<p>
|
||||
*
|
||||
* For more information refer to the following
|
||||
* <a href=http://www.xmpp.org/specs/rfc3921.html#session>link</a>.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Session extends IQ {
|
||||
|
||||
public Session() {
|
||||
setType(IQ.Type.SET);
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
return "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>";
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack.packet;
|
||||
|
||||
/**
|
||||
* IQ packet that will be sent to the server to establish a session.<p>
|
||||
*
|
||||
* If a server supports sessions, it MUST include a <i>session</i> element in the
|
||||
* stream features it advertises to a client after the completion of stream authentication.
|
||||
* Upon being informed that session establishment is required by the server the client MUST
|
||||
* establish a session if it desires to engage in instant messaging and presence functionality.<p>
|
||||
*
|
||||
* For more information refer to the following
|
||||
* <a href=http://www.xmpp.org/specs/rfc3921.html#session>link</a>.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class Session extends IQ {
|
||||
|
||||
public Session() {
|
||||
setType(IQ.Type.SET);
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
return "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,120 +1,120 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2005 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack.packet;
|
||||
|
||||
/**
|
||||
* Represents a stream error packet. Stream errors are unrecoverable errors where the server
|
||||
* will close the unrelying TCP connection after the stream error was sent to the client.
|
||||
* These is the list of stream errors as defined in the XMPP spec:<p>
|
||||
*
|
||||
* <table border=1>
|
||||
* <tr><td><b>Code</b></td><td><b>Description</b></td></tr>
|
||||
* <tr><td> bad-format </td><td> the entity has sent XML that cannot be processed </td></tr>
|
||||
* <tr><td> unsupported-encoding </td><td> the entity has sent a namespace prefix that is
|
||||
* unsupported </td></tr>
|
||||
* <tr><td> bad-namespace-prefix </td><td> Remote Server Timeout </td></tr>
|
||||
* <tr><td> conflict </td><td> the server is closing the active stream for this entity
|
||||
* because a new stream has been initiated that conflicts with the existing
|
||||
* stream. </td></tr>
|
||||
* <tr><td> connection-timeout </td><td> the entity has not generated any traffic over
|
||||
* the stream for some period of time. </td></tr>
|
||||
* <tr><td> host-gone </td><td> the value of the 'to' attribute provided by the initiating
|
||||
* entity in the stream header corresponds to a hostname that is no longer hosted by
|
||||
* the server. </td></tr>
|
||||
* <tr><td> host-unknown </td><td> the value of the 'to' attribute provided by the
|
||||
* initiating entity in the stream header does not correspond to a hostname that is
|
||||
* hosted by the server. </td></tr>
|
||||
* <tr><td> improper-addressing </td><td> a stanza sent between two servers lacks a 'to'
|
||||
* or 'from' attribute </td></tr>
|
||||
* <tr><td> internal-server-error </td><td> the server has experienced a
|
||||
* misconfiguration. </td></tr>
|
||||
* <tr><td> invalid-from </td><td> the JID or hostname provided in a 'from' address does
|
||||
* not match an authorized JID. </td></tr>
|
||||
* <tr><td> invalid-namespace </td><td> the streams namespace name is invalid. </td></tr>
|
||||
* <tr><td> invalid-xml </td><td> the entity has sent invalid XML over the stream. </td></tr>
|
||||
* <tr><td> not-authorized </td><td> the entity has attempted to send data before the
|
||||
* stream has been authenticated </td></tr>
|
||||
* <tr><td> policy-violation </td><td> the entity has violated some local service
|
||||
* policy. </td></tr>
|
||||
* <tr><td> remote-connection-failed </td><td> Rthe server is unable to properly connect
|
||||
* to a remote entity. </td></tr>
|
||||
* <tr><td> resource-constraint </td><td> Rthe server lacks the system resources necessary
|
||||
* to service the stream. </td></tr>
|
||||
* <tr><td> restricted-xml </td><td> the entity has attempted to send restricted XML
|
||||
* features. </td></tr>
|
||||
* <tr><td> see-other-host </td><td> the server will not provide service to the initiating
|
||||
* entity but is redirecting traffic to another host. </td></tr>
|
||||
* <tr><td> system-shutdown </td><td> the server is being shut down and all active streams
|
||||
* are being closed. </td></tr>
|
||||
* <tr><td> undefined-condition </td><td> the error condition is not one of those defined
|
||||
* by the other conditions in this list. </td></tr>
|
||||
* <tr><td> unsupported-encoding </td><td> the initiating entity has encoded the stream in
|
||||
* an encoding that is not supported. </td></tr>
|
||||
* <tr><td> unsupported-stanza-type </td><td> the initiating entity has sent a first-level
|
||||
* child of the stream that is not supported. </td></tr>
|
||||
* <tr><td> unsupported-version </td><td> the value of the 'version' attribute provided by
|
||||
* the initiating entity in the stream header specifies a version of XMPP that is not
|
||||
* supported. </td></tr>
|
||||
* <tr><td> not-well-formed </td><td> the initiating entity has sent XML that is not
|
||||
* well-formed. </td></tr>
|
||||
* </table>
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class StreamError {
|
||||
|
||||
public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-streams";
|
||||
|
||||
private String code;
|
||||
private String text;
|
||||
|
||||
public StreamError(String code) {
|
||||
super();
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public StreamError(String code, String text) {
|
||||
this(code);
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code.
|
||||
*
|
||||
* @return the error code.
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error text, which may be null.
|
||||
*
|
||||
* @return the error text.
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder txt = new StringBuilder();
|
||||
txt.append("stream:error (").append(code).append(")");
|
||||
if (text != null) txt.append(" text: ").append(text);
|
||||
return txt.toString();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2005 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack.packet;
|
||||
|
||||
/**
|
||||
* Represents a stream error packet. Stream errors are unrecoverable errors where the server
|
||||
* will close the unrelying TCP connection after the stream error was sent to the client.
|
||||
* These is the list of stream errors as defined in the XMPP spec:<p>
|
||||
*
|
||||
* <table border=1>
|
||||
* <tr><td><b>Code</b></td><td><b>Description</b></td></tr>
|
||||
* <tr><td> bad-format </td><td> the entity has sent XML that cannot be processed </td></tr>
|
||||
* <tr><td> unsupported-encoding </td><td> the entity has sent a namespace prefix that is
|
||||
* unsupported </td></tr>
|
||||
* <tr><td> bad-namespace-prefix </td><td> Remote Server Timeout </td></tr>
|
||||
* <tr><td> conflict </td><td> the server is closing the active stream for this entity
|
||||
* because a new stream has been initiated that conflicts with the existing
|
||||
* stream. </td></tr>
|
||||
* <tr><td> connection-timeout </td><td> the entity has not generated any traffic over
|
||||
* the stream for some period of time. </td></tr>
|
||||
* <tr><td> host-gone </td><td> the value of the 'to' attribute provided by the initiating
|
||||
* entity in the stream header corresponds to a hostname that is no longer hosted by
|
||||
* the server. </td></tr>
|
||||
* <tr><td> host-unknown </td><td> the value of the 'to' attribute provided by the
|
||||
* initiating entity in the stream header does not correspond to a hostname that is
|
||||
* hosted by the server. </td></tr>
|
||||
* <tr><td> improper-addressing </td><td> a stanza sent between two servers lacks a 'to'
|
||||
* or 'from' attribute </td></tr>
|
||||
* <tr><td> internal-server-error </td><td> the server has experienced a
|
||||
* misconfiguration. </td></tr>
|
||||
* <tr><td> invalid-from </td><td> the JID or hostname provided in a 'from' address does
|
||||
* not match an authorized JID. </td></tr>
|
||||
* <tr><td> invalid-namespace </td><td> the streams namespace name is invalid. </td></tr>
|
||||
* <tr><td> invalid-xml </td><td> the entity has sent invalid XML over the stream. </td></tr>
|
||||
* <tr><td> not-authorized </td><td> the entity has attempted to send data before the
|
||||
* stream has been authenticated </td></tr>
|
||||
* <tr><td> policy-violation </td><td> the entity has violated some local service
|
||||
* policy. </td></tr>
|
||||
* <tr><td> remote-connection-failed </td><td> Rthe server is unable to properly connect
|
||||
* to a remote entity. </td></tr>
|
||||
* <tr><td> resource-constraint </td><td> Rthe server lacks the system resources necessary
|
||||
* to service the stream. </td></tr>
|
||||
* <tr><td> restricted-xml </td><td> the entity has attempted to send restricted XML
|
||||
* features. </td></tr>
|
||||
* <tr><td> see-other-host </td><td> the server will not provide service to the initiating
|
||||
* entity but is redirecting traffic to another host. </td></tr>
|
||||
* <tr><td> system-shutdown </td><td> the server is being shut down and all active streams
|
||||
* are being closed. </td></tr>
|
||||
* <tr><td> undefined-condition </td><td> the error condition is not one of those defined
|
||||
* by the other conditions in this list. </td></tr>
|
||||
* <tr><td> unsupported-encoding </td><td> the initiating entity has encoded the stream in
|
||||
* an encoding that is not supported. </td></tr>
|
||||
* <tr><td> unsupported-stanza-type </td><td> the initiating entity has sent a first-level
|
||||
* child of the stream that is not supported. </td></tr>
|
||||
* <tr><td> unsupported-version </td><td> the value of the 'version' attribute provided by
|
||||
* the initiating entity in the stream header specifies a version of XMPP that is not
|
||||
* supported. </td></tr>
|
||||
* <tr><td> not-well-formed </td><td> the initiating entity has sent XML that is not
|
||||
* well-formed. </td></tr>
|
||||
* </table>
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class StreamError {
|
||||
|
||||
public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-streams";
|
||||
|
||||
private String code;
|
||||
private String text;
|
||||
|
||||
public StreamError(String code) {
|
||||
super();
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public StreamError(String code, String text) {
|
||||
this(code);
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code.
|
||||
*
|
||||
* @return the error code.
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error text, which may be null.
|
||||
*
|
||||
* @return the error text.
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder txt = new StringBuilder();
|
||||
txt.append("stream:error (").append(code).append(")");
|
||||
if (text != null) txt.append(" text: ").append(text);
|
||||
return txt.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
abstract class AbstractProviderInfo {
|
||||
private String element;
|
||||
private String ns;
|
||||
private Object provider;
|
||||
|
||||
AbstractProviderInfo(String elementName, String namespace, Object iqOrExtProvider) {
|
||||
element = elementName;
|
||||
ns = namespace;
|
||||
provider = iqOrExtProvider;
|
||||
}
|
||||
|
||||
public String getElementName() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return ns;
|
||||
}
|
||||
|
||||
Object getProvider() {
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
abstract class AbstractProviderInfo {
|
||||
private String element;
|
||||
private String ns;
|
||||
private Object provider;
|
||||
|
||||
AbstractProviderInfo(String elementName, String namespace, Object iqOrExtProvider) {
|
||||
element = elementName;
|
||||
ns = namespace;
|
||||
provider = iqOrExtProvider;
|
||||
}
|
||||
|
||||
public String getElementName() {
|
||||
return element;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return ns;
|
||||
}
|
||||
|
||||
Object getProvider() {
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,109 +1,109 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class simplifies parsing of embedded elements by using the
|
||||
* <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>.
|
||||
* After extracting the current element attributes and content of any child elements, the template method
|
||||
* ({@link #createReturnExtension(String, String, Map, List)} is called. Subclasses
|
||||
* then override this method to create the specific return type.
|
||||
*
|
||||
* <p>To use this class, you simply register your subclasses as extension providers in the
|
||||
* <b>smack.properties</b> file. Then they will be automatically picked up and used to parse
|
||||
* any child elements.
|
||||
*
|
||||
* <pre>
|
||||
* For example, given the following message
|
||||
*
|
||||
* <message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo>
|
||||
* <event xmlns='http://jabber.org/protocol/pubsub#event>
|
||||
* <items node='princely_musings'>
|
||||
* <item id='asdjkwei3i34234n356'>
|
||||
* <entry xmlns='http://www.w3.org/2005/Atom'>
|
||||
* <title>Soliloquy</title>
|
||||
* <link rel='alternative' type='text/html'/>
|
||||
* <id>tag:denmark.lit,2003:entry-32397</id>
|
||||
* </entry>
|
||||
* </item>
|
||||
* </items>
|
||||
* </event>
|
||||
* </message>
|
||||
*
|
||||
* I would have a classes
|
||||
* {@link ItemsProvider} extends {@link EmbeddedExtensionProvider}
|
||||
* {@link ItemProvider} extends {@link EmbeddedExtensionProvider}
|
||||
* and
|
||||
* AtomProvider extends {@link PacketExtensionProvider}
|
||||
*
|
||||
* These classes are then registered in the meta-inf/smack.providers file
|
||||
* as follows.
|
||||
*
|
||||
* <extensionProvider>
|
||||
* <elementName>items</elementName>
|
||||
* <namespace>http://jabber.org/protocol/pubsub#event</namespace>
|
||||
* <className>org.jivesoftware.smackx.provider.ItemsEventProvider</className>
|
||||
* </extensionProvider>
|
||||
* <extensionProvider>
|
||||
* <elementName>item</elementName>
|
||||
* <namespace>http://jabber.org/protocol/pubsub#event</namespace>
|
||||
* <className>org.jivesoftware.smackx.provider.ItemProvider</className>
|
||||
* </extensionProvider>
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
abstract public class EmbeddedExtensionProvider implements PacketExtensionProvider
|
||||
{
|
||||
|
||||
final public PacketExtension parseExtension(XmlPullParser parser) throws Exception
|
||||
{
|
||||
String namespace = parser.getNamespace();
|
||||
String name = parser.getName();
|
||||
Map<String, String> attMap = new HashMap<String, String>();
|
||||
|
||||
for(int i=0; i<parser.getAttributeCount(); i++)
|
||||
{
|
||||
attMap.put(parser.getAttributeName(i), parser.getAttributeValue(i));
|
||||
}
|
||||
List<PacketExtension> extensions = new ArrayList<PacketExtension>();
|
||||
|
||||
do
|
||||
{
|
||||
int tag = parser.next();
|
||||
|
||||
if (tag == XmlPullParser.START_TAG)
|
||||
extensions.add(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
|
||||
} while (!name.equals(parser.getName()));
|
||||
|
||||
return createReturnExtension(name, namespace, attMap, extensions);
|
||||
}
|
||||
|
||||
abstract protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class simplifies parsing of embedded elements by using the
|
||||
* <a href="http://en.wikipedia.org/wiki/Template_method_pattern">Template Method Pattern</a>.
|
||||
* After extracting the current element attributes and content of any child elements, the template method
|
||||
* ({@link #createReturnExtension(String, String, Map, List)} is called. Subclasses
|
||||
* then override this method to create the specific return type.
|
||||
*
|
||||
* <p>To use this class, you simply register your subclasses as extension providers in the
|
||||
* <b>smack.properties</b> file. Then they will be automatically picked up and used to parse
|
||||
* any child elements.
|
||||
*
|
||||
* <pre>
|
||||
* For example, given the following message
|
||||
*
|
||||
* <message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo>
|
||||
* <event xmlns='http://jabber.org/protocol/pubsub#event>
|
||||
* <items node='princely_musings'>
|
||||
* <item id='asdjkwei3i34234n356'>
|
||||
* <entry xmlns='http://www.w3.org/2005/Atom'>
|
||||
* <title>Soliloquy</title>
|
||||
* <link rel='alternative' type='text/html'/>
|
||||
* <id>tag:denmark.lit,2003:entry-32397</id>
|
||||
* </entry>
|
||||
* </item>
|
||||
* </items>
|
||||
* </event>
|
||||
* </message>
|
||||
*
|
||||
* I would have a classes
|
||||
* {@link ItemsProvider} extends {@link EmbeddedExtensionProvider}
|
||||
* {@link ItemProvider} extends {@link EmbeddedExtensionProvider}
|
||||
* and
|
||||
* AtomProvider extends {@link PacketExtensionProvider}
|
||||
*
|
||||
* These classes are then registered in the meta-inf/smack.providers file
|
||||
* as follows.
|
||||
*
|
||||
* <extensionProvider>
|
||||
* <elementName>items</elementName>
|
||||
* <namespace>http://jabber.org/protocol/pubsub#event</namespace>
|
||||
* <className>org.jivesoftware.smackx.provider.ItemsEventProvider</className>
|
||||
* </extensionProvider>
|
||||
* <extensionProvider>
|
||||
* <elementName>item</elementName>
|
||||
* <namespace>http://jabber.org/protocol/pubsub#event</namespace>
|
||||
* <className>org.jivesoftware.smackx.provider.ItemProvider</className>
|
||||
* </extensionProvider>
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
abstract public class EmbeddedExtensionProvider implements PacketExtensionProvider
|
||||
{
|
||||
|
||||
final public PacketExtension parseExtension(XmlPullParser parser) throws Exception
|
||||
{
|
||||
String namespace = parser.getNamespace();
|
||||
String name = parser.getName();
|
||||
Map<String, String> attMap = new HashMap<String, String>();
|
||||
|
||||
for(int i=0; i<parser.getAttributeCount(); i++)
|
||||
{
|
||||
attMap.put(parser.getAttributeName(i), parser.getAttributeValue(i));
|
||||
}
|
||||
List<PacketExtension> extensions = new ArrayList<PacketExtension>();
|
||||
|
||||
do
|
||||
{
|
||||
int tag = parser.next();
|
||||
|
||||
if (tag == XmlPullParser.START_TAG)
|
||||
extensions.add(PacketParserUtils.parsePacketExtension(parser.getName(), parser.getNamespace(), parser));
|
||||
} while (!name.equals(parser.getName()));
|
||||
|
||||
return createReturnExtension(name, namespace, attMap, extensions);
|
||||
}
|
||||
|
||||
abstract protected PacketExtension createReturnExtension(String currentElement, String currentNamespace, Map<String, String> attributeMap, List<? extends PacketExtension> content);
|
||||
}
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
/**
|
||||
* Defines the information required to register a packet extension Provider with the {@link ProviderManager} when using the
|
||||
* {@link ProviderLoader}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public final class ExtensionProviderInfo extends AbstractProviderInfo {
|
||||
|
||||
/**
|
||||
* Defines an extension provider which implements the <code>PacketExtensionProvider</code> interface.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param extProvider The provider implementation.
|
||||
*/
|
||||
public ExtensionProviderInfo(String elementName, String namespace, PacketExtensionProvider extProvider) {
|
||||
super(elementName, namespace, extProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an extension provider which is adheres to the JavaBean spec for parsing the extension.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param beanClass The provider bean class.
|
||||
*/
|
||||
public ExtensionProviderInfo(String elementName, String namespace, Class<?> beanClass) {
|
||||
super(elementName, namespace, beanClass);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
/**
|
||||
* Defines the information required to register a packet extension Provider with the {@link ProviderManager} when using the
|
||||
* {@link ProviderLoader}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public final class ExtensionProviderInfo extends AbstractProviderInfo {
|
||||
|
||||
/**
|
||||
* Defines an extension provider which implements the <code>PacketExtensionProvider</code> interface.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param extProvider The provider implementation.
|
||||
*/
|
||||
public ExtensionProviderInfo(String elementName, String namespace, PacketExtensionProvider extProvider) {
|
||||
super(elementName, namespace, extProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an extension provider which is adheres to the JavaBean spec for parsing the extension.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param beanClass The provider bean class.
|
||||
*/
|
||||
public ExtensionProviderInfo(String elementName, String namespace, Class<?> beanClass) {
|
||||
super(elementName, namespace, beanClass);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,4 +41,4 @@ public interface IQProvider {
|
|||
* @throws Exception if an error occurs parsing the XML.
|
||||
*/
|
||||
public IQ parseIQ(XmlPullParser parser) throws Exception;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
/**
|
||||
* Defines the information required to register an IQ Provider with the {@link ProviderManager} when using the
|
||||
* {@link ProviderLoader}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public final class IQProviderInfo extends AbstractProviderInfo {
|
||||
|
||||
/**
|
||||
* Defines an IQ provider which implements the <code>IQProvider</code> interface.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param iqProvider The provider implementation.
|
||||
*/
|
||||
public IQProviderInfo(String elementName, String namespace, IQProvider iqProvider) {
|
||||
super(elementName, namespace, iqProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an IQ class which can be used as a provider via introspection.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param iqProviderClass The IQ class being parsed.
|
||||
*/
|
||||
public IQProviderInfo(String elementName, String namespace, Class<? extends IQ> iqProviderClass) {
|
||||
super(elementName, namespace, iqProviderClass);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
|
||||
/**
|
||||
* Defines the information required to register an IQ Provider with the {@link ProviderManager} when using the
|
||||
* {@link ProviderLoader}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public final class IQProviderInfo extends AbstractProviderInfo {
|
||||
|
||||
/**
|
||||
* Defines an IQ provider which implements the <code>IQProvider</code> interface.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param iqProvider The provider implementation.
|
||||
*/
|
||||
public IQProviderInfo(String elementName, String namespace, IQProvider iqProvider) {
|
||||
super(elementName, namespace, iqProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an IQ class which can be used as a provider via introspection.
|
||||
*
|
||||
* @param elementName Element that provider parses.
|
||||
* @param namespace Namespace that provider parses.
|
||||
* @param iqProviderClass The IQ class being parsed.
|
||||
*/
|
||||
public IQProviderInfo(String elementName, String namespace, Class<? extends IQ> iqProviderClass) {
|
||||
super(elementName, namespace, iqProviderClass);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,172 +1,172 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.xmlpull.mxp1.MXParser;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* Loads the {@link IQProvider} and {@link PacketExtensionProvider} information from a standard provider file in preparation
|
||||
* for loading into the {@link ProviderManager}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public class ProviderFileLoader implements ProviderLoader {
|
||||
private final static Logger log = Logger.getLogger(ProviderFileLoader.class.getName());
|
||||
|
||||
private Collection<IQProviderInfo> iqProviders;
|
||||
private Collection<ExtensionProviderInfo> extProviders;
|
||||
private InputStream providerStream;
|
||||
private List<Exception> exceptions = new LinkedList<Exception>();
|
||||
|
||||
public ProviderFileLoader(InputStream providerFileInputStream) {
|
||||
setInputStream(providerFileInputStream);
|
||||
}
|
||||
|
||||
public ProviderFileLoader() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<IQProviderInfo> getIQProviderInfo() {
|
||||
initialize();
|
||||
return iqProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ExtensionProviderInfo> getExtensionProviderInfo() {
|
||||
initialize();
|
||||
return extProviders;
|
||||
}
|
||||
|
||||
public List<Exception> getLoadingExceptions() {
|
||||
return Collections.unmodifiableList(exceptions);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private synchronized void initialize() {
|
||||
// Check to see if already initialized
|
||||
if (iqProviders != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (providerStream == null) {
|
||||
throw new IllegalArgumentException("No input stream set for loader");
|
||||
}
|
||||
iqProviders = new ArrayList<IQProviderInfo>();
|
||||
extProviders = new ArrayList<ExtensionProviderInfo>();
|
||||
|
||||
// Load processing providers.
|
||||
try {
|
||||
XmlPullParser parser = new MXParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||
parser.setInput(providerStream, "UTF-8");
|
||||
int eventType = parser.getEventType();
|
||||
do {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
String typeName = parser.getName();
|
||||
|
||||
try {
|
||||
if (!"smackProviders".equals(typeName)) {
|
||||
parser.next();
|
||||
parser.next();
|
||||
String elementName = parser.nextText();
|
||||
parser.next();
|
||||
parser.next();
|
||||
String namespace = parser.nextText();
|
||||
parser.next();
|
||||
parser.next();
|
||||
String className = parser.nextText();
|
||||
|
||||
try {
|
||||
// Attempt to load the provider class and then create
|
||||
// a new instance if it's an IQProvider. Otherwise, if it's
|
||||
// an IQ class, add the class object itself, then we'll use
|
||||
// reflection later to create instances of the class.
|
||||
if ("iqProvider".equals(typeName)) {
|
||||
// Add the provider to the map.
|
||||
Class<?> provider = Class.forName(className);
|
||||
|
||||
if (IQProvider.class.isAssignableFrom(provider)) {
|
||||
iqProviders.add(new IQProviderInfo(elementName, namespace, (IQProvider) provider.newInstance()));
|
||||
}
|
||||
else if (IQ.class.isAssignableFrom(provider)) {
|
||||
iqProviders.add(new IQProviderInfo(elementName, namespace, (Class<? extends IQ>)provider));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Attempt to load the provider class and then create
|
||||
// a new instance if it's an ExtensionProvider. Otherwise, if it's
|
||||
// a PacketExtension, add the class object itself and
|
||||
// then we'll use reflection later to create instances
|
||||
// of the class.
|
||||
Class<?> provider = Class.forName(className);
|
||||
if (PacketExtensionProvider.class.isAssignableFrom(provider)) {
|
||||
extProviders.add(new ExtensionProviderInfo(elementName, namespace, (PacketExtensionProvider) provider.newInstance()));
|
||||
}
|
||||
else if (PacketExtension.class.isAssignableFrom(provider)) {
|
||||
extProviders.add(new ExtensionProviderInfo(elementName, namespace, provider));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.log(Level.SEVERE, "Could not find provider class", cnfe);
|
||||
exceptions.add(cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException illExc) {
|
||||
log.log(Level.SEVERE, "Invalid provider type found [" + typeName + "] when expecting iqProvider or extensionProvider", illExc);
|
||||
exceptions.add(illExc);
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
while (eventType != XmlPullParser.END_DOCUMENT);
|
||||
}
|
||||
catch (Exception e){
|
||||
log.log(Level.SEVERE, "Unknown error occurred while parsing provider file", e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
providerStream.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setInputStream(InputStream providerFileInput) {
|
||||
if (providerFileInput == null) {
|
||||
throw new IllegalArgumentException("InputStream cannot be null");
|
||||
}
|
||||
providerStream = providerFileInput;
|
||||
initialize();
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.PacketExtension;
|
||||
import org.xmlpull.mxp1.MXParser;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* Loads the {@link IQProvider} and {@link PacketExtensionProvider} information from a standard provider file in preparation
|
||||
* for loading into the {@link ProviderManager}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public class ProviderFileLoader implements ProviderLoader {
|
||||
private final static Logger log = Logger.getLogger(ProviderFileLoader.class.getName());
|
||||
|
||||
private Collection<IQProviderInfo> iqProviders;
|
||||
private Collection<ExtensionProviderInfo> extProviders;
|
||||
private InputStream providerStream;
|
||||
private List<Exception> exceptions = new LinkedList<Exception>();
|
||||
|
||||
public ProviderFileLoader(InputStream providerFileInputStream) {
|
||||
setInputStream(providerFileInputStream);
|
||||
}
|
||||
|
||||
public ProviderFileLoader() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<IQProviderInfo> getIQProviderInfo() {
|
||||
initialize();
|
||||
return iqProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ExtensionProviderInfo> getExtensionProviderInfo() {
|
||||
initialize();
|
||||
return extProviders;
|
||||
}
|
||||
|
||||
public List<Exception> getLoadingExceptions() {
|
||||
return Collections.unmodifiableList(exceptions);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private synchronized void initialize() {
|
||||
// Check to see if already initialized
|
||||
if (iqProviders != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (providerStream == null) {
|
||||
throw new IllegalArgumentException("No input stream set for loader");
|
||||
}
|
||||
iqProviders = new ArrayList<IQProviderInfo>();
|
||||
extProviders = new ArrayList<ExtensionProviderInfo>();
|
||||
|
||||
// Load processing providers.
|
||||
try {
|
||||
XmlPullParser parser = new MXParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||
parser.setInput(providerStream, "UTF-8");
|
||||
int eventType = parser.getEventType();
|
||||
do {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
String typeName = parser.getName();
|
||||
|
||||
try {
|
||||
if (!"smackProviders".equals(typeName)) {
|
||||
parser.next();
|
||||
parser.next();
|
||||
String elementName = parser.nextText();
|
||||
parser.next();
|
||||
parser.next();
|
||||
String namespace = parser.nextText();
|
||||
parser.next();
|
||||
parser.next();
|
||||
String className = parser.nextText();
|
||||
|
||||
try {
|
||||
// Attempt to load the provider class and then create
|
||||
// a new instance if it's an IQProvider. Otherwise, if it's
|
||||
// an IQ class, add the class object itself, then we'll use
|
||||
// reflection later to create instances of the class.
|
||||
if ("iqProvider".equals(typeName)) {
|
||||
// Add the provider to the map.
|
||||
Class<?> provider = Class.forName(className);
|
||||
|
||||
if (IQProvider.class.isAssignableFrom(provider)) {
|
||||
iqProviders.add(new IQProviderInfo(elementName, namespace, (IQProvider) provider.newInstance()));
|
||||
}
|
||||
else if (IQ.class.isAssignableFrom(provider)) {
|
||||
iqProviders.add(new IQProviderInfo(elementName, namespace, (Class<? extends IQ>)provider));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Attempt to load the provider class and then create
|
||||
// a new instance if it's an ExtensionProvider. Otherwise, if it's
|
||||
// a PacketExtension, add the class object itself and
|
||||
// then we'll use reflection later to create instances
|
||||
// of the class.
|
||||
Class<?> provider = Class.forName(className);
|
||||
if (PacketExtensionProvider.class.isAssignableFrom(provider)) {
|
||||
extProviders.add(new ExtensionProviderInfo(elementName, namespace, (PacketExtensionProvider) provider.newInstance()));
|
||||
}
|
||||
else if (PacketExtension.class.isAssignableFrom(provider)) {
|
||||
extProviders.add(new ExtensionProviderInfo(elementName, namespace, provider));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
log.log(Level.SEVERE, "Could not find provider class", cnfe);
|
||||
exceptions.add(cnfe);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException illExc) {
|
||||
log.log(Level.SEVERE, "Invalid provider type found [" + typeName + "] when expecting iqProvider or extensionProvider", illExc);
|
||||
exceptions.add(illExc);
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
while (eventType != XmlPullParser.END_DOCUMENT);
|
||||
}
|
||||
catch (Exception e){
|
||||
log.log(Level.SEVERE, "Unknown error occurred while parsing provider file", e);
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
providerStream.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setInputStream(InputStream providerFileInput) {
|
||||
if (providerFileInput == null) {
|
||||
throw new IllegalArgumentException("InputStream cannot be null");
|
||||
}
|
||||
providerStream = providerFileInput;
|
||||
initialize();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Used to load providers into the {@link ProviderManager}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public interface ProviderLoader {
|
||||
|
||||
/**
|
||||
* Provides the IQ provider info for the creation of IQ providers to be added to the <code>ProviderManager</code>.
|
||||
* @return The IQ provider info to load.
|
||||
*/
|
||||
Collection<IQProviderInfo> getIQProviderInfo();
|
||||
|
||||
/**
|
||||
* Provides the extension providers for the creation of extension providers to be added to the <code>ProviderManager</code>.
|
||||
* @return The extension provider info to load.
|
||||
*/
|
||||
Collection<ExtensionProviderInfo> getExtensionProviderInfo();
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.provider;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Used to load providers into the {@link ProviderManager}.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
public interface ProviderLoader {
|
||||
|
||||
/**
|
||||
* Provides the IQ provider info for the creation of IQ providers to be added to the <code>ProviderManager</code>.
|
||||
* @return The IQ provider info to load.
|
||||
*/
|
||||
Collection<IQProviderInfo> getIQProviderInfo();
|
||||
|
||||
/**
|
||||
* Provides the extension providers for the creation of extension providers to be added to the <code>ProviderManager</code>.
|
||||
* @return The extension provider info to load.
|
||||
*/
|
||||
Collection<ExtensionProviderInfo> getExtensionProviderInfo();
|
||||
}
|
||||
|
|
|
@ -295,4 +295,4 @@ public final class ProviderManager {
|
|||
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL ANONYMOUS mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLAnonymous extends SASLMechanism {
|
||||
|
||||
public SASLAnonymous(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "ANONYMOUS";
|
||||
}
|
||||
|
||||
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException {
|
||||
authenticate();
|
||||
}
|
||||
|
||||
public void authenticate(String username, String host, String password) throws IOException {
|
||||
authenticate();
|
||||
}
|
||||
|
||||
protected void authenticate() throws IOException {
|
||||
// Send the authentication to the server
|
||||
getSASLAuthentication().send(new AuthMechanism(getName(), null));
|
||||
}
|
||||
|
||||
public void challengeReceived(String challenge) throws IOException {
|
||||
// Build the challenge response stanza encoding the response text
|
||||
// and send the authentication to the server
|
||||
getSASLAuthentication().send(new Response());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL ANONYMOUS mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLAnonymous extends SASLMechanism {
|
||||
|
||||
public SASLAnonymous(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "ANONYMOUS";
|
||||
}
|
||||
|
||||
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException {
|
||||
authenticate();
|
||||
}
|
||||
|
||||
public void authenticate(String username, String host, String password) throws IOException {
|
||||
authenticate();
|
||||
}
|
||||
|
||||
protected void authenticate() throws IOException {
|
||||
// Send the authentication to the server
|
||||
getSASLAuthentication().send(new AuthMechanism(getName(), null));
|
||||
}
|
||||
|
||||
public void challengeReceived(String challenge) throws IOException {
|
||||
// Build the challenge response stanza encoding the response text
|
||||
// and send the authentication to the server
|
||||
getSASLAuthentication().send(new Response());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL CRAM-MD5 mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLCramMD5Mechanism extends SASLMechanism {
|
||||
|
||||
public SASLCramMD5Mechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "CRAM-MD5";
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL CRAM-MD5 mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLCramMD5Mechanism extends SASLMechanism {
|
||||
|
||||
public SASLCramMD5Mechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "CRAM-MD5";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL DIGEST-MD5 mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLDigestMD5Mechanism extends SASLMechanism {
|
||||
|
||||
public SASLDigestMD5Mechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "DIGEST-MD5";
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL DIGEST-MD5 mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLDigestMD5Mechanism extends SASLMechanism {
|
||||
|
||||
public SASLDigestMD5Mechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "DIGEST-MD5";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL EXTERNAL mechanism.
|
||||
*
|
||||
* To effectively use this mechanism, Java must be configured to properly
|
||||
* supply a client SSL certificate (of some sort) to the server. It is up
|
||||
* to the implementer to determine how to do this. Here is one method:
|
||||
*
|
||||
* Create a java keystore with your SSL certificate in it:
|
||||
* keytool -genkey -alias username -dname "cn=username,ou=organizationalUnit,o=organizationaName,l=locality,s=state,c=country"
|
||||
*
|
||||
* Next, set the System Properties:
|
||||
* <ul>
|
||||
* <li>javax.net.ssl.keyStore to the location of the keyStore
|
||||
* <li>javax.net.ssl.keyStorePassword to the password of the keyStore
|
||||
* <li>javax.net.ssl.trustStore to the location of the trustStore
|
||||
* <li>javax.net.ssl.trustStorePassword to the the password of the trustStore
|
||||
* </ul>
|
||||
*
|
||||
* Then, when the server requests or requires the client certificate, java will
|
||||
* simply provide the one in the keyStore.
|
||||
*
|
||||
* Also worth noting is the EXTERNAL mechanism in Smack is not enabled by default.
|
||||
* To enable it, the implementer will need to call SASLAuthentication.supportSASLMechamism("EXTERNAL");
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLExternalMechanism extends SASLMechanism {
|
||||
|
||||
public SASLExternalMechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "EXTERNAL";
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL EXTERNAL mechanism.
|
||||
*
|
||||
* To effectively use this mechanism, Java must be configured to properly
|
||||
* supply a client SSL certificate (of some sort) to the server. It is up
|
||||
* to the implementer to determine how to do this. Here is one method:
|
||||
*
|
||||
* Create a java keystore with your SSL certificate in it:
|
||||
* keytool -genkey -alias username -dname "cn=username,ou=organizationalUnit,o=organizationaName,l=locality,s=state,c=country"
|
||||
*
|
||||
* Next, set the System Properties:
|
||||
* <ul>
|
||||
* <li>javax.net.ssl.keyStore to the location of the keyStore
|
||||
* <li>javax.net.ssl.keyStorePassword to the password of the keyStore
|
||||
* <li>javax.net.ssl.trustStore to the location of the trustStore
|
||||
* <li>javax.net.ssl.trustStorePassword to the the password of the trustStore
|
||||
* </ul>
|
||||
*
|
||||
* Then, when the server requests or requires the client certificate, java will
|
||||
* simply provide the one in the keyStore.
|
||||
*
|
||||
* Also worth noting is the EXTERNAL mechanism in Smack is not enabled by default.
|
||||
* To enable it, the implementer will need to call SASLAuthentication.supportSASLMechamism("EXTERNAL");
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLExternalMechanism extends SASLMechanism {
|
||||
|
||||
public SASLExternalMechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "EXTERNAL";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,86 +1,86 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import javax.security.sasl.Sasl;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL GSSAPI mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLGSSAPIMechanism extends SASLMechanism {
|
||||
|
||||
public SASLGSSAPIMechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
|
||||
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
|
||||
System.setProperty("java.security.auth.login.config","gss.conf");
|
||||
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "GSSAPI";
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server.
|
||||
* This overrides from the abstract class because the initial token
|
||||
* needed for GSSAPI is binary, and not safe to put in a string, thus
|
||||
* getAuthenticationText() cannot be used.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param cbh the CallbackHandler (not used with GSSAPI)
|
||||
* @throws IOException If a network error occures while authenticating.
|
||||
*/
|
||||
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String,String>();
|
||||
props.put(Sasl.SERVER_AUTH,"TRUE");
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server.
|
||||
* This overrides from the abstract class because the initial token
|
||||
* needed for GSSAPI is binary, and not safe to put in a string, thus
|
||||
* getAuthenticationText() cannot be used.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param password the password of the user (ignored for GSSAPI)
|
||||
* @throws IOException If a network error occures while authenticating.
|
||||
*/
|
||||
public void authenticate(String username, String host, String password) throws IOException, XMPPException {
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String, String>();
|
||||
props.put(Sasl.SERVER_AUTH,"TRUE");
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import javax.security.sasl.Sasl;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL GSSAPI mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLGSSAPIMechanism extends SASLMechanism {
|
||||
|
||||
public SASLGSSAPIMechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
|
||||
System.setProperty("javax.security.auth.useSubjectCredsOnly","false");
|
||||
System.setProperty("java.security.auth.login.config","gss.conf");
|
||||
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "GSSAPI";
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server.
|
||||
* This overrides from the abstract class because the initial token
|
||||
* needed for GSSAPI is binary, and not safe to put in a string, thus
|
||||
* getAuthenticationText() cannot be used.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param cbh the CallbackHandler (not used with GSSAPI)
|
||||
* @throws IOException If a network error occures while authenticating.
|
||||
*/
|
||||
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String,String>();
|
||||
props.put(Sasl.SERVER_AUTH,"TRUE");
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server.
|
||||
* This overrides from the abstract class because the initial token
|
||||
* needed for GSSAPI is binary, and not safe to put in a string, thus
|
||||
* getAuthenticationText() cannot be used.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param password the password of the user (ignored for GSSAPI)
|
||||
* @throws IOException If a network error occures while authenticating.
|
||||
*/
|
||||
public void authenticate(String username, String host, String password) throws IOException, XMPPException {
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String, String>();
|
||||
props.put(Sasl.SERVER_AUTH,"TRUE");
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, this);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,400 +1,400 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.sasl.RealmCallback;
|
||||
import javax.security.sasl.RealmChoiceCallback;
|
||||
import javax.security.sasl.Sasl;
|
||||
import javax.security.sasl.SaslClient;
|
||||
import javax.security.sasl.SaslException;
|
||||
|
||||
/**
|
||||
* Base class for SASL mechanisms. Subclasses must implement these methods:
|
||||
* <ul>
|
||||
* <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li>
|
||||
* </ul>
|
||||
* Subclasses will likely want to implement their own versions of these mthods:
|
||||
* <li>{@link #authenticate(String, String, String)} -- Initiate authentication stanza using the
|
||||
* deprecated method.</li>
|
||||
* <li>{@link #authenticate(String, String, CallbackHandler)} -- Initiate authentication stanza
|
||||
* using the CallbackHandler method.</li>
|
||||
* <li>{@link #challengeReceived(String)} -- Handle a challenge from the server.</li>
|
||||
* </ul>
|
||||
*
|
||||
* Basic XMPP SASL authentication steps:
|
||||
* 1. Client authentication initialization, stanza sent to the server (Base64 encoded):
|
||||
* <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
|
||||
* 2. Server sends back to the client the challenge response (Base64 encoded)
|
||||
* sample:
|
||||
* realm=<sasl server realm>,nonce="OA6MG9tEQGm2hh",qop="auth",charset=utf-8,algorithm=md5-sess
|
||||
* 3. The client responds back to the server (Base 64 encoded):
|
||||
* sample:
|
||||
* username=<userid>,realm=<sasl server realm from above>,nonce="OA6MG9tEQGm2hh",
|
||||
* cnonce="OA6MHXh6VqTrRk",nc=00000001,qop=auth,
|
||||
* digest-uri=<digesturi>,
|
||||
* response=d388dad90d4bbd760a152321f2143af7,
|
||||
* charset=utf-8,
|
||||
* authzid=<id>
|
||||
* 4. The server evaluates if the user is present and contained in the REALM
|
||||
* if successful it sends: <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> (Base64 encoded)
|
||||
* if not successful it sends:
|
||||
* sample:
|
||||
* <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
|
||||
* cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
|
||||
* </challenge>
|
||||
*
|
||||
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public abstract class SASLMechanism implements CallbackHandler {
|
||||
|
||||
private SASLAuthentication saslAuthentication;
|
||||
protected SaslClient sc;
|
||||
protected String authenticationId;
|
||||
protected String password;
|
||||
protected String hostname;
|
||||
|
||||
public SASLMechanism(SASLAuthentication saslAuthentication) {
|
||||
this.saslAuthentication = saslAuthentication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of
|
||||
* authentication is not recommended, since it is very inflexable. Use
|
||||
* {@link #authenticate(String, String, CallbackHandler)} whenever possible.
|
||||
*
|
||||
* Explanation of auth stanza:
|
||||
*
|
||||
* The client authentication stanza needs to include the digest-uri of the form: xmpp/serverName
|
||||
* From RFC-2831:
|
||||
* digest-uri = "digest-uri" "=" digest-uri-value
|
||||
* digest-uri-value = serv-type "/" host [ "/" serv-name ]
|
||||
*
|
||||
* digest-uri:
|
||||
* Indicates the principal name of the service with which the client
|
||||
* wishes to connect, formed from the serv-type, host, and serv-name.
|
||||
* For example, the FTP service
|
||||
* on "ftp.example.com" would have a "digest-uri" value of "ftp/ftp.example.com"; the SMTP
|
||||
* server from the example above would have a "digest-uri" value of
|
||||
* "smtp/mail3.example.com/example.com".
|
||||
*
|
||||
* host:
|
||||
* The DNS host name or IP address for the service requested. The DNS host name
|
||||
* must be the fully-qualified canonical name of the host. The DNS host name is the
|
||||
* preferred form; see notes on server processing of the digest-uri.
|
||||
*
|
||||
* serv-name:
|
||||
* Indicates the name of the service if it is replicated. The service is
|
||||
* considered to be replicated if the client's service-location process involves resolution
|
||||
* using standard DNS lookup operations, and if these operations involve DNS records (such
|
||||
* as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case,
|
||||
* the initial name used by the client is the "serv-name", and the final name is the "host"
|
||||
* component. For example, the incoming mail service for "example.com" may be replicated
|
||||
* through the use of MX records stored in the DNS, one of which points at an SMTP server
|
||||
* called "mail3.example.com"; it's "serv-name" would be "example.com", it's "host" would be
|
||||
* "mail3.example.com". If the service is not replicated, or the serv-name is identical to
|
||||
* the host, then the serv-name component MUST be omitted
|
||||
*
|
||||
* digest-uri verification is needed for ejabberd 2.0.3 and higher
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param serviceName the xmpp service location - used by the SASL client in digest-uri creation
|
||||
* serviceName format is: host [ "/" serv-name ] as per RFC-2831
|
||||
* @param password the password for this account.
|
||||
* @throws IOException If a network error occurs while authenticating.
|
||||
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
|
||||
*/
|
||||
public void authenticate(String username, String host, String serviceName, String password) throws IOException, XMPPException {
|
||||
//Since we were not provided with a CallbackHandler, we will use our own with the given
|
||||
//information
|
||||
|
||||
//Set the authenticationID as the username, since they must be the same in this case.
|
||||
this.authenticationId = username;
|
||||
this.password = password;
|
||||
this.hostname = host;
|
||||
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String,String>();
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", serviceName, props, this);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #authenticate(String, String, String, String)}, but with the hostname used as the serviceName.
|
||||
* <p>
|
||||
* Kept for backward compatibility only.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param password the password for this account.
|
||||
* @throws IOException If a network error occurs while authenticating.
|
||||
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
|
||||
* @deprecated Please use {@link #authenticate(String, String, String, String)} instead.
|
||||
*/
|
||||
public void authenticate(String username, String host, String password) throws IOException, XMPPException {
|
||||
authenticate(username, host, host, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server. The callback handler will handle
|
||||
* any additional information, such as the authentication ID or realm, if it is needed.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param cbh the CallbackHandler to obtain user information.
|
||||
* @throws IOException If a network error occures while authenticating.
|
||||
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
|
||||
*/
|
||||
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String,String>();
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
protected void authenticate() throws IOException, XMPPException {
|
||||
String authenticationText = null;
|
||||
try {
|
||||
if(sc.hasInitialResponse()) {
|
||||
byte[] response = sc.evaluateChallenge(new byte[0]);
|
||||
authenticationText = StringUtils.encodeBase64(response, false);
|
||||
}
|
||||
} catch (SaslException e) {
|
||||
throw new XMPPException("SASL authentication failed", e);
|
||||
}
|
||||
|
||||
// Send the authentication to the server
|
||||
getSASLAuthentication().send(new AuthMechanism(getName(), authenticationText));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The server is challenging the SASL mechanism for the stanza he just sent. Send a
|
||||
* response to the server's challenge.
|
||||
*
|
||||
* @param challenge a base64 encoded string representing the challenge.
|
||||
* @throws IOException if an exception sending the response occurs.
|
||||
*/
|
||||
public void challengeReceived(String challenge) throws IOException {
|
||||
byte response[];
|
||||
if(challenge != null) {
|
||||
response = sc.evaluateChallenge(StringUtils.decodeBase64(challenge));
|
||||
} else {
|
||||
response = sc.evaluateChallenge(new byte[0]);
|
||||
}
|
||||
|
||||
Packet responseStanza;
|
||||
if (response == null) {
|
||||
responseStanza = new Response();
|
||||
}
|
||||
else {
|
||||
responseStanza = new Response(StringUtils.encodeBase64(response, false));
|
||||
}
|
||||
|
||||
// Send the authentication to the server
|
||||
getSASLAuthentication().send(responseStanza);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or GSSAPI.
|
||||
*
|
||||
* @return the common name of the SASL mechanism.
|
||||
*/
|
||||
protected abstract String getName();
|
||||
|
||||
|
||||
protected SASLAuthentication getSASLAuthentication() {
|
||||
return saslAuthentication;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
||||
for (int i = 0; i < callbacks.length; i++) {
|
||||
if (callbacks[i] instanceof NameCallback) {
|
||||
NameCallback ncb = (NameCallback)callbacks[i];
|
||||
ncb.setName(authenticationId);
|
||||
} else if(callbacks[i] instanceof PasswordCallback) {
|
||||
PasswordCallback pcb = (PasswordCallback)callbacks[i];
|
||||
pcb.setPassword(password.toCharArray());
|
||||
} else if(callbacks[i] instanceof RealmCallback) {
|
||||
RealmCallback rcb = (RealmCallback)callbacks[i];
|
||||
//Retrieve the REALM from the challenge response that the server returned when the client initiated the authentication
|
||||
//exchange. If this value is not null or empty, *this value* has to be sent back to the server in the client's response
|
||||
//to the server's challenge
|
||||
String text = rcb.getDefaultText();
|
||||
//The SASL client (sc) created in smack uses rcb.getText when creating the negotiatedRealm to send it back to the server
|
||||
//Make sure that this value matches the server's realm
|
||||
rcb.setText(text);
|
||||
} else if(callbacks[i] instanceof RealmChoiceCallback){
|
||||
//unused
|
||||
//RealmChoiceCallback rccb = (RealmChoiceCallback)callbacks[i];
|
||||
} else {
|
||||
throw new UnsupportedCallbackException(callbacks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiating SASL authentication by select a mechanism.
|
||||
*/
|
||||
public class AuthMechanism extends Packet {
|
||||
final private String name;
|
||||
final private String authenticationText;
|
||||
|
||||
public AuthMechanism(String name, String authenticationText) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("SASL mechanism name shouldn't be null.");
|
||||
}
|
||||
this.name = name;
|
||||
this.authenticationText = authenticationText;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<auth mechanism=\"").append(name);
|
||||
stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (authenticationText != null &&
|
||||
authenticationText.trim().length() > 0) {
|
||||
stanza.append(authenticationText);
|
||||
}
|
||||
stanza.append("</auth>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL challenge stanza.
|
||||
*/
|
||||
public static class Challenge extends Packet {
|
||||
final private String data;
|
||||
|
||||
public Challenge(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (data != null &&
|
||||
data.trim().length() > 0) {
|
||||
stanza.append(data);
|
||||
}
|
||||
stanza.append("</challenge>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL response stanza.
|
||||
*/
|
||||
public class Response extends Packet {
|
||||
final private String authenticationText;
|
||||
|
||||
public Response() {
|
||||
authenticationText = null;
|
||||
}
|
||||
|
||||
public Response(String authenticationText) {
|
||||
if (authenticationText == null || authenticationText.trim().length() == 0) {
|
||||
this.authenticationText = null;
|
||||
}
|
||||
else {
|
||||
this.authenticationText = authenticationText;
|
||||
}
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (authenticationText != null) {
|
||||
stanza.append(authenticationText);
|
||||
}
|
||||
stanza.append("</response>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL success stanza.
|
||||
*/
|
||||
public static class Success extends Packet {
|
||||
final private String data;
|
||||
|
||||
public Success(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (data != null &&
|
||||
data.trim().length() > 0) {
|
||||
stanza.append(data);
|
||||
}
|
||||
stanza.append("</success>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL failure stanza.
|
||||
*/
|
||||
public static class Failure extends Packet {
|
||||
final private String condition;
|
||||
|
||||
public Failure(String condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SASL related error condition.
|
||||
*
|
||||
* @return the SASL related error condition.
|
||||
*/
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (condition != null &&
|
||||
condition.trim().length() > 0) {
|
||||
stanza.append("<").append(condition).append("/>");
|
||||
}
|
||||
stanza.append("</failure>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.sasl.RealmCallback;
|
||||
import javax.security.sasl.RealmChoiceCallback;
|
||||
import javax.security.sasl.Sasl;
|
||||
import javax.security.sasl.SaslClient;
|
||||
import javax.security.sasl.SaslException;
|
||||
|
||||
/**
|
||||
* Base class for SASL mechanisms. Subclasses must implement these methods:
|
||||
* <ul>
|
||||
* <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li>
|
||||
* </ul>
|
||||
* Subclasses will likely want to implement their own versions of these mthods:
|
||||
* <li>{@link #authenticate(String, String, String)} -- Initiate authentication stanza using the
|
||||
* deprecated method.</li>
|
||||
* <li>{@link #authenticate(String, String, CallbackHandler)} -- Initiate authentication stanza
|
||||
* using the CallbackHandler method.</li>
|
||||
* <li>{@link #challengeReceived(String)} -- Handle a challenge from the server.</li>
|
||||
* </ul>
|
||||
*
|
||||
* Basic XMPP SASL authentication steps:
|
||||
* 1. Client authentication initialization, stanza sent to the server (Base64 encoded):
|
||||
* <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>
|
||||
* 2. Server sends back to the client the challenge response (Base64 encoded)
|
||||
* sample:
|
||||
* realm=<sasl server realm>,nonce="OA6MG9tEQGm2hh",qop="auth",charset=utf-8,algorithm=md5-sess
|
||||
* 3. The client responds back to the server (Base 64 encoded):
|
||||
* sample:
|
||||
* username=<userid>,realm=<sasl server realm from above>,nonce="OA6MG9tEQGm2hh",
|
||||
* cnonce="OA6MHXh6VqTrRk",nc=00000001,qop=auth,
|
||||
* digest-uri=<digesturi>,
|
||||
* response=d388dad90d4bbd760a152321f2143af7,
|
||||
* charset=utf-8,
|
||||
* authzid=<id>
|
||||
* 4. The server evaluates if the user is present and contained in the REALM
|
||||
* if successful it sends: <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> (Base64 encoded)
|
||||
* if not successful it sends:
|
||||
* sample:
|
||||
* <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
|
||||
* cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
|
||||
* </challenge>
|
||||
*
|
||||
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public abstract class SASLMechanism implements CallbackHandler {
|
||||
|
||||
private SASLAuthentication saslAuthentication;
|
||||
protected SaslClient sc;
|
||||
protected String authenticationId;
|
||||
protected String password;
|
||||
protected String hostname;
|
||||
|
||||
public SASLMechanism(SASLAuthentication saslAuthentication) {
|
||||
this.saslAuthentication = saslAuthentication;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of
|
||||
* authentication is not recommended, since it is very inflexable. Use
|
||||
* {@link #authenticate(String, String, CallbackHandler)} whenever possible.
|
||||
*
|
||||
* Explanation of auth stanza:
|
||||
*
|
||||
* The client authentication stanza needs to include the digest-uri of the form: xmpp/serverName
|
||||
* From RFC-2831:
|
||||
* digest-uri = "digest-uri" "=" digest-uri-value
|
||||
* digest-uri-value = serv-type "/" host [ "/" serv-name ]
|
||||
*
|
||||
* digest-uri:
|
||||
* Indicates the principal name of the service with which the client
|
||||
* wishes to connect, formed from the serv-type, host, and serv-name.
|
||||
* For example, the FTP service
|
||||
* on "ftp.example.com" would have a "digest-uri" value of "ftp/ftp.example.com"; the SMTP
|
||||
* server from the example above would have a "digest-uri" value of
|
||||
* "smtp/mail3.example.com/example.com".
|
||||
*
|
||||
* host:
|
||||
* The DNS host name or IP address for the service requested. The DNS host name
|
||||
* must be the fully-qualified canonical name of the host. The DNS host name is the
|
||||
* preferred form; see notes on server processing of the digest-uri.
|
||||
*
|
||||
* serv-name:
|
||||
* Indicates the name of the service if it is replicated. The service is
|
||||
* considered to be replicated if the client's service-location process involves resolution
|
||||
* using standard DNS lookup operations, and if these operations involve DNS records (such
|
||||
* as SRV, or MX) which resolve one DNS name into a set of other DNS names. In this case,
|
||||
* the initial name used by the client is the "serv-name", and the final name is the "host"
|
||||
* component. For example, the incoming mail service for "example.com" may be replicated
|
||||
* through the use of MX records stored in the DNS, one of which points at an SMTP server
|
||||
* called "mail3.example.com"; it's "serv-name" would be "example.com", it's "host" would be
|
||||
* "mail3.example.com". If the service is not replicated, or the serv-name is identical to
|
||||
* the host, then the serv-name component MUST be omitted
|
||||
*
|
||||
* digest-uri verification is needed for ejabberd 2.0.3 and higher
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param serviceName the xmpp service location - used by the SASL client in digest-uri creation
|
||||
* serviceName format is: host [ "/" serv-name ] as per RFC-2831
|
||||
* @param password the password for this account.
|
||||
* @throws IOException If a network error occurs while authenticating.
|
||||
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
|
||||
*/
|
||||
public void authenticate(String username, String host, String serviceName, String password) throws IOException, XMPPException {
|
||||
//Since we were not provided with a CallbackHandler, we will use our own with the given
|
||||
//information
|
||||
|
||||
//Set the authenticationID as the username, since they must be the same in this case.
|
||||
this.authenticationId = username;
|
||||
this.password = password;
|
||||
this.hostname = host;
|
||||
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String,String>();
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", serviceName, props, this);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #authenticate(String, String, String, String)}, but with the hostname used as the serviceName.
|
||||
* <p>
|
||||
* Kept for backward compatibility only.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param password the password for this account.
|
||||
* @throws IOException If a network error occurs while authenticating.
|
||||
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
|
||||
* @deprecated Please use {@link #authenticate(String, String, String, String)} instead.
|
||||
*/
|
||||
public void authenticate(String username, String host, String password) throws IOException, XMPPException {
|
||||
authenticate(username, host, host, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds and sends the <tt>auth</tt> stanza to the server. The callback handler will handle
|
||||
* any additional information, such as the authentication ID or realm, if it is needed.
|
||||
*
|
||||
* @param username the username of the user being authenticated.
|
||||
* @param host the hostname where the user account resides.
|
||||
* @param cbh the CallbackHandler to obtain user information.
|
||||
* @throws IOException If a network error occures while authenticating.
|
||||
* @throws XMPPException If a protocol error occurs or the user is not authenticated.
|
||||
*/
|
||||
public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException {
|
||||
String[] mechanisms = { getName() };
|
||||
Map<String,String> props = new HashMap<String,String>();
|
||||
sc = Sasl.createSaslClient(mechanisms, username, "xmpp", host, props, cbh);
|
||||
authenticate();
|
||||
}
|
||||
|
||||
protected void authenticate() throws IOException, XMPPException {
|
||||
String authenticationText = null;
|
||||
try {
|
||||
if(sc.hasInitialResponse()) {
|
||||
byte[] response = sc.evaluateChallenge(new byte[0]);
|
||||
authenticationText = StringUtils.encodeBase64(response, false);
|
||||
}
|
||||
} catch (SaslException e) {
|
||||
throw new XMPPException("SASL authentication failed", e);
|
||||
}
|
||||
|
||||
// Send the authentication to the server
|
||||
getSASLAuthentication().send(new AuthMechanism(getName(), authenticationText));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The server is challenging the SASL mechanism for the stanza he just sent. Send a
|
||||
* response to the server's challenge.
|
||||
*
|
||||
* @param challenge a base64 encoded string representing the challenge.
|
||||
* @throws IOException if an exception sending the response occurs.
|
||||
*/
|
||||
public void challengeReceived(String challenge) throws IOException {
|
||||
byte response[];
|
||||
if(challenge != null) {
|
||||
response = sc.evaluateChallenge(StringUtils.decodeBase64(challenge));
|
||||
} else {
|
||||
response = sc.evaluateChallenge(new byte[0]);
|
||||
}
|
||||
|
||||
Packet responseStanza;
|
||||
if (response == null) {
|
||||
responseStanza = new Response();
|
||||
}
|
||||
else {
|
||||
responseStanza = new Response(StringUtils.encodeBase64(response, false));
|
||||
}
|
||||
|
||||
// Send the authentication to the server
|
||||
getSASLAuthentication().send(responseStanza);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the common name of the SASL mechanism. E.g.: PLAIN, DIGEST-MD5 or GSSAPI.
|
||||
*
|
||||
* @return the common name of the SASL mechanism.
|
||||
*/
|
||||
protected abstract String getName();
|
||||
|
||||
|
||||
protected SASLAuthentication getSASLAuthentication() {
|
||||
return saslAuthentication;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
|
||||
for (int i = 0; i < callbacks.length; i++) {
|
||||
if (callbacks[i] instanceof NameCallback) {
|
||||
NameCallback ncb = (NameCallback)callbacks[i];
|
||||
ncb.setName(authenticationId);
|
||||
} else if(callbacks[i] instanceof PasswordCallback) {
|
||||
PasswordCallback pcb = (PasswordCallback)callbacks[i];
|
||||
pcb.setPassword(password.toCharArray());
|
||||
} else if(callbacks[i] instanceof RealmCallback) {
|
||||
RealmCallback rcb = (RealmCallback)callbacks[i];
|
||||
//Retrieve the REALM from the challenge response that the server returned when the client initiated the authentication
|
||||
//exchange. If this value is not null or empty, *this value* has to be sent back to the server in the client's response
|
||||
//to the server's challenge
|
||||
String text = rcb.getDefaultText();
|
||||
//The SASL client (sc) created in smack uses rcb.getText when creating the negotiatedRealm to send it back to the server
|
||||
//Make sure that this value matches the server's realm
|
||||
rcb.setText(text);
|
||||
} else if(callbacks[i] instanceof RealmChoiceCallback){
|
||||
//unused
|
||||
//RealmChoiceCallback rccb = (RealmChoiceCallback)callbacks[i];
|
||||
} else {
|
||||
throw new UnsupportedCallbackException(callbacks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiating SASL authentication by select a mechanism.
|
||||
*/
|
||||
public class AuthMechanism extends Packet {
|
||||
final private String name;
|
||||
final private String authenticationText;
|
||||
|
||||
public AuthMechanism(String name, String authenticationText) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("SASL mechanism name shouldn't be null.");
|
||||
}
|
||||
this.name = name;
|
||||
this.authenticationText = authenticationText;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<auth mechanism=\"").append(name);
|
||||
stanza.append("\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (authenticationText != null &&
|
||||
authenticationText.trim().length() > 0) {
|
||||
stanza.append(authenticationText);
|
||||
}
|
||||
stanza.append("</auth>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL challenge stanza.
|
||||
*/
|
||||
public static class Challenge extends Packet {
|
||||
final private String data;
|
||||
|
||||
public Challenge(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<challenge xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (data != null &&
|
||||
data.trim().length() > 0) {
|
||||
stanza.append(data);
|
||||
}
|
||||
stanza.append("</challenge>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL response stanza.
|
||||
*/
|
||||
public class Response extends Packet {
|
||||
final private String authenticationText;
|
||||
|
||||
public Response() {
|
||||
authenticationText = null;
|
||||
}
|
||||
|
||||
public Response(String authenticationText) {
|
||||
if (authenticationText == null || authenticationText.trim().length() == 0) {
|
||||
this.authenticationText = null;
|
||||
}
|
||||
else {
|
||||
this.authenticationText = authenticationText;
|
||||
}
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (authenticationText != null) {
|
||||
stanza.append(authenticationText);
|
||||
}
|
||||
stanza.append("</response>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL success stanza.
|
||||
*/
|
||||
public static class Success extends Packet {
|
||||
final private String data;
|
||||
|
||||
public Success(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<success xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (data != null &&
|
||||
data.trim().length() > 0) {
|
||||
stanza.append(data);
|
||||
}
|
||||
stanza.append("</success>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A SASL failure stanza.
|
||||
*/
|
||||
public static class Failure extends Packet {
|
||||
final private String condition;
|
||||
|
||||
public Failure(String condition) {
|
||||
this.condition = condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SASL related error condition.
|
||||
*
|
||||
* @return the SASL related error condition.
|
||||
*/
|
||||
public String getCondition() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
public String toXML() {
|
||||
StringBuilder stanza = new StringBuilder();
|
||||
stanza.append("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">");
|
||||
if (condition != null &&
|
||||
condition.trim().length() > 0) {
|
||||
stanza.append("<").append(condition).append("/>");
|
||||
}
|
||||
stanza.append("</failure>");
|
||||
return stanza.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL PLAIN mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLPlainMechanism extends SASLMechanism {
|
||||
|
||||
public SASLPlainMechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "PLAIN";
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.sasl;
|
||||
|
||||
import org.jivesoftware.smack.SASLAuthentication;
|
||||
|
||||
/**
|
||||
* Implementation of the SASL PLAIN mechanism
|
||||
*
|
||||
* @author Jay Kline
|
||||
*/
|
||||
public class SASLPlainMechanism extends SASLMechanism {
|
||||
|
||||
public SASLPlainMechanism(SASLAuthentication saslAuthentication) {
|
||||
super(saslAuthentication);
|
||||
}
|
||||
|
||||
protected String getName() {
|
||||
return "PLAIN";
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -675,4 +675,4 @@ public class Cache<K, V> implements Map<K, V> {
|
|||
return object.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,4 +230,4 @@ public class DNSUtil {
|
|||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,75 +1,75 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class FileUtils {
|
||||
|
||||
private FileUtils() {
|
||||
}
|
||||
|
||||
public static InputStream getStreamForUrl(String url, ClassLoader loader) throws MalformedURLException, IOException {
|
||||
URI fileUri = URI.create(url);
|
||||
|
||||
if (fileUri.getScheme() == null) {
|
||||
throw new MalformedURLException("No protocol found in file URL: " + url);
|
||||
}
|
||||
|
||||
if (fileUri.getScheme().equals("classpath")) {
|
||||
// Get an array of class loaders to try loading the providers files from.
|
||||
ClassLoader[] classLoaders = getClassLoaders();
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
InputStream is = classLoader.getResourceAsStream(fileUri.getSchemeSpecificPart());
|
||||
|
||||
if (is != null) {
|
||||
return is;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return fileUri.toURL().openStream();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default classloaders.
|
||||
*
|
||||
* @return an array of ClassLoader instances.
|
||||
*/
|
||||
public static ClassLoader[] getClassLoaders() {
|
||||
ClassLoader[] classLoaders = new ClassLoader[2];
|
||||
classLoaders[0] = FileUtils.class.getClassLoader();
|
||||
classLoaders[1] = Thread.currentThread().getContextClassLoader();
|
||||
// Clean up possible null values. Note that #getClassLoader may return a null value.
|
||||
List<ClassLoader> loaders = new ArrayList<ClassLoader>();
|
||||
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
if (classLoader != null) {
|
||||
loaders.add(classLoader);
|
||||
}
|
||||
}
|
||||
return loaders.toArray(new ClassLoader[loaders.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class FileUtils {
|
||||
|
||||
private FileUtils() {
|
||||
}
|
||||
|
||||
public static InputStream getStreamForUrl(String url, ClassLoader loader) throws MalformedURLException, IOException {
|
||||
URI fileUri = URI.create(url);
|
||||
|
||||
if (fileUri.getScheme() == null) {
|
||||
throw new MalformedURLException("No protocol found in file URL: " + url);
|
||||
}
|
||||
|
||||
if (fileUri.getScheme().equals("classpath")) {
|
||||
// Get an array of class loaders to try loading the providers files from.
|
||||
ClassLoader[] classLoaders = getClassLoaders();
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
InputStream is = classLoader.getResourceAsStream(fileUri.getSchemeSpecificPart());
|
||||
|
||||
if (is != null) {
|
||||
return is;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return fileUri.toURL().openStream();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default classloaders.
|
||||
*
|
||||
* @return an array of ClassLoader instances.
|
||||
*/
|
||||
public static ClassLoader[] getClassLoaders() {
|
||||
ClassLoader[] classLoaders = new ClassLoader[2];
|
||||
classLoaders[0] = FileUtils.class.getClassLoader();
|
||||
classLoaders[1] = Thread.currentThread().getContextClassLoader();
|
||||
// Clean up possible null values. Note that #getClassLoader may return a null value.
|
||||
List<ClassLoader> loaders = new ArrayList<ClassLoader>();
|
||||
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
if (classLoader != null) {
|
||||
loaders.add(classLoader);
|
||||
}
|
||||
}
|
||||
return loaders.toArray(new ClassLoader[loaders.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,67 +1,67 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.util;
|
||||
|
||||
import org.jivesoftware.smack.PacketCollector;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.SmackError;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.PacketFilter;
|
||||
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
||||
/**
|
||||
* Utility class for doing synchronous calls to the server. Provides several
|
||||
* methods for sending a packet to the server and waiting for the reply.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
final public class SyncPacketSend
|
||||
{
|
||||
private SyncPacketSend()
|
||||
{ }
|
||||
|
||||
static public Packet getReply(Connection connection, Packet packet, long timeout)
|
||||
throws XMPPException
|
||||
{
|
||||
PacketFilter responseFilter = new PacketIDFilter(packet.getPacketID());
|
||||
PacketCollector response = connection.createPacketCollector(responseFilter);
|
||||
|
||||
connection.sendPacket(packet);
|
||||
|
||||
// Wait up to a certain number of seconds for a reply.
|
||||
Packet result = response.nextResult(timeout);
|
||||
|
||||
// Stop queuing results
|
||||
response.cancel();
|
||||
|
||||
if (result == null) {
|
||||
throw new XMPPException(SmackError.NO_RESPONSE_FROM_SERVER);
|
||||
}
|
||||
else if (result.getError() != null) {
|
||||
throw new XMPPException(result.getError());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public Packet getReply(Connection connection, Packet packet)
|
||||
throws XMPPException
|
||||
{
|
||||
return getReply(connection, packet, SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.util;
|
||||
|
||||
import org.jivesoftware.smack.PacketCollector;
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.SmackError;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.PacketFilter;
|
||||
import org.jivesoftware.smack.filter.PacketIDFilter;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
||||
/**
|
||||
* Utility class for doing synchronous calls to the server. Provides several
|
||||
* methods for sending a packet to the server and waiting for the reply.
|
||||
*
|
||||
* @author Robin Collier
|
||||
*/
|
||||
final public class SyncPacketSend
|
||||
{
|
||||
private SyncPacketSend()
|
||||
{ }
|
||||
|
||||
static public Packet getReply(Connection connection, Packet packet, long timeout)
|
||||
throws XMPPException
|
||||
{
|
||||
PacketFilter responseFilter = new PacketIDFilter(packet.getPacketID());
|
||||
PacketCollector response = connection.createPacketCollector(responseFilter);
|
||||
|
||||
connection.sendPacket(packet);
|
||||
|
||||
// Wait up to a certain number of seconds for a reply.
|
||||
Packet result = response.nextResult(timeout);
|
||||
|
||||
// Stop queuing results
|
||||
response.cancel();
|
||||
|
||||
if (result == null) {
|
||||
throw new XMPPException(SmackError.NO_RESPONSE_FROM_SERVER);
|
||||
}
|
||||
else if (result.getError() != null) {
|
||||
throw new XMPPException(result.getError());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public Packet getReply(Connection connection, Packet packet)
|
||||
throws XMPPException
|
||||
{
|
||||
return getReply(connection, packet, SmackConfiguration.getPacketReplyTimeout());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# Java Util Logging configuration for Smack.
|
||||
handlers = java.util.logging.ConsoleHandler
|
||||
# Java Util Logging configuration for Smack.
|
||||
handlers = java.util.logging.ConsoleHandler
|
||||
.level = WARNING
|
|
@ -1,440 +1,440 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2010 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.jivesoftware.smack.ChatManager.MatchMode;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ChatConnectionTest {
|
||||
|
||||
private DummyConnection connection;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
connection = getConnection();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null)
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetNormalIncluded() {
|
||||
ChatManager.setDefaultIsNormalIncluded(false);
|
||||
assertFalse(getConnection().getChatManager().isNormalIncluded());
|
||||
|
||||
ChatManager.setDefaultIsNormalIncluded(true);
|
||||
assertTrue(getConnection().getChatManager().isNormalIncluded());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetMatchMode() {
|
||||
ChatManager.setDefaultMatchMode(MatchMode.NONE);
|
||||
assertEquals(MatchMode.NONE, getConnection().getChatManager().getMatchMode());
|
||||
|
||||
ChatManager.setDefaultMatchMode(MatchMode.BARE_JID);
|
||||
assertEquals(MatchMode.BARE_JID, getConnection().getChatManager().getMatchMode());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults() {
|
||||
DummyConnection dc = getConnection();
|
||||
ChatManager cm = dc.getChatManager();
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNotNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNotNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.groupchat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.headline);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal() {
|
||||
ChatManager.setDefaultIsNormalIncluded(false);
|
||||
DummyConnection dc = getConnection();
|
||||
ChatManager cm = dc.getChatManager();
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNotNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
// No thread behaviour
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadBareMode() {
|
||||
// MatchMode.BARE_JID is the default, so setting required.
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
con.getChatManager().addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should match on chat with bare jid
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(3, msgListener.getNumMessages());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadJidMode() {
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
ChatManager cm = con.getChatManager();
|
||||
cm.setMatchMode(MatchMode.SUPPLIED_JID);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
assertNotNull(listener2.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadNoneMode() {
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
ChatManager cm = con.getChatManager();
|
||||
cm.setMatchMode(MatchMode.NONE);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should not match on chat with full jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener2);
|
||||
|
||||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener3 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener3);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(listener3.getNewChat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same user as a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatNotMatchedWithTypeNormal() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
DummyConnection con = getConnection();
|
||||
ChatManager cm = con.getChatManager();
|
||||
cm.setNormalIncluded(false);
|
||||
cm.addChatListener(listener);
|
||||
|
||||
Message incomingChat = createChatPacket(null, false);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private ChatManager getChatManager(boolean includeNormal, MatchMode mode) {
|
||||
ChatManager cm = getConnection().getChatManager();
|
||||
cm.setMatchMode(mode);
|
||||
cm.setNormalIncluded(includeNormal);
|
||||
return cm;
|
||||
}
|
||||
|
||||
private DummyConnection getConnection() {
|
||||
DummyConnection con = new DummyConnection();
|
||||
|
||||
try {
|
||||
con.connect();
|
||||
con.login("me", "secret");
|
||||
} catch (XMPPException e) {
|
||||
// No need for handling in a dummy connection.
|
||||
}
|
||||
return con;
|
||||
}
|
||||
private Message createChatPacket(final String threadId, final boolean isFullJid) {
|
||||
Message chatMsg = new Message("me@testserver", Message.Type.chat);
|
||||
chatMsg.setBody("the body message - " + System.currentTimeMillis());
|
||||
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
||||
|
||||
if (threadId != null)
|
||||
chatMsg.setThread(threadId);
|
||||
return chatMsg;
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat) {
|
||||
processServerMessage(incomingChat, connection);
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat, DummyConnection con) {
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat, con);
|
||||
chatServer.start();
|
||||
try {
|
||||
chatServer.join();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
class TestChatManagerListener implements ChatManagerListener {
|
||||
private Chat newChat;
|
||||
private MessageListener listener;
|
||||
|
||||
public TestChatManagerListener(TestMessageListener msgListener) {
|
||||
listener = msgListener;
|
||||
}
|
||||
|
||||
public TestChatManagerListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chatCreated(Chat chat, boolean createdLocally) {
|
||||
newChat = chat;
|
||||
|
||||
if (listener != null)
|
||||
newChat.addMessageListener(listener);
|
||||
}
|
||||
|
||||
public Chat getNewChat() {
|
||||
return newChat;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestChatServer extends Thread {
|
||||
private Packet chatPacket;
|
||||
private DummyConnection con;
|
||||
|
||||
TestChatServer(Packet chatMsg, DummyConnection conect) {
|
||||
chatPacket = chatMsg;
|
||||
con = conect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
con.processPacket(chatPacket);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestMessageListener implements MessageListener {
|
||||
private Chat msgChat;
|
||||
private int counter = 0;
|
||||
|
||||
@Override
|
||||
public void processMessage(Chat chat, Message message) {
|
||||
msgChat = chat;
|
||||
counter++;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Chat getChat() {
|
||||
return msgChat;
|
||||
}
|
||||
|
||||
public int getNumMessages() {
|
||||
return counter;
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright 2010 Jive Software.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.jivesoftware.smack.ChatManager.MatchMode;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ChatConnectionTest {
|
||||
|
||||
private DummyConnection connection;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
connection = getConnection();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (connection != null)
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetNormalIncluded() {
|
||||
ChatManager.setDefaultIsNormalIncluded(false);
|
||||
assertFalse(getConnection().getChatManager().isNormalIncluded());
|
||||
|
||||
ChatManager.setDefaultIsNormalIncluded(true);
|
||||
assertTrue(getConnection().getChatManager().isNormalIncluded());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateDefaultSetMatchMode() {
|
||||
ChatManager.setDefaultMatchMode(MatchMode.NONE);
|
||||
assertEquals(MatchMode.NONE, getConnection().getChatManager().getMatchMode());
|
||||
|
||||
ChatManager.setDefaultMatchMode(MatchMode.BARE_JID);
|
||||
assertEquals(MatchMode.BARE_JID, getConnection().getChatManager().getMatchMode());
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults() {
|
||||
DummyConnection dc = getConnection();
|
||||
ChatManager cm = dc.getChatManager();
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNotNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNotNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.groupchat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.headline);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal() {
|
||||
ChatManager.setDefaultIsNormalIncluded(false);
|
||||
DummyConnection dc = getConnection();
|
||||
ChatManager cm = dc.getChatManager();
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNotNull(listener.getNewChat());
|
||||
|
||||
dc = getConnection();
|
||||
cm = dc.getChatManager();
|
||||
listener = new TestChatManagerListener();
|
||||
cm.addChatListener(listener);
|
||||
incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat, dc);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
// No thread behaviour
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadBareMode() {
|
||||
// MatchMode.BARE_JID is the default, so setting required.
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
con.getChatManager().addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should match on chat with bare jid
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(3, msgListener.getNumMessages());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadJidMode() {
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
ChatManager cm = con.getChatManager();
|
||||
cm.setMatchMode(MatchMode.SUPPLIED_JID);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
assertNotNull(listener2.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatMatchedOnJIDWhenNoThreadNoneMode() {
|
||||
DummyConnection con = getConnection();
|
||||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
ChatManager cm = con.getChatManager();
|
||||
cm.setMatchMode(MatchMode.NONE);
|
||||
cm.addChatListener(listener);
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should not match on chat with full jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener2);
|
||||
|
||||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener3 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener3);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat, con);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(listener3.getNewChat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has no thread
|
||||
* id and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWhenNoThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a full jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is matched to an incoming chat message that has the same id
|
||||
* and the user is a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatFoundWithSameThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertTrue(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same user as a base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that an existing chat created with a base jid is not matched to an incoming chat message that has a
|
||||
* different id and the same base jid.
|
||||
*/
|
||||
@Test
|
||||
public void chatNotFoundWithDiffThreadFullJid() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
connection.getChatManager().addChatListener(listener);
|
||||
Chat outgoing = connection.getChatManager().createChat("you@testserver", null);
|
||||
|
||||
Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
assertFalse(newChat == outgoing);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatNotMatchedWithTypeNormal() {
|
||||
TestChatManagerListener listener = new TestChatManagerListener();
|
||||
DummyConnection con = getConnection();
|
||||
ChatManager cm = con.getChatManager();
|
||||
cm.setNormalIncluded(false);
|
||||
cm.addChatListener(listener);
|
||||
|
||||
Message incomingChat = createChatPacket(null, false);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private ChatManager getChatManager(boolean includeNormal, MatchMode mode) {
|
||||
ChatManager cm = getConnection().getChatManager();
|
||||
cm.setMatchMode(mode);
|
||||
cm.setNormalIncluded(includeNormal);
|
||||
return cm;
|
||||
}
|
||||
|
||||
private DummyConnection getConnection() {
|
||||
DummyConnection con = new DummyConnection();
|
||||
|
||||
try {
|
||||
con.connect();
|
||||
con.login("me", "secret");
|
||||
} catch (XMPPException e) {
|
||||
// No need for handling in a dummy connection.
|
||||
}
|
||||
return con;
|
||||
}
|
||||
private Message createChatPacket(final String threadId, final boolean isFullJid) {
|
||||
Message chatMsg = new Message("me@testserver", Message.Type.chat);
|
||||
chatMsg.setBody("the body message - " + System.currentTimeMillis());
|
||||
chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : ""));
|
||||
|
||||
if (threadId != null)
|
||||
chatMsg.setThread(threadId);
|
||||
return chatMsg;
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat) {
|
||||
processServerMessage(incomingChat, connection);
|
||||
}
|
||||
|
||||
private void processServerMessage(Packet incomingChat, DummyConnection con) {
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat, con);
|
||||
chatServer.start();
|
||||
try {
|
||||
chatServer.join();
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
class TestChatManagerListener implements ChatManagerListener {
|
||||
private Chat newChat;
|
||||
private MessageListener listener;
|
||||
|
||||
public TestChatManagerListener(TestMessageListener msgListener) {
|
||||
listener = msgListener;
|
||||
}
|
||||
|
||||
public TestChatManagerListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void chatCreated(Chat chat, boolean createdLocally) {
|
||||
newChat = chat;
|
||||
|
||||
if (listener != null)
|
||||
newChat.addMessageListener(listener);
|
||||
}
|
||||
|
||||
public Chat getNewChat() {
|
||||
return newChat;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestChatServer extends Thread {
|
||||
private Packet chatPacket;
|
||||
private DummyConnection con;
|
||||
|
||||
TestChatServer(Packet chatMsg, DummyConnection conect) {
|
||||
chatPacket = chatMsg;
|
||||
con = conect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
con.processPacket(chatPacket);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestMessageListener implements MessageListener {
|
||||
private Chat msgChat;
|
||||
private int counter = 0;
|
||||
|
||||
@Override
|
||||
public void processMessage(Chat chat, Message message) {
|
||||
msgChat = chat;
|
||||
counter++;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Chat getChat() {
|
||||
return msgChat;
|
||||
}
|
||||
|
||||
public int getNumMessages() {
|
||||
return counter;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,214 +1,214 @@
|
|||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.jivesoftware.smack.filter.PacketFilter;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PacketCollectorTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void verifyRollover()
|
||||
{
|
||||
TestPacketCollector collector = new TestPacketCollector(null, new OKEverything(), 5);
|
||||
|
||||
for (int i=0; i<6; i++)
|
||||
{
|
||||
Packet testPacket = new TestPacket(i);
|
||||
collector.processPacket(testPacket);
|
||||
}
|
||||
|
||||
// Assert that '0' has rolled off
|
||||
assertEquals("1", collector.nextResult().getPacketID());
|
||||
assertEquals("2", collector.nextResult().getPacketID());
|
||||
assertEquals("3", collector.nextResult().getPacketID());
|
||||
assertEquals("4", collector.nextResult().getPacketID());
|
||||
assertEquals("5", collector.pollResult().getPacketID());
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
for (int i=10; i<15; i++)
|
||||
{
|
||||
Packet testPacket = new TestPacket(i);
|
||||
collector.processPacket(testPacket);
|
||||
}
|
||||
|
||||
assertEquals("10", collector.nextResult().getPacketID());
|
||||
assertEquals("11", collector.nextResult().getPacketID());
|
||||
assertEquals("12", collector.nextResult().getPacketID());
|
||||
assertEquals("13", collector.nextResult().getPacketID());
|
||||
assertEquals("14", collector.pollResult().getPacketID());
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
assertNull(collector.nextResult(1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Although this doesn't guarentee anything due to the nature of threading, it can
|
||||
* potentially catch problems.
|
||||
*/
|
||||
@Test
|
||||
public void verifyThreadSafety()
|
||||
{
|
||||
int insertCount = 500;
|
||||
final TestPacketCollector collector = new TestPacketCollector(null, new OKEverything(), insertCount);
|
||||
|
||||
Thread consumer1 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
Packet packet = collector.nextResult();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + packet);
|
||||
}
|
||||
}
|
||||
catch (RuntimeException re)
|
||||
{
|
||||
if (re.getCause() instanceof InterruptedException)
|
||||
{
|
||||
// System.out.println(Thread.currentThread().getName() + " has been interupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
consumer1.setName("consumer 1");
|
||||
|
||||
Thread consumer2 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Packet p = null;
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
p = collector.nextResult(1);
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer2.setName("consumer 2");
|
||||
|
||||
Thread consumer3 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Packet p = null;
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
p = collector.pollResult();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer3.setName("consumer 3");
|
||||
|
||||
consumer1.start();
|
||||
consumer2.start();
|
||||
consumer3.start();
|
||||
|
||||
for(int i=0; i<insertCount; i++)
|
||||
{
|
||||
collector.processPacket(new TestPacket(i));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(5000);
|
||||
consumer3.join();
|
||||
consumer2.join();
|
||||
consumer1.interrupt();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
//We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
|
||||
// and main, but the probability is extremely remote.
|
||||
assertNull(collector.pollResult());
|
||||
}
|
||||
|
||||
class OKEverything implements PacketFilter
|
||||
{
|
||||
@Override
|
||||
public boolean accept(Packet packet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestPacketCollector extends PacketCollector
|
||||
{
|
||||
protected TestPacketCollector(Connection conection, PacketFilter packetFilter, int size)
|
||||
{
|
||||
super(conection, packetFilter, size);
|
||||
}
|
||||
}
|
||||
|
||||
class TestPacket extends Packet
|
||||
{
|
||||
public TestPacket(int i)
|
||||
{
|
||||
setPacketID(String.valueOf(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return toXML();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
return "<packetId>" + getPacketID() + "</packetId>";
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright the original author or authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.jivesoftware.smack.filter.PacketFilter;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PacketCollectorTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void verifyRollover()
|
||||
{
|
||||
TestPacketCollector collector = new TestPacketCollector(null, new OKEverything(), 5);
|
||||
|
||||
for (int i=0; i<6; i++)
|
||||
{
|
||||
Packet testPacket = new TestPacket(i);
|
||||
collector.processPacket(testPacket);
|
||||
}
|
||||
|
||||
// Assert that '0' has rolled off
|
||||
assertEquals("1", collector.nextResult().getPacketID());
|
||||
assertEquals("2", collector.nextResult().getPacketID());
|
||||
assertEquals("3", collector.nextResult().getPacketID());
|
||||
assertEquals("4", collector.nextResult().getPacketID());
|
||||
assertEquals("5", collector.pollResult().getPacketID());
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
for (int i=10; i<15; i++)
|
||||
{
|
||||
Packet testPacket = new TestPacket(i);
|
||||
collector.processPacket(testPacket);
|
||||
}
|
||||
|
||||
assertEquals("10", collector.nextResult().getPacketID());
|
||||
assertEquals("11", collector.nextResult().getPacketID());
|
||||
assertEquals("12", collector.nextResult().getPacketID());
|
||||
assertEquals("13", collector.nextResult().getPacketID());
|
||||
assertEquals("14", collector.pollResult().getPacketID());
|
||||
assertNull(collector.pollResult());
|
||||
|
||||
assertNull(collector.nextResult(1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* Although this doesn't guarentee anything due to the nature of threading, it can
|
||||
* potentially catch problems.
|
||||
*/
|
||||
@Test
|
||||
public void verifyThreadSafety()
|
||||
{
|
||||
int insertCount = 500;
|
||||
final TestPacketCollector collector = new TestPacketCollector(null, new OKEverything(), insertCount);
|
||||
|
||||
Thread consumer1 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
Packet packet = collector.nextResult();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + packet);
|
||||
}
|
||||
}
|
||||
catch (RuntimeException re)
|
||||
{
|
||||
if (re.getCause() instanceof InterruptedException)
|
||||
{
|
||||
// System.out.println(Thread.currentThread().getName() + " has been interupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
consumer1.setName("consumer 1");
|
||||
|
||||
Thread consumer2 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Packet p = null;
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
p = collector.nextResult(1);
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer2.setName("consumer 2");
|
||||
|
||||
Thread consumer3 = new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Packet p = null;
|
||||
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(3);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
p = collector.pollResult();
|
||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||
}
|
||||
while (p != null);
|
||||
}
|
||||
});
|
||||
consumer3.setName("consumer 3");
|
||||
|
||||
consumer1.start();
|
||||
consumer2.start();
|
||||
consumer3.start();
|
||||
|
||||
for(int i=0; i<insertCount; i++)
|
||||
{
|
||||
collector.processPacket(new TestPacket(i));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(5000);
|
||||
consumer3.join();
|
||||
consumer2.join();
|
||||
consumer1.interrupt();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
//We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
|
||||
// and main, but the probability is extremely remote.
|
||||
assertNull(collector.pollResult());
|
||||
}
|
||||
|
||||
class OKEverything implements PacketFilter
|
||||
{
|
||||
@Override
|
||||
public boolean accept(Packet packet)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestPacketCollector extends PacketCollector
|
||||
{
|
||||
protected TestPacketCollector(Connection conection, PacketFilter packetFilter, int size)
|
||||
{
|
||||
super(conection, packetFilter, size);
|
||||
}
|
||||
}
|
||||
|
||||
class TestPacket extends Packet
|
||||
{
|
||||
public TestPacket(int i)
|
||||
{
|
||||
setPacketID(String.valueOf(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return toXML();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toXML()
|
||||
{
|
||||
return "<packetId>" + getPacketID() + "</packetId>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,100 +14,100 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jivesoftware.smack.filters;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import org.jivesoftware.smack.filter.FromMatchesFilter;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.junit.Test;
|
||||
package org.jivesoftware.smack.filters;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import org.jivesoftware.smack.filter.FromMatchesFilter;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Robin Collier
|
||||
*
|
||||
*/
|
||||
public class FromMatchesFilterTest {
|
||||
private static final String BASE_JID1 = "ss@muc.myserver.com";
|
||||
private static final String FULL_JID1_R1 = BASE_JID1 + "/resource";
|
||||
private static final String FULL_JID1_R2 = BASE_JID1 + "/resource2";
|
||||
private static final String BASE_JID2 = "sss@muc.myserver.com";
|
||||
private static final String FULL_JID2 = BASE_JID2 + "/resource";
|
||||
|
||||
private static final String SERVICE_JID1 = "muc.myserver.com";
|
||||
private static final String SERVICE_JID2 = "pubsub.myserver.com";
|
||||
|
||||
@Test
|
||||
public void compareMatchingFullJid()
|
||||
{
|
||||
FromMatchesFilter filter = new FromMatchesFilter(FULL_JID1_R1);
|
||||
< |