aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl/callhistory/CallHistorySourceContact.java
blob: 3fe42c55c94027a4cc220682a45c1055e7f88930 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/*
 * 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.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.service.protocol.event.*;
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
    extends DataObject
    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 the contact source
     * @param callRecord the call record
     */
    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(
                    callRecord.getStartTime(), callRecord.getEndTime());
    }

    /**
     * Initializes peer details.
     */
    private void initPeerDetails()
    {
        Iterator<CallPeerRecord> recordsIter
            = callRecord.getPeerRecords().iterator();

        while (recordsIter.hasNext())
        {
            CallPeerRecord peerRecord = recordsIter.next();

            String peerAddress = peerRecord.getPeerAddress();

            if (peerAddress != null)
            {
                ContactDetail contactDetail = new ContactDetail(peerAddress);

                Map<Class<? extends OperationSet>, ProtocolProviderService>
                    preferredProviders = null;
                Map<Class<? extends OperationSet>, String>
                    preferredProtocols = null;

                ProtocolProviderService preferredProvider
                    = callRecord.getProtocolProvider();

                if (preferredProvider != null)
                {
                    preferredProviders
                        = new Hashtable<Class<? extends OperationSet>,
                                        ProtocolProviderService>();

                    OperationSetPresence opSetPres =
                        preferredProvider.getOperationSet(
                                OperationSetPresence.class);

                    Contact contact = null;
                    if(opSetPres != null)
                        contact = opSetPres.findContactByID(peerAddress);

                    OperationSetContactCapabilities opSetCaps =
                        preferredProvider.getOperationSet(
                                OperationSetContactCapabilities.class);

                    if(opSetCaps != null && opSetPres != null)
                    {
                        if(contact != null && opSetCaps.getOperationSet(
                                contact,
                                OperationSetBasicTelephony.class) != null)
                        {
                            preferredProviders.put(
                                    OperationSetBasicTelephony.class,
                                    preferredProvider);
                        }
                    }
                    else
                    {
                        preferredProviders.put(OperationSetBasicTelephony.class,
                                            preferredProvider);
                    }

                    contactDetail.setPreferredProviders(preferredProviders);
                }
                // If there's no preferred provider set we just specify that
                // the SIP protocol should be used for the telephony operation
                // set. This is needed for all history records stored before
                // the protocol provider property had been introduced.
                else
                {
                    preferredProtocols
                        = new Hashtable<Class<? extends OperationSet>,
                                        String>();

                    preferredProtocols.put( OperationSetBasicTelephony.class,
                                            ProtocolNames.SIP);

                    contactDetail.setPreferredProtocols(preferredProtocols);
                }

                LinkedList<Class<? extends OperationSet>> supportedOpSets
                    = new LinkedList<Class<? extends OperationSet>>();

                // if the contat supports call
                if((preferredProviders != null &&
                        preferredProviders.containsKey(
                                OperationSetBasicTelephony.class)) ||
                                (preferredProtocols != null))
                {
                    supportedOpSets.add(OperationSetBasicTelephony.class);
                }

                contactDetail.setSupportedOpSets(supportedOpSets);

                contactDetails.add(contactDetail);

                // Set the displayName.
                String name = peerRecord.getDisplayName();

                if (name == null || name.length() <= 0)
                    name = peerAddress;

                if (displayName == null || displayName.length() <= 0)
                    if (callRecord.getPeerRecords().size() > 1)
                        displayName
                            = "Conference " + name;
                    else
                        displayName = name;

            }
        }
    }

    /**
     * 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 the call record has reason for normal call clearing
            // means it was answered somewhere else and we don't
            // mark it as missed
            if (callRecord.getStartTime().equals(callRecord.getEndTime())
                && (callRecord.getEndReason()
                        != CallPeerChangeEvent.NORMAL_CALL_CLEARING))
                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 a list of all <tt>ContactDetail</tt>s corresponding to the given
     * category.
     * @param category the <tt>OperationSet</tt> class we're looking for
     * @return a list of all <tt>ContactDetail</tt>s corresponding to the given
     * category
     */
    public List<ContactDetail> getContactDetails(String category)
        throws OperationNotSupportedException
    {
        // We don't support category for call history details, so we return null.
        throw new OperationNotSupportedException(
            "Categories are not supported for call history records.");
    }

    /**
     * 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;
    }

    /**
     * Returns the status of the source contact. And null if such information
     * is not available.
     * @return the PresenceStatus representing the state of this source contact.
     */
    public PresenceStatus getPresenceStatus()
    {
        return null;
    }
}