Adds possible subtype of stored messages, and option to filter them by this subtype.

fix-message-formatting 5135
Damian Minkov 13 years ago
parent 220bcbf20b
commit 8a8b05170c

@ -164,6 +164,27 @@ public synchronized QueryResultSet<HistoryRecord> findByEndDate(Date endDate)
*/
public synchronized QueryResultSet<HistoryRecord> findLast(int count)
throws RuntimeException
{
return findLast(count, null, null, false);
}
/**
* Returns the supplied number of recent messages
* containing all <tt>keywords</tt>.
*
* @param count messages count
* @param keywords array of keywords we search for
* @param field the field where to look for the keyword
* @param caseSensitive is keywords search case sensitive
* @return the found records
* @throws RuntimeException
*/
public synchronized QueryResultSet<HistoryRecord> findLast(
int count,
String[] keywords,
String field,
boolean caseSensitive)
throws RuntimeException
{
// the files are supposed to be ordered from oldest to newest
Vector<String> filelist =
@ -227,37 +248,14 @@ public synchronized QueryResultSet<HistoryRecord> findLast(int count)
timestamp = new Date(Long.parseLong(ts));
}
ArrayList<String> nameVals = new ArrayList<String>();
HistoryRecord record =
filterByKeyword(propertyNodes, timestamp,
keywords, field, caseSensitive);
int len = propertyNodes.getLength();
for (int j = 0; j < len; j++)
if(record != null)
{
Node propertyNode = propertyNodes.item(j);
if (propertyNode.getNodeType() == Node.ELEMENT_NODE)
{
// Get nested TEXT node's value
Node nodeValue = propertyNode.getFirstChild();
if(nodeValue == null)
continue;
nameVals.add(propertyNode.getNodeName());
nameVals.add(nodeValue.getNodeValue());
}
}
String[] propertyNames = new String[nameVals.size() / 2];
String[] propertyValues = new String[propertyNames.length];
for (int j = 0; j < propertyNames.length; j++)
{
propertyNames[j] = nameVals.get(j * 2);
propertyValues[j] = nameVals.get(j * 2 + 1);
result.add(record);
}
HistoryRecord record = new HistoryRecord(propertyNames,
propertyValues, timestamp);
result.add(record);
}
currentFile--;

