aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/installer-exclude/otr4j.jarbin94429 -> 99877 bytes
-rw-r--r--src/net/java/sip/communicator/impl/protocol/icq/OperationSetBasicInstantMessagingIcqImpl.java40
-rw-r--r--src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java108
-rw-r--r--src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java67
-rw-r--r--src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf3
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java81
-rw-r--r--src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java28
-rw-r--r--src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicInstantMessagingSipImpl.java107
-rw-r--r--src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java84
-rw-r--r--src/net/java/sip/communicator/plugin/otr/OtrTransformLayer.java64
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java2
-rw-r--r--src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java65
-rw-r--r--src/net/java/sip/communicator/plugin/otr/otr.manifest.mf3
-rw-r--r--src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java173
-rw-r--r--src/net/java/sip/communicator/service/protocol/TransformLayer.java11
-rw-r--r--test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java7
16 files changed, 556 insertions, 287 deletions
diff --git a/lib/installer-exclude/otr4j.jar b/lib/installer-exclude/otr4j.jar
index 06dc4a7..e8c57ba 100644
--- a/lib/installer-exclude/otr4j.jar
+++ b/lib/installer-exclude/otr4j.jar
Binary files differ
diff --git a/src/net/java/sip/communicator/impl/protocol/icq/OperationSetBasicInstantMessagingIcqImpl.java b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetBasicInstantMessagingIcqImpl.java
index b4e08e7..5ef2532 100644
--- a/src/net/java/sip/communicator/impl/protocol/icq/OperationSetBasicInstantMessagingIcqImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/icq/OperationSetBasicInstantMessagingIcqImpl.java
@@ -172,29 +172,35 @@ public class OperationSetBasicInstantMessagingIcqImpl
MessageDeliveredEvent msgDeliveryPendingEvt
= new MessageDeliveredEvent(message, to);
- msgDeliveryPendingEvt = this.messageDeliveryPendingTransform(msgDeliveryPendingEvt);
-
- if (msgDeliveryPendingEvt == null)
+ MessageDeliveredEvent[] msgDeliveryPendingEvts = this.messageDeliveryPendingTransform(msgDeliveryPendingEvt);
+ if (msgDeliveryPendingEvts == null || msgDeliveryPendingEvts.length == 0)
return;
- String transformedContent = msgDeliveryPendingEvt.getSourceMessage().getContent();
-
- if (to.getPresenceStatus().isOnline())
+ for (MessageDeliveredEvent pendingEvt : msgDeliveryPendingEvts)
{
- //do not add the conversation listener in here. we'll add it
- //inside the icbm listener
- imConversation.sendMessage(new SimpleMessage(transformedContent));
- }
- else
- imConversation.sendMessage(new SimpleMessage(transformedContent), true);
+ String transformedContent =
+ pendingEvt.getSourceMessage().getContent();
- MessageDeliveredEvent msgDeliveredEvt
- = new MessageDeliveredEvent(message, to);
+ if (to.getPresenceStatus().isOnline())
+ {
+ // do not add the conversation listener in here. we'll add it
+ // inside the icbm listener
+ imConversation
+ .sendMessage(new SimpleMessage(transformedContent));
+ }
+ else
+ imConversation.sendMessage(
+ new SimpleMessage(transformedContent), true);
- // msgDeliveredEvt = this.messageDeliveredTransform(msgDeliveredEvt);
+ MessageDeliveredEvent msgDeliveredEvt =
+ new MessageDeliveredEvent(message, to);
- if (msgDeliveredEvt != null)
- fireMessageEvent(msgDeliveredEvt);
+ // msgDeliveredEvt =
+ // this.messageDeliveredTransform(msgDeliveredEvt);
+
+ if (msgDeliveredEvt != null)
+ fireMessageEvent(msgDeliveredEvt);
+ }
}
/**
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java
index b819131..22aab66 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java
+++ b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java
@@ -152,6 +152,12 @@ public class IrcStack
private PresenceManager presence = null;
/**
+ * The local user's identity as it will be used in server-client
+ * communication for sent messages.
+ */
+ private Identity identity;
+
+ /**
* The cached channel list.
*
* Contained inside a simple container object in order to lock the container
@@ -253,6 +259,8 @@ public class IrcStack
connectSynchronized();
+ queryIdentity();
+
// TODO Read IRC network capabilities based on RPL_ISUPPORT (005)
// replies if available. This information should be available in
// irc-api if possible.
@@ -363,6 +371,27 @@ public class IrcStack
}
/**
+ * Issue WHOIS query to discover identity as seen by the server.
+ */
+ private void queryIdentity()
+ {
+ this.session.get().rawMessage(
+ "WHOIS " + this.connectionState.getNickname());
+ }
+
+ /**
+ * Get the current identity string, based on nick, user and host of local
+ * user.
+ *
+ * @return returns identity string
+ */
+ public String getIdentityString()
+ {
+ final String currentNick = this.connectionState.getNickname();
+ return this.identity.getIdentityString(currentNick);
+ }
+
+ /**
* Create a custom SSL context for this particular server.
*
* @param hostname host name of the host we are connecting to such that we
@@ -1022,16 +1051,12 @@ public class IrcStack
{
final IRCApi irc = this.session.get();
irc.message(target, message.getContent());
- IrcStack.this.provider.getBasicInstantMessaging()
- .fireMessageDelivered(message, contact);
LOGGER.trace("Message delivered to server successfully.");
}
catch (RuntimeException e)
{
- IrcStack.this.provider.getBasicInstantMessaging()
- .fireMessageDeliveryFailed(message, contact,
- MessageDeliveryFailedEvent.NETWORK_FAILURE);
LOGGER.trace("Failed to deliver message: " + e.getMessage(), e);
+ throw e;
}
}
@@ -1185,6 +1210,11 @@ public class IrcStack
*/
private static final int RPL_LISTEND =
IRCServerNumerics.CHANNEL_NICKS_END_OF_LIST;
+
+ /**
+ * Reply for WHOIS query.
+ */
+ private static final int IRC_RPL_WHOISUSER = 311;
/**
* IRCApi instance.
@@ -1359,6 +1389,29 @@ public class IrcStack
.fireMessageReceived(awayMessage, awayUser);
break;
+ case IRC_RPL_WHOISUSER:
+ final String whoismsg = msg.getText();
+ final int endNickIndex = whoismsg.indexOf(' ');
+ final String nick = whoismsg.substring(0, endNickIndex);
+ if (!IrcStack.this.connectionState.getNickname().equals(nick))
+ {
+ // We need WHOIS info on ourselves to discover our identity
+ // on the IRC server. So skip other WHOIS replies.
+ return;
+ }
+ final int endUserIndex =
+ whoismsg.indexOf(' ', endNickIndex + 1);
+ final int endHostIndex =
+ whoismsg.indexOf(' ', endUserIndex + 1);
+ final String user =
+ whoismsg.substring(endNickIndex + 1, endUserIndex);
+ final String host =
+ whoismsg.substring(endUserIndex + 1, endHostIndex);
+ LOGGER.debug(String.format("Current identity: %s!%s@%s",
+ IrcStack.this.connectionState.getNickname(), user, host));
+ IrcStack.this.identity = new IrcStack.Identity(user, host);
+ break;
+
default:
if (LOGGER.isTraceEnabled())
{
@@ -2592,4 +2645,49 @@ public class IrcStack
LOGGER.debug("Old channel list cache has been cleared.");
}
}
+
+ /**
+ * Storage container for identity components.
+ *
+ * IRC identity components user and host are stored. The nick name component
+ * isn't stored, because it changes too frequently. When getting the
+ * identity string, the nick name component is provided at calling time.
+ *
+ * @author Danny van Heumen
+ */
+ private static final class Identity
+ {
+ /**
+ * User name.
+ */
+ private final String user;
+
+ /**
+ * Host name.
+ */
+ private final String host;
+
+ /**
+ * Constructor.
+ *
+ * @param user user
+ * @param host host
+ */
+ private Identity(final String user, final String host)
+ {
+ this.user = user;
+ this.host = host;
+ }
+
+ /**
+ * Get identity string.
+ *
+ * @param currentNick the current nick
+ * @return returns identity string
+ */
+ public String getIdentityString(final String currentNick)
+ {
+ return String.format("%s!%s@%s", currentNick, this.user, this.host);
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java
index 09a0b79..6130263 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java
@@ -6,6 +6,8 @@
package net.java.sip.communicator.impl.protocol.irc;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
/**
* Implementation of Basic Instant Messaging as utilized for IRC private
@@ -17,6 +19,11 @@ public class OperationSetBasicInstantMessagingIrcImpl
extends AbstractOperationSetBasicInstantMessaging
{
/**
+ * Logger.
+ */
+ private static final Logger LOGGER = Logger.getLogger(OperationSetBasicInstantMessagingIrcImpl.class);
+
+ /**
* IRC protocol provider service.
*/
private final ProtocolProviderServiceIrcImpl provider;
@@ -59,28 +66,74 @@ public class OperationSetBasicInstantMessagingIrcImpl
* Send instant message.
*
* @param to contact to send message to
- * @param message message to send
+ * @param original message to send
* @throws IllegalStateException in case of bad internal state
* @throws IllegalArgumentException in case invalid arguments have been
* passed
*/
@Override
- public void sendInstantMessage(final Contact to, final Message message)
+ public void sendInstantMessage(final Contact to, final Message original)
throws IllegalStateException,
IllegalArgumentException
{
+ if (!(original instanceof MessageIrcImpl))
+ {
+ LOGGER.error("Invalid class of Message implementation received. "
+ + "Not sending message.");
+ return;
+ }
+
// OTR seems to be compatible with the command syntax (starts with '/')
// and there were no other obvious problems so we decided to implement
// IRC command support for IM infrastructure too.
- if (message instanceof MessageIrcImpl
- && ((MessageIrcImpl) message).isCommand())
+ final MessageDeliveredEvent[] msgDeliveryPendingEvts =
+ messageDeliveryPendingTransform(new MessageDeliveredEvent(original,
+ to));
+
+ try
{
- this.provider.getIrcStack().command(to, (MessageIrcImpl) message);
+ for (MessageDeliveredEvent event : msgDeliveryPendingEvts)
+ {
+ if (event == null)
+ {
+ return;
+ }
+
+ String transformedContent =
+ event.getSourceMessage().getContent();
+
+ // FIXME how to handle HTML content?
+
+ // Note: can't set subject since it leaks information while
+ // message content actually gets encoded.
+ MessageIrcImpl message = this.createMessage(transformedContent,
+ original.getContentType(), original.getEncoding(), "");
+
+ try
+ {
+ if (message.isCommand())
+ {
+ this.provider.getIrcStack().command(to, message);
+ }
+ else
+ {
+ this.provider.getIrcStack().message(to, message);
+ }
+ }
+ catch (RuntimeException e)
+ {
+ LOGGER.debug("Failed to deliver (raw) message: " + message);
+ throw e;
+ }
+ }
+ fireMessageDelivered(original, to);
}
- else
+ catch (RuntimeException e)
{
- this.provider.getIrcStack().message(to, message);
+ LOGGER.warn("Failed to deliver message: " + original, e);
+ fireMessageDeliveryFailed(original, to,
+ MessageDeliveryFailedEvent.NETWORK_FAILURE);
}
}
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf
index a28001a..2de13b0 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf
+++ b/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf
@@ -3,7 +3,8 @@ Bundle-Name: Irc Protocol Provider
Bundle-Description: A bundle providing support for the Irc protocol.
Bundle-Vendor: jitsi.org
Bundle-Version: 0.0.1
-Bundle-SymbolicName: net.java.sip.communicator.protocol.irc
+Bundle-SymbolicName: net.java.sip.communicator.impl.protocol.irc
+Export-Package: net.java.sip.communicator.impl.protocol.irc
Import-Package: org.osgi.framework,
org.jitsi.service.configuration,
org.jitsi.service.resources,
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
index 0b53ccb..486d49f 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
@@ -442,62 +442,60 @@ public class OperationSetBasicInstantMessagingJabberImpl
MessageDeliveredEvent msgDeliveryPendingEvt
= new MessageDeliveredEvent(message, to, toResource);
- msgDeliveryPendingEvt
- = messageDeliveryPendingTransform(msgDeliveryPendingEvt);
+ MessageDeliveredEvent[] transformedEvents = messageDeliveryPendingTransform(msgDeliveryPendingEvt);
- if (msgDeliveryPendingEvt == null)
+ if (transformedEvents == null || transformedEvents.length == 0)
return null;
- String content = msgDeliveryPendingEvt
- .getSourceMessage().getContent();
-
- if(message.getContentType().equals(HTML_MIME_TYPE))
+ for (MessageDeliveredEvent event : transformedEvents)
{
- msg.setBody(Html2Text.extractText(content));
+ String content = event.getSourceMessage().getContent();
- // Check if the other user supports XHTML messages
- // make sure we use our discovery manager as it caches calls
- if(jabberProvider.isFeatureListSupported(
- toJID,
- HTML_NAMESPACE))
+ if (message.getContentType().equals(HTML_MIME_TYPE))
{
- // Add the XHTML text to the message
- XHTMLManager.addBody(msg,
- OPEN_BODY_TAG + content + CLOSE_BODY_TAG);
- }
- }
- else
- {
- // this is plain text so keep it as it is.
- msg.setBody(content);
- }
+ msg.setBody(Html2Text.extractText(content));
- //msg.addExtension(new Version());
+ // Check if the other user supports XHTML messages
+ // make sure we use our discovery manager as it caches calls
+ if (jabberProvider
+ .isFeatureListSupported(toJID, HTML_NAMESPACE))
+ {
+ // Add the XHTML text to the message
+ XHTMLManager.addBody(msg, OPEN_BODY_TAG + content
+ + CLOSE_BODY_TAG);
+ }
+ }
+ else
+ {
+ // this is plain text so keep it as it is.
+ msg.setBody(content);
+ }
- if(msgDeliveryPendingEvt.isMessageEncrypted())
- {
- msg.addExtension(new CarbonPacketExtension.PrivateExtension());
- }
+ // msg.addExtension(new Version());
- MessageEventManager.
- addNotificationsRequests(msg, true, false, false, true);
+ if (event.isMessageEncrypted())
+ {
+ msg.addExtension(new CarbonPacketExtension.PrivateExtension());
+ }
- String threadID = getThreadIDForAddress(toJID);
- if(threadID == null)
- threadID = nextThreadID();
+ MessageEventManager.addNotificationsRequests(msg, true, false,
+ false, true);
- msg.setThread(threadID);
- msg.setType(org.jivesoftware.smack.packet.Message.Type.chat);
- msg.setFrom(jabberProvider.getConnection().getUser());
+ String threadID = getThreadIDForAddress(toJID);
+ if (threadID == null)
+ threadID = nextThreadID();
- jabberProvider.getConnection().sendPacket(msg);
+ msg.setThread(threadID);
+ msg.setType(org.jivesoftware.smack.packet.Message.Type.chat);
+ msg.setFrom(jabberProvider.getConnection().getUser());
- putJidForAddress(toJID, threadID);
+ jabberProvider.getConnection().sendPacket(msg);
- MessageDeliveredEvent msgDeliveredEvt
- = new MessageDeliveredEvent(message, to, toResource);
+ putJidForAddress(toJID, threadID);
+ }
- // msgDeliveredEvt = messageDeliveredTransform(msgDeliveredEvt);
+ MessageDeliveredEvent msgDeliveredEvt =
+ new MessageDeliveredEvent(message, to, toResource);
return msgDeliveredEvt;
}
@@ -1119,6 +1117,7 @@ public class OperationSetBasicInstantMessagingJabberImpl
? "service.gui.NEW_GMAIL_MANY_FOOTER"
: "service.gui.NEW_GMAIL_FOOTER";
+ // FIXME Escape HTML!
String newMailHeader = JabberActivator.getResources().getI18NString(
resourceHeaderKey,
new String[]
diff --git a/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java b/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java
index e614586..e09d9c1 100644
--- a/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/msn/OperationSetBasicInstantMessagingMsnImpl.java
@@ -113,7 +113,7 @@ public class OperationSetBasicInstantMessagingMsnImpl
* @throws java.lang.IllegalArgumentException if <tt>to</tt> is not an
* instance of ContactImpl.
*/
- public void sendInstantMessage(final Contact to, Message message)
+ public void sendInstantMessage(final Contact to, final Message message)
throws IllegalStateException, IllegalArgumentException
{
assertConnected();
@@ -123,29 +123,30 @@ public class OperationSetBasicInstantMessagingMsnImpl
"The specified contact is not an MSN contact."
+ to);
- final MessageDeliveredEvent msgDeliveryPendingEvt
- = messageDeliveryPendingTransform(
- new MessageDeliveredEvent(message, to));
+ MessageDeliveredEvent[] transformedEvents = messageDeliveryPendingTransform(
+ new MessageDeliveredEvent(message, to));
- if (msgDeliveryPendingEvt == null)
+ if (transformedEvents == null || transformedEvents.length == 0)
return;
- MessageDeliveredEvent msgDeliveredEvt
- = new MessageDeliveredEvent(message, to);
+ MessageDeliveredEvent msgDeliveredEvt =
+ new MessageDeliveredEvent(message, to);
fireMessageEvent(msgDeliveredEvt);
- // send message in separate thread so we won't block ui if
- // it takes time.
- if(senderThread == null)
+ // send message in separate thread so we won't block ui if it takes
+ // time.
+ if (senderThread == null)
{
senderThread = new SenderThread();
senderThread.start();
}
- senderThread.sendMessage(
- (ContactMsnImpl)to,
- msgDeliveryPendingEvt.getSourceMessage().getContent());
+ for (MessageDeliveredEvent event : transformedEvents)
+ {
+ senderThread.sendMessage((ContactMsnImpl) to, event
+ .getSourceMessage().getContent());
+ }
}
/**
@@ -323,6 +324,7 @@ public class OperationSetBasicInstantMessagingMsnImpl
logger.warn("Failed to decode the subject of a new e-mail", ex);
}
+ // FIXME Escape HTML!
String messageFrom = message.getFrom();
Message newMailMessage = new MessageMsnImpl(
MessageFormat.format(
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicInstantMessagingSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicInstantMessagingSipImpl.java
index 3b40ba8..2e0534a 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicInstantMessagingSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetBasicInstantMessagingSipImpl.java
@@ -214,53 +214,44 @@ public class OperationSetBasicInstantMessagingSipImpl
}
// create the message
- Request mes;
- try
- {
- Message transformedMessage = transformSIPMessage(to, message);
- mes = createMessageRequest(to, transformedMessage);
- }
- catch (OperationFailedException ex)
+ Message[] transformedMessages = transformSIPMessage(to, message);
+ for (Message msg : transformedMessages)
{
- logger.error(
- "Failed to create the message."
- , ex);
+ Request mes;
+ try
+ {
+ mes = createMessageRequest(to, msg);
+ }
+ catch (OperationFailedException ex)
+ {
+ logger.error("Failed to create the message.", ex);
- fireMessageDeliveryFailed(
- message,
- to,
- MessageDeliveryFailedEvent.INTERNAL_ERROR);
- return;
- }
+ fireMessageDeliveryFailed(message, to,
+ MessageDeliveryFailedEvent.INTERNAL_ERROR);
+ continue;
+ }
- try
- {
- sendMessageRequest(mes, to, message);
- }
- catch(TransactionUnavailableException ex)
- {
- logger.error(
- "Failed to create messageTransaction.\n"
- + "This is most probably a network connection error."
- , ex);
+ try
+ {
+ sendMessageRequest(mes, to, message);
+ }
+ catch (TransactionUnavailableException ex)
+ {
+ logger.error("Failed to create messageTransaction.\n"
+ + "This is most probably a network connection error.", ex);
- fireMessageDeliveryFailed(
- message,
- to,
- MessageDeliveryFailedEvent.NETWORK_FAILURE);
- return;
- }
- catch(SipException ex)
- {
- logger.error(
- "Failed to send the message."
- , ex);
+ fireMessageDeliveryFailed(message, to,
+ MessageDeliveryFailedEvent.NETWORK_FAILURE);
+ continue;
+ }
+ catch (SipException ex)
+ {
+ logger.error("Failed to send the message.", ex);
- fireMessageDeliveryFailed(
- message,
- to,
- MessageDeliveryFailedEvent.INTERNAL_ERROR);
- return;
+ fireMessageDeliveryFailed(message, to,
+ MessageDeliveryFailedEvent.INTERNAL_ERROR);
+ continue;
+ }
}
}
@@ -482,28 +473,36 @@ public class OperationSetBasicInstantMessagingSipImpl
*
* @return The new transformed <tt>Message</tt>
*/
- private Message transformSIPMessage(Contact to, Message message)
+ private Message[] transformSIPMessage(final Contact to,
+ final Message message)
{
MessageDeliveredEvent msgDeliveryPendingEvt
= new MessageDeliveredEvent(message, to);
- msgDeliveryPendingEvt
- = messageDeliveryPendingTransform(msgDeliveryPendingEvt);
+ MessageDeliveredEvent[] msgDeliveryPendingEvts =
+ messageDeliveryPendingTransform(msgDeliveryPendingEvt);
- if (msgDeliveryPendingEvt == null)
- return null;
-
- String content = msgDeliveryPendingEvt.getSourceMessage().getContent();
+ if (msgDeliveryPendingEvts == null
+ || msgDeliveryPendingEvts.length == 0)
+ {
+ return new Message[0];
+ }
OperationSetBasicInstantMessaging opSetBasicIM =
(OperationSetBasicInstantMessaging) sipProvider
.getSupportedOperationSets().get(
OperationSetBasicInstantMessaging.class.getName());
- Message transformedMesssage =
- opSetBasicIM.createMessage(content, message.getContentType(),
- message.getEncoding(), message.getSubject());
-
- return transformedMesssage;
+ Message[] transformedMessages =
+ new Message[msgDeliveryPendingEvts.length];
+ for (int i = 0; i < msgDeliveryPendingEvts.length; i++)
+ {
+ MessageDeliveredEvent event = msgDeliveryPendingEvts[i];
+ String content = event.getSourceMessage().getContent();
+ transformedMessages[i] =
+ opSetBasicIM.createMessage(content, message.getContentType(),
+ message.getEncoding(), message.getSubject());
+ }
+ return transformedMessages;
}
/**
diff --git a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java
index ab9ba26..eb53d4a 100644
--- a/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/yahoo/OperationSetBasicInstantMessagingYahooImpl.java
@@ -150,56 +150,55 @@ public class OperationSetBasicInstantMessagingYahooImpl
{
String toUserID = ((ContactYahooImpl) to).getID();
- MessageDeliveredEvent msgDeliveryPendingEvt
- = new MessageDeliveredEvent(
- message, to, new Date());
+ MessageDeliveredEvent msgDeliveryPendingEvt =
+ new MessageDeliveredEvent(message, to, new Date());
- msgDeliveryPendingEvt = messageDeliveryPendingTransform(msgDeliveryPendingEvt);
+ MessageDeliveredEvent[] msgDeliveryPendingEvts = messageDeliveryPendingTransform(msgDeliveryPendingEvt);
- if (msgDeliveryPendingEvt == null)
+ if (msgDeliveryPendingEvts == null || msgDeliveryPendingEvts.length == 0)
return;
- byte[] msgBytesToBeSent = msgDeliveryPendingEvt.getSourceMessage().
- getContent().trim().getBytes("UTF-8");
-
- // split the message in parts with max allowed length
- // and send them all
- do
+ for (MessageDeliveredEvent event : msgDeliveryPendingEvts)
{
- if(msgBytesToBeSent.length > MAX_MESSAGE_LENGTH)
- {
- byte[] tmp1 = new byte[MAX_MESSAGE_LENGTH];
- System.arraycopy(msgBytesToBeSent,
- 0, tmp1, 0, MAX_MESSAGE_LENGTH);
-
- byte[] tmp2 =
- new byte[msgBytesToBeSent.length - MAX_MESSAGE_LENGTH];
- System.arraycopy(msgBytesToBeSent,
- MAX_MESSAGE_LENGTH, tmp2, 0, tmp2.length);
+ byte[] msgBytesToBeSent =
+ event.getSourceMessage().getContent().trim()
+ .getBytes("UTF-8");
- msgBytesToBeSent = tmp2;
-
- yahooProvider.getYahooSession().sendMessage(
- toUserID,
- new String(tmp1, "UTF-8"));
- }
- else
+ // split the message in parts with max allowed length
+ // and send them all
+ do
{
- yahooProvider.getYahooSession().sendMessage(
- toUserID,
- new String(msgBytesToBeSent, "UTF-8"));
+ if (msgBytesToBeSent.length > MAX_MESSAGE_LENGTH)
+ {
+ byte[] tmp1 = new byte[MAX_MESSAGE_LENGTH];
+ System.arraycopy(msgBytesToBeSent, 0, tmp1, 0,
+ MAX_MESSAGE_LENGTH);
+
+ byte[] tmp2 =
+ new byte[msgBytesToBeSent.length
+ - MAX_MESSAGE_LENGTH];
+ System.arraycopy(msgBytesToBeSent, MAX_MESSAGE_LENGTH,
+ tmp2, 0, tmp2.length);
+
+ msgBytesToBeSent = tmp2;
+
+ yahooProvider.getYahooSession().sendMessage(toUserID,
+ new String(tmp1, "UTF-8"));
+ }
+ else
+ {
+ yahooProvider.getYahooSession().sendMessage(toUserID,
+ new String(msgBytesToBeSent, "UTF-8"));
+ }
+
+ MessageDeliveredEvent msgDeliveredEvt =
+ new MessageDeliveredEvent(message, to, new Date());
+
+ if (msgDeliveredEvt != null)
+ fireMessageEvent(msgDeliveredEvt);
}
-
- MessageDeliveredEvent msgDeliveredEvt
- = new MessageDeliveredEvent(
- message, to, new Date());
-
- // msgDeliveredEvt = messageDeliveredTransform(msgDeliveredEvt);
-
- if (msgDeliveredEvt != null)
- fireMessageEvent(msgDeliveredEvt);
+ while (msgBytesToBeSent.length > MAX_MESSAGE_LENGTH);
}
- while(msgBytesToBeSent.length > MAX_MESSAGE_LENGTH);
}
catch (IOException ex)
{
@@ -210,8 +209,6 @@ public class OperationSetBasicInstantMessagingYahooImpl
to,
MessageDeliveryFailedEvent.NETWORK_FAILURE);
- // evt = messageDeliveryFailedTransform(evt);
-
if (evt != null)
fireMessageEvent(evt);
}
@@ -374,6 +371,7 @@ public class OperationSetBasicInstantMessagingYahooImpl
+ yahooMailLogon + "\">"
+ yahooMailLogon + "</a>";
+ // FIXME Escape HTML!
String newMail = YahooActivator.getResources().getI18NString(
"service.gui.NEW_MAIL",
new String[]{ev.getFrom(),
diff --git a/src/net/java/sip/communicator/plugin/otr/OtrTransformLayer.java b/src/net/java/sip/communicator/plugin/otr/OtrTransformLayer.java
index f447de0..7c94eac 100644
--- a/src/net/java/sip/communicator/plugin/otr/OtrTransformLayer.java
+++ b/src/net/java/sip/communicator/plugin/otr/OtrTransformLayer.java
@@ -61,7 +61,7 @@ public class OtrTransformLayer
/*
* Implements TransformLayer#messageDeliveryPending(MessageDeliveredEvent).
*/
- public MessageDeliveredEvent messageDeliveryPending(
+ public MessageDeliveredEvent[] messageDeliveryPending(
MessageDeliveredEvent evt)
{
Contact contact = evt.getDestinationContact();
@@ -76,47 +76,57 @@ public class OtrTransformLayer
if (!policy.getEnableManual()
&& sessionStatus != ScSessionStatus.ENCRYPTED
&& sessionStatus != ScSessionStatus.FINISHED)
- return evt;
+ return new MessageDeliveredEvent[] {evt};
// If this is a message otr4j injected earlier, return the event as is.
if (OtrActivator.scOtrEngine.isMessageUIDInjected(evt
.getSourceMessage().getMessageUID()))
- return evt;
+ return new MessageDeliveredEvent[] {evt};
// Process the outgoing message.
String msgContent = evt.getSourceMessage().getContent();
- String processedMessageContent =
+ String[] processedMessageContent =
OtrActivator.scOtrEngine.transformSending(otrContact, msgContent);
if (processedMessageContent == null
- || processedMessageContent.length() < 1)
- return null;
-
- if (processedMessageContent.equals(msgContent))
- return evt;
-
- // Forge a new message based on the new contents.
- OperationSetBasicInstantMessaging imOpSet =
- contact.getProtocolProvider().getOperationSet(
- OperationSetBasicInstantMessaging.class);
- Message processedMessage =
- imOpSet.createMessage(
- processedMessageContent,
- evt.getSourceMessage().getContentType(),
- evt.getSourceMessage().getEncoding(),
- evt.getSourceMessage().getSubject());
+ || processedMessageContent.length <= 0
+ || processedMessageContent[0].length() < 1)
+ return new MessageDeliveredEvent[0];
- // Create a new event and return.
- MessageDeliveredEvent processedEvent =
- new MessageDeliveredEvent(processedMessage, contact, evt
- .getTimestamp());
+ if (processedMessageContent.length == 1
+ && processedMessageContent[0].equals(msgContent))
+ return new MessageDeliveredEvent[] {evt};
- if(processedMessage.getContent().contains(SerializationConstants.HEAD))
+ final MessageDeliveredEvent[] processedEvents =
+ new MessageDeliveredEvent[processedMessageContent.length];
+ for (int i = 0; i < processedMessageContent.length; i++)
{
- processedEvent.setMessageEncrypted(true);
+ final String fragmentContent = processedMessageContent[i];
+ // Forge a new message based on the new contents.
+ OperationSetBasicInstantMessaging imOpSet =
+ contact.getProtocolProvider().getOperationSet(
+ OperationSetBasicInstantMessaging.class);
+ Message processedMessage =
+ imOpSet.createMessage(fragmentContent, evt
+ .getSourceMessage().getContentType(), evt
+ .getSourceMessage().getEncoding(), evt.getSourceMessage()
+ .getSubject());
+
+ // Create a new event and return.
+ final MessageDeliveredEvent processedEvent =
+ new MessageDeliveredEvent(processedMessage, contact,
+ evt.getTimestamp());
+
+ if (processedMessage.getContent().contains(
+ SerializationConstants.HEAD))
+ {
+ processedEvent.setMessageEncrypted(true);
+ }
+
+ processedEvents[i] = processedEvent;
}
- return processedEvent;
+ return processedEvents;
}
/*
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java b/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java
index f9ee909..5bd9688 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java
@@ -70,7 +70,7 @@ public interface ScOtrEngine
* @param content the original message content.
* @return the transformed message content.
*/
- public abstract String transformSending(OtrContact contact, String content);
+ public abstract String[] transformSending(OtrContact contact, String content);
/**
* Transforms an incoming message.
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java
index a06b61d..f14c2ec 100644
--- a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java
+++ b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java
@@ -14,6 +14,7 @@ import java.util.concurrent.*;
import net.java.otr4j.*;
import net.java.otr4j.crypto.*;
import net.java.otr4j.session.*;
+import net.java.sip.communicator.impl.protocol.irc.*;
import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
import net.java.sip.communicator.plugin.otr.authdialog.*;
import net.java.sip.communicator.service.browserlauncher.*;
@@ -420,6 +421,44 @@ public class ScOtrEngineImpl
message,
OperationSetBasicInstantMessaging.HTML_MIME_TYPE);
}
+
+ /**
+ * Provide fragmenter instructions according to the Instant Messaging
+ * transport channel of the contact's protocol.
+ */
+ @Override
+ public FragmenterInstructions getFragmenterInstructions(
+ final SessionID sessionID)
+ {
+ final OtrContact otrContact = getOtrContact(sessionID);
+ // FIXME Change this into querying an Operation Set that provides
+ // Instant Message medium/transport information that we can use to
+ // determine fragmentation parameters.
+ if (ProtocolNames.IRC.equals(otrContact.contact
+ .getProtocolProvider().getProtocolName()))
+ {
+ // :<nick>!<user>@<host> PRIVMSG <targetnick> :<message>
+ //
+ // Example:
+ // :ircotrtest!~ircotrtes@77-175-185-165.FTTH.ispfabriek.nl
+ // PRIVMSG test12345abc :
+ final String identity =
+ ((ProtocolProviderServiceIrcImpl) otrContact.contact
+ .getProtocolProvider()).getIrcStack()
+ .getIdentityString();
+ final int size =
+ 510 - (":" + identity + " PRIVMSG "
+ + otrContact.contact.getAddress() + " :").length();
+ return new FragmenterInstructions(
+ FragmenterInstructions.UNLIMITED, size);
+ }
+ else
+ {
+ return new FragmenterInstructions(
+ FragmenterInstructions.UNLIMITED,
+ FragmenterInstructions.UNLIMITED);
+ }
+ }
}
/**
@@ -510,11 +549,11 @@ public class ScOtrEngineImpl
private final OtrEngineHost otrEngineHost = new ScOtrEngineHost();
- private final OtrEngine otrEngine;
+ private final OtrSessionManager otrEngine;
public ScOtrEngineImpl()
{
- otrEngine = new OtrEngineImpl(otrEngineHost);
+ otrEngine = new OtrSessionManagerImpl(otrEngineHost);
// Clears the map after previous instance
// This is required because of OSGi restarts in the same VM on Android
@@ -539,13 +578,13 @@ public class ScOtrEngineImpl
ScSessionStatus scSessionStatus = getSessionStatus(otrContact);
String message = "";
- switch (otrEngine.getSessionStatus(sessionID))
+ final Session session = otrEngine.getSession(sessionID);
+ switch (session.getSessionStatus())
{
case ENCRYPTED:
scSessionStatus = ScSessionStatus.ENCRYPTED;
scSessionStatusMap.put(sessionID, scSessionStatus);
- PublicKey remotePubKey =
- otrEngine.getRemotePublicKey(sessionID);
+ PublicKey remotePubKey = session.getRemotePublicKey();
String remoteFingerprint = null;
try
@@ -790,7 +829,7 @@ public class ScOtrEngineImpl
{
setSessionStatus(otrContact, ScSessionStatus.PLAINTEXT);
- otrEngine.endSession(sessionID);
+ otrEngine.getSession(sessionID).endSession();
}
catch (OtrException e)
{
@@ -926,7 +965,7 @@ public class ScOtrEngineImpl
public ScSessionStatus getSessionStatus(OtrContact contact)
{
SessionID sessionID = getSessionID(contact);
- SessionStatus sessionStatus = otrEngine.getSessionStatus(sessionID);
+ SessionStatus sessionStatus = otrEngine.getSession(sessionID).getSessionStatus();
ScSessionStatus scSessionStatus = null;
if (!scSessionStatusMap.containsKey(sessionID))
{
@@ -976,7 +1015,7 @@ public class ScOtrEngineImpl
SessionID sessionID = getSessionID(otrContact);
try
{
- otrEngine.refreshSession(sessionID);
+ otrEngine.getSession(sessionID).refreshSession();
}
catch (OtrException e)
{
@@ -1112,7 +1151,7 @@ public class ScOtrEngineImpl
try
{
- otrEngine.startSession(sessionID);
+ otrEngine.getSession(sessionID).startSession();
}
catch (OtrException e)
{
@@ -1127,7 +1166,7 @@ public class ScOtrEngineImpl
SessionID sessionID = getSessionID(otrContact);
try
{
- return otrEngine.transformReceiving(sessionID, msgText);
+ return otrEngine.getSession(sessionID).transformReceiving(msgText);
}
catch (OtrException e)
{
@@ -1138,12 +1177,12 @@ public class ScOtrEngineImpl
}
@Override
- public String transformSending(OtrContact otrContact, String msgText)
+ public String[] transformSending(OtrContact otrContact, String msgText)
{
SessionID sessionID = getSessionID(otrContact);
try
{
- return otrEngine.transformSending(sessionID, msgText);
+ return otrEngine.getSession(sessionID).transformSending(msgText);
}
catch (OtrException e)
{
@@ -1280,6 +1319,6 @@ public class ScOtrEngineImpl
SessionID sessionID = getSessionID(contact);
- return otrEngine.getOutgoingSession(sessionID);
+ return otrEngine.getSession(sessionID).getOutgoingInstance();
}
}
diff --git a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf
index 07807d4..0dbc565 100644
--- a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf
+++ b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf
@@ -33,4 +33,5 @@ Import-Package: org.osgi.framework,
org.bouncycastle.crypto.modes,
org.bouncycastle.util,
org.bouncycastle.util.encoders,
- net.java.sip.communicator.service.msghistory
+ net.java.sip.communicator.service.msghistory,
+ net.java.sip.communicator.impl.protocol.irc
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
index d3c42eb..28ab995 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
@@ -205,38 +205,41 @@ public abstract class AbstractOperationSetBasicInstantMessaging
}
// Transform the event.
- try
+ EventObject[] events = messageTransform(evt, eventType);
+ for (EventObject event : events)
{
- evt = messageTransform(evt, eventType);
- if (evt == null)
- return;
-
- for (MessageListener listener : listeners)
+ try
{
- switch (eventType)
+ if (event == null)
+ return;
+
+ for (MessageListener listener : listeners)
{
- case MessageDelivered:
- listener.messageDelivered((MessageDeliveredEvent) evt);
- break;
- case MessageDeliveryFailed:
- listener.messageDeliveryFailed(
- (MessageDeliveryFailedEvent)evt);
- break;
- case MessageReceived:
- listener.messageReceived((MessageReceivedEvent) evt);
- break;
- default:
- /*
- * We either have nothing to do or we do not know what to
- * do. Anyway, we'll silence the compiler.
- */
- break;
+ switch (eventType)
+ {
+ case MessageDelivered:
+ listener.messageDelivered((MessageDeliveredEvent) event);
+ break;
+ case MessageDeliveryFailed:
+ listener
+ .messageDeliveryFailed((MessageDeliveryFailedEvent) event);
+ break;
+ case MessageReceived:
+ listener.messageReceived((MessageReceivedEvent) event);
+ break;
+ default:
+ /*
+ * We either have nothing to do or we do not know what
+ * to do. Anyway, we'll silence the compiler.
+ */
+ break;
+ }
}
}
- }
- catch (Throwable e)
- {
- logger.error("Error delivering message", e);
+ catch (Throwable e)
+ {
+ logger.error("Error delivering message", e);
+ }
}
}
@@ -268,18 +271,44 @@ public abstract class AbstractOperationSetBasicInstantMessaging
}
}
- public MessageDeliveredEvent messageDeliveryPendingTransform(
- MessageDeliveredEvent evt)
+ /**
+ * Messages pending delivery to be transformed.
+ *
+ * @param evt the message delivery event
+ * @return returns message delivery events
+ */
+ public MessageDeliveredEvent[] messageDeliveryPendingTransform(
+ final MessageDeliveredEvent evt)
{
- return (MessageDeliveredEvent) messageTransform(
+ EventObject[] transformed = messageTransform(
evt, MessageEventType.MessageDeliveryPending);
- }
- private EventObject messageTransform( EventObject evt,
- MessageEventType eventType){
+ final int size = transformed.length;
+ MessageDeliveredEvent[] events =
+ new MessageDeliveredEvent[size];
+ System.arraycopy(transformed, 0, events, 0, size);
+ return events;
+ }
+ /**
+ * Transform provided source event by processing transform layers in
+ * sequence.
+ *
+ * @param evt the source event to transform
+ * @param eventType the event type of the source event
+ * @return returns the resulting (transformed) events, if any. (I.e. an
+ * array of 0 or more size containing events.)
+ */
+ private EventObject[] messageTransform(final EventObject evt,
+ final MessageEventType eventType)
+ {
+ if (evt == null)
+ {
+ return new EventObject[0];
+ }
ProtocolProviderService protocolProvider;
- switch (eventType){
+ switch (eventType)
+ {
case MessageDelivered:
protocolProvider
= ((MessageDeliveredEvent) evt)
@@ -301,7 +330,7 @@ public abstract class AbstractOperationSetBasicInstantMessaging
.getSourceContact().getProtocolProvider();
break;
default:
- return evt;
+ return new EventObject[] {evt};
}
OperationSetInstantMessageTransformImpl opSetMessageTransform
@@ -309,49 +338,81 @@ public abstract class AbstractOperationSetBasicInstantMessaging
.getOperationSet(OperationSetInstantMessageTransform.class);
if (opSetMessageTransform == null)
- return evt;
-
+ return new EventObject[] {evt};
+
+ // 'current' contains the events that need to be transformed. It should
+ // not contain null values.
+ final LinkedList<EventObject> current = new LinkedList<EventObject>();
+ // Add source event as start of transformation.
+ current.add(evt);
+ // 'next' contains the resulting events after transformation in the
+ // current iteration. It should not contain null values.
+ final LinkedList<EventObject> next = new LinkedList<EventObject>();
for (Map.Entry<Integer, Vector<TransformLayer>> entry
: opSetMessageTransform.transformLayers.entrySet())
{
for (TransformLayer transformLayer : entry.getValue())
{
- if (evt != null){
- switch (eventType){
+ next.clear();
+ while (!current.isEmpty())
+ {
+ final EventObject event = current.remove();
+ switch (eventType)
+ {
case MessageDelivered:
- evt
- = transformLayer
- .messageDelivered((MessageDeliveredEvent)evt);
+ MessageDeliveredEvent transformedDelivered =
+ transformLayer.messageDelivered(
+ (MessageDeliveredEvent) event);
+ if (transformedDelivered != null)
+ {
+ next.add(transformedDelivered);
+ }
break;
case MessageDeliveryPending:
- evt
- = transformLayer
- .messageDeliveryPending(
- (MessageDeliveredEvent)evt);
+ MessageDeliveredEvent[] evts = transformLayer
+ .messageDeliveryPending(
+ (MessageDeliveredEvent) event);
+ for (MessageDeliveredEvent mde : evts)
+ {
+ if (mde != null)
+ {
+ next.add(mde);
+ }
+ }
break;
case MessageDeliveryFailed:
- evt
- = transformLayer
- .messageDeliveryFailed(
- (MessageDeliveryFailedEvent)evt);
+ MessageDeliveryFailedEvent transformedDeliveryFailed =
+ transformLayer.messageDeliveryFailed(
+ (MessageDeliveryFailedEvent) event);
+ if (transformedDeliveryFailed != null)
+ {
+ next.add(transformedDeliveryFailed);
+ }
break;
case MessageReceived:
- evt
- = transformLayer
- .messageReceived((MessageReceivedEvent)evt);
+ MessageReceivedEvent transformedReceived =
+ transformLayer
+ .messageReceived((MessageReceivedEvent) event);
+ if (transformedReceived != null)
+ {
+ next.add(transformedReceived);
+ }
break;
default:
+ next.add(event);
/*
- * We either have nothing to do or we do not know what
- * to do. Anyway, we'll silence the compiler.
+ * We either have nothing to do or we do not know
+ * what to do. Anyway, we'll silence the compiler.
*/
break;
}
}
+ // Set events for next round of transformations.
+ current.addAll(next);
}
}
- return evt;
+ return current.toArray(new EventObject[current.size()]);
}
/**
diff --git a/src/net/java/sip/communicator/service/protocol/TransformLayer.java b/src/net/java/sip/communicator/service/protocol/TransformLayer.java
index fb48f6c..f9615bd 100644
--- a/src/net/java/sip/communicator/service/protocol/TransformLayer.java
+++ b/src/net/java/sip/communicator/service/protocol/TransformLayer.java
@@ -61,12 +61,13 @@ public interface TransformLayer
* @param evt the MessageDeliveredEvent containing the id of the message
* that has caused the event.
*
- * @return an instance of a (possibly new) <tt>MessageDeliveredEvent</tt>
- * instance containing the transformed message or <tt>null</tt> if the
- * <tt>TransportLayer</tt> has determined that this message event should not
- * be delivered to the upper layers.
+ * @return a number of instances of (possibly new)
+ * <tt>MessageDeliveredEvent</tt> instances containing the transformed
+ * message(s) or an empty array if the <tt>TransportLayer</tt> has
+ * determined that there are no message event that should be delivered to
+ * the upper layers.
*/
- public MessageDeliveredEvent messageDeliveryPending(MessageDeliveredEvent evt);
+ public MessageDeliveredEvent[] messageDeliveryPending(MessageDeliveredEvent evt);
/**
* Called when the underlying implementation has received an indication
diff --git a/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java b/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java
index 035cc9b..11d1e0d 100644
--- a/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java
+++ b/test/net/java/sip/communicator/slick/protocol/generic/PredictableTransformLayer.java
@@ -40,7 +40,7 @@ public class PredictableTransformLayer
.getDestinationContact(), evt.getErrorCode());
}
- public MessageDeliveredEvent messageDeliveryPending(
+ public MessageDeliveredEvent[] messageDeliveryPending(
MessageDeliveredEvent evt)
{
logger
@@ -51,8 +51,9 @@ public class PredictableTransformLayer
"DELIVERY_PENDING");
logger.debug("OUT: " + transformedMessage.getContent());
- return new MessageDeliveredEvent(transformedMessage, evt
- .getDestinationContact(), evt.getTimestamp());
+ return new MessageDeliveredEvent[]
+ { new MessageDeliveredEvent(transformedMessage,
+ evt.getDestinationContact(), evt.getTimestamp()) };
}
public MessageReceivedEvent messageReceived(MessageReceivedEvent evt)