Example #1
0
  /**
   * Searches for additional phone numbers found in contact information
   *
   * @return additional phone numbers found in contact information;
   */
  private List<UIContactDetail> getAdditionalNumbers(boolean onlyMobile) {
    List<UIContactDetail> telephonyContacts = new ArrayList<UIContactDetail>();

    Iterator<Contact> contacts = getMetaContact().getContacts();

    while (contacts.hasNext()) {
      Contact contact = contacts.next();
      OperationSetServerStoredContactInfo infoOpSet =
          contact.getProtocolProvider().getOperationSet(OperationSetServerStoredContactInfo.class);
      Iterator<GenericDetail> details;
      ArrayList<String> phones = new ArrayList<String>();

      if (infoOpSet != null) {
        details = infoOpSet.getAllDetailsForContact(contact);

        while (details.hasNext()) {
          GenericDetail d = details.next();

          boolean process = false;

          if (onlyMobile) {
            if (d instanceof MobilePhoneDetail) process = true;
          } else if (d instanceof PhoneNumberDetail
              && !(d instanceof PagerDetail)
              && !(d instanceof FaxDetail)) {
            process = true;
          }

          if (process) {
            PhoneNumberDetail pnd = (PhoneNumberDetail) d;
            if (pnd.getNumber() != null && pnd.getNumber().length() > 0) {
              // skip phones which were already added
              if (phones.contains(pnd.getNumber())) continue;

              phones.add(pnd.getNumber());

              UIContactDetail cd =
                  new UIContactDetailImpl(
                      pnd.getNumber(),
                      pnd.getNumber() + " (" + getLocalizedPhoneNumber(d) + ")",
                      null,
                      new ArrayList<String>(),
                      GuiActivator.getResources().getImage("service.gui.icons.EXTERNAL_PHONE"),
                      null,
                      null,
                      pnd) {
                    @Override
                    public PresenceStatus getPresenceStatus() {
                      return null;
                    }
                  };
              telephonyContacts.add(cd);
            }
          }
        }
      }
    }

    return telephonyContacts;
  }
  /**
   * Permanently removes locally stored message history for the metacontact, remove any recent
   * contacts if any.
   */
  public void eraseLocallyStoredHistory(MetaContact contact) throws IOException {
    List<ComparableEvtObj> toRemove = null;
    synchronized (recentMessages) {
      toRemove = new ArrayList<ComparableEvtObj>();
      Iterator<Contact> iter = contact.getContacts();
      while (iter.hasNext()) {
        Contact item = iter.next();
        String id = item.getAddress();
        ProtocolProviderService provider = item.getProtocolProvider();

        for (ComparableEvtObj msc : recentMessages) {
          if (msc.getProtocolProviderService().equals(provider)
              && msc.getContactAddress().equals(id)) {
            toRemove.add(msc);
          }
        }
      }

      recentMessages.removeAll(toRemove);
    }
    if (recentQuery != null) {
      for (ComparableEvtObj msc : toRemove) {
        recentQuery.fireContactRemoved(msc);
      }
    }
  }
  /**
   * Process list of event objects. Checks whether message source contact already exist for this
   * event object, if yes just update it with the new values (not sure whether we should do this, as
   * it may bring old messages) and if status of provider is changed, init its details, updates its
   * capabilities. It still adds the found messages source contact to the list of the new contacts,
   * as later we will detect this and fire update event. If nothing found a new contact is created.
   *
   * @param res list of event
   * @param cachedRecentMessages list of newly created source contacts or already existed but
   *     updated with corresponding event object
   * @param isStatusChanged whether provider status changed and we are processing
   */
  private void processEventObjects(
      Collection<EventObject> res,
      List<ComparableEvtObj> cachedRecentMessages,
      boolean isStatusChanged) {
    for (EventObject obj : res) {
      ComparableEvtObj oldMsg = findRecentMessage(obj, recentMessages);

      if (oldMsg != null) {
        oldMsg.update(obj); // update

        if (isStatusChanged && recentQuery != null) recentQuery.updateCapabilities(oldMsg, obj);

        // we still add it to cachedRecentMessages
        // later we will find it is duplicate and will fire
        // update event
        if (!cachedRecentMessages.contains(oldMsg)) cachedRecentMessages.add(oldMsg);

        continue;
      }

      oldMsg = findRecentMessage(obj, cachedRecentMessages);

      if (oldMsg == null) {
        oldMsg = new ComparableEvtObj(obj);

        if (isStatusChanged && recentQuery != null) recentQuery.updateCapabilities(oldMsg, obj);

        cachedRecentMessages.add(oldMsg);
      }
    }
  }
  /**
   * When a provider is added. As searching can be slow especially when handling special type of
   * messages (with subType) this need to be run in new Thread.
   *
   * @param provider ProtocolProviderService
   */
  private void handleProviderAddedInSeparateThread(
      ProtocolProviderService provider, boolean isStatusChanged) {
    // lets check if we have cached recent messages for this provider, and
    // fire events if found and are newer

    synchronized (recentMessages) {
      List<ComparableEvtObj> cachedRecentMessages =
          getCachedRecentMessages(provider, isStatusChanged);

      if (cachedRecentMessages.isEmpty()) {
        // maybe there is no cached history for this
        // let's check
        // load it not from cache, but do a local search
        Collection<EventObject> res =
            messageHistoryService.findRecentMessagesPerContact(
                numberOfMessages, provider.getAccountID().getAccountUniqueID(), null, isSMSEnabled);

        List<ComparableEvtObj> newMsc = new ArrayList<ComparableEvtObj>();

        processEventObjects(res, newMsc, isStatusChanged);

        addNewRecentMessages(newMsc);

        for (ComparableEvtObj msc : newMsc) {
          saveRecentMessageToHistory(msc);
        }
      } else addNewRecentMessages(cachedRecentMessages);
    }
  }
  /**
   * Returns the index of the source contact, in the list of recent messages.
   *
   * @param messageSourceContact
   * @return
   */
  int getIndex(MessageSourceContact messageSourceContact) {
    synchronized (recentMessages) {
      for (int i = 0; i < recentMessages.size(); i++)
        if (recentMessages.get(i).equals(messageSourceContact)) return i;

      return -1;
    }
  }
