aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl/callhistory
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2010-05-03 12:27:34 +0000
committerYana Stamcheva <yana@jitsi.org>2010-05-03 12:27:34 +0000
commitafcafe3061f9abaa52633b727fe34769d4cc0e04 (patch)
treea36c09734602576e9a8388794142420f06ce649c /src/net/java/sip/communicator/impl/callhistory
parentc454284e43c6db33c1d13f4a1c9d9e06d7726d9f (diff)
downloadjitsi-afcafe3061f9abaa52633b727fe34769d4cc0e04.zip
jitsi-afcafe3061f9abaa52633b727fe34769d4cc0e04.tar.gz
jitsi-afcafe3061f9abaa52633b727fe34769d4cc0e04.tar.bz2
- Introduces new contact list data model that allows adding of external contact sources and hence the search in such sources.
- As part of the support for external contact sources, implements a call history external source and its user interface. - Addresses issue #706 Indicate missed calls
Diffstat (limited to 'src/net/java/sip/communicator/impl/callhistory')
-rwxr-xr-xsrc/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java122
-rw-r--r--src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java153
-rw-r--r--src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java259
-rw-r--r--src/net/java/sip/communicator/impl/callhistory/CallHistorySourceContact.java266
-rw-r--r--src/net/java/sip/communicator/impl/callhistory/CallRecordImpl.java9
-rw-r--r--src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf5
6 files changed, 712 insertions, 102 deletions
diff --git a/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java b/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java
index 37118c7..049ca9c 100755
--- a/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java
+++ b/src/net/java/sip/communicator/impl/callhistory/CallHistoryActivator.java
@@ -6,15 +6,22 @@
*/
package net.java.sip.communicator.impl.callhistory;
+import java.util.*;
+
import org.osgi.framework.*;
+
import net.java.sip.communicator.service.history.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.service.callhistory.*;
+import net.java.sip.communicator.service.contactsource.*;
/**
- * Activates the CallHistoryService
+ * Activates the <tt>CallHistoryService</tt>.
*
* @author Damian Minkov
+ * @author Yana Stamcheva
*/
public class CallHistoryActivator
implements BundleActivator
@@ -22,18 +29,39 @@ public class CallHistoryActivator
private static Logger logger =
Logger.getLogger(CallHistoryActivator.class);
- private CallHistoryServiceImpl callHistoryService = null;
+ /**
+ * The bundle context.
+ */
+ public static BundleContext bundleContext;
+
+ /**
+ * The <tt>CallHistoryServiceImpl</tt> instantiated in the start method
+ * of this bundle.
+ */
+ private static CallHistoryServiceImpl callHistoryService = null;
+
+ /**
+ * The service responsible for resources.
+ */
+ private static ResourceManagementService resourcesService;
+
+ /**
+ * The map containing all registered
+ */
+ private static final Map<Object, ProtocolProviderFactory>
+ providerFactoriesMap = new Hashtable<Object, ProtocolProviderFactory>();
/**
* Initialize and start call history
*
- * @param bundleContext BundleContext
+ * @param bc the <tt>BundleContext</tt>
* @throws Exception
*/
- public void start(BundleContext bundleContext) throws Exception
+ public void start(BundleContext bc) throws Exception
{
- try{
+ bundleContext = bc;
+ try{
logger.logEntry();
ServiceReference refHistory = bundleContext.getServiceReference(
@@ -53,6 +81,10 @@ public class CallHistoryActivator
bundleContext.registerService(
CallHistoryService.class.getName(), callHistoryService, null);
+ bundleContext.registerService(
+ ContactSourceService.class.getName(),
+ new CallHistoryContactSource(), null);
+
logger.info("Call History Service ...[REGISTERED]");
}
finally
@@ -62,9 +94,89 @@ public class CallHistoryActivator
}
+ /**
+ * Stops this bundle.
+ * @param bundleContext the <tt>BundleContext</tt>
+ * @throws Exception if the stop operation goes wrong
+ */
public void stop(BundleContext bundleContext) throws Exception
{
if(callHistoryService != null)
callHistoryService.stop(bundleContext);
}
+
+ /**
+ * Returns the instance of <tt>CallHistoryService</tt> created in this
+ * activator.
+ * @return the instance of <tt>CallHistoryService</tt> created in this
+ * activator
+ */
+ public static CallHistoryService getCallHistoryService()
+ {
+ return callHistoryService;
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ *
+ * @return the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ {
+ ServiceReference serviceReference = bundleContext
+ .getServiceReference(ResourceManagementService.class.getName());
+
+ if(serviceReference == null)
+ return null;
+
+ resourcesService = (ResourceManagementService) bundleContext
+ .getService(serviceReference);
+ }
+ return resourcesService;
+ }
+
+ /**
+ * Returns all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
+ * context.
+ *
+ * @return all <tt>ProtocolProviderFactory</tt>s obtained from the bundle
+ * context
+ */
+ public static Map<Object, ProtocolProviderFactory>
+ getProtocolProviderFactories()
+ {
+ ServiceReference[] serRefs = null;
+ try
+ {
+ // get all registered provider factories
+ serRefs =
+ bundleContext.getServiceReferences(
+ ProtocolProviderFactory.class.getName(), null);
+
+ }
+ catch (InvalidSyntaxException e)
+ {
+ logger.error("LoginManager : " + e);
+ }
+
+ if (serRefs != null)
+ {
+ for (int i = 0; i < serRefs.length; i++)
+ {
+
+ ProtocolProviderFactory providerFactory
+ = (ProtocolProviderFactory) bundleContext
+ .getService(serRefs[i]);
+
+ providerFactoriesMap.put(serRefs[i]
+ .getProperty(ProtocolProviderFactory.PROTOCOL),
+ providerFactory);
+ }
+ }
+ return providerFactoriesMap;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java b/src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java
new file mode 100644
index 0000000..74d4249
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/callhistory/CallHistoryContactSource.java
@@ -0,0 +1,153 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.callhistory;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.callhistory.*;
+import net.java.sip.communicator.service.contactsource.*;
+
+/**
+ * The <tt>CallHistoryContactSource</tt> is the contact source for the call
+ * history.
+ *
+ * @author Yana Stamcheva
+ */
+public class CallHistoryContactSource implements ContactSourceService
+{
+ /**
+ * The display name of this contact source.
+ */
+ private static final String CALL_HISTORY_NAME = "Call history";
+
+ /**
+ * Returns the display name of this contact source.
+ * @return the display name of this contact source
+ */
+ public String getDisplayName()
+ {
+ return CALL_HISTORY_NAME;
+ }
+
+ /**
+ * Queries this contact source for the given <tt>searchString</tt>.
+ * @param queryString the string to search for
+ * @return the created query
+ */
+ public ContactQuery queryContactSource(String queryString)
+ {
+ if (queryString != null && queryString.length() > 0)
+ return new CallHistoryQuery(
+ CallHistoryActivator.getCallHistoryService()
+ .findByPeer(queryString));
+ else
+ return new CallHistoryQuery(
+ CallHistoryActivator.getCallHistoryService()
+ .findLast(50));
+ }
+
+ /**
+ * The <tt>CallHistoryQuery</tt> contains information about a current query
+ * to the contact source.
+ */
+ private class CallHistoryQuery implements ContactQuery
+ {
+ /**
+ * A list of all registered query listeners.
+ */
+ private final List<ContactQueryListener> queryListeners
+ = new LinkedList<ContactQueryListener>();
+
+ /**
+ * A list of all source contact results.
+ */
+ private final List<SourceContact> sourceContacts
+ = new LinkedList<SourceContact>();
+
+ /**
+ * Creates a <tt>CallHistoryQuery</tt>.
+ * @param callRecords a collection of the result call records
+ */
+ public CallHistoryQuery(Collection<CallRecord> callRecords)
+ {
+ Iterator<CallRecord> recordsIter = callRecords.iterator();
+
+ while (recordsIter.hasNext())
+ {
+ sourceContacts.add(
+ new CallHistorySourceContact(
+ CallHistoryContactSource.this,
+ recordsIter.next()));
+ }
+ }
+
+ /**
+ * Adds the given <tt>ContactQueryListener</tt> to the list of query
+ * listeners.
+ * @param l the <tt>ContactQueryListener</tt> to add
+ */
+ public void addContactQueryListener(ContactQueryListener l)
+ {
+ synchronized (queryListeners)
+ {
+ queryListeners.add(l);
+ }
+ }
+
+ /**
+ * This query could not be canceled.
+ */
+ public void cancel()
+ {
+
+ }
+
+ /**
+ * Removes the given <tt>ContactQueryListener</tt> from the list of
+ * query listeners.
+ * @param l the <tt>ContactQueryListener</tt> to remove
+ */
+ public void removeContactQueryListener(ContactQueryListener l)
+ {
+ synchronized (queryListeners)
+ {
+ queryListeners.remove(l);
+ }
+ }
+
+ /**
+ * Returns a list containing the results of this query.
+ * @return a list containing the results of this query
+ */
+ public List<SourceContact> getQueryResults()
+ {
+ return sourceContacts;
+ }
+
+ /**
+ * Returns the <tt>ContactSourceService</tt>, where this query was first
+ * initiated.
+ * @return the <tt>ContactSourceService</tt>, where this query was first
+ * initiated
+ */
+ public ContactSourceService getContactSource()
+ {
+ return CallHistoryContactSource.this;
+ }
+ }
+
+ /**
+ * Returns the identifier of this contact source. Some of the common
+ * identifiers are defined here (For example the CALL_HISTORY identifier
+ * should be returned by all call history implementations of this interface)
+ * @return the identifier of this contact source
+ */
+ public String getIdentifier()
+ {
+ return CALL_HISTORY;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java b/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java
index 48fbbb6..93d83f4 100644
--- a/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/callhistory/CallHistoryServiceImpl.java
@@ -42,8 +42,9 @@ public class CallHistoryServiceImpl
Logger.getLogger(CallHistoryServiceImpl.class);
private static String[] STRUCTURE_NAMES =
- new String[] { "callStart", "callEnd", "dir", "callParticipantIDs",
- "callParticipantStart", "callParticipantEnd","callParticipantStates" };
+ new String[] { "accountUID", "callStart", "callEnd", "dir",
+ "callParticipantIDs", "callParticipantStart",
+ "callParticipantEnd", "callParticipantStates" };
private static HistoryRecordStructure recordStructure =
new HistoryRecordStructure(STRUCTURE_NAMES);
@@ -59,8 +60,10 @@ public class CallHistoryServiceImpl
private Object syncRoot_HistoryService = new Object();
- private final Map<CallHistorySearchProgressListener, SearchProgressWrapper> progressListeners =
- new Hashtable<CallHistorySearchProgressListener, SearchProgressWrapper>();
+ private final Map<CallHistorySearchProgressListener, SearchProgressWrapper>
+ progressListeners
+ = new Hashtable<CallHistorySearchProgressListener,
+ SearchProgressWrapper>();
private final List<CallRecordImpl> currentCallRecords =
new Vector<CallRecordImpl>();
@@ -68,22 +71,29 @@ public class CallHistoryServiceImpl
private final CallChangeListener historyCallChangeListener =
new HistoryCallChangeListener();
+ private HistoryReader historyReader;
+
+ /**
+ * Returns the underlying history service.
+ * @return the underlying history service
+ */
public HistoryService getHistoryService()
{
return historyService;
}
/**
- * Returns all the calls made by all the contacts
- * in the supplied metacontact after the given date
+ * Returns all the calls made by all the contacts in the supplied
+ * <tt>contact</tt> after the given date.
*
* @param contact MetaContact which contacts participate in
* the returned calls
* @param startDate Date the start date of the calls
- * @return Collection of CallRecords with CallPeerRecord
+ * @return the <tt>CallHistoryQuery</tt>, corresponding to this find
* @throws RuntimeException
*/
- public Collection<CallRecord> findByStartDate(MetaContact contact, Date startDate)
+ public Collection<CallRecord> findByStartDate(
+ MetaContact contact, Date startDate)
throws RuntimeException
{
throw new UnsupportedOperationException("Not implemented yet!");
@@ -93,7 +103,7 @@ public class CallHistoryServiceImpl
* Returns all the calls made after the given date
*
* @param startDate Date the start date of the calls
- * @return Collection of CallRecords with CallPeerRecord
+ * @return the <tt>CallHistoryQuery</tt>, corresponding to this find
* @throws RuntimeException
*/
public Collection<CallRecord> findByStartDate(Date startDate)
@@ -104,16 +114,16 @@ public class CallHistoryServiceImpl
{
// the default ones
History history = this.getHistory(null, null);
- HistoryReader reader = history.getReader();
- addHistorySearchProgressListeners(reader, 1);
+ historyReader = history.getReader();
+ addHistorySearchProgressListeners(historyReader, 1);
QueryResultSet<HistoryRecord> rs
- = reader.findByStartDate(startDate);
+ = historyReader.findByStartDate(startDate);
while (rs.hasNext())
{
HistoryRecord hr = rs.next();
result.add(convertHistoryRecordToCallRecord(hr));
}
- removeHistorySearchProgressListeners(reader);
+ removeHistorySearchProgressListeners(historyReader);
}
catch (IOException ex)
{
@@ -133,7 +143,8 @@ public class CallHistoryServiceImpl
* @return Collection of CallRecords with CallPeerRecord
* @throws RuntimeException
*/
- public Collection<CallRecord> findByEndDate(MetaContact contact, Date endDate)
+ public Collection<CallRecord> findByEndDate(MetaContact contact,
+ Date endDate)
throws RuntimeException
{
throw new UnsupportedOperationException("Not implemented yet!");
@@ -146,22 +157,25 @@ public class CallHistoryServiceImpl
* @return Collection of CallRecords with CallPeerRecord
* @throws RuntimeException
*/
- public Collection<CallRecord> findByEndDate(Date endDate) throws RuntimeException
+ public Collection<CallRecord> findByEndDate(Date endDate)
+ throws RuntimeException
{
- TreeSet<CallRecord> result = new TreeSet<CallRecord>(new CallRecordComparator());
+ TreeSet<CallRecord> result
+ = new TreeSet<CallRecord>(new CallRecordComparator());
try
{
// the default ones
History history = this.getHistory(null, null);
- HistoryReader reader = history.getReader();
- addHistorySearchProgressListeners(reader, 1);
- QueryResultSet<HistoryRecord> rs = reader.findByEndDate(endDate);
+ historyReader = history.getReader();
+ addHistorySearchProgressListeners(historyReader, 1);
+ QueryResultSet<HistoryRecord> rs
+ = historyReader.findByEndDate(endDate);
while (rs.hasNext())
{
HistoryRecord hr = rs.next();
result.add(convertHistoryRecordToCallRecord(hr));
}
- removeHistorySearchProgressListeners(reader);
+ removeHistorySearchProgressListeners(historyReader);
}
catch (IOException ex)
{
@@ -181,7 +195,8 @@ public class CallHistoryServiceImpl
* @return Collection of CallRecords with CallPeerRecord
* @throws RuntimeException
*/
- public Collection<CallRecord> findByPeriod(MetaContact contact, Date startDate, Date endDate)
+ public Collection<CallRecord> findByPeriod(MetaContact contact,
+ Date startDate, Date endDate)
throws RuntimeException
{
throw new UnsupportedOperationException("Not implemented yet!");
@@ -195,24 +210,25 @@ public class CallHistoryServiceImpl
* @return Collection of CallRecords with CallPeerRecord
* @throws RuntimeException
*/
- public Collection<CallRecord> findByPeriod(Date startDate, Date endDate) throws
- RuntimeException
+ public Collection<CallRecord> findByPeriod(Date startDate, Date endDate)
+ throws RuntimeException
{
- TreeSet<CallRecord> result = new TreeSet<CallRecord>(new CallRecordComparator());
+ TreeSet<CallRecord> result
+ = new TreeSet<CallRecord>(new CallRecordComparator());
try
{
// the default ones
History history = this.getHistory(null, null);
- HistoryReader reader = history.getReader();
- addHistorySearchProgressListeners(reader, 1);
+ historyReader = history.getReader();
+ addHistorySearchProgressListeners(historyReader, 1);
QueryResultSet<HistoryRecord> rs
- = reader.findByPeriod(startDate, endDate);
+ = historyReader.findByPeriod(startDate, endDate);
while (rs.hasNext())
{
HistoryRecord hr = rs.next();
result.add(convertHistoryRecordToCallRecord(hr));
}
- removeHistorySearchProgressListeners(reader);
+ removeHistorySearchProgressListeners(historyReader);
}
catch (IOException ex)
{
@@ -247,13 +263,14 @@ public class CallHistoryServiceImpl
*/
public Collection<CallRecord> findLast(int count) throws RuntimeException
{
- TreeSet<CallRecord> result = new TreeSet<CallRecord>(new CallRecordComparator());
+ TreeSet<CallRecord> result
+ = new TreeSet<CallRecord>(new CallRecordComparator());
try
{
// the default ones
History history = this.getHistory(null, null);
- QueryResultSet<HistoryRecord> rs
- = history.getReader().findLast(count);
+ historyReader = history.getReader();
+ QueryResultSet<HistoryRecord> rs = historyReader.findLast(count);
while (rs.hasNext())
{
HistoryRecord hr = rs.next();
@@ -277,21 +294,22 @@ public class CallHistoryServiceImpl
public Collection<CallRecord> findByPeer(String address)
throws RuntimeException
{
- TreeSet<CallRecord> result = new TreeSet<CallRecord>(new CallRecordComparator());
+ TreeSet<CallRecord> result
+ = new TreeSet<CallRecord>(new CallRecordComparator());
try
{
// the default ones
History history = this.getHistory(null, null);
- HistoryReader reader = history.getReader();
- addHistorySearchProgressListeners(reader, 1);
+ historyReader = history.getReader();
+ addHistorySearchProgressListeners(historyReader, 1);
QueryResultSet<HistoryRecord> rs
- = reader.findByKeyword(address, "callParticipantIDs");
+ = historyReader.findByKeyword(address, "callParticipantIDs");
while (rs.hasNext())
{
HistoryRecord hr = rs.next();
result.add(convertHistoryRecordToCallRecord(hr));
}
- removeHistorySearchProgressListeners(reader);
+ removeHistorySearchProgressListeners(historyReader);
}
catch (IOException ex)
{
@@ -364,19 +382,21 @@ public class CallHistoryServiceImpl
String propName = hr.getPropertyNames()[i];
String value = hr.getPropertyValues()[i];
- if(propName.equals(STRUCTURE_NAMES[0]))
- result.setStartTime(new Date(Long.parseLong(value)));
+ if (propName.equals(STRUCTURE_NAMES[0]))
+ result.setProtocolProvider(getProtocolProvider(value));
else if(propName.equals(STRUCTURE_NAMES[1]))
- result.setEndTime(new Date(Long.parseLong(value)));
+ result.setStartTime(new Date(Long.parseLong(value)));
else if(propName.equals(STRUCTURE_NAMES[2]))
- result.setDirection(value);
+ result.setEndTime(new Date(Long.parseLong(value)));
else if(propName.equals(STRUCTURE_NAMES[3]))
- callPeerIDs = getCSVs(value);
+ result.setDirection(value);
else if(propName.equals(STRUCTURE_NAMES[4]))
- callPeerStart = getCSVs(value);
+ callPeerIDs = getCSVs(value);
else if(propName.equals(STRUCTURE_NAMES[5]))
- callPeerEnd = getCSVs(value);
+ callPeerStart = getCSVs(value);
else if(propName.equals(STRUCTURE_NAMES[6]))
+ callPeerEnd = getCSVs(value);
+ else if(propName.equals(STRUCTURE_NAMES[7]))
callPeerStates = getStates(value);
}
@@ -557,10 +577,12 @@ public class CallHistoryServiceImpl
* @param source Contact
* @param destination Contact
*/
- private void writeCall(CallRecord callRecord, Contact source,
- Contact destination)
+ private void writeCall( CallRecordImpl callRecord,
+ Contact source,
+ Contact destination)
{
- try {
+ try
+ {
History history = this.getHistory(source, destination);
HistoryWriter historyWriter = history.getWriter();
@@ -589,6 +611,8 @@ public class CallHistoryServiceImpl
}
historyWriter.addRecord(new String[] {
+ callRecord.getSourceCall().getProtocolProvider()
+ .getAccountID().getAccountUniqueID(),
String.valueOf(callRecord.getStartTime().getTime()),
String.valueOf(callRecord.getEndTime().getTime()),
callRecord.getDirection(),
@@ -596,8 +620,10 @@ public class CallHistoryServiceImpl
callPeerStartTime.toString(),
callPeerEndTime.toString(),
callPeerStates.toString()},
- new Date()); // this date is when the history record is written
- } catch (IOException e)
+ new Date()); // this date is when the history
+ // record is written
+ }
+ catch (IOException e)
{
logger.error("Could not add call to history", e);
}
@@ -646,9 +672,11 @@ public class CallHistoryServiceImpl
*/
public void serviceChanged(ServiceEvent serviceEvent)
{
- Object sService = bundleContext.getService(serviceEvent.getServiceReference());
+ Object sService
+ = bundleContext.getService(serviceEvent.getServiceReference());
- logger.trace("Received a service event for: " + sService.getClass().getName());
+ logger.trace("Received a service event for: "
+ + sService.getClass().getName());
// we don't care if the source service is not a protocol provider
if (! (sService instanceof ProtocolProviderService))
@@ -667,13 +695,12 @@ public class CallHistoryServiceImpl
{
this.handleProviderRemoved( (ProtocolProviderService) sService);
}
-
}
/**
* Used to attach the Call History Service to existing or
- * just registered protocol provider. Checks if the provider has implementation
- * of OperationSetBasicTelephony
+ * just registered protocol provider. Checks if the provider has
+ * implementation of OperationSetBasicTelephony
*
* @param provider ProtocolProviderService
*/
@@ -779,34 +806,6 @@ public class CallHistoryServiceImpl
}
/**
- * Gets all the history readers for the contacts in the given MetaContact
- *
- * @param contact MetaContact
- * @return Hashtable
- */
- private Map<Contact, HistoryReader> getHistoryReaders(MetaContact contact)
- {
- Map<Contact, HistoryReader> readers =
- new Hashtable<Contact, HistoryReader>();
- Iterator<Contact> iter = contact.getContacts();
- while (iter.hasNext())
- {
- Contact item = iter.next();
-
- try
- {
- History history = this.getHistory(null, item);
- readers.put(item, history.getReader());
- }
- catch (IOException e)
- {
- logger.error("Could not read history", e);
- }
- }
- return readers;
- }
-
- /**
* CallListener implementation for incoming calls
* @param event CallEvent
*/
@@ -830,17 +829,8 @@ public class CallHistoryServiceImpl
*/
public void callEnded(CallEvent event)
{
- CallRecordImpl callRecord = findCallRecord(event.getSourceCall());
-
- // no such call
- if (callRecord == null)
- return;
-
- callRecord.setEndTime(new Date());
-
- writeCall(callRecord, null, null);
-
- currentCallRecords.remove(callRecord);
+ // We store the call in the callStateChangeEvent where we
+ // have more information on the previous state of the call.
}
/**
@@ -1027,9 +1017,11 @@ public class CallHistoryServiceImpl
*/
private int getProgressMapping(int historyProgress)
{
- currentProgress += (historyProgress - lastHistoryProgress)/contactCount;
+ currentProgress
+ += (historyProgress - lastHistoryProgress)/contactCount;
- if(historyProgress == HistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE)
+ if(historyProgress
+ == HistorySearchProgressListener.PROGRESS_MAXIMUM_VALUE)
{
currentContactCount++;
lastHistoryProgress = 0;
@@ -1074,18 +1066,93 @@ public class CallHistoryServiceImpl
/**
* Receive events for adding or removing peers from a call
*/
- private class HistoryCallChangeListener
- extends CallChangeAdapter
+ private class HistoryCallChangeListener implements CallChangeListener
{
+ /**
+ * Indicates that a new call peer has joined the source call.
+ *
+ * @param evt the <tt>CallPeerEvent</tt> containing the source call
+ * and call peer.
+ */
public void callPeerAdded(CallPeerEvent evt)
{
handlePeerAdded(evt.getSourceCallPeer());
}
+ /**
+ * Indicates that a call peer has left the source call.
+ *
+ * @param evt the <tt>CallPeerEvent</tt> containing the source call
+ * and call peer.
+ */
public void callPeerRemoved(CallPeerEvent evt)
{
handlePeerRemoved(evt.getSourceCallPeer(),
evt.getSourceCall());
}
+
+ /**
+ * A dummy implementation of this listener's callStateChanged() method.
+ *
+ * @param evt the <tt>CallChangeEvent</tt> instance containing the source
+ * calls and its old and new state.
+ */
+ public void callStateChanged(CallChangeEvent evt)
+ {
+ CallRecordImpl callRecord = findCallRecord(evt.getSourceCall());
+
+ // no such call
+ if (callRecord == null)
+ return;
+
+ if (evt.getNewValue().equals(CallState.CALL_ENDED)
+ && evt.getOldValue().equals(CallState.CALL_INITIALIZATION))
+ {
+ callRecord.setEndTime(callRecord.getStartTime());
+ }
+ else
+ callRecord.setEndTime(new Date());
+
+ writeCall(callRecord, null, null);
+
+ currentCallRecords.remove(callRecord);
+ }
+ }
+
+ /**
+ * Returns the <tt>ProtocolProviderService</tt> corresponding to the given
+ * account identifier.
+ * @param accountUID the identifier of the account.
+ * @return the <tt>ProtocolProviderService</tt> corresponding to the given
+ * account identifier
+ */
+ private ProtocolProviderService getProtocolProvider(String accountUID)
+ {
+ for (ProtocolProviderFactory providerFactory
+ : CallHistoryActivator.getProtocolProviderFactories().values())
+ {
+ ServiceReference serRef;
+
+ for (AccountID accountID : providerFactory.getRegisteredAccounts())
+ {
+ if (accountID.getAccountUniqueID().equals(accountUID))
+ {
+ serRef = providerFactory.getProviderForAccount(accountID);
+
+ return (ProtocolProviderService) CallHistoryActivator
+ .bundleContext.getService(serRef);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Cancels the current find. If there's no find going on, then does nothing.
+ */
+ public void cancelCurrentFind()
+ {
+ if (historyReader != null)
+ historyReader.cancelCurrentFind();
}
}
diff --git a/src/net/java/sip/communicator/impl/callhistory/CallHistorySourceContact.java b/src/net/java/sip/communicator/impl/callhistory/CallHistorySourceContact.java
new file mode 100644
index 0000000..b9f7c8c
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/callhistory/CallHistorySourceContact.java
@@ -0,0 +1,266 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.callhistory;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.callhistory.*;
+import net.java.sip.communicator.service.contactsource.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * The <tt>CallHistorySourceContact</tt> is an implementation of the
+ * <tt>SourceContact</tt> interface based on a <tt>CallRecord</tt>.
+ *
+ * @author Yana Stamcheva
+ */
+public class CallHistorySourceContact implements SourceContact
+{
+ /**
+ * The parent <tt>CallHistoryContactSource</tt>, where this contact is
+ * contained.
+ */
+ private final CallHistoryContactSource contactSource;
+
+ /**
+ * The corresponding call record.
+ */
+ private final CallRecord callRecord;
+
+ /**
+ * The incoming call icon.
+ */
+ private static final byte[] incomingIcon
+ = CallHistoryActivator.getResources()
+ .getImageInBytes("service.gui.icons.INCOMING_CALL");
+
+ /**
+ * The outgoing call icon.
+ */
+ private static byte[] outgoingIcon
+ = CallHistoryActivator.getResources()
+ .getImageInBytes("service.gui.icons.OUTGOING_CALL");
+
+ /**
+ * The missed call icon.
+ */
+ private static byte[] missedCallIcon
+ = CallHistoryActivator.getResources()
+ .getImageInBytes("service.gui.icons.MISSED_CALL");
+
+ /**
+ * A list of all contact details.
+ */
+ private final List<ContactDetail> contactDetails
+ = new LinkedList<ContactDetail>();
+
+ /**
+ * The display name of this contact.
+ */
+ private String displayName = "";
+
+ /**
+ * The display details of this contact.
+ */
+ private final String displayDetails;
+
+ /**
+ * Creates an instance of <tt>CallHistorySourceContact</tt>
+ * @param contactSource
+ * @param callRecord
+ */
+ public CallHistorySourceContact(CallHistoryContactSource contactSource,
+ CallRecord callRecord)
+ {
+ this.contactSource = contactSource;
+ this.callRecord = callRecord;
+
+ this.initPeerDetails();
+
+ this.displayDetails
+ = CallHistoryActivator.getResources()
+ .getI18NString("service.gui.AT") + ": "
+ + getDateString(callRecord.getStartTime().getTime())
+ + " " + CallHistoryActivator.getResources()
+ .getI18NString("service.gui.DURATION") + ": "
+ + GuiUtils.formatTime(
+ GuiUtils.substractDates(
+ callRecord.getEndTime(), callRecord.getStartTime()));
+ }
+
+ /**
+ * Initializes peer details.
+ */
+ private void initPeerDetails()
+ {
+ Iterator<CallPeerRecord> recordsIter
+ = callRecord.getPeerRecords().iterator();
+
+ while (recordsIter.hasNext())
+ {
+ String peerAddress = recordsIter.next().getPeerAddress();
+
+ if (displayName.length() > 0)
+ displayName += "," + peerAddress;
+ else
+ displayName += peerAddress;
+
+ if (peerAddress != null)
+ {
+ ContactDetail contactDetail = new ContactDetail(peerAddress);
+
+ Map<Class<? extends OperationSet>, ProtocolProviderService>
+ preferredProviders = null;
+ if (callRecord.getProtocolProvider() != null)
+ {
+ preferredProviders
+ = new Hashtable<Class<? extends OperationSet>,
+ ProtocolProviderService>();
+
+ preferredProviders.put( OperationSetBasicTelephony.class,
+ callRecord.getProtocolProvider());
+
+ contactDetail
+ .setPreferredProviders(preferredProviders);
+ }
+
+ // Set supported operation sets.
+ LinkedList<Class<? extends OperationSet>> supportedOpSets
+ = new LinkedList<Class<? extends OperationSet>>();
+
+ supportedOpSets.add(OperationSetBasicTelephony.class);
+ contactDetail.setSupportedOpSets(supportedOpSets);
+
+ contactDetails.add(contactDetail);
+ }
+ }
+ }
+
+ /**
+ * Returns a list of available contact details.
+ * @return a list of available contact details
+ */
+ public List<ContactDetail> getContactDetails()
+ {
+ return new LinkedList<ContactDetail>(contactDetails);
+ }
+
+ /**
+ * Returns the parent <tt>ContactSourceService</tt> from which this contact
+ * came from.
+ * @return the parent <tt>ContactSourceService</tt> from which this contact
+ * came from
+ */
+ public ContactSourceService getContactSource()
+ {
+ return contactSource;
+ }
+
+ /**
+ * Returns the display details of this search contact. This could be any
+ * important information that should be shown to the user.
+ *
+ * @return the display details of the search contact
+ */
+ public String getDisplayDetails()
+ {
+ return displayDetails;
+ }
+
+ /**
+ * Returns the display name of this search contact. This is a user-friendly
+ * name that could be shown in the user interface.
+ *
+ * @return the display name of this search contact
+ */
+ public String getDisplayName()
+ {
+ return displayName;
+ }
+
+ /**
+ * An image (or avatar) corresponding to this search contact. If such is
+ * not available this method will return null.
+ *
+ * @return the byte array of the image or null if no image is available
+ */
+ public byte[] getImage()
+ {
+ if (callRecord.getDirection().equals(CallRecord.IN))
+ {
+ if (callRecord.getStartTime().equals(callRecord.getEndTime()))
+ return missedCallIcon;
+ else
+ return incomingIcon;
+ }
+ else if (callRecord.getDirection().equals(CallRecord.OUT))
+ return outgoingIcon;
+
+ return null;
+ }
+
+ /**
+ * Returns a list of all <tt>ContactDetail</tt>s supporting the given
+ * <tt>OperationSet</tt> class.
+ * @param operationSet the <tt>OperationSet</tt> class we're looking for
+ * @return a list of all <tt>ContactDetail</tt>s supporting the given
+ * <tt>OperationSet</tt> class
+ */
+ public List<ContactDetail> getContactDetails(
+ Class<? extends OperationSet> operationSet)
+ {
+ // We support only call details.
+ if (!operationSet.equals(OperationSetBasicTelephony.class))
+ return null;
+
+ return new LinkedList<ContactDetail>(contactDetails);
+ }
+
+ /**
+ * Returns the preferred <tt>ContactDetail</tt> for a given
+ * <tt>OperationSet</tt> class.
+ * @param operationSet the <tt>OperationSet</tt> class, for which we would
+ * like to obtain a <tt>ContactDetail</tt>
+ * @return the preferred <tt>ContactDetail</tt> for a given
+ * <tt>OperationSet</tt> class
+ */
+ public ContactDetail getPreferredContactDetail(
+ Class<? extends OperationSet> operationSet)
+ {
+ // We support only call details.
+ if (!operationSet.equals(OperationSetBasicTelephony.class))
+ return null;
+
+ return contactDetails.get(0);
+ }
+
+ /**
+ * Returns the date string to show for the given date.
+ *
+ * @param date the date to format
+ * @return the date string to show for the given date
+ */
+ public static String getDateString(long date)
+ {
+ String time = GuiUtils.formatTime(date);
+
+ // If the current date we don't go in there and we'll return just the
+ // time.
+ if (GuiUtils.compareDatesOnly(date, System.currentTimeMillis()) < 0)
+ {
+ StringBuffer dateStrBuf = new StringBuffer();
+
+ GuiUtils.formatDate(date, dateStrBuf);
+ dateStrBuf.append(" ");
+ dateStrBuf.append(time);
+ return dateStrBuf.toString();
+ }
+
+ return time;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/callhistory/CallRecordImpl.java b/src/net/java/sip/communicator/impl/callhistory/CallRecordImpl.java
index c52728a..bda0907 100644
--- a/src/net/java/sip/communicator/impl/callhistory/CallRecordImpl.java
+++ b/src/net/java/sip/communicator/impl/callhistory/CallRecordImpl.java
@@ -96,4 +96,13 @@ public class CallRecordImpl
{
this.direction = direction;
}
+
+ /**
+ * Sets the given <tt>ProtocolProviderService</tt> used for the call.
+ * @param pps the <tt>ProtocolProviderService</tt> to set
+ */
+ public void setProtocolProvider(ProtocolProviderService pps)
+ {
+ this.protocolProvider = pps;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf b/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf
index b8db32f..44a6baf 100644
--- a/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf
+++ b/src/net/java/sip/communicator/impl/callhistory/callhistory.manifest.mf
@@ -14,6 +14,9 @@ Import-Package: org.osgi.framework,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.icqconstants,
net.java.sip.communicator.service.protocol.event,
+ net.java.sip.communicator.service.contactsource,
+ net.java.sip.communicator.service.resources
Export-Package: net.java.sip.communicator.service.callhistory,
net.java.sip.communicator.service.callhistory.event
-Metadata-Location: /net/java/sip/communicator/impl/msghistory/callhistory.metadata.xml
+Metadata-Location: net.java.sip.communicator.impl.msghistory,
+ callhistory.metadata.xml