/** * Parses the given date string in different ways and returns the date that * lies in the past and/or is nearest to the current date-time. * * @param stampString date in string representation * @return the parsed date */ private Date handleDateWithMissingLeadingZeros(String stampString) { Calendar now = new GregorianCalendar(); Calendar xep91 = null; Calendar xep91Fallback = null; xep91 = parseXEP91Date(stampString, DelayInformation.XEP_0091_UTC_FORMAT); xep91Fallback = parseXEP91Date(stampString, XEP_0091_UTC_FALLBACK_FORMAT); List<Calendar> dates = filterDatesBefore(now, xep91, xep91Fallback); if (!dates.isEmpty()) { return determineNearestDate(now, dates).getTime(); } return null; }
public static String getSendDate(final Message msg, final Locale loc) { for (final Iterator iter = msg.getExtensions().iterator(); iter.hasNext();) { final PacketExtension extension = (PacketExtension) iter.next(); if (extension.getNamespace().equals("jabber:x:delay")) { final DelayInformation delayInfo = (DelayInformation) extension; final Date date = delayInfo.getStamp(); // why does formatter with this method return a time in the afternoon // like 03:24 instead of 15:24 like formatTime does?? return Formatter.getInstance(loc).formatDateAndTime(date); } } // if no delay time now is returned // return Formatter.getInstance(locale).formatTime(new Date()); final Long receiveTime = (Long) msg.getProperty("receiveTime"); final Date d = new Date(); d.setTime(receiveTime.longValue()); return Formatter.getInstance(loc).formatTime(d); }
/** * Parses the given date string in different ways and returns the date that * lies in the past and/or is nearest to the current date-time. * * @param stampString * date in string representation * @return the parsed date */ private Date handleDateWithMissingLeadingZeros(String stampString) { Calendar now = new GregorianCalendar(); Calendar xep91 = null; Calendar xep91Fallback = null; xep91 = parseXEP91Date(stampString, DelayInformation.XEP_0091_UTC_FORMAT); xep91Fallback = parseXEP91Date(stampString, XEP_0091_UTC_FALLBACK_FORMAT); List<Calendar> dates = filterDatesBefore(now, xep91, xep91Fallback); if (!dates.isEmpty()) { return determineNearestDate(now, dates).getTime(); } return null; }
public PacketExtension parseExtension(XmlPullParser parser) throws Exception { String stampString = (parser.getAttributeValue("", "stamp")); Date stamp = null; try { stamp = StringUtils.parseDate(stampString); } catch (ParseException parseExc) { /* * if date could not be parsed but XML is valid, don't shutdown * connection by throwing an exception instead set timestamp to epoch * so that it is obviously wrong. */ if (stamp == null) { stamp = new Date(0); } } DelayInformation delayInformation = new DelayInformation(stamp); delayInformation.setFrom(parser.getAttributeValue("", "from")); String reason = parser.nextText(); /* * parser.nextText() returns empty string if there is no reason. * DelayInformation API specifies that null should be returned in that * case. */ reason = "".equals(reason) ? null : reason; delayInformation.setReason(reason); return delayInformation; }
public void sendOfflineMessages() { Cursor cursor = mContentResolver.query(ChatProvider.CONTENT_URI, SEND_OFFLINE_PROJECTION, SEND_OFFLINE_SELECTION, null, null); final int _ID_COL = cursor.getColumnIndexOrThrow(ChatConstants._ID); final int JID_COL = cursor.getColumnIndexOrThrow(ChatConstants.JID); final int MSG_COL = cursor.getColumnIndexOrThrow(ChatConstants.MESSAGE); final int TS_COL = cursor.getColumnIndexOrThrow(ChatConstants.DATE); final int PACKETID_COL = cursor.getColumnIndexOrThrow(ChatConstants.PACKET_ID); ContentValues mark_sent = new ContentValues(); mark_sent.put(ChatConstants.DELIVERY_STATUS, ChatConstants.DS_SENT_OR_READ); while (cursor.moveToNext()) { int _id = cursor.getInt(_ID_COL); String toJID = cursor.getString(JID_COL); String message = cursor.getString(MSG_COL); String packetID = cursor.getString(PACKETID_COL); long ts = cursor.getLong(TS_COL); Log.d(TAG, "sendOfflineMessages: " + toJID + " > " + message); final Message newMessage = new Message(toJID, Message.Type.chat); newMessage.setBody(message); DelayInformation delay = new DelayInformation(new Date(ts)); newMessage.addExtension(delay); newMessage.addExtension(new DelayInfo(delay)); newMessage.addExtension(new DeliveryReceiptRequest()); if ((packetID != null) && (packetID.length() > 0)) { newMessage.setPacketID(packetID); } else { packetID = newMessage.getPacketID(); mark_sent.put(ChatConstants.PACKET_ID, packetID); } Uri rowuri = Uri.parse("content://" + ChatProvider.AUTHORITY + "/" + ChatProvider.TABLE_NAME + "/" + _id); mContentResolver.update(rowuri, mark_sent, null, null); mXMPPConnection.sendPacket(newMessage); // must be after marking delivered, otherwise it may override the SendFailListener } cursor.close(); }
public void processPacket(final Packet packet) { SwingUtilities.invokeLater(new Runnable() { public void run() { try { final Message message = (Message)packet; // Do not handle errors or offline messages final DelayInformation offlineInformation = (DelayInformation)message.getExtension("x", "jabber:x:delay"); if (offlineInformation != null || message.getError() != null) { return; } boolean broadcast = message.getProperty("broadcast") != null; if ((broadcast || message.getType() == Message.Type.normal || message.getType() == Message.Type.headline) && message.getBody() != null) { showAlert((Message)packet); } else { String host = SparkManager.getSessionManager().getServerAddress(); String from = packet.getFrom() != null ? packet.getFrom() : ""; if (host.equalsIgnoreCase(from) || !ModelUtil.hasLength(from)) { showAlert((Message)packet); } } } catch (Exception e) { Log.error(e); } } }); }
public void messageReceived(ChatRoom room, Message message) { // Do not play sounds on history updates. DelayInformation inf = (DelayInformation)message.getExtension("x", "jabber:x:delay"); if (inf != null) { return; } SoundPreferences preferences = soundPreference.getPreferences(); if (preferences.isPlayIncomingSound()) { File incomingFile = new File(preferences.getIncomingSound()); SparkManager.getSoundManager().playClip(incomingFile); } }
public void testDiscussionHistory() { try { // User1 sends some messages to the room muc.sendMessage("Message 1"); muc.sendMessage("Message 2"); // Wait 5 seconds before sending the last message Thread.sleep(5000); muc.sendMessage("Message 3"); // User2 joins the room requesting to receive the messages of the last 2 seconds. MultiUserChat muc2 = new MultiUserChat(getConnection(1), room); DiscussionHistory history = new DiscussionHistory(); history.setSeconds(2); muc2.join("testbot2", null, history, SmackConfiguration.getPacketReplyTimeout()); Message msg; // Get first historic message msg = muc2.nextMessage(1000); assertNotNull("First message is null", msg); DelayInformation delay = DelayInformationManager.getDelayInformation(msg); assertNotNull("Message contains no delay information", delay); SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss"); UTC_FORMAT.setTimeZone(TimeZone.getDefault()); System.out.println(UTC_FORMAT.format(delay.getStamp())); assertEquals("Body of first message is incorrect", "Message 3", msg.getBody()); // Try to get second historic message msg = muc2.nextMessage(1000); assertNull("Second message is not null", msg); // User3 joins the room requesting to receive the last 2 messages. MultiUserChat muc3 = new MultiUserChat(getConnection(2), room); history = new DiscussionHistory(); history.setMaxStanzas(2); muc3.join("testbot3", null, history, SmackConfiguration.getPacketReplyTimeout()); // Get first historic message msg = muc3.nextMessage(1000); assertNotNull("First message is null", msg); assertEquals("Body of first message is incorrect", "Message 2", msg.getBody()); // Get second historic message msg = muc3.nextMessage(1000); assertNotNull("Second message is null", msg); assertEquals("Body of second message is incorrect", "Message 3", msg.getBody()); // Try to get third historic message msg = muc3.nextMessage(1000); assertNull("Third message is not null", msg); // User2 leaves the room muc2.leave(); // User3 leaves the room muc3.leave(); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }
public PacketExtension parseExtension(XmlPullParser parser) throws Exception { String stampString = (parser.getAttributeValue("", "stamp")); Date stamp = null; DateFormat format = null; for (String regexp : formats.keySet()) { if (stampString.matches(regexp)) { try { format = formats.get(regexp); synchronized (format) { stamp = format.parse(stampString); } } catch (ParseException e) { // do nothing, format is still set } // break because only one regexp can match break; } } /* * if date is in XEP-0091 format handle ambiguous dates missing the * leading zero in month and day */ if (format == DelayInformation.XEP_0091_UTC_FORMAT && stampString.split("T")[0].length() < 8) { stamp = handleDateWithMissingLeadingZeros(stampString); } /* * if date could not be parsed but XML is valid, don't shutdown * connection by throwing an exception instead set timestamp to current * time */ if (stamp == null) { stamp = new Date(); } DelayInformation delayInformation = new DelayInformation(stamp); delayInformation.setFrom(parser.getAttributeValue("", "from")); String reason = parser.nextText(); /* * parser.nextText() returns empty string if there is no reason. * DelayInformation API specifies that null should be returned in that * case. */ reason = "".equals(reason) ? null : reason; delayInformation.setReason(reason); return delayInformation; }
@Override public PacketExtension parseExtension(XmlPullParser parser) throws Exception { return new DelayInfo((DelayInformation)super.parseExtension(parser)); }
/***************** start 发送离线消息 ***********************/ public void sendOfflineMessages() { Cursor cursor = mContentResolver.query(ChatProvider.CONTENT_URI, SEND_OFFLINE_PROJECTION, SEND_OFFLINE_SELECTION, null, null);// 查询数据库获取离线消息游标 final int _ID_COL = cursor.getColumnIndexOrThrow(ChatConstants._ID); final int JID_COL = cursor.getColumnIndexOrThrow(ChatConstants.JID); final int MSG_COL = cursor.getColumnIndexOrThrow(ChatConstants.MESSAGE); final int TS_COL = cursor.getColumnIndexOrThrow(ChatConstants.DATE); final int PACKETID_COL = cursor .getColumnIndexOrThrow(ChatConstants.PACKET_ID); ContentValues mark_sent = new ContentValues(); mark_sent.put(ChatConstants.DELIVERY_STATUS, ChatConstants.DS_SENT_OR_READ); while (cursor.moveToNext()) {// 遍历之后将离线消息发出 int _id = cursor.getInt(_ID_COL); String toJID = cursor.getString(JID_COL); String message = cursor.getString(MSG_COL); String packetID = cursor.getString(PACKETID_COL); long ts = cursor.getLong(TS_COL); L.d("sendOfflineMessages: " + toJID + " > " + message); final Message newMessage = new Message(toJID, Message.Type.chat); newMessage.setBody(message); DelayInformation delay = new DelayInformation(new Date(ts)); newMessage.addExtension(delay); newMessage.addExtension(new DelayInfo(delay)); newMessage.addExtension(new DeliveryReceiptRequest()); if ((packetID != null) && (packetID.length() > 0)) { newMessage.setPacketID(packetID); } else { packetID = newMessage.getPacketID(); mark_sent.put(ChatConstants.PACKET_ID, packetID); } Uri rowuri = Uri.parse("content://" + ChatProvider.AUTHORITY + "/" + ChatProvider.TABLE_NAME + "/" + _id); // 将消息标记为已发送再调用发送,因为,假设此消息又未发送成功,有SendFailListener重新标记消息 mContentResolver.update(rowuri, mark_sent, null, null); mXMPPConnection.sendPacket(newMessage); // must be after marking // delivered, otherwise it // may override the // SendFailListener } cursor.close(); }
@Override public PacketExtension parseExtension(XmlPullParser parser) throws Exception { return new DelayInfo((DelayInformation) super.parseExtension(parser)); }
public void listenForMessages(final XMPPConnection con, MultiUserChat chat) { PacketListener packetListener = new PacketListener() { public void processPacket(Packet packet) { Message message = (Message)packet; if (ModelUtil.hasLength(message.getBody())) { ChatMessage chatMessage = new ChatMessage(message); String from = StringUtils.parseResource(message.getFrom()); if (from.equalsIgnoreCase(nickname)) { return; } String body = message.getBody(); chatMessage.setFrom(from); chatMessage.setBody(body); DelayInformation inf = (DelayInformation)message.getExtension("x", "jabber:x:delay"); Date sentDate; if (inf != null) { sentDate = inf.getStamp(); } else { sentDate = new Date(); } SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("MM/dd/yy h:mm"); String dateToInsert = "[" + DATE_FORMATTER.format(sentDate) + "] "; chatMessage.setDate(dateToInsert); messageList.add(chatMessage); updateTranscript(chatMessage.getFrom(), chatMessage.getBody()); } else { // Check if cobrowsing ChatMessage me = new ChatMessage(message); messageList.add(me); } } }; groupChat.addMessageListener(packetListener); }
/***************** start 发送离线消息 ***********************/ public void sendOfflineMessages() { Cursor cursor = mContentResolver.query(ChatProvider.CONTENT_URI, SEND_OFFLINE_PROJECTION, SEND_OFFLINE_SELECTION, null, null);// 查询数据库获取离线消息游标 final int _ID_COL = cursor.getColumnIndexOrThrow(ChatConstants._ID); final int JID_COL = cursor.getColumnIndexOrThrow(ChatConstants.JID); final int MSG_COL = cursor.getColumnIndexOrThrow(ChatConstants.MESSAGE); final int TS_COL = cursor.getColumnIndexOrThrow(ChatConstants.DATE); final int PACKETID_COL = cursor .getColumnIndexOrThrow(ChatConstants.PACKET_ID); ContentValues mark_sent = new ContentValues(); mark_sent.put(ChatConstants.DELIVERY_STATUS, ChatConstants.DS_SENT_OR_READ); while (cursor.moveToNext()) {// 遍历之后将离线消息发出 int _id = cursor.getInt(_ID_COL); String toJID = cursor.getString(JID_COL); String message = cursor.getString(MSG_COL); String packetID = cursor.getString(PACKETID_COL); long ts = cursor.getLong(TS_COL); AppLogger.d("sendOfflineMessages: " + toJID + " > " + message); final Message newMessage = new Message(toJID, Message.Type.chat); newMessage.setBody(message); DelayInformation delay = new DelayInformation(new Date(ts)); newMessage.addExtension(delay); newMessage.addExtension(new DelayInfo(delay)); newMessage.addExtension(new DeliveryReceiptRequest()); if ((packetID != null) && (packetID.length() > 0)) { newMessage.setPacketID(packetID); } else { packetID = newMessage.getPacketID(); mark_sent.put(ChatConstants.PACKET_ID, packetID); } Uri rowuri = Uri.parse("content://" + ChatProvider.AUTHORITY + "/" + ChatProvider.TABLE_NAME + "/" + _id); // 将消息标记为已发送再调用发送,因为,假设此消息又未发送成功,有SendFailListener重新标记消息 mContentResolver.update(rowuri, mark_sent, null, null); mXMPPConnection.sendPacket(newMessage); // must be after marking // delivered, otherwise it // may override the // SendFailListener } cursor.close(); }
public void testDiscussionHistory() { try { // User1 sends some messages to the room muc.sendMessage("Message 1"); muc.sendMessage("Message 2"); // Wait 5 seconds before sending the last message Thread.sleep(5000); muc.sendMessage("Message 3"); // User2 joins the room requesting to receive the messages of the last 2 seconds. MultiUserChat muc2 = new MultiUserChat(getConnection(1), room); DiscussionHistory history = new DiscussionHistory(); history.setSeconds(2); muc2.join("testbot2", null, history, SmackConfiguration.getPacketReplyTimeout()); Message msg; // Get first historic message msg = muc2.nextMessage(1000); assertNotNull("First message is null", msg); DelayInformation delay = (DelayInformation) msg.getExtension("x", "jabber:x:delay"); assertNotNull("Message contains no delay information", delay); SimpleDateFormat UTC_FORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss"); UTC_FORMAT.setTimeZone(TimeZone.getDefault()); System.out.println(UTC_FORMAT.format(delay.getStamp())); assertEquals("Body of first message is incorrect", "Message 3", msg.getBody()); // Try to get second historic message msg = muc2.nextMessage(1000); assertNull("Second message is not null", msg); // User3 joins the room requesting to receive the last 2 messages. MultiUserChat muc3 = new MultiUserChat(getConnection(2), room); history = new DiscussionHistory(); history.setMaxStanzas(2); muc3.join("testbot3", null, history, SmackConfiguration.getPacketReplyTimeout()); // Get first historic message msg = muc3.nextMessage(1000); assertNotNull("First message is null", msg); assertEquals("Body of first message is incorrect", "Message 2", msg.getBody()); // Get second historic message msg = muc3.nextMessage(1000); assertNotNull("Second message is null", msg); assertEquals("Body of second message is incorrect", "Message 3", msg.getBody()); // Try to get third historic message msg = muc3.nextMessage(1000); assertNull("Third message is not null", msg); // User2 leaves the room muc2.leave(); // User3 leaves the room muc3.leave(); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }
/** * Construct a message from a smack message packet. * @param smackMsg Smack message packet */ public Message(final org.jivesoftware.smack.packet.Message smackMsg) { this(smackMsg.getTo()); switch (smackMsg.getType()) { case chat: mType = MSG_TYPE_CHAT; break; case groupchat: mType = MSG_TYPE_GROUP_CHAT; break; case normal: mType = MSG_TYPE_NORMAL; break; // TODO gerer les message de type error // this a little work around waiting for a better handling of error // messages case error: mType = MSG_TYPE_ERROR; break; default: mType = MSG_TYPE_NORMAL; break; } this.mFrom = smackMsg.getFrom(); //TODO better handling of error messages if (mType == MSG_TYPE_ERROR) { XMPPError er = smackMsg.getError(); String msg = er.getMessage(); if (msg != null) mBody = msg; else mBody = er.getCondition(); } else { mBody = smackMsg.getBody(); mSubject = smackMsg.getSubject(); mThread = smackMsg.getThread(); } PacketExtension pTime = smackMsg.getExtension("delay", "urn:xmpp:delay"); if (pTime instanceof DelayInformation) { mTimestamp = ((DelayInformation) pTime).getStamp(); } else { mTimestamp = new Date(); } }
/** * Create and insert a message from the current user. * * @param nickname the nickname of the current user. * @param message the message to insert. * @param foreground the color to use for the message foreground. * @param background the color to use for the message background. */ public void insertMessage(String nickname, Message message, Color foreground, Color background) { // Check interceptors. for (TranscriptWindowInterceptor interceptor : SparkManager.getChatManager().getTranscriptWindowInterceptors()) { boolean handled = interceptor.isMessageIntercepted(this, nickname, message); if (handled) { // Do nothing. return; } } String body = message.getBody(); try { DelayInformation inf = (DelayInformation)message.getExtension("x", "jabber:x:delay"); Date sentDate; if (inf != null) { sentDate = inf.getStamp(); body = "(Offline) " + body; } else { sentDate = new Date(); } String date = getDate(sentDate); // Agent color is always blue StyleConstants.setBold(styles, false); StyleConstants.setForeground(styles, foreground); StyleConstants.setBackground(styles, background); final Document doc = getDocument(); styles.removeAttribute("link"); StyleConstants.setFontSize(styles, defaultFont.getSize()); doc.insertString(doc.getLength(), date + nickname + ": ", styles); // Reset Styles for message StyleConstants.setBold(styles, false); StyleConstants.setForeground(styles, getMessageColor()); setText(body); insertText("\n"); } catch (BadLocationException e) { Log.error("Error message.", e); } }
private void handleIncomingPacket(Packet packet) { // We only handle message packets here. if (packet instanceof Message) { final Message message = (Message)packet; boolean isGroupChat = message.getType() == Message.Type.groupchat; // Check if Conference invite. If so, do not handle here. if (message.getExtension("x", "jabber:x:conference") != null) { return; } final String body = message.getBody(); boolean broadcast = message.getProperty("broadcast") != null; // Handle offline message. DelayInformation offlineInformation = (DelayInformation)message.getExtension("x", "jabber:x:delay"); if (offlineInformation != null && (Message.Type.chat == message.getType() || Message.Type.normal == message.getType())) { handleOfflineMessage(message); } if (body == null || isGroupChat || broadcast || message.getType() == Message.Type.normal || message.getType() == Message.Type.headline || message.getType() == Message.Type.error) { return; } // Create new chat room for Agent Invite. final String from = packet.getFrom(); final String host = SparkManager.getSessionManager().getServerAddress(); // Don't allow workgroup notifications to come through here. final String bareJID = StringUtils.parseBareAddress(from); if (host.equalsIgnoreCase(from) || from == null) { return; } ChatRoom room = null; try { room = SparkManager.getChatManager().getChatContainer().getChatRoom(bareJID); } catch (ChatRoomNotFoundException e) { // Ignore } // Check for non-existent rooms. if (room == null) { createOneToOneRoom(bareJID, message); } } }