Example #6
0
  /**
   * Returns a list of all <tt>UIContactDetail</tt>s within this <tt>UIContact</tt>.
   *
   * @return a list of all <tt>UIContactDetail</tt>s within this <tt>UIContact</tt>
   */
  public List<UIContactDetail> getContactDetails() {
    List<UIContactDetail> resultList = new LinkedList<UIContactDetail>();

    Iterator<Contact> contacts = metaContact.getContacts();

    while (contacts.hasNext()) {
      resultList.add(new MetaContactDetail(contacts.next()));
    }
    return resultList;
  }
Example #7
0
  /**
   * Returns a list of <tt>UIContactDetail</tt>s supporting the given <tt>OperationSet</tt> class.
   *
   * @param opSetClass the <tt>OperationSet</tt> class we're interested in
   * @return a list of <tt>UIContactDetail</tt>s supporting the given <tt>OperationSet</tt> class
   */
  public List<UIContactDetail> getContactDetailsForOperationSet(
      Class<? extends OperationSet> opSetClass) {
    List<UIContactDetail> resultList = new LinkedList<UIContactDetail>();

    Iterator<Contact> contacts = metaContact.getContactsForOperationSet(opSetClass).iterator();

    while (contacts.hasNext()) {
      resultList.add(new MetaContactDetail(contacts.next()));
    }
    return resultList;
  }
