mirror of https://github.com/sipwise/jitsi.git
Attempts to fix the problem of writingcyrillic text (it's just an example but it should happen with other encodings as well) and sending ??? instead and receiving cyrillic text which should be displayed correctly but is instead displayed as ???.
parent
d36c3f5d96
commit
7562dd0052
@ -1,168 +1,35 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*
|
||||
* Distributable under LGPL license. See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.protocol.sip;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.*;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* A simple implementation of the <tt>Message</tt> interface for SIP/SIMPLE.
|
||||
*
|
||||
*
|
||||
* @author Benoit Pradelle
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public class MessageSipImpl
|
||||
implements Message
|
||||
extends AbstractMessage
|
||||
{
|
||||
private static final Logger logger = Logger.getLogger(MessageSipImpl.class);
|
||||
|
||||
/**
|
||||
* The content of this message.
|
||||
*/
|
||||
private String textContent = null;
|
||||
|
||||
/**
|
||||
* The content of this message, in raw bytes according to the encoding.
|
||||
*/
|
||||
private byte[] rawContent = null;
|
||||
|
||||
/**
|
||||
* The content type of text. Right now only text/plain is supported.
|
||||
*/
|
||||
private String contentType = null;
|
||||
|
||||
/**
|
||||
* The encoding under which the contennt of this message is encoded.
|
||||
*/
|
||||
private String contentEncoding = null;
|
||||
|
||||
/**
|
||||
* An String uniquely identifying this Message.
|
||||
*/
|
||||
private String messageUID = null;
|
||||
|
||||
/**
|
||||
* The subject of the message if any (may remain null).
|
||||
*/
|
||||
private String subject = null;
|
||||
|
||||
/**
|
||||
* Creates an instance of this Message with the specified parameters.
|
||||
*
|
||||
*
|
||||
* @param content the text content of the message.
|
||||
* @param contentType a MIME string indicating the content type of the
|
||||
* <tt>content</tt> String.
|
||||
* <tt>content</tt> String.
|
||||
* @param contentEncoding a MIME String indicating the content encoding of
|
||||
* the <tt>content</tt> String.
|
||||
* the <tt>content</tt> String.
|
||||
* @param subject the subject of the message or null for empty.
|
||||
*/
|
||||
public MessageSipImpl(String content,
|
||||
String contentType,
|
||||
String contentEncoding,
|
||||
String subject)
|
||||
{
|
||||
this.textContent = content;
|
||||
this.contentType = contentType;
|
||||
this.contentEncoding = contentEncoding;
|
||||
this.subject = subject;
|
||||
|
||||
try
|
||||
{
|
||||
this.rawContent = content.getBytes(contentEncoding);
|
||||
}
|
||||
catch (UnsupportedEncodingException ex)
|
||||
{
|
||||
logger.warn("can't handle the requested encoding", ex);
|
||||
|
||||
this.contentEncoding = Charset.defaultCharset().name();
|
||||
this.rawContent = content.getBytes();
|
||||
}
|
||||
|
||||
//generate the uid
|
||||
this.messageUID = String.valueOf(System.currentTimeMillis())
|
||||
+ String.valueOf(hashCode());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content of this message if representable in text form or
|
||||
* null if this message does not contain text data.
|
||||
*
|
||||
* @return a String containing the content of this message or null if
|
||||
* the message does not contain data representable in text form.
|
||||
*/
|
||||
public String getContent()
|
||||
{
|
||||
return this.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MIME type for the message content.
|
||||
*
|
||||
* @return a String containing the mime type of the message contant.
|
||||
*/
|
||||
public String getContentType()
|
||||
{
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MIME content encoding of this message.
|
||||
*
|
||||
* @return a String indicating the MIME encoding of this message.
|
||||
*/
|
||||
public String getEncoding()
|
||||
{
|
||||
return this.contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a unique identifier of this message.
|
||||
*
|
||||
* @return a String that uniquely represents this message in the scope
|
||||
* of this protocol.
|
||||
*/
|
||||
public String getMessageUID()
|
||||
{
|
||||
return this.messageUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw/binary content of an instant message.
|
||||
*
|
||||
* @return a byte[] array containing message bytes.
|
||||
*/
|
||||
public byte[] getRawData()
|
||||
{
|
||||
return rawContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the content stored in this message.
|
||||
*
|
||||
* @return an int indicating the number of bytes that this message
|
||||
* contains.
|
||||
*/
|
||||
public int getSize()
|
||||
{
|
||||
return rawContent.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subject of this message or null if the message contains no
|
||||
* subject.
|
||||
*
|
||||
* @return the subject of this message or null if the message contains
|
||||
* no subject.
|
||||
*/
|
||||
public String getSubject()
|
||||
public MessageSipImpl(String content, String contentType,
|
||||
String contentEncoding, String subject)
|
||||
{
|
||||
return this.subject;
|
||||
super(content, contentType, contentEncoding, subject);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,143 +1,54 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*
|
||||
*
|
||||
* Distributable under LGPL license. See terms of license at gnu.org.
|
||||
*
|
||||
* MessageSSHImpl.java
|
||||
*
|
||||
*
|
||||
* SSH Suport in SIP Communicator - GSoC' 07 Project
|
||||
*
|
||||
*/
|
||||
|
||||
package net.java.sip.communicator.impl.protocol.ssh;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.*;
|
||||
|
||||
/**
|
||||
* Very simple message implementation for the SSH protocol.
|
||||
*
|
||||
*
|
||||
* @author Shobhit Jindal
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public class MessageSSHImpl
|
||||
implements Message
|
||||
extends AbstractMessage
|
||||
{
|
||||
/**
|
||||
* The actual message content.
|
||||
*/
|
||||
private String textContent = null;
|
||||
|
||||
/**
|
||||
* The content type of the message.
|
||||
* The content type of the message.
|
||||
*/
|
||||
public static String contentType = "text/plain";
|
||||
|
||||
/**
|
||||
* The message encoding. (UTF8 if null).
|
||||
*/
|
||||
private String contentEncoding = null;
|
||||
|
||||
/**
|
||||
* A String uniquely identifying the message
|
||||
*/
|
||||
private String messageUID = null;
|
||||
|
||||
/**
|
||||
* The subject of the message. (most often is null)
|
||||
*/
|
||||
private String subject = null;
|
||||
|
||||
/**
|
||||
* Creates a message instance according to the specified parameters.
|
||||
*
|
||||
*
|
||||
* @param content the message body
|
||||
* @param contentType message content type or null for text/plain
|
||||
* @param contentEncoding message encoding or null for UTF8
|
||||
* @param subject the subject of the message or null for no subject.
|
||||
*/
|
||||
public MessageSSHImpl(String content,
|
||||
String contentType,
|
||||
String contentEncoding,
|
||||
String subject)
|
||||
public MessageSSHImpl(String content, String contentType,
|
||||
String contentEncoding, String subject)
|
||||
{
|
||||
this.textContent = content;
|
||||
this.contentType = contentType;
|
||||
this.contentEncoding = contentEncoding;
|
||||
this.subject = subject;
|
||||
|
||||
//generate the uid
|
||||
this.messageUID = String.valueOf(System.currentTimeMillis())
|
||||
+ String.valueOf(hashCode());
|
||||
super(content, null, contentEncoding, subject);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message body.
|
||||
*
|
||||
* @return the message content.
|
||||
*/
|
||||
public String getContent()
|
||||
{
|
||||
return textContent;
|
||||
MessageSSHImpl.contentType = contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the content of this message.
|
||||
*
|
||||
*
|
||||
* @return the type of the content of this message.
|
||||
*/
|
||||
public String getContentType()
|
||||
{
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoding used for the message content.
|
||||
*
|
||||
* @return the encoding of the message body.
|
||||
*/
|
||||
public String getEncoding()
|
||||
{
|
||||
return contentEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* A string uniquely identifying the message.
|
||||
*
|
||||
* @return a <tt>String</tt> uniquely identifying the message.
|
||||
*/
|
||||
public String getMessageUID()
|
||||
{
|
||||
return messageUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message body in a binary form.
|
||||
*
|
||||
* @return a <tt>byte[]</tt> representation of the message body.
|
||||
*/
|
||||
public byte[] getRawData()
|
||||
{
|
||||
return getContent().getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of this message.
|
||||
*
|
||||
* @return the length of this message.
|
||||
*/
|
||||
public int getSize()
|
||||
{
|
||||
return getContent().length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message subject.
|
||||
*
|
||||
* @return the message subject.
|
||||
*/
|
||||
public String getSubject()
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license. See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.service.protocol;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.*;
|
||||
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* Represents a default implementation of {@link Message} in order to make it
|
||||
* easier for implementers to provide complete solutions while focusing on
|
||||
* implementation-specific details.
|
||||
*
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public abstract class AbstractMessage
|
||||
implements Message
|
||||
{
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(AbstractMessage.class);
|
||||
|
||||
private static boolean equals(String a, String b)
|
||||
{
|
||||
return (a == null) ? (b == null) : a.equals(b);
|
||||
}
|
||||
|
||||
private String content;
|
||||
|
||||
private final String contentType;
|
||||
|
||||
private String encoding;
|
||||
|
||||
private final String messageUID;
|
||||
|
||||
/**
|
||||
* The content of this message, in raw bytes according to the encoding.
|
||||
*/
|
||||
private byte[] rawData;
|
||||
|
||||
private final String subject;
|
||||
|
||||
protected AbstractMessage(String content, String contentType,
|
||||
String encoding, String subject)
|
||||
{
|
||||
this.contentType = contentType;
|
||||
this.subject = subject;
|
||||
|
||||
setEncoding(encoding);
|
||||
setContent(content);
|
||||
|
||||
this.messageUID = createMessageUID();
|
||||
}
|
||||
|
||||
protected AbstractMessage(String content, String contentType,
|
||||
String encoding, String subject, String messageUID)
|
||||
{
|
||||
this.contentType = contentType;
|
||||
this.subject = subject;
|
||||
|
||||
setEncoding(encoding);
|
||||
setContent(content);
|
||||
|
||||
this.messageUID = messageUID;
|
||||
}
|
||||
|
||||
protected String createMessageUID()
|
||||
{
|
||||
return String.valueOf(System.currentTimeMillis())
|
||||
+ String.valueOf(hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content of this message if representable in text form or null
|
||||
* if this message does not contain text data.
|
||||
* <p>
|
||||
* The implementation is final because it caches the raw data of the
|
||||
* content.
|
||||
* </p>
|
||||
*
|
||||
* @return a String containing the content of this message or null if the
|
||||
* message does not contain data representable in text form.
|
||||
*/
|
||||
public final String getContent()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see net.java.sip.communicator.service.protocol.Message#getContentType()
|
||||
*/
|
||||
public String getContentType()
|
||||
{
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MIME content encoding of this message.
|
||||
* <p>
|
||||
* The implementation is final because of the presumption it can set the
|
||||
* encoding.
|
||||
* </p>
|
||||
*
|
||||
* @return a String indicating the MIME encoding of this message.
|
||||
*/
|
||||
public final String getEncoding()
|
||||
{
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see net.java.sip.communicator.service.protocol.Message#getMessageUID()
|
||||
*/
|
||||
public String getMessageUID()
|
||||
{
|
||||
return messageUID;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see net.java.sip.communicator.service.protocol.Message#getRawData()
|
||||
*/
|
||||
public byte[] getRawData()
|
||||
{
|
||||
if (rawData == null)
|
||||
{
|
||||
String content = getContent();
|
||||
String encoding = getEncoding();
|
||||
boolean useDefaultEncoding = true;
|
||||
if (encoding != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
rawData = content.getBytes(encoding);
|
||||
useDefaultEncoding = false;
|
||||
}
|
||||
catch (UnsupportedEncodingException ex)
|
||||
{
|
||||
logger.warn(
|
||||
"Failed to get raw data from content using encoding "
|
||||
+ encoding, ex);
|
||||
|
||||
// We'll use the default encoding
|
||||
}
|
||||
}
|
||||
if (useDefaultEncoding)
|
||||
{
|
||||
setEncoding(Charset.defaultCharset().name());
|
||||
rawData = content.getBytes();
|
||||
}
|
||||
}
|
||||
return rawData;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see net.java.sip.communicator.service.protocol.Message#getSize()
|
||||
*/
|
||||
public int getSize()
|
||||
{
|
||||
return getRawData().length;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see net.java.sip.communicator.service.protocol.Message#getSubject()
|
||||
*/
|
||||
public String getSubject()
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
|
||||
protected void setContent(String content)
|
||||
{
|
||||
if (equals(this.content, content) == false)
|
||||
{
|
||||
this.content = content;
|
||||
this.rawData = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setEncoding(String encoding)
|
||||
{
|
||||
if (equals(this.encoding, encoding) == false)
|
||||
{
|
||||
this.encoding = encoding;
|
||||
this.rawData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license. See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.service.protocol;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.*;
|
||||
|
||||
import net.java.sip.communicator.service.protocol.event.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
/**
|
||||
* Represents a default implementation of
|
||||
* {@link OperationSetBasicInstantMessaging} in order to make it easier for
|
||||
* implementers to provide complete solutions while focusing on
|
||||
* implementation-specific details.
|
||||
*
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public abstract class AbstractOperationSetBasicInstantMessaging
|
||||
implements OperationSetBasicInstantMessaging
|
||||
{
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(AbstractOperationSetBasicInstantMessaging.class);
|
||||
|
||||
/**
|
||||
* A list of listeners registered for message events.
|
||||
*/
|
||||
private final List<MessageListener> messageListeners =
|
||||
new LinkedList<MessageListener>();
|
||||
|
||||
/**
|
||||
* Registers a MessageListener with this operation set so that it gets
|
||||
* notifications of successful message delivery, failure or reception of
|
||||
* incoming messages..
|
||||
*
|
||||
* @param listener the <tt>MessageListener</tt> to register.
|
||||
*/
|
||||
public void addMessageListener(MessageListener listener)
|
||||
{
|
||||
synchronized (messageListeners)
|
||||
{
|
||||
if (!messageListeners.contains(listener))
|
||||
{
|
||||
messageListeners.add(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Message instance for sending arbitrary MIME-encoding content.
|
||||
*
|
||||
* @param content content value
|
||||
* @param contentType the MIME-type for <tt>content</tt>
|
||||
* @param encoding encoding used for <tt>content</tt>
|
||||
* @param subject a <tt>String</tt> subject or <tt>null</tt> for now
|
||||
* subject.
|
||||
* @return the newly created message.
|
||||
*/
|
||||
public Message createMessage(byte[] content, String contentType,
|
||||
String encoding, String subject)
|
||||
{
|
||||
String contentAsString = null;
|
||||
boolean useDefaultEncoding = true;
|
||||
if (encoding != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
contentAsString = new String(content, encoding);
|
||||
useDefaultEncoding = false;
|
||||
}
|
||||
catch (UnsupportedEncodingException ex)
|
||||
{
|
||||
logger.warn("Failed to decode content using encoding "
|
||||
+ encoding, ex);
|
||||
|
||||
// We'll use the default encoding.
|
||||
}
|
||||
}
|
||||
if (useDefaultEncoding)
|
||||
{
|
||||
encoding = Charset.defaultCharset().name();
|
||||
contentAsString = new String(content);
|
||||
}
|
||||
|
||||
return createMessage(contentAsString, contentType, encoding, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Message instance for sending a simple text messages with default
|
||||
* (text/plain) content type and encoding.
|
||||
*
|
||||
* @param messageText the string content of the message.
|
||||
* @return Message the newly created message
|
||||
*/
|
||||
public Message createMessage(String messageText)
|
||||
{
|
||||
return createMessage(messageText, DEFAULT_MIME_TYPE,
|
||||
DEFAULT_MIME_ENCODING, null);
|
||||
}
|
||||
|
||||
public abstract Message createMessage(String content, String contentType,
|
||||
String encoding, String subject);
|
||||
|
||||
/**
|
||||
* Notifies all registered message listeners that a message has been
|
||||
* delivered successfully to its addressee..
|
||||
*
|
||||
* @param message the <tt>Message</tt> that has been delivered.
|
||||
* @param to the <tt>Contact</tt> that <tt>message</tt> was delivered to.
|
||||
*/
|
||||
protected void fireMessageDelivered(Message message, Contact to)
|
||||
{
|
||||
fireMessageEvent(new MessageDeliveredEvent(message, to, new Date()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delivers the specified event to all registered message listeners.
|
||||
*
|
||||
* @param evt the <tt>EventObject</tt> that we'd like delivered to all
|
||||
* registered message listeners.
|
||||
*/
|
||||
protected void fireMessageEvent(EventObject evt)
|
||||
{
|
||||
Collection<MessageListener> listeners = null;
|
||||
synchronized (this.messageListeners)
|
||||
{
|
||||
listeners = new ArrayList<MessageListener>(this.messageListeners);
|
||||
}
|
||||
|
||||
logger.debug("Dispatching Message Listeners=" + listeners.size()
|
||||
+ " evt=" + evt);
|
||||
|
||||
for (Iterator<MessageListener> listenerIter = listeners.iterator(); listenerIter
|
||||
.hasNext();)
|
||||
{
|
||||
MessageListener listener = listenerIter.next();
|
||||
|
||||
if (evt instanceof MessageDeliveredEvent)
|
||||
{
|
||||
listener.messageDelivered((MessageDeliveredEvent) evt);
|
||||
}
|
||||
else if (evt instanceof MessageReceivedEvent)
|
||||
{
|
||||
listener.messageReceived((MessageReceivedEvent) evt);
|
||||
}
|
||||
else if (evt instanceof MessageDeliveryFailedEvent)
|
||||
{
|
||||
listener
|
||||
.messageDeliveryFailed((MessageDeliveryFailedEvent) evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all registered message listeners that a message has been
|
||||
* received.
|
||||
*
|
||||
* @param message the <tt>Message</tt> that has been received.
|
||||
* @param from the <tt>Contact</tt> that <tt>message</tt> was received from.
|
||||
*/
|
||||
protected void fireMessageReceived(Message message, Contact from)
|
||||
{
|
||||
fireMessageEvent(new MessageReceivedEvent(message, from, new Date()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters <tt>listener</tt> so that it won't receive any further
|
||||
* notifications upon successful message delivery, failure or reception of
|
||||
* incoming messages..
|
||||
*
|
||||
* @param listener the <tt>MessageListener</tt> to unregister.
|
||||
*/
|
||||
public void removeMessageListener(MessageListener listener)
|
||||
{
|
||||
synchronized (messageListeners)
|
||||
{
|
||||
messageListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue