1package eu.siacs.conversations.generator;
2
3import java.text.SimpleDateFormat;
4import java.util.Date;
5import java.util.Locale;
6import java.util.TimeZone;
7
8import net.java.otr4j.OtrException;
9import net.java.otr4j.session.Session;
10import eu.siacs.conversations.entities.Account;
11import eu.siacs.conversations.entities.Conversation;
12import eu.siacs.conversations.entities.Message;
13import eu.siacs.conversations.services.XmppConnectionService;
14import eu.siacs.conversations.xml.Element;
15import eu.siacs.conversations.xmpp.jid.Jid;
16import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
17
18public class MessageGenerator extends AbstractGenerator {
19 public MessageGenerator(XmppConnectionService service) {
20 super(service);
21 }
22
23 private MessagePacket preparePacket(Message message, boolean addDelay) {
24 Conversation conversation = message.getConversation();
25 Account account = conversation.getAccount();
26 MessagePacket packet = new MessagePacket();
27 if (conversation.getMode() == Conversation.MODE_SINGLE) {
28 packet.setTo(message.getCounterpart());
29 packet.setType(MessagePacket.TYPE_CHAT);
30 packet.addChild("markable", "urn:xmpp:chat-markers:0");
31 if (this.mXmppConnectionService.indicateReceived()) {
32 packet.addChild("request", "urn:xmpp:receipts");
33 }
34 } else if (message.getType() == Message.TYPE_PRIVATE) {
35 packet.setTo(message.getCounterpart());
36 packet.setType(MessagePacket.TYPE_CHAT);
37 } else {
38 packet.setTo(message.getCounterpart().toBareJid());
39 packet.setType(MessagePacket.TYPE_GROUPCHAT);
40 }
41 packet.setFrom(account.getJid());
42 packet.setId(message.getUuid());
43 if (addDelay) {
44 addDelay(packet, message.getTimeSent());
45 }
46 return packet;
47 }
48
49 private void addDelay(MessagePacket packet, long timestamp) {
50 final SimpleDateFormat mDateFormat = new SimpleDateFormat(
51 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
52 mDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
53 Element delay = packet.addChild("delay", "urn:xmpp:delay");
54 Date date = new Date(timestamp);
55 delay.setAttribute("stamp", mDateFormat.format(date));
56 }
57
58 public MessagePacket generateOtrChat(Message message) {
59 return generateOtrChat(message, false);
60 }
61
62 public MessagePacket generateOtrChat(Message message, boolean addDelay) {
63 Session otrSession = message.getConversation().getOtrSession();
64 if (otrSession == null) {
65 return null;
66 }
67 MessagePacket packet = preparePacket(message, addDelay);
68 packet.addChild("private", "urn:xmpp:carbons:2");
69 packet.addChild("no-copy", "urn:xmpp:hints");
70 try {
71 packet.setBody(otrSession.transformSending(message.getBody())[0]);
72 return packet;
73 } catch (OtrException e) {
74 return null;
75 }
76 }
77
78 public MessagePacket generateChat(Message message) {
79 return generateChat(message, false);
80 }
81
82 public MessagePacket generateChat(Message message, boolean addDelay) {
83 MessagePacket packet = preparePacket(message, addDelay);
84 packet.setBody(message.getBody());
85 return packet;
86 }
87
88 public MessagePacket generatePgpChat(Message message) {
89 return generatePgpChat(message, false);
90 }
91
92 public MessagePacket generatePgpChat(Message message, boolean addDelay) {
93 MessagePacket packet = preparePacket(message, addDelay);
94 packet.setBody("This is an XEP-0027 encryted message");
95 if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) {
96 packet.addChild("x", "jabber:x:encrypted").setContent(
97 message.getEncryptedBody());
98 } else if (message.getEncryption() == Message.ENCRYPTION_PGP) {
99 packet.addChild("x", "jabber:x:encrypted").setContent(
100 message.getBody());
101 }
102 return packet;
103 }
104
105 public MessagePacket generateNotAcceptable(MessagePacket origin) {
106 MessagePacket packet = generateError(origin);
107 Element error = packet.addChild("error");
108 error.setAttribute("type", "modify");
109 error.setAttribute("code", "406");
110 error.addChild("not-acceptable");
111 return packet;
112 }
113
114 private MessagePacket generateError(MessagePacket origin) {
115 MessagePacket packet = new MessagePacket();
116 packet.setId(origin.getId());
117 packet.setTo(origin.getFrom());
118 packet.setBody(origin.getBody());
119 packet.setType(MessagePacket.TYPE_ERROR);
120 return packet;
121 }
122
123 public MessagePacket confirm(final Account account, final Jid to, final String id) {
124 MessagePacket packet = new MessagePacket();
125 packet.setType(MessagePacket.TYPE_NORMAL);
126 packet.setTo(to);
127 packet.setFrom(account.getJid());
128 Element received = packet.addChild("displayed",
129 "urn:xmpp:chat-markers:0");
130 received.setAttribute("id", id);
131 return packet;
132 }
133
134 public MessagePacket conferenceSubject(Conversation conversation,
135 String subject) {
136 MessagePacket packet = new MessagePacket();
137 packet.setType(MessagePacket.TYPE_GROUPCHAT);
138 packet.setTo(conversation.getJid().toBareJid());
139 Element subjectChild = new Element("subject");
140 subjectChild.setContent(subject);
141 packet.addChild(subjectChild);
142 packet.setFrom(conversation.getAccount().getJid().toBareJid());
143 return packet;
144 }
145
146 public MessagePacket directInvite(final Conversation conversation, final Jid contact) {
147 MessagePacket packet = new MessagePacket();
148 packet.setType(MessagePacket.TYPE_NORMAL);
149 packet.setTo(contact);
150 packet.setFrom(conversation.getAccount().getJid());
151 Element x = packet.addChild("x", "jabber:x:conference");
152 x.setAttribute("jid", conversation.getJid().toBareJid().toString());
153 return packet;
154 }
155
156 public MessagePacket invite(Conversation conversation, Jid contact) {
157 MessagePacket packet = new MessagePacket();
158 packet.setTo(conversation.getJid().toBareJid());
159 packet.setFrom(conversation.getAccount().getJid());
160 Element x = new Element("x");
161 x.setAttribute("xmlns", "http://jabber.org/protocol/muc#user");
162 Element invite = new Element("invite");
163 invite.setAttribute("to", contact.toBareJid().toString());
164 x.addChild(invite);
165 packet.addChild(x);
166 return packet;
167 }
168
169 public MessagePacket received(Account account,
170 MessagePacket originalMessage, String namespace) {
171 MessagePacket receivedPacket = new MessagePacket();
172 receivedPacket.setType(MessagePacket.TYPE_NORMAL);
173 receivedPacket.setTo(originalMessage.getFrom());
174 receivedPacket.setFrom(account.getJid());
175 Element received = receivedPacket.addChild("received", namespace);
176 received.setAttribute("id", originalMessage.getId());
177 return receivedPacket;
178 }
179}