/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License,
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.xabber.android.data.message;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.xabber.android.data.log.LogManager;
import com.xabber.android.data.database.messagerealm.MessageItem;
import com.xabber.android.data.entity.AccountJid;
import com.xabber.android.data.entity.UserJid;
import com.xabber.android.data.extension.muc.MUCManager;
import com.xabber.android.data.extension.otr.OTRManager;
import com.xabber.android.data.extension.otr.OTRUnencryptedException;
import net.java.otr4j.OtrException;
import org.greenrobot.eventbus.EventBus;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Message.Type;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smackx.delay.packet.DelayInformation;
import org.jivesoftware.smackx.muc.packet.MUCUser;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Domainpart;
import org.jxmpp.jid.parts.Resourcepart;
import java.util.Date;
/**
* Represents normal chat.
*
* @author alexander.ivanov
*/
public class RegularChat extends AbstractChat {
/**
* Resource used for contact.
*/
private Resourcepart resource;
RegularChat(AccountJid account, UserJid user, boolean isPrivateMucChat) {
super(account, user, isPrivateMucChat);
resource = null;
}
public Resourcepart getResource() {
return resource;
}
@NonNull
@Override
public Jid getTo() {
if (resource == null
|| (MUCManager.getInstance().hasRoom(account, user.getJid().asEntityBareJidIfPossible()) && getType() != Message.Type.groupchat )) {
return user.getJid();
} else {
return JidCreate.fullFrom(user.getJid().asEntityBareJidIfPossible(), resource);
}
}
@Override
public Type getType() {
return Type.chat;
}
// @Override
// protected boolean canSendMessage() {
// if (super.canSendMessage()) {
// if (SettingsManager.securityOtrMode() != SecurityOtrMode.required)
// return true;
// SecurityLevel securityLevel = OTRManager.getInstance()
// .getSecurityLevel(account, user);
// if (securityLevel != SecurityLevel.plain)
// return true;
// try {
// OTRManager.getInstance().startSession(account, user);
// } catch (NetworkException e) {
// }
// }
// return false;
// }
@Override
protected String prepareText(String text) {
text = super.prepareText(text);
try {
return OTRManager.getInstance().transformSending(account, user, text);
} catch (OtrException e) {
LogManager.exception(this, e);
return null;
}
}
@Override
protected MessageItem createNewMessageItem(String text) {
return createMessageItem(
null,
text,
null,
null,
false,
false,
false,
false,
null);
}
@Override
protected boolean onPacket(UserJid bareAddress, Stanza packet) {
if (!super.onPacket(bareAddress, packet))
return false;
final Resourcepart resource = packet.getFrom().getResourceOrNull();
if (packet instanceof Presence) {
final Presence presence = (Presence) packet;
if (this.resource != null && presence.getType() == Presence.Type.unavailable
&& resource != null && this.resource.equals(resource)) {
this.resource = null;
}
if (presence.getType() == Presence.Type.unavailable) {
OTRManager.getInstance().onContactUnAvailable(account, user);
}
} else if (packet instanceof Message) {
final Message message = (Message) packet;
if (message.getType() == Message.Type.error)
return true;
MUCUser mucUser = MUCUser.from(message);
if (mucUser != null && mucUser.getInvite() != null)
return true;
String text = message.getBody();
if (text == null)
return true;
String thread = message.getThread();
updateThreadId(thread);
boolean unencrypted = false;
try {
text = OTRManager.getInstance().transformReceiving(account, user, text);
} catch (OtrException e) {
if (e.getCause() instanceof OTRUnencryptedException) {
text = ((OTRUnencryptedException) e.getCause()).getText();
unencrypted = true;
} else {
LogManager.exception(this, e);
// Invalid message received.
return true;
}
}
// System message received.
if (text == null || text.trim().equals(""))
return true;
if (resource != null && !resource.equals(Resourcepart.EMPTY)) {
this.resource = resource;
}
createAndSaveNewMessage(
resource,
text,
null,
getDelayStamp(message),
true,
true,
unencrypted,
isOfflineMessage(account.getFullJid().getDomain(), packet),
packet.getStanzaId());
EventBus.getDefault().post(new NewIncomingMessageEvent(account, user));
}
return true;
}
/**
* @return Whether message was delayed by server.
*/
public static boolean isOfflineMessage(Domainpart server, Stanza stanza) {
DelayInformation delayInformation = DelayInformation.from(stanza);
return delayInformation != null
&& TextUtils.equals(delayInformation.getFrom(), server);
}
public static Date getDelayStamp(Message message) {
DelayInformation delayInformation = DelayInformation.from(message);
if (delayInformation != null) {
return delayInformation.getStamp();
} else {
return null;
}
}
@Override
protected void onComplete() {
super.onComplete();
sendMessages();
}
}