Example #8
0
  /** Initializes all search strings for this <tt>MetaUIGroup</tt>. */
  private void initSearchStrings() {
    searchStrings.add(metaContact.getDisplayName());

    Iterator<Contact> contacts = metaContact.getContacts();
    while (contacts.hasNext()) {
      Contact contact = contacts.next();

      searchStrings.add(contact.getDisplayName());
      searchStrings.add(contact.getAddress());
    }
  }
  /**
   * Searches for contact ids in history of recent messages.
   *
   * @param provider
   * @param after
   * @return
   */
  List<String> getRecentContactIDs(String provider, Date after) {
    List<String> res = new ArrayList<String>();

    try {
      History history = getHistory();

      if (history != null) {
        Iterator<HistoryRecord> recs = history.getReader().findLast(NUMBER_OF_MSGS_IN_HISTORY);
        SimpleDateFormat sdf = new SimpleDateFormat(HistoryService.DATE_FORMAT);

        while (recs.hasNext()) {
          HistoryRecord hr = recs.next();

          String contact = null;
          String recordProvider = null;
          Date timestamp = null;

          for (int i = 0; i < hr.getPropertyNames().length; i++) {
            String propName = hr.getPropertyNames()[i];

            if (propName.equals(STRUCTURE_NAMES[0])) recordProvider = hr.getPropertyValues()[i];
            else if (propName.equals(STRUCTURE_NAMES[1])) contact = hr.getPropertyValues()[i];
            else if (propName.equals(STRUCTURE_NAMES[2])) {
              try {
                timestamp = sdf.parse(hr.getPropertyValues()[i]);
              } catch (ParseException e) {
                timestamp = new Date(Long.parseLong(hr.getPropertyValues()[i]));
              }
            }
          }

          if (recordProvider == null || contact == null) continue;

          if (after != null && timestamp != null && timestamp.before(after)) continue;

          if (recordProvider.equals(provider)) res.add(contact);
        }
      }
    } catch (IOException ex) {
      logger.error("cannot create recent_messages history", ex);
    }

    return res;
  }
  /**
   * Updates the contact sources in the recent query if any. Done here in order to sync with
   * recentMessages instance, and to check for already existing instances of contact sources.
   * Normally called from the query.
   */
  public void updateRecentMessages() {
    if (recentQuery == null) return;

    synchronized (recentMessages) {
      List<SourceContact> currentContactsInQuery = recentQuery.getQueryResults();

      for (ComparableEvtObj evtObj : recentMessages) {
        // the contains will use the correct equals method of
        // the object evtObj
        if (!currentContactsInQuery.contains(evtObj)) {
          MessageSourceContact newSourceContact =
              new MessageSourceContact(evtObj.getEventObject(), MessageSourceService.this);
          newSourceContact.initDetails(evtObj.getEventObject());

          recentQuery.addQueryResult(newSourceContact);
        }
      }
    }
  }
  /** Permanently removes all locally stored message history, remove recent contacts. */
  public void eraseLocallyStoredHistory() throws IOException {
    List<ComparableEvtObj> toRemove = null;
    synchronized (recentMessages) {
      toRemove = new ArrayList<ComparableEvtObj>(recentMessages);

      recentMessages.clear();
    }

    if (recentQuery != null) {
      for (ComparableEvtObj msc : toRemove) {
        recentQuery.fireContactRemoved(msc);
      }
    }
  }
  /** Initializes "select account" spinner with existing accounts. */
  private void initAccountSpinner() {
    Spinner accountsSpiner = (Spinner) findViewById(R.id.selectAccountSpinner);

    Iterator<ProtocolProviderService> providers = AccountUtils.getRegisteredProviders().iterator();

    List<AccountID> accounts = new ArrayList<AccountID>();

    int selectedIdx = -1;
    int idx = 0;

    while (providers.hasNext()) {
      ProtocolProviderService provider = providers.next();

      OperationSet opSet = provider.getOperationSet(OperationSetPresence.class);

      if (opSet == null) continue;

      AccountID account = provider.getAccountID();
      accounts.add(account);
      idx++;

      if (account.isPreferredProvider()) {
        selectedIdx = idx;
      }
    }

    AccountsListAdapter accountsAdapter =
        new AccountsListAdapter(
            this, R.layout.select_account_row, R.layout.select_account_dropdown, accounts, true);
    accountsSpiner.setAdapter(accountsAdapter);

    // if we have only select account option and only one account
    // select the available account
    if (accounts.size() == 1) accountsSpiner.setSelection(0);
    else accountsSpiner.setSelection(selectedIdx);
  }
  /**
   * Permanently removes locally stored message history for the chatroom, remove any recent contacts
   * if any.
   */
  public void eraseLocallyStoredHistory(ChatRoom room) {
    ComparableEvtObj toRemove = null;
    synchronized (recentMessages) {
      for (ComparableEvtObj msg : recentMessages) {
        if (msg.getRoom() != null && msg.getRoom().equals(room)) {
          toRemove = msg;
          break;
        }
      }

      if (toRemove == null) return;

      recentMessages.remove(toRemove);
    }

    if (recentQuery != null) recentQuery.fireContactRemoved(toRemove);
  }
  /**
   * Searches for entries in cached recent messages in history.
   *
   * @param provider the provider which contact messages we will search
   * @param isStatusChanged is the search because of status changed
   * @return entries in cached recent messages in history.
   */
  private List<ComparableEvtObj> getCachedRecentMessages(
      ProtocolProviderService provider, boolean isStatusChanged) {
    String providerID = provider.getAccountID().getAccountUniqueID();
    List<String> recentMessagesContactIDs =
        getRecentContactIDs(
            providerID, recentMessages.size() < numberOfMessages ? null : oldestRecentMessage);

    List<ComparableEvtObj> cachedRecentMessages = new ArrayList<ComparableEvtObj>();

    for (String contactID : recentMessagesContactIDs) {
      Collection<EventObject> res =
          messageHistoryService.findRecentMessagesPerContact(
              numberOfMessages, providerID, contactID, isSMSEnabled);

      processEventObjects(res, cachedRecentMessages, isStatusChanged);
    }

    return cachedRecentMessages;
  }
  /**
   * A provider has been removed.
   *
   * @param provider the ProtocolProviderService that has been unregistered.
   */
  void handleProviderRemoved(ProtocolProviderService provider) {
    // lets remove the recent messages for this provider, and update
    // with recent messages for the available providers
    synchronized (recentMessages) {
      if (provider != null) {
        List<ComparableEvtObj> removedItems = new ArrayList<ComparableEvtObj>();
        for (ComparableEvtObj msc : recentMessages) {
          if (msc.getProtocolProviderService().equals(provider)) removedItems.add(msc);
        }

        recentMessages.removeAll(removedItems);
        if (!recentMessages.isEmpty())
          oldestRecentMessage = recentMessages.get(recentMessages.size() - 1).getTimestamp();
        else oldestRecentMessage = null;

        if (recentQuery != null) {
          for (ComparableEvtObj msc : removedItems) {
            recentQuery.fireContactRemoved(msc);
          }
        }
      }

      // handleProviderRemoved can be invoked due to stopped
      // history service, if this is the case we do not want to
      // update messages
      if (!this.messageHistoryService.isHistoryLoggingEnabled()) return;

      // lets do the same as we enable provider
      // for all registered providers and finally fire events
      List<ComparableEvtObj> contactsToAdd = new ArrayList<ComparableEvtObj>();
      for (ProtocolProviderService pps : messageHistoryService.getCurrentlyAvailableProviders()) {
        contactsToAdd.addAll(getCachedRecentMessages(pps, true));
      }

      addNewRecentMessages(contactsToAdd);
    }
  }
  /**
   * Handles new events.
   *
   * @param obj the event object
   * @param provider the provider
   * @param id the id of the source of the event
   */
  private void handle(EventObject obj, ProtocolProviderService provider, String id) {
    // check if provider - contact exist update message content
    synchronized (recentMessages) {
      ComparableEvtObj existingMsc = null;
      for (ComparableEvtObj msc : recentMessages) {
        if (msc.getProtocolProviderService().equals(provider)
            && msc.getContactAddress().equals(id)) {
          // update
          msc.update(obj);
          updateRecentMessageToHistory(msc);

          existingMsc = msc;
        }
      }

      if (existingMsc != null) {
        Collections.sort(recentMessages);
        oldestRecentMessage = recentMessages.get(recentMessages.size() - 1).getTimestamp();

        if (recentQuery != null) {
          recentQuery.updateContact(existingMsc, existingMsc.getEventObject());
          recentQuery.fireContactChanged(existingMsc);
        }

        return;
      }

      // if missing create source contact
      // and update recent messages, trim and sort
      MessageSourceContact newSourceContact =
          new MessageSourceContact(obj, MessageSourceService.this);
      newSourceContact.initDetails(obj);
      // we have already checked for duplicate
      ComparableEvtObj newMsg = new ComparableEvtObj(obj);
      recentMessages.add(newMsg);

      Collections.sort(recentMessages);
      oldestRecentMessage = recentMessages.get(recentMessages.size() - 1).getTimestamp();

      // trim
      List<ComparableEvtObj> removedItems = null;
      if (recentMessages.size() > numberOfMessages) {
        removedItems =
            new ArrayList<ComparableEvtObj>(
                recentMessages.subList(numberOfMessages, recentMessages.size()));

        recentMessages.removeAll(removedItems);
      }

      // save
      saveRecentMessageToHistory(newMsg);

      // no query nothing to fire
      if (recentQuery == null) return;

      // now fire
      if (removedItems != null) {
        for (ComparableEvtObj msc : removedItems) {
          recentQuery.fireContactRemoved(msc);
        }
      }

      recentQuery.addQueryResult(newSourceContact);
    }
  }
