Adds new call history listeners which will be notified when new call peer record is added and implements updating a call history record.

ice4sip
hristoterezov 12 years ago
parent 40341d37b6
commit 96cfcc5ac8

@ -46,7 +46,7 @@ public class CallHistoryServiceImpl
new String[] { "accountUID", "callStart", "callEnd", "dir",
"callParticipantIDs", "callParticipantStart",
"callParticipantEnd", "callParticipantStates", "callEndReason",
"callParticipantNames"};
"callParticipantNames", "secondaryCallParticipantIDs"};
private static HistoryRecordStructure recordStructure =
new HistoryRecordStructure(STRUCTURE_NAMES);
@ -75,6 +75,9 @@ public class CallHistoryServiceImpl
private HistoryReader historyReader;
private List<CallHistoryPeerRecordListener> callHistoryRecordlisteners
= new LinkedList<CallHistoryPeerRecordListener>();
/**
* Returns the underlying history service.
* @return the underlying history service
@ -685,6 +688,7 @@ private void writeCall( CallRecordImpl callRecord,
StringBuffer callPeerStartTime = new StringBuffer();
StringBuffer callPeerEndTime = new StringBuffer();
StringBuffer callPeerStates = new StringBuffer();
StringBuffer callPeerSecondaryIDs = new StringBuffer();
for (CallPeerRecord item : callRecord
.getPeerRecords())
@ -696,6 +700,7 @@ private void writeCall( CallRecordImpl callRecord,
callPeerStartTime.append(DELIM);
callPeerEndTime.append(DELIM);
callPeerStates.append(DELIM);
callPeerSecondaryIDs.append(DELIM);
}
callPeerIDs.append(item.getPeerAddress());
@ -703,6 +708,10 @@ private void writeCall( CallRecordImpl callRecord,
callPeerStartTime.append(sdf.format(item.getStartTime()));
callPeerEndTime.append(sdf.format(item.getEndTime()));
callPeerStates.append(item.getState().getStateString());
callPeerSecondaryIDs.append(
item.getPeerSecondaryAddress() == null?
"" : item.getPeerSecondaryAddress());
}
historyWriter.addRecord(new String[] {
@ -716,7 +725,8 @@ private void writeCall( CallRecordImpl callRecord,
callPeerEndTime.toString(),
callPeerStates.toString(),
String.valueOf(callRecord.getEndReason()),
callPeerNames.toString()},
callPeerNames.toString(),
callPeerSecondaryIDs.toString()},
new Date()); // this date is when the history
// record is written
}
@ -871,6 +881,54 @@ public void removeSearchProgressListener(
}
}
/**
* Adding <tt>CallHistoryRecordListener</tt> listener to the list.
*
* @param listener CallHistoryRecordListener
*/
public void addCallHistoryRecordListener(CallHistoryPeerRecordListener
listener)
{
synchronized (callHistoryRecordlisteners)
{
callHistoryRecordlisteners.add(listener);
}
}
/**
* Removing <tt>CallHistoryRecordListener</tt> listener
*
* @param listener CallHistoryRecordListener
*/
public void removeCallHistoryRecordListener(
CallHistoryPeerRecordListener listener)
{
synchronized(callHistoryRecordlisteners){
callHistoryRecordlisteners.remove(listener);
}
}
/**
* Fires the given event to all <tt>CallHistoryRecordListener</tt> listeners
* @param event the <tt>CallHistoryRecordReceivedEvent</tt> event to be
* fired
*/
private void fireCallHistoryRecordReceivedEvent(
CallHistoryPeerRecordEvent event)
{
List<CallHistoryPeerRecordListener> tmpListeners;
synchronized (callHistoryRecordlisteners)
{
tmpListeners = new LinkedList<CallHistoryPeerRecordListener>(
callHistoryRecordlisteners);
}
for(CallHistoryPeerRecordListener listener : tmpListeners)
{
listener.callPeerRecordReceived(event);
}
}
/**
* Add the registered CallHistorySearchProgressListeners to the given
* HistoryReader
@ -990,6 +1048,8 @@ public void peerStateChanged(CallPeerChangeEvent evt)
newRec.setDisplayName(callPeer.getDisplayName());
callRecord.getPeerRecords().add(newRec);
fireCallHistoryRecordReceivedEvent(new CallHistoryPeerRecordEvent(
callPeer.getAddress(), startDate));
}
/**
@ -1025,6 +1085,152 @@ private void handlePeerRemoved( CallPeer callPeer,
}
}
/**
* Updates the secondary address field of call record.
* @param date the start date of the record which will be updated.
* @param peer the peer of the record which will be updated.
* @param address the value of the secondary address .
*/
public void updateCallRecordPeerSecondaryAddress(final Date date,
final CallPeer peer,
final String address)
{
CallRecord record = findCallRecord(peer.getCall());
if(record != null)
{
for(CallPeerRecord peerRecord : record.getPeerRecords())
{
if(peerRecord.getPeerAddress().equals(peer.getAddress()))
{
peerRecord.setPeerSecondaryAddress(address);
}
}
return;
}
History history;
try
{
history = this.getHistory(null, null);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
HistoryWriter historyWriter = history.getWriter();
HistoryWriter.HistoryRecordUpdater updater = new HistoryWriter.HistoryRecordUpdater()
{
private HistoryRecord record;
private int dateIndex;
private int peerIDIndex;
private int peerSecondaryIDIndex;
@Override
public void setHistoryRecord(HistoryRecord historyRecord)
{
record = historyRecord;
String propertyNames[] = record.getPropertyNames();
for(int i = 0; i < propertyNames.length; i++)
{
if(propertyNames[i].equals(STRUCTURE_NAMES[5]))
{
dateIndex = i;
}
if(propertyNames[i].equals(STRUCTURE_NAMES[4]))
{
peerIDIndex = i;
}
if(propertyNames[i].equals(STRUCTURE_NAMES[10]))
{
peerSecondaryIDIndex = i;
}
}
}
@Override
public boolean isMatching()
{
String[] propertyVlaues = record.getPropertyValues();
List<String> peerIDs
= getCSVs(propertyVlaues[peerIDIndex]);
int i = peerIDs.indexOf(peer.getAddress());
if(i == -1)
return false;
String dateString = getCSVs(propertyVlaues[dateIndex]).get(i);
SimpleDateFormat sdf
= new SimpleDateFormat(HistoryService.DATE_FORMAT);
try
{
if(!sdf.parse(dateString).equals(date))
return false;
}
catch (ParseException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
String secondaryID
= getCSVs(propertyVlaues[peerSecondaryIDIndex]).get(i);
if(secondaryID != null)
return false;
return true;
}
@Override
public Map<String, String> getUpdateChanges()
{
String[] propertyVlaues = record.getPropertyValues();
List<String> peerIDs
= getCSVs(propertyVlaues[peerIDIndex]);
int i = peerIDs.indexOf(peer.getAddress());
if(i == -1)
return null;
List<String> secondaryID
= getCSVs(record.getPropertyValues()[peerSecondaryIDIndex]);
secondaryID.set(i, peer.getAddress());
String res = "";
int j = 0;
for(String id : secondaryID)
{
if(j++ != 0)
res += DELIM;
res += id;
}
Map<String, String> changesMap = new HashMap<String, String>();
changesMap.put(STRUCTURE_NAMES[10], res);
return changesMap;
}
};
try
{
historyWriter.updateRecord(updater);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Finding a CallRecord for the given call
*
@ -1083,6 +1289,7 @@ private void handleNewCall(Call sourceCall, String direction)
currentCallRecords.add(newRecord);
// if has already perticipants Dispatch them
Iterator<? extends CallPeer> iter = sourceCall.getCallPeers();
while (iter.hasNext())

@ -308,4 +308,100 @@ public void updateRecord(String idProperty, String idValue,
}
}
}
/**
* Updates history record using given <tt>HistoryRecordUpdater</tt> instance
* to find which is the record to be updated and to get the new values for
* the fields
* @param updater the <tt>HistoryRecordUpdater</tt> instance.
*/
public void updateRecord(HistoryRecordUpdater updater) throws IOException
{
Iterator<String> fileIterator = this.historyImpl.getFileList();
String filename = null;
while (fileIterator.hasNext())
{
filename = fileIterator.next();
Document doc = this.historyImpl.getDocumentForFile(filename);
if(doc == null)
continue;
NodeList nodes = doc.getElementsByTagName("record");
boolean changed = false;
Node node;
for (int i = 0; i < nodes.getLength(); i++)
{
node = nodes.item(i);
updater.setHistoryRecord(createHistoryRecordFromNode(node));
if(!updater.isMatching())
continue;
Map<String, String> updates = updater.getUpdateChanges();
for(String nodeName : updates.keySet())
{
Element changedNode =
XMLUtils.findChild((Element)node, nodeName);
if(changedNode != null)
{
Node changedNestedNode = changedNode.getFirstChild();
changedNestedNode.setNodeValue(updates.get(nodeName));
changed = true;
}
}
}
if(changed)
{
// write changes
synchronized (this.docWriteLock)
{
this.historyImpl.writeFile(filename, doc);
}
// this prevents that the current writer, which holds
// instance for the last document he is editing will not
// override our last changes to the document
if(filename.equals(this.currentFile))
{
this.currentDoc = doc;
}
break;
}
}
}
/**
* Creates <tt>HistoryRecord</tt> instance from <tt>Node</tt> object.
* @param node the node
* @return the <tt>HistoryRecord</tt> instance
*/
private HistoryRecord createHistoryRecordFromNode(Node node)
{
HistoryRecordStructure structure
= historyImpl.getHistoryRecordsStructure();
String propertyValues[] = new String[structure.getPropertyCount()];
int i = 0;
for(String propertyName : structure.getPropertyNames())
{
Element childNode = XMLUtils.findChild((Element)node, propertyName);
if(childNode == null)
{
i++;
continue;
}
propertyValues[i] = childNode.getTextContent();
i++;
}
return new HistoryRecord(structure, propertyValues);
}
}

@ -10,12 +10,14 @@
import net.java.sip.communicator.service.callhistory.event.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.protocol.*;
/**
* The Call History Service stores info about calls made from various protocols
*
* @author Alexander Pelov
* @author Damian Minkov
* @author Hristo Terezov
*/
public interface CallHistoryService
{
@ -143,4 +145,14 @@ public void addSearchProgressListener(
*/
public void removeSearchProgressListener(
CallHistorySearchProgressListener listener);
/**
* Updates the secondary address field of call record.
* @param date the start date of the record which will be updated.
* @param peer the peer of the record which will be updated.
* @param address the value of the secondary address .
*/
public void updateCallRecordPeerSecondaryAddress(final Date date,
final CallPeer peer,
final String address);
}

@ -10,6 +10,7 @@
* from the Call History Service
*
* @author Damian Minkov
* @author Hristo Terezov
*/
public class CallPeerRecord
{
@ -33,6 +34,11 @@ public class CallPeerRecord
*/
protected Date endTime = null;
/**
* The secondary address of the peer.
*/
protected String secondaryPeerAddress = null;
/**
* The state of <tt>CallPeer</tt>.
*/
@ -99,4 +105,22 @@ public CallPeerState getState()
{
return state;
}
/**
* Sets secondary address to the <tt>CallPeerRecord</tt>
* @param address the address to be set.
*/
public void setPeerSecondaryAddress(String address)
{
secondaryPeerAddress = address;
}
/**
* Returns the secondary address to the <tt>CallPeerRecord</tt>
* @return the secondary address to the <tt>CallPeerRecord</tt>
*/
public String getPeerSecondaryAddress()
{
return secondaryPeerAddress;
}
}

@ -0,0 +1,58 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.callhistory.event;
import java.util.*;
/**
* An event which is fired when a new call peer history record is added.
* @author Hristo Terezov
*/
public class CallHistoryPeerRecordEvent
extends EventObject
{
/**
* Serial ID.
*/
private static final long serialVersionUID = 1L;
/**
* The date when the call peer have started the conversation.
*/
private static Date startDate;
/**
* Constructs new <tt>CallHistoryPeerRecordEvent</tt> event.
* @param peer the peer associated with the event.
*/
public CallHistoryPeerRecordEvent(String peerAddress, Date startDate)
{
super(peerAddress);
this.startDate = startDate;
}
/**
* Returns the start date property of the event.
* @return the start date property of the event.
*/
public Date getStartDate()
{
return startDate;
}
/**
* Returns the peer address of the event.
* @return the peer address of the event.
*/
public String getPeerAddress()
{
return (String) getSource();
}
}

@ -0,0 +1,21 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.service.callhistory.event;
/**
* Interface for a listener that will be notified when new call peer is added to
* the history.
* @author Hristo Terezov
*/
public interface CallHistoryPeerRecordListener
{
/**
* This method is called when <tt>CallHistoryPeerRecordEvent</tt> occurred.
* @param event the event
*/
public void callPeerRecordReceived(CallHistoryPeerRecordEvent event);
}

@ -13,6 +13,7 @@
/**
* @author Alexander Pelov
* @author Hristo Terezov
*/
public interface HistoryWriter {
@ -61,4 +62,39 @@ public interface HistoryWriter {
*/
public void updateRecord(String idProperty, String idValue,
String property, String newValue) throws IOException;
/**
* Updates history record using given <tt>HistoryRecordUpdater</tt> instance
* to find which is the record to be updated and to get the new values for
* the fields
* @param updater the <tt>HistoryRecordUpdater</tt> instance.
*/
public void updateRecord(HistoryRecordUpdater updater) throws IOException;
/**
* This interface is used to find a history record to update and to get the
* new values for the record.
*/
public interface HistoryRecordUpdater
{
/**
* Sets the current history record.
* @param historyRecord the history record.
*/
public void setHistoryRecord(HistoryRecord historyRecord);
/**
* Checks if the history record should be updated or not
* @return <tt>true<tt> if the record should be updated.
*/
public boolean isMatching();
/**
* Returns a map with the names and new values of the fields that will
* be updated
* @return a map with the names and new values of the fields that will
* be updated
*/
public Map<String, String> getUpdateChanges();
}
}

Loading…
Cancel
Save