@ -56,16 +56,23 @@ public class MessageHistoryServiceImpl
private static Logger logger = Logger
.getLogger(MessageHistoryServiceImpl.class);
private static String[] STRUCTURE_NAMES
static String[] STRUCTURE_NAMES
= new String[] { "dir", "msg_CDATA", "msgTyp", "enc", "uid", "sub",
"receivedTimestamp" };
"receivedTimestamp", "msgSubTyp" };
private static HistoryRecordStructure recordStructure =
new HistoryRecordStructure(STRUCTURE_NAMES);
// the field used to search by keywords
/**
* the field used to search by keywords
*/
private static final String SEARCH_FIELD = "msg";
/**
* Subtype sms to mark sms messages.
*/
static final String MSG_SUBTYPE_SMS = "sms";
/**
* The BundleContext that we got from the OSGI bus.
*/
@ -345,6 +352,39 @@ public Collection<EventObject> findLast(MetaContact contact, int count)
return resultAsList.subList(startIndex, resultAsList.size());
}
/**
* Checks whether this historyID contains messages of certain type.
* @param historyID
* @param keywords
* @param field
* @param caseSensitive
* @return
* @throws IOException
*/
private boolean hasMessages(HistoryID historyID,
String[] keywords,
String field,
boolean caseSensitive)
throws IOException
{
if(!this.historyService.isHistoryCreated(historyID))
return false;
History history;
if (this.historyService.isHistoryExisting(historyID))
{
history = this.historyService.getHistory(historyID);
}
else
{
history = this.historyService.createHistory(historyID,
recordStructure);
}
return history.getReader().findLast(
1, keywords, field, caseSensitive).hasNext();
}
/**
* Returns the messages for the recently contacted <tt>count</tt> contacts.
*
@ -357,7 +397,8 @@ public Collection<EventObject> findLast(MetaContact contact, int count)
* @throws RuntimeException
*/
Collection<EventObject> findRecentMessagesPerContact(
int count, String providerToFilter, String contactToFilter)
int count, String providerToFilter, String contactToFilter,
boolean isSMSEnabled)
throws RuntimeException
{
TreeSet<EventObject> result
@ -396,7 +437,9 @@ Collection<EventObject> findRecentMessagesPerContact(
// find contact or chatroom for historyID
Object descriptor = getContactOrRoomByID(
accountID,
id.getID()[3]);
id.getID()[3],
id,
isSMSEnabled);
// skip not found contacts, disabled accounts and hidden one
if(descriptor == null)
@ -415,7 +458,22 @@ Collection<EventObject> findRecentMessagesPerContact(
HistoryReader reader = history.getReader();
Iterator<HistoryRecord> recs = reader.findLast(1);
// find last by type
Iterator<HistoryRecord> recs;
if(isSMSEnabled)
{
recs = reader.findLast(
1,
new String[]{MessageHistoryServiceImpl.MSG_SUBTYPE_SMS},
MessageHistoryServiceImpl.STRUCTURE_NAMES[7],
true);
}
else
{
recs = reader.findLast(1);
}
while (recs.hasNext())
{
if(descriptor instanceof Contact)
@ -453,7 +511,11 @@ Collection<EventObject> findRecentMessagesPerContact(
* @param id the contact or room id.
* @return contact or chat room.
*/
private Object getContactOrRoomByID(String accountID, String id)
private Object getContactOrRoomByID(String accountID,
String id,
HistoryID historyID,
boolean isSMSEnabled)
throws IOException
{
AccountID account = null;
for(AccountID acc : AccountUtils.getStoredAccounts())
@ -484,6 +546,37 @@ private Object getContactOrRoomByID(String accountID, String id)
Contact contact = opSetPresence.findContactByID(id);
if(isSMSEnabled)
{
//lets check if we have a contact and it has sms messages return it
if(contact != null
&& hasMessages(
historyID,
new String[]{MessageHistoryServiceImpl.MSG_SUBTYPE_SMS},
MessageHistoryServiceImpl.STRUCTURE_NAMES[7],
true))
{
return contact;
}
// we will check only for sms contacts
OperationSetSmsMessaging opSetSMS =
pps.getOperationSet(OperationSetSmsMessaging.class);
// return the contact only if it has stored sms messages
if(opSetSMS == null
|| !hasMessages(
historyID,
new String[]{MessageHistoryServiceImpl.MSG_SUBTYPE_SMS},
MessageHistoryServiceImpl.STRUCTURE_NAMES[7],
true))
{
return null;
}
return opSetSMS.getContact(id);
}
if(contact != null)
return contact;
@ -831,16 +924,36 @@ private EventObject convertHistoryRecordToMessageEvent( HistoryRecord hr,
if(msg.isOutgoing)
{
return new MessageDeliveredEvent(
msg,
contact,
timestamp);
MessageDeliveredEvent evt
= new MessageDeliveredEvent(
msg,
contact,
timestamp);
if(msg.getMsgSubType() != null
&& msg.getMsgSubType().equals(MSG_SUBTYPE_SMS))
{
evt.setSmsMessage(true);
}
return evt;
}
else
{
int eventType = MessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED;
if(msg.getMsgSubType() != null
&& msg.getMsgSubType().equals(MSG_SUBTYPE_SMS))
{
eventType = MessageReceivedEvent.SMS_MESSAGE_RECEIVED;
}
return new MessageReceivedEvent(
msg,
contact,
timestamp);
timestamp,
eventType);
}
}
/**
@ -910,6 +1023,7 @@ private MessageImpl createMessageFromHistoryRecord(HistoryRecord hr)
// 4- uid
// 5 - sub
// 6 - receivedTimestamp
// 7 - msgSubType
String textContent = null;
String contentType = null;
String contentEncoding = null;
@ -917,6 +1031,7 @@ private MessageImpl createMessageFromHistoryRecord(HistoryRecord hr)
String subject = null;
boolean isOutgoing = false;
Date messageReceivedDate = new Date(0);
String msgSubType = null;
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
for (int i = 0; i < hr.getPropertyNames().length; i++)
{
@ -951,9 +1066,13 @@ else if (propName.equals(STRUCTURE_NAMES[6]))
new Date(Long.parseLong(hr.getPropertyValues()[i]));
}
}
else if (propName.equals(STRUCTURE_NAMES[7]))
{
msgSubType = hr.getPropertyValues()[i];
}
}
return new MessageImpl(textContent, contentType, contentEncoding,
subject, messageUID, isOutgoing, messageReceivedDate);
subject, messageUID, isOutgoing, messageReceivedDate, msgSubType);
}
/**
@ -1049,14 +1168,24 @@ public void stop(BundleContext bc)
public void messageReceived(MessageReceivedEvent evt)
{
this.writeMessage("in", null, evt.getSourceContact(), evt
.getSourceMessage(), evt.getTimestamp());
this.writeMessage(
"in",
null,
evt.getSourceContact(),
evt.getSourceMessage(),
evt.getTimestamp(),
evt.getEventType() == MessageReceivedEvent.SMS_MESSAGE_RECEIVED);
}
public void messageDelivered(MessageDeliveredEvent evt)
{
this.writeMessage("out", null, evt.getDestinationContact(), evt
.getSourceMessage(), evt.getTimestamp());
this.writeMessage(
"out",
null,
evt.getDestinationContact(),
evt.getSourceMessage(),
evt.getTimestamp(),
evt.isSmsMessage());
}
public void messageDeliveryFailed(MessageDeliveryFailedEvent evt)
@ -1201,7 +1330,8 @@ public void messageDelivered(ChatRoomMessageDeliveredEvent evt)
return;
}
writeMessage(history, "out", evt.getMessage(), evt.getTimestamp());
writeMessage(
history, "out", evt.getMessage(), evt.getTimestamp(), false);
} catch (IOException e)
{
logger.error("Could not add message to history", e);
@ -1218,11 +1348,17 @@ public void messageDeliveryFailed(ChatRoomMessageDeliveryFailedEvent evt)
* @param source The source Contact
* @param destination The destination Contact
* @param message Message message to be written
* @param messageTimestamp Date this is the timestamp when was message received
* that came from the protocol provider
*/
private void writeMessage(String direction, Contact source,
Contact destination, Message message, Date messageTimestamp)
* @param messageTimestamp Date this is the timestamp when was message
* received that came from the protocol provider
* @param isSmsSubtype whether message to write is an sms
*/
private void writeMessage(
String direction,
Contact source,
Contact destination,
Message message,
Date messageTimestamp,
boolean isSmsSubtype)
{
try
{
@ -1238,7 +1374,8 @@ private void writeMessage(String direction, Contact source,
History history = this.getHistory(source, destination);
writeMessage(history, direction, message, messageTimestamp);
writeMessage(
history, direction, message, messageTimestamp, isSmsSubtype);
} catch (IOException e)
{
logger.error("Could not add message to history", e);
@ -1250,11 +1387,11 @@ private void writeMessage(String direction, Contact source,
* @param history The history to which will write the message
* @param direction coming from
* @param message Message
* @param messageTimestamp Date this is the timestamp when was message received
* that came from the protocol provider
* @param messageTimestamp Date this is the timestamp when was message
* received that came from the protocol provider
*/
private void writeMessage(History history, String direction,
Message message, Date messageTimestamp)
Message message, Date messageTimestamp, boolean isSmsSubtype)
{
try {
HistoryWriter historyWriter = history.getWriter();
@ -1263,7 +1400,8 @@ private void writeMessage(History history, String direction,
historyWriter.addRecord(new String[] { direction,
message.getContent(), message.getContentType(),
message.getEncoding(), message.getMessageUID(),
message.getSubject(), sdf.format(messageTimestamp) },
message.getSubject(), sdf.format(messageTimestamp),
isSmsSubtype ? MSG_SUBTYPE_SMS : null},
new Date()); // this date is when the history record is written
} catch (IOException e)
{
@ -2344,20 +2482,28 @@ private static class MessageImpl
private final Date messageReceivedDate;
private String msgSubType;
MessageImpl(String content, String contentType, String encoding,
String subject, String messageUID, boolean isOutgoing,
Date messageReceivedDate)
Date messageReceivedDate, String msgSubType)
{
super(content, contentType, encoding, subject, messageUID);
this.isOutgoing = isOutgoing;
this.messageReceivedDate = messageReceivedDate;
this.msgSubType = msgSubType;
}
public Date getMessageReceivedDate()
{
return messageReceivedDate;
}
public String getMsgSubType()
{
return msgSubType;
}
}
/**
@ -2686,7 +2832,8 @@ public void messageDelivered(AdHocChatRoomMessageDeliveredEvent evt)
getHistoryForAdHocMultiChat(
evt.getSourceAdHocChatRoom());
writeMessage(history, "out", evt.getMessage(), evt.getTimestamp());
writeMessage(
history, "out", evt.getMessage(), evt.getTimestamp(), false);
}
catch (IOException e)
{

@ -63,6 +63,12 @@ public class MessageSourceService
private static final String NUMBER_OF_RECENT_MSGS_PROP
= "net.java.sip.communicator.impl.msghistory.contactsrc.MSG_NUMBER";
/**
* Property to control messages type. Can query for message sub type.
*/
private static final String IS_MESSAGE_SUBTYPE_SMS_PROP
= "net.java.sip.communicator.impl.msghistory.contactsrc.IS_SMS_ENABLED";
/**
* Number of messages to show.
*/
@ -101,6 +107,11 @@ public class MessageSourceService
*/
private MessageHistoryContactQuery recentQuery = null;
/**
* The message subtype if any.
*/
private boolean isSMSEnabled = false;
/**
* Constructs MessageSourceService.
*/
@ -117,6 +128,9 @@ public class MessageSourceService
numberOfMessages = MessageHistoryActivator.getConfigurationService()
.getInt(NUMBER_OF_RECENT_MSGS_PROP, numberOfMessages);
isSMSEnabled = MessageHistoryActivator.getConfigurationService()
.getBoolean(IS_MESSAGE_SUBTYPE_SMS_PROP, isSMSEnabled);
}
/**
@ -192,7 +206,8 @@ private synchronized List<MessageSourceContact> getRecentMessages()
MessageHistoryServiceImpl msgHistoryService =
MessageHistoryActivator.getMessageHistoryService();
Collection<EventObject> res = msgHistoryService
.findRecentMessagesPerContact(numberOfMessages, null, null);
.findRecentMessagesPerContact(
numberOfMessages, null, null, isSMSEnabled);
for(EventObject obj : res)
{
@ -218,9 +233,9 @@ private History getHistory()
{
synchronized(historyID)
{
MessageHistoryServiceImpl msgService
= MessageHistoryActivator.getMessageHistoryService();
HistoryService historyService = msgService.getHistoryService();
HistoryService historyService =
MessageHistoryActivator.getMessageHistoryService()
.getHistoryService();
// if not existing, return to search for initial load
if (history == null
@ -282,8 +297,9 @@ else if (propName.equals(STRUCTURE_NAMES[1]))
if(provider == null || contact == null)
return res;
for(EventObject ev : msgService.findRecentMessagesPerContact(
numberOfMessages, provider, contact))
for(EventObject ev
: msgService.findRecentMessagesPerContact(
numberOfMessages, provider, contact, isSMSEnabled))
{
res.add(new MessageSourceContact(ev, this));
}
@ -425,7 +441,8 @@ public void providerStatusChanged(ProviderPresenceStatusChangeEvent evt)
.findRecentMessagesPerContact(
numberOfMessages,
evt.getProvider().getAccountID().getAccountUniqueID(),
null);
null,
isSMSEnabled);
List<String> recentMessagesForProvider = new LinkedList<String>();
List<MessageSourceContact> messages = getRecentMessages();
@ -595,6 +612,12 @@ private void handle(EventObject obj,
@Override
public void messageReceived(MessageReceivedEvent evt)
{
if(isSMSEnabled
&& evt.getEventType() != MessageReceivedEvent.SMS_MESSAGE_RECEIVED)
{
return;
}
handle(
evt,
evt.getSourceContact().getProtocolProvider(),
@ -604,6 +627,9 @@ public void messageReceived(MessageReceivedEvent evt)
@Override
public void messageDelivered(MessageDeliveredEvent evt)
{
if(isSMSEnabled && !evt.isSmsMessage())
return;
handle(
evt,
evt.getDestinationContact().getProtocolProvider(),
@ -621,6 +647,9 @@ public void messageDeliveryFailed(MessageDeliveryFailedEvent evt)
@Override
public void messageReceived(ChatRoomMessageReceivedEvent evt)
{
if(isSMSEnabled)
return;
// ignore non conversation messages
if(evt.getEventType() !=
ChatRoomMessageReceivedEvent.CONVERSATION_MESSAGE_RECEIVED)
@ -635,6 +664,9 @@ public void messageReceived(ChatRoomMessageReceivedEvent evt)
@Override
public void messageDelivered(ChatRoomMessageDeliveredEvent evt)
{
if(isSMSEnabled)
return;
handle(
evt,
evt.getSourceChatRoom().getParentProvider(),

@ -14,6 +14,7 @@ Import-Package: ch.imvs.sdes4j.srtp,
net.java.sip.communicator.service.certificate,
net.java.sip.communicator.service.credentialsstorage,
net.java.sip.communicator.service.customavatar,
net.java.sip.communicator.service.contactsource,
net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.hid,
net.java.sip.communicator.service.httputil,

@ -167,7 +167,25 @@ public QueryResultSet<HistoryRecord> findByPeriod( Date startDate,
* @return the found records
* @throws RuntimeException
*/
QueryResultSet<HistoryRecord> findLast(int count) throws RuntimeException;
QueryResultSet<HistoryRecord> findLast(int count)
throws RuntimeException;
/**
* Returns the supplied number of recent messages
* containing all <tt>keywords</tt>.
*
* @param count messages count
* @param keywords array of keywords we search for
* @param field the field where to look for the keyword
* @param caseSensitive is keywords search case sensitive
* @return the found records
* @throws RuntimeException
*/
QueryResultSet<HistoryRecord> findLast( int count,
String[] keywords,
String field,
boolean caseSensitive)
throws RuntimeException;
/**
* Returns the supplied number of recent messages after the given date

Loading…
Cancel
Save