Example #17
0
  /**
   * Loads the tooltip with the data for current metacontact.
   *
   * @param tip the tooltip to fill.
   */
  private void loadTooltip(final ExtendedTooltip tip) {
    Iterator<Contact> i = metaContact.getContacts();

    ContactPhoneUtil contactPhoneUtil = ContactPhoneUtil.getPhoneUtil(metaContact);

    String statusMessage = null;
    Contact protocolContact;
    boolean isLoading = false;
    while (i.hasNext()) {
      protocolContact = i.next();

      // Set the first found status message.
      if (statusMessage == null
          && protocolContact.getStatusMessage() != null
          && protocolContact.getStatusMessage().length() > 0)
        statusMessage = protocolContact.getStatusMessage();

      if (ConfigurationUtils.isHideAccountStatusSelectorsEnabled()) break;

      ImageIcon protocolStatusIcon =
          ImageLoader.getIndexedProtocolIcon(
              ImageUtils.getBytesInImage(protocolContact.getPresenceStatus().getStatusIcon()),
              protocolContact.getProtocolProvider());

      String contactAddress = protocolContact.getAddress();
      // String statusMessage = protocolContact.getStatusMessage();

      tip.addLine(protocolStatusIcon, contactAddress);

      addContactResourceTooltipLines(tip, protocolContact);

      if (!protocolContact.getProtocolProvider().isRegistered()) continue;

      contactPhoneUtil.addDetailsResponseListener(
          protocolContact,
          new OperationSetServerStoredContactInfo.DetailsResponseListener() {
            public void detailsRetrieved(final Iterator<GenericDetail> details) {
              if (!SwingUtilities.isEventDispatchThread()) {
                SwingUtilities.invokeLater(
                    new Runnable() {
                      public void run() {
                        detailsRetrieved(details);
                      }
                    });
                return;
              }

              // remove previously shown information
              // as it contains "Loading..." text
              tip.removeAllLines();

              // load it again
              loadTooltip(tip);
            }
          });

      List<String> phones = contactPhoneUtil.getPhones(protocolContact);

      if (phones != null) {
        addPhoneTooltipLines(tip, phones.iterator());
      } else isLoading = true;
    }

    if (isLoading)
      tip.addLine(null, GuiActivator.getResources().getI18NString("service.gui.LOADING"));

    if (statusMessage != null) tip.setBottomText(statusMessage);
  }
  /**
   * Add the ComparableEvtObj, newly added will fire new, for existing fire update and when trimming
   * the list to desired length fire remove for those that were removed
   *
   * @param contactsToAdd
   */
  private void addNewRecentMessages(List<ComparableEvtObj> contactsToAdd) {
    // now find object to fire new, and object to fire remove
    // let us find duplicates and fire update
    List<ComparableEvtObj> duplicates = new ArrayList<ComparableEvtObj>();
    for (ComparableEvtObj msgToAdd : contactsToAdd) {
      if (recentMessages.contains(msgToAdd)) {
        duplicates.add(msgToAdd);

        // save update
        updateRecentMessageToHistory(msgToAdd);
      }
    }
    recentMessages.removeAll(duplicates);

    // now contacts to add has no duplicates, add them all
    boolean changed = recentMessages.addAll(contactsToAdd);

    if (changed) {
      Collections.sort(recentMessages);

      if (recentQuery != null) {
        for (ComparableEvtObj obj : duplicates)
          recentQuery.updateContact(obj, obj.getEventObject());
      }
    }

    if (!recentMessages.isEmpty())
      oldestRecentMessage = recentMessages.get(recentMessages.size() - 1).getTimestamp();

    // trim
    List<ComparableEvtObj> removedItems = null;
    if (recentMessages.size() > numberOfMessages) {
      removedItems =
          new ArrayList<ComparableEvtObj>(
              recentMessages.subList(numberOfMessages, recentMessages.size()));

      recentMessages.removeAll(removedItems);
    }

    if (recentQuery != null) {
      // now fire, removed for all that were in the list
      // and now are removed after trim
      if (removedItems != null) {
        for (ComparableEvtObj msc : removedItems) {
          if (!contactsToAdd.contains(msc)) recentQuery.fireContactRemoved(msc);
        }
      }

      // fire new for all that were added, and not removed after trim
      for (ComparableEvtObj msc : contactsToAdd) {
        if ((removedItems == null || !removedItems.contains(msc)) && !duplicates.contains(msc)) {
          MessageSourceContact newSourceContact =
              new MessageSourceContact(msc.getEventObject(), MessageSourceService.this);
          newSourceContact.initDetails(msc.getEventObject());

          recentQuery.addQueryResult(newSourceContact);
        }
      }

      // if recent messages were changed, indexes have change lets
      // fire event for the last element which will reorder the whole
      // group if needed.
      if (changed) recentQuery.fireContactChanged(recentMessages.get(recentMessages.size() - 1));
    }
  }
Example #19
0
  /**
   * Returns the default <tt>ContactDetail</tt> to use for any operations depending to the given
   * <tt>OperationSet</tt> class.
   *
   * @param opSetClass the <tt>OperationSet</tt> class we're interested in
   * @return the default <tt>ContactDetail</tt> to use for any operations depending to the given
   *     <tt>OperationSet</tt> class
   */
  public UIContactDetail getDefaultContactDetail(Class<? extends OperationSet> opSetClass) {
    List<UIContactDetail> details = getContactDetailsForOperationSet(opSetClass);

    return (details != null && !details.isEmpty()) ? details.get(0) : null;
  }
Example #20
0
 /**
  * Returns an <tt>Iterator</tt> over a list of strings, which can be used to find this contact.
  *
  * @return an <tt>Iterator</tt> over a list of search strings
  */
 public Iterator<String> getSearchStrings() {
   return searchStrings.iterator();
 }