1
0
Fork 0
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:
Florian Schmaus 2014-02-17 23:58:40 +01:00
parent 1e57f1c659
commit d069e1be64
364 changed files with 50349 additions and 50346 deletions

View file

@ -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"/>

View file

@ -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
}
}

View file

@ -332,4 +332,4 @@ public class AccountManager {
info = (Registration)result;
}
}
}
}

View file

@ -186,4 +186,4 @@ public class Chat {
&& threadID.equals(((Chat)obj).getThreadID())
&& participant.equals(((Chat)obj).getParticipant());
}
}
}

View file

@ -63,4 +63,4 @@ public interface ConnectionListener {
* @param e the exception that caused the reconnection to fail.
*/
public void reconnectionFailed(Exception e);
}
}

View file

@ -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();
}
}
}

View file

@ -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 {
}
}

View file

@ -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);
}

View file

@ -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
}
}

View file

@ -238,4 +238,4 @@ public class RosterEntry {
return item;
}
}
}

View file

@ -248,4 +248,4 @@ public class RosterGroup {
}
}
}
}
}

View file

@ -77,4 +77,4 @@ public interface RosterListener {
* @see Roster#getPresence(String)
*/
public void presenceChanged(Presence presence);
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -235,4 +235,4 @@ public class XMPPException extends Exception {
return buf.toString();
}
}
}

View file

@ -92,4 +92,4 @@ public interface SmackDebugger {
* the GUI
*/
public abstract PacketListener getWriterListener();
}
}

View file

@ -48,4 +48,4 @@ public class FromContainsFilter implements PacketFilter {
return packet.getFrom().toLowerCase().indexOf(from) != -1;
}
}
}
}

View file

@ -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));
}
}

View file

@ -97,4 +97,4 @@ public class OrFilter implements PacketFilter {
public String toString() {
return filters.toString();
}
}
}

View file

@ -49,4 +49,4 @@ public class ToContainsFilter implements PacketFilter {
return packet.getTo().toLowerCase().indexOf(to) != -1;
}
}
}
}

View file

@ -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);
}
}

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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();
}
}
}

View file

@ -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();
}
}

View file

@ -127,4 +127,4 @@ public class DefaultPacketExtension implements PacketExtension {
}
map.put(name, value);
}
}
}

View file

@ -669,4 +669,4 @@ public class Message extends Packet {
}
}
}
}

View file

@ -352,4 +352,4 @@ public class Presence extends Packet {
*/
dnd
}
}
}

View file

@ -104,4 +104,4 @@ public class Registration extends IQ {
buf.append("</query>");
return buf.toString();
}
}
}

View file

@ -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\"/>";
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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
*
* &lt;message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo&gt;
* &lt;event xmlns='http://jabber.org/protocol/pubsub#event&gt;
* &lt;items node='princely_musings'&gt;
* &lt;item id='asdjkwei3i34234n356'&gt;
* &lt;entry xmlns='http://www.w3.org/2005/Atom'&gt;
* &lt;title&gt;Soliloquy&lt;/title&gt;
* &lt;link rel='alternative' type='text/html'/&gt;
* &lt;id>tag:denmark.lit,2003:entry-32397&lt;/id&gt;
* &lt;/entry&gt;
* &lt;/item&gt;
* &lt;/items&gt;
* &lt;/event&gt;
* &lt;/message&gt;
*
* 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.
*
* &lt;extensionProvider&gt;
* &lt;elementName&gt;items&lt;/elementName&gt;
* &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
* &lt;className&gt;org.jivesoftware.smackx.provider.ItemsEventProvider&lt;/className&gt;
* &lt;/extensionProvider&gt;
* &lt;extensionProvider&gt;
* &lt;elementName&gt;item&lt;/elementName&gt;
* &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
* &lt;className&gt;org.jivesoftware.smackx.provider.ItemProvider&lt;/className&gt;
* &lt;/extensionProvider&gt;
*
* </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
*
* &lt;message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo&gt;
* &lt;event xmlns='http://jabber.org/protocol/pubsub#event&gt;
* &lt;items node='princely_musings'&gt;
* &lt;item id='asdjkwei3i34234n356'&gt;
* &lt;entry xmlns='http://www.w3.org/2005/Atom'&gt;
* &lt;title&gt;Soliloquy&lt;/title&gt;
* &lt;link rel='alternative' type='text/html'/&gt;
* &lt;id>tag:denmark.lit,2003:entry-32397&lt;/id&gt;
* &lt;/entry&gt;
* &lt;/item&gt;
* &lt;/items&gt;
* &lt;/event&gt;
* &lt;/message&gt;
*
* 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.
*
* &lt;extensionProvider&gt;
* &lt;elementName&gt;items&lt;/elementName&gt;
* &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
* &lt;className&gt;org.jivesoftware.smackx.provider.ItemsEventProvider&lt;/className&gt;
* &lt;/extensionProvider&gt;
* &lt;extensionProvider&gt;
* &lt;elementName&gt;item&lt;/elementName&gt;
* &lt;namespace&gt;http://jabber.org/protocol/pubsub#event&lt;/namespace&gt;
* &lt;className&gt;org.jivesoftware.smackx.provider.ItemProvider&lt;/className&gt;
* &lt;/extensionProvider&gt;
*
* </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);
}

View file

@ -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);
}
}

View file

@ -41,4 +41,4 @@ public interface IQProvider {
* @throws Exception if an error occurs parsing the XML.
*/
public IQ parseIQ(XmlPullParser parser) throws Exception;
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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();
}

View file

@ -295,4 +295,4 @@ public final class ProviderManager {
buf.append("<").append(elementName).append("/><").append(namespace).append("/>");
return buf.toString();
}
}
}

View file

@ -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());
}
}

View file

@ -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";
}
}

View file

@ -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";
}
}

View file

@ -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";
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}
}

View file

@ -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

View file

@ -675,4 +675,4 @@ public class Cache<K, V> implements Map<K, V> {
return object.toString();
}
}
}
}

View file

@ -230,4 +230,4 @@ public class DNSUtil {
}
return pos;
}
}
}

View file

@ -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()]);
}
}

View file

@ -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());
}
}

View file

@ -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

View file

@ -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;
}
};
}

View file

@ -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>";
}
}
}

View file

@ -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);
<