/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* 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 net.java.sip.communicator.impl.protocol.zeroconf;
import java.io.*;
import java.net.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
/**
* Instant messaging functionalities for the Zeroconf protocol.
*
* @author Christian Vincenot
*
*/
public class OperationSetBasicInstantMessagingZeroconfImpl
extends AbstractOperationSetBasicInstantMessaging
{
private static final Logger logger
= Logger.getLogger(OperationSetBasicInstantMessagingZeroconfImpl.class);
/**
* The currently valid persistent presence operation set..
*/
private final OperationSetPersistentPresenceZeroconfImpl opSetPersPresence;
/**
* The protocol provider that created us.
*/
private final ProtocolProviderServiceZeroconfImpl parentProvider;
/**
* Creates an instance of this operation set keeping a reference to the
* parent protocol provider and presence operation set.
*
* @param provider The provider instance that creates us.
* @param opSetPersPresence the currently valid
* OperationSetPersistentPresenceZeroconfImpl instance.
*/
public OperationSetBasicInstantMessagingZeroconfImpl(
ProtocolProviderServiceZeroconfImpl provider,
OperationSetPersistentPresenceZeroconfImpl opSetPersPresence)
{
this.opSetPersPresence = opSetPersPresence;
this.parentProvider = provider;
}
@Override
public Message createMessage(String content, String contentType,
String encoding, String subject)
{
return new MessageZeroconfImpl(content, encoding, contentType,
MessageZeroconfImpl.MESSAGE);
}
/**
* Sends the message to the destination indicated by the
* to contact.
*
* @param to the Contact to send message to
* @param message the Message to send.
* @throws IllegalStateException if the underlying Zeroconf stack is not
* registered and initialized.
* @throws IllegalArgumentException if to is not an instance
* belonging to the underlying implementation.
*/
public void sendInstantMessage(Contact to, Message message) throws
IllegalStateException, IllegalArgumentException
{
if( !(to instanceof ContactZeroconfImpl) )
throw new IllegalArgumentException(
"The specified contact is not a Zeroconf contact."
+ to);
MessageZeroconfImpl msg =
(MessageZeroconfImpl)createMessage(message.getContent());
deliverMessage(msg, (ContactZeroconfImpl)to);
}
/**
* In case the to the to Contact corresponds to another zeroconf
* protocol provider registered with SIP Communicator, we deliver
* the message to them, in case the to Contact represents us, we
* fire a MessageReceivedEvent, and if to is simply
* a contact in our contact list, then we simply echo the message.
*
* @param message the Message the message to deliver.
* @param to the Contact that we should deliver the message to.
*/
private void deliverMessage(Message message, ContactZeroconfImpl to)
{
ClientThread thread = to.getClientThread();
try
{
if (thread == null)
{
Socket sock;
if (logger.isDebugEnabled())
logger.debug("ZEROCONF: Creating a chat connexion to "
+to.getIpAddress()+":"+to.getPort());
sock = new Socket(to.getIpAddress(), to.getPort());
thread = new ClientThread(sock, to.getBonjourService());
thread.setStreamOpen();
thread.setContact(to);
to.setClientThread(thread);
thread.sendHello();
if (to.getClientType() == ContactZeroconfImpl.GAIM)
{
try
{
Thread.sleep(300);
}
catch (InterruptedException ex)
{
logger.error(ex);
}
}
}
//System.out.println("ZEROCONF: Message content => "+
//message.getContent());
thread.sendMessage((MessageZeroconfImpl) message);
fireMessageDelivered(message, to);
}
catch (IOException ex)
{
logger.error(ex);
}
}
/**
* Notifies all registered message listeners that a message has been
* received.
*
* @param message the Message that has been received.
* @param from the Contact that message was received from.
*/
@Override
public void fireMessageReceived(Message message, Contact from)
{
super.fireMessageReceived(message, from);
}
/**
* Determines whether the protocol provider (or the protocol itself) support
* sending and receiving offline messages. Most often this method would
* return true for protocols that support offline messages and false for
* those that don't. It is however possible for a protocol to support these
* messages and yet have a particular account that does not (i.e. feature
* not enabled on the protocol server). In cases like this it is possible
* for this method to return true even when offline messaging is not
* supported, and then have the sendMessage method throw an
* OperationFailedException with code - OFFLINE_MESSAGES_NOT_SUPPORTED.
*
* @return true if the protocol supports offline messages and
* false otherwise.
*/
public boolean isOfflineMessagingSupported()
{
return true;
}
/**
* Determines whether the protocol supports the supplied content type
*
* @param contentType the type we want to check
* @return true if the protocol supports it and
* false otherwise.
*/
public boolean isContentTypeSupported(String contentType)
{
return contentType.equals(DEFAULT_MIME_TYPE);
}
}