Package org.rssowl.ui.internal.notifier

Source Code of org.rssowl.ui.internal.notifier.NotificationService

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-2006 RSSOwl Development Team                                  **
**   http://www.rssowl.org/                                                 **
**                                                                          **
**   All rights reserved                                                    **
**                                                                          **
**   This program and the accompanying materials are made available under   **
**   the terms of the Eclipse Public License v1.0 which accompanies this    **
**   distribution, and is available at:                                     **
**   http://www.rssowl.org/legal/epl-v10.html                               **
**                                                                          **
**   A copy is found in the file epl-v10.html and important notices to the  **
**   license from the team is found in the textfile LICENSE.txt distributed **
**   in this package.                                                       **
**                                                                          **
**   This copyright notice MUST APPEAR in all copies of the file!           **
**                                                                          **
**   Contributors:                                                          **
**     RSSOwl Development Team - initial API and implementation             **
**                                                                          **
**  **********************************************************************  */

package org.rssowl.ui.internal.notifier;

import org.rssowl.core.Owl;
import org.rssowl.core.internal.persist.pref.DefaultPreferences;
import org.rssowl.core.persist.IBookMark;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.ISearchCondition;
import org.rssowl.core.persist.ISearchMark;
import org.rssowl.core.persist.dao.DynamicDAO;
import org.rssowl.core.persist.event.NewsAdapter;
import org.rssowl.core.persist.event.NewsEvent;
import org.rssowl.core.persist.event.NewsListener;
import org.rssowl.core.persist.event.SearchMarkAdapter;
import org.rssowl.core.persist.event.SearchMarkEvent;
import org.rssowl.core.persist.event.SearchMarkListener;
import org.rssowl.core.persist.pref.IPreferenceScope;
import org.rssowl.core.persist.reference.FeedLinkReference;
import org.rssowl.core.util.BatchedBuffer;
import org.rssowl.ui.internal.ApplicationWorkbenchAdvisor;
import org.rssowl.ui.internal.ApplicationWorkbenchWindowAdvisor;
import org.rssowl.ui.internal.Controller;
import org.rssowl.ui.internal.OwlUI;
import org.rssowl.ui.internal.util.JobRunner;

import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* The <code>NotificationService</code> listens on News being downloaded and
* opens the <code>NotificationPopup</code> to show them in case the
* preferences are set to show notifications.
*
* @author bpasero
*/
public class NotificationService {

  /* Batch News-Events for every 5 seconds */
  private static final int BATCH_INTERVAL = 5000;

  private final NewsListener fNewsListener;
  private SearchMarkListener fSearchMarkListener;
  private final IPreferenceScope fGlobalPreferences;
  private final BatchedBuffer<NotificationItem> fBatchedBuffer;

  /* Singleton instance */
  private static NotificationPopup fgNotificationPopup;

  /** Creates a new Notification Service */
  public NotificationService() {

    /* Process Events batched */
    BatchedBuffer.Receiver<NotificationItem> receiver = new BatchedBuffer.Receiver<NotificationItem>() {
      public void receive(Set<NotificationItem> items) {
        showItems(items);
      }
    };

    fBatchedBuffer = new BatchedBuffer<NotificationItem>(receiver, BATCH_INTERVAL);
    fGlobalPreferences = Owl.getPreferenceService().getGlobalScope();
    fNewsListener = registerNewsListener();
    fSearchMarkListener = registerSearchMarkListener();
  }

  /** Shutdown this Service */
  public void stopService() {
    DynamicDAO.removeEntityListener(INews.class, fNewsListener);
    DynamicDAO.removeEntityListener(ISearchMark.class, fSearchMarkListener);
  }

  private boolean isPopupVisible() {
    return fgNotificationPopup != null;
  }

  /* Listen on News Events */
  private NewsListener registerNewsListener() {
    NewsListener listener = new NewsAdapter() {
      @Override
      public void entitiesAdded(final Set<NewsEvent> events) {
        onNewsAdded(events);
      }
    };

    DynamicDAO.addEntityListener(INews.class, listener);
    return listener;
  }

  /* Listen on Search Mark Events */
  private SearchMarkListener registerSearchMarkListener() {
    SearchMarkListener listener = new SearchMarkAdapter() {
      @Override
      public void resultsChanged(Set<SearchMarkEvent> events) {
        onResultsChanged(events);
      }
    };

    DynamicDAO.addEntityListener(ISearchMark.class, listener);
    return listener;
  }

  private void onResultsChanged(Set<SearchMarkEvent> events) {

    /* Return if Notification is disabled */
    if (!fGlobalPreferences.getBoolean(DefaultPreferences.SHOW_NOTIFICATION_POPUP))
      return;

    /* Filter Events if user decided to show Notifier only for selected Elements */
    Set<SearchMarkEvent> filteredEvents = new HashSet<SearchMarkEvent>(events.size());
    if (fGlobalPreferences.getBoolean(DefaultPreferences.LIMIT_NOTIFIER_TO_SELECTION)) {
      for (SearchMarkEvent event : events) {

        /* Check for new *new* News matching now */
        if (!event.isAddedNewNews())
          continue;

        /* Check for explicit selection */
        IPreferenceScope prefs = Owl.getPreferenceService().getEntityScope(event.getEntity());
        if (prefs.getBoolean(DefaultPreferences.ENABLE_NOTIFIER))
          filteredEvents.add(event);
      }
    }

    /* Filter Events based on other criterias otherwise */
    else {
      for (SearchMarkEvent event : events) {
        ISearchMark searchmark = event.getEntity();
        List<ISearchCondition> conditions = searchmark.getSearchConditions();

        /* Check for new *new* News matching now */
        if (!event.isAddedNewNews())
          continue;

        /* Look for a String search condition that is not Label */
        for (ISearchCondition condition : conditions) {
          if (condition.getValue() instanceof String && condition.getField().getId() != INews.LABEL) {
            filteredEvents.add(event);
            break;
          }
        }
      }
    }

    /* Create Items */
    List<NotificationItem> items = new ArrayList<NotificationItem>(filteredEvents.size());
    for (SearchMarkEvent event : filteredEvents)
      items.add(new SearchNotificationItem(event.getEntity(), event.getEntity().getResultCount(EnumSet.of(INews.State.NEW, INews.State.UNREAD, INews.State.UPDATED))));

    /* Add into Buffer */
    if (!isPopupVisible())
      fBatchedBuffer.addAll(items);

    /* Show Directly */
    else
      showItems(items);
  }

  private void onNewsAdded(Set<NewsEvent> events) {

    /* Return if Notification is disabled */
    if (!fGlobalPreferences.getBoolean(DefaultPreferences.SHOW_NOTIFICATION_POPUP))
      return;

    /* Filter Events if user decided to show Notifier only for selected Elements */
    if (fGlobalPreferences.getBoolean(DefaultPreferences.LIMIT_NOTIFIER_TO_SELECTION)) {
      List<FeedLinkReference> enabledFeeds = new ArrayList<FeedLinkReference>();

      /* TODO This can be slow, try to optimize performance! */
      Set<IBookMark> bookMarks = Controller.getDefault().getCacheService().getBookMarks();
      for (IBookMark bookMark : bookMarks) {
        IPreferenceScope prefs = Owl.getPreferenceService().getEntityScope(bookMark);
        if (prefs.getBoolean(DefaultPreferences.ENABLE_NOTIFIER))
          enabledFeeds.add(bookMark.getFeedLinkReference());
      }

      events = filterEvents(events, enabledFeeds);
    }

    /* Create Items */
    List<NotificationItem> items = new ArrayList<NotificationItem>(events.size());
    for (NewsEvent event : events)
      items.add(new NewsNotificationItem(event.getEntity()));

    /* Add into Buffer */
    if (!isPopupVisible())
      fBatchedBuffer.addAll(items);

    /* Show Directly */
    else
      showItems(items);
  }

  private Set<NewsEvent> filterEvents(Set<NewsEvent> events, List<FeedLinkReference> enabledFeeds) {
    Set<NewsEvent> filteredEvents = new HashSet<NewsEvent>();

    for (NewsEvent event : events) {
      if (enabledFeeds.contains(event.getEntity().getFeedReference()))
        filteredEvents.add(event);
    }

    return filteredEvents;
  }

  /* Show Notification in UI Thread */
  private void showItems(final Collection<NotificationItem> items) {

    /* Ignore empty lists */
    if (items.isEmpty())
      return;

    /* Make sure to run in UI Thread */
    JobRunner.runInUIThread(OwlUI.getPrimaryShell(), new Runnable() {
      public void run() {

        /* Return if Notification should only show when minimized */
        ApplicationWorkbenchWindowAdvisor advisor = ApplicationWorkbenchAdvisor.fgPrimaryApplicationWorkbenchWindowAdvisor;
        boolean minimized = advisor != null && (advisor.isMinimizedToTray() || advisor.isMinimized());
        if (!minimized && fGlobalPreferences.getBoolean(DefaultPreferences.SHOW_NOTIFICATION_POPUP_ONLY_WHEN_MINIMIZED))
          return;

        /* Show News in Popup */
        synchronized (this) {
          if (fgNotificationPopup == null) {
            fgNotificationPopup = new NotificationPopup(items.size()) {
              @Override
              public boolean doClose() {
                fgNotificationPopup = null;
                return super.doClose();
              }
            };
            fgNotificationPopup.open();
          }

          /* Show Items */
          fgNotificationPopup.makeVisible(items);
        }
      }
    });
  }
}
TOP

Related Classes of org.rssowl.ui.internal.notifier.NotificationService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.