Package org.rssowl.ui.internal.editors.feed

Source Code of org.rssowl.ui.internal.editors.feed.NewsGrouping

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-2009 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.editors.feed;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.resource.ImageDescriptor;
import org.rssowl.core.internal.InternalOwl;
import org.rssowl.core.persist.IBookMark;
import org.rssowl.core.persist.ICategory;
import org.rssowl.core.persist.IEntity;
import org.rssowl.core.persist.ILabel;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.IPerson;
import org.rssowl.core.persist.ISearchMark;
import org.rssowl.core.persist.dao.DynamicDAO;
import org.rssowl.core.persist.dao.IBookMarkDAO;
import org.rssowl.core.persist.event.ModelEvent;
import org.rssowl.core.persist.reference.FeedLinkReference;
import org.rssowl.core.util.CoreUtils;
import org.rssowl.core.util.DateUtils;
import org.rssowl.core.util.StringUtils;
import org.rssowl.ui.internal.EntityGroup;
import org.rssowl.ui.internal.EntityGroupItem;
import org.rssowl.ui.internal.OwlUI;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**
* @author bpasero
*/
public class NewsGrouping {

  /* Some Date Constants */
  private static final long DAY = 24 * 60 * 60 * 1000;
  private static final long WEEK = 7 * DAY;

  /* ID Ranges */
  private static final int TITLE_ID_BEGIN = 1000;
  private static final int LABEL_ID_BEGIN = 2000;
  private static final int CATEGORY_ID_BEGIN = 3000;
  private static final int AUTHOR_ID_BEGIN = 4000;

  /** ID of News Group Category */
  public static final String GROUP_CATEGORY_ID = "org.rssowl.ui.internal.editors.feed.NewsGrouping"; //$NON-NLS-1$

  /** Supported Grouping Types */
  public enum Type {

    /** Grouping is Disabled */
    NO_GROUPING(Messages.NewsGrouping_NO_GROUPING, Messages.NewsGrouping_UNGROUPED),

    /** Group by Date */
    GROUP_BY_DATE(Messages.NewsGrouping_GROUP_BY_DATE, Messages.NewsGrouping_GROUPED_BY_DATE),

    /** Group by State */
    GROUP_BY_STATE(Messages.NewsGrouping_GROUP_BY_STATE, Messages.NewsGrouping_GROUPED_BY_STATE),

    /** Group by Author */
    GROUP_BY_AUTHOR(Messages.NewsGrouping_GROUP_BY_AUTHOR, Messages.NewsGrouping_GROUPED_BY_AUTHOR),

    /** Group by Category */
    GROUP_BY_CATEGORY(Messages.NewsGrouping_GROUP_BY_CATEGORY, Messages.NewsGrouping_GROUPED_BY_CATEGORY),

    /** Group by Title */
    GROUP_BY_TOPIC(Messages.NewsGrouping_GROUP_BY_TITLE, Messages.NewsGrouping_GROUPED_BY_TITLE),

    /** Group by Feed */
    GROUP_BY_FEED(Messages.NewsGrouping_GROUP_BY_FEED, Messages.NewsGrouping_GROUPED_BY_FEED),

    /** Group by Label */
    GROUP_BY_LABEL(Messages.NewsGrouping_GROUP_BY_LABEL, Messages.NewsGrouping_GROUPED_BY_LABEL),

    /** Group by Rating */
    GROUP_BY_RATING(Messages.NewsGrouping_GROUP_BY_RATING, Messages.NewsGrouping_GROUPED_BY_RATING),

    /** Group by Stickyness */
    GROUP_BY_STICKY(Messages.NewsGrouping_GROUP_BY_STICKY, Messages.NewsGrouping_GROUPED_BY_STICKY);

    String fActionName;
    String fDisplayName;

    Type(String actionName, String displayName) {
      fActionName = actionName;
      fDisplayName = displayName;
    }

    /**
     * Returns a human-readable Action Name of this enum-value.
     *
     * @return A human-readable Action Name of this enum-value.
     */
    public String getName() {
      return fActionName;
    }

    /**
     * @return the display name when this grouping is active.
     */
    public String getDisplayName() {
      return fDisplayName;
    }
  }

  /** Groups */
  public enum Group {

    /** Group: No Topic */
    NO_TOPIC(Messages.NewsGrouping_NO_TOPIC),

    /** Group: Unknown Category */
    UNKNOWN_CATEGORY(Messages.NewsGrouping_UNKNOWN_CATEGORY),

    /** Group: Unknown Author */
    UNKNOWN_AUTHOR(Messages.NewsGrouping_UNKNOWN_AUTHOR),

    /** Group: None (alternative default) */
    NONE(Messages.NewsGrouping_NONE),

    /** Group: Today */
    TODAY(Messages.NewsGrouping_TODAY),

    /** Group: Yesterday */
    YESTERDAY(Messages.NewsGrouping_YESTERDAY),

    /** Group: Earlier this Week */
    EARLIER_THIS_WEEK(Messages.NewsGrouping_EARLIER_THIS_WEEK),

    /** Group: Last Week */
    LAST_WEEK(Messages.NewsGrouping_LAST_WEEK),

    /** Group: Older News */
    OLDER(Messages.NewsGrouping_OLDER_NEWS),

    /** Group: Fantastic */
    FANTASTIC(Messages.NewsGrouping_FANTASTIC),

    /** Group: Good */
    GOOD(Messages.NewsGrouping_GOOD),

    /** Group: Moderate */
    MODERATE(Messages.NewsGrouping_MODERATE),

    /** Group: Bad */
    BAD(Messages.NewsGrouping_BAD),

    /** Group: Very Bad */
    VERY_BAD(Messages.NewsGrouping_UNRATED),

    /** Group: New */
    NEW(Messages.NewsGrouping_NEW),

    /** Group: Updated */
    UPDATED(Messages.NewsGrouping_UPDATED),

    /** Group: Unread */
    UNREAD(Messages.NewsGrouping_UNREAD),

    /** Group: Read */
    READ(Messages.NewsGrouping_READ),

    /** Group: Sticky */
    STICKY(Messages.NewsGrouping_STICKY),

    /** Group: Not Sticky */
    NOT_STICKY(Messages.NewsGrouping_NOT_STICKY);

    String fName;

    Group(String name) {
      fName = name;
    }

    /**
     * Returns a human-readable Name of this enum-value.
     *
     * @return A human-readable Name of this enum-value.
     */
    public String getName() {
      return fName;
    }
  }

  /* Current Type of Grouping */
  private Type fType = Type.NO_GROUPING;

  /* Get the Type of grouping as defined in the Type Enum */
  Type getType() {
    return fType;
  }

  /**
   * Set the Type of grouping as defined in the Type Enum
   *
   * @param type The type of grouping.
   */
  public void setType(Type type) {
    fType = type;
  }

  boolean needsRefresh(Class<? extends IEntity> entity, Set<? extends ModelEvent> events, boolean isUpdate) {

    /* In case the Grouping is not active at all */
    if (fType == Type.NO_GROUPING)
      return false;

    /* News Event */
    if (entity.equals(INews.class)) {

      /* Update if a News got Deleted or Restored */
      if (CoreUtils.gotDeleted(events) || CoreUtils.gotRestored(events))
        return true;

      /* Check in dependence of Group Type */
      if (fType == Type.GROUP_BY_STATE)
        return CoreUtils.isStateChange(events);
      else if (fType == Type.GROUP_BY_DATE)
        return CoreUtils.isDateChange(events);
      else if (fType == Type.GROUP_BY_AUTHOR)
        return CoreUtils.isAuthorChange(events);
      else if (fType == Type.GROUP_BY_CATEGORY)
        return CoreUtils.isCategoryChange(events);
      else if (fType == Type.GROUP_BY_LABEL)
        return CoreUtils.isLabelChange(events);
      else if (fType == Type.GROUP_BY_FEED && isUpdate) //TODO To be reconsidered when News can be reparented
        return false;
      else if (fType == Type.GROUP_BY_TOPIC)
        return CoreUtils.isTitleChange(events);
      else if (fType == Type.GROUP_BY_STICKY)
        return CoreUtils.isStickyStateChange(events);
      else if (fType == Type.GROUP_BY_RATING)
        return false;

      return true;
    }

    /* Return TRUE in this case for now */
    else if (entity.equals(ISearchMark.class))
      return true;

    return false;
  }

  /**
   * Group the Input based on the selected Type
   *
   * @param input The Input to Group.
   * @return The Input grouped in an array of EntityGroup, as specified by the
   * Type of Group.
   */
  public Collection<EntityGroup> group(Collection<INews> input) {
    Assert.isTrue(fType != Type.NO_GROUPING, "Grouping is not enabled!"); //$NON-NLS-1$

    /* In case the List is empty */
    if (input.size() == 0)
      return new ArrayList<EntityGroup>(0);

    /* Group by Date */
    if (Type.GROUP_BY_DATE == fType)
      return createDateGroups(input);

    /* Group by State */
    else if (Type.GROUP_BY_STATE == fType)
      return createStateGroups(input);

    /* Group by Author */
    else if (Type.GROUP_BY_AUTHOR == fType)
      return createAuthorGroups(input);

    /* Group by Category */
    else if (Type.GROUP_BY_CATEGORY == fType)
      return createCategoryGroups(input);

    /* Group by State */
    else if (Type.GROUP_BY_LABEL == fType)
      return createLabelGroups(input);

    /* Group by State */
    else if (Type.GROUP_BY_RATING == fType)
      return createRatingGroups(input);

    /* Group by Feed */
    else if (Type.GROUP_BY_FEED == fType)
      return createFeedGroups(input);

    /* Group by Stickyness */
    else if (Type.GROUP_BY_STICKY == fType)
      return createStickyGroups(input);

    /* Group by Title */
    else if (Type.GROUP_BY_TOPIC == fType)
      return createTopicGroups(input);

    /* Should not happen */
    return new ArrayList<EntityGroup>(0);
  }

  private List<EntityGroup> createTopicGroups(Collection<INews> input) {

    /* Default Group */
    EntityGroup gDefault = new EntityGroup(Group.NO_TOPIC.ordinal(), GROUP_CATEGORY_ID, Group.NO_TOPIC.getName());

    Map<String, EntityGroup> groupCache = new HashMap<String, EntityGroup>();
    groupCache.put(Group.NO_TOPIC.getName(), gDefault);

    /* Group Input */
    int nextId = Group.NO_TOPIC.ordinal() + TITLE_ID_BEGIN;
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;
        EntityGroup group = gDefault;

        /* Normalize Title */
        String normalizedTitle = CoreUtils.getHeadline(news, true);
        normalizedTitle = CoreUtils.normalizeTitle(normalizedTitle);

        /* Determine Group ID */
        String groupId;
        if (StringUtils.isSet(news.getInReplyTo()))
          groupId = news.getInReplyTo();
        else
          groupId = normalizedTitle;

        /* Add or Create Group */
        if (StringUtils.isSet(groupId)) {
          group = groupCache.get(groupId);

          /* Create new Group */
          if (group == null) {
            group = new EntityGroup(nextId++, GROUP_CATEGORY_ID, normalizedTitle);
            groupCache.put(groupId, group);
          }
        }

        /* Add to Group */
        new EntityGroupItem(group, news);
      }
    }

    /* Select all that are non empty */
    return maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(groupCache.values().toArray(new EntityGroup[groupCache.values().size()]))));
  }

  private List<EntityGroup> createStickyGroups(Collection<INews> input) {

    /* Build Groups */
    EntityGroup gSticky = new EntityGroup(Group.STICKY.ordinal(), GROUP_CATEGORY_ID, Group.STICKY.getName());
    EntityGroup gNotSticky = new EntityGroup(Group.NOT_STICKY.ordinal(), GROUP_CATEGORY_ID, Group.NOT_STICKY.getName());

    /* Group Input */
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;

        /* Sticky */
        if (news.isFlagged())
          new EntityGroupItem(gSticky, news);

        /* Not Sticky */
        else
          new EntityGroupItem(gNotSticky, news);
      }
    }

    /* Select all that are non empty */
    return maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(new EntityGroup[] { gSticky, gNotSticky })));
  }

  private Collection<EntityGroup> createFeedGroups(Collection<INews> input) {
    Map<Long, EntityGroup> groupCache = new HashMap<Long, EntityGroup>();
    IBookMarkDAO bookmarkDao = DynamicDAO.getDAO(IBookMarkDAO.class);
    Map<FeedLinkReference, IBookMark> feedToBookMarkCache = new HashMap<FeedLinkReference, IBookMark>();

    /* Group Input */
    int nextId = 0;
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;
        FeedLinkReference feedRef = news.getFeedReference();

        IBookMark bookmark = feedToBookMarkCache.get(feedRef);
        if (bookmark == null) {
          Collection<IBookMark> bookmarks = bookmarkDao.loadAll(feedRef);
          if (bookmarks.isEmpty())
            continue;

          bookmark = bookmarks.iterator().next();
          feedToBookMarkCache.put(feedRef, bookmark);
        }

        EntityGroup group = groupCache.get(bookmark.getId());
        if (group == null) {
          String name = bookmark.getName();
          group = new EntityGroup(nextId++, GROUP_CATEGORY_ID, name);

          if (!InternalOwl.TESTING) {
            ImageDescriptor feedIcon = OwlUI.getFavicon(bookmark);
            group.setImage(feedIcon != null ? feedIcon : OwlUI.BOOKMARK);
          }

          /* Cache */
          groupCache.put(bookmark.getId(), group);
        }

        new EntityGroupItem(group, news);
      }
    }

    /* Select all that are non empty */
    return sort(maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(groupCache.values().toArray(new EntityGroup[groupCache.values().size()])))));
  }

  private List<EntityGroup> createRatingGroups(Collection<INews> input) {

    /* Build Groups */
    EntityGroup gFantastic = new EntityGroup(Group.FANTASTIC.ordinal(), GROUP_CATEGORY_ID, Group.FANTASTIC.getName());
    EntityGroup gGood = new EntityGroup(Group.GOOD.ordinal(), GROUP_CATEGORY_ID, Group.GOOD.getName());
    EntityGroup gModerate = new EntityGroup(Group.MODERATE.ordinal(), GROUP_CATEGORY_ID, Group.MODERATE.getName());
    EntityGroup gBad = new EntityGroup(Group.BAD.ordinal(), GROUP_CATEGORY_ID, Group.BAD.getName());
    EntityGroup gVeryBad = new EntityGroup(Group.VERY_BAD.ordinal(), GROUP_CATEGORY_ID, Group.VERY_BAD.getName());

    /* Group Input */
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;

        if (news.getRating() >= 80)
          new EntityGroupItem(gFantastic, news);
        else if (news.getRating() >= 60)
          new EntityGroupItem(gGood, news);
        else if (news.getRating() >= 40)
          new EntityGroupItem(gModerate, news);
        else if (news.getRating() >= 20)
          new EntityGroupItem(gBad, news);
        else
          new EntityGroupItem(gVeryBad, news);
      }
    }

    /* Select all that are non empty */
    return maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(new EntityGroup[] { gFantastic, gGood, gModerate, gBad, gVeryBad })));
  }

  private Collection<EntityGroup> createLabelGroups(Collection<INews> input) {

    /* Default Group */
    EntityGroup gDefault = new EntityGroup(Group.NONE.ordinal(), GROUP_CATEGORY_ID, Messages.NewsGrouping_UNLABELED, Integer.MAX_VALUE, null);

    Map<String, EntityGroup> groupCache = new HashMap<String, EntityGroup>();
    groupCache.put(Group.NONE.getName(), gDefault);

    /* Group Input */
    int nextId = Group.NONE.ordinal() + LABEL_ID_BEGIN;
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;
        Set<ILabel> labels = CoreUtils.getSortedLabels(news);
        EntityGroup group = gDefault;

        if (!labels.isEmpty()) {
          ILabel label = labels.iterator().next();
          String name = label.getName();
          group = groupCache.get(name);
          if (group == null) {
            group = new EntityGroup(nextId++, GROUP_CATEGORY_ID, name, label.getOrder(), OwlUI.getRGB(label));
            groupCache.put(name, group);
          }
        }

        new EntityGroupItem(group, news);
      }
    }

    /* Select all that are non empty */
    return sort(maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(groupCache.values().toArray(new EntityGroup[groupCache.values().size()])))));
  }

  private Collection<EntityGroup> createCategoryGroups(Collection<INews> input) {

    /* Default Group */
    EntityGroup gDefault = new EntityGroup(Group.UNKNOWN_CATEGORY.ordinal(), GROUP_CATEGORY_ID, Group.UNKNOWN_CATEGORY.getName());

    Map<String, EntityGroup> groupCache = new HashMap<String, EntityGroup>();
    groupCache.put(Group.UNKNOWN_CATEGORY.getName(), gDefault);

    /* Group Input */
    int nextId = Group.UNKNOWN_CATEGORY.ordinal() + CATEGORY_ID_BEGIN;
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;
        List<ICategory> categories = news.getCategories();
        EntityGroup group = gDefault;

        if (categories.size() > 0) {
          String name = categories.get(0).getName();
          if (!StringUtils.isSet(name))
            name = Group.UNKNOWN_CATEGORY.getName();

          group = groupCache.get(name);
          if (group == null) {
            group = new EntityGroup(nextId++, GROUP_CATEGORY_ID, name);
            groupCache.put(name, group);
          }
        }

        new EntityGroupItem(group, news);
      }
    }

    /* Select all that are non empty */
    return sort(maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(groupCache.values().toArray(new EntityGroup[groupCache.values().size()])))));
  }

  private Collection<EntityGroup> createAuthorGroups(Collection<INews> input) {

    /* Default Group */
    EntityGroup gDefault = new EntityGroup(Group.UNKNOWN_AUTHOR.ordinal(), GROUP_CATEGORY_ID, Group.UNKNOWN_AUTHOR.getName());

    Map<String, EntityGroup> groupCache = new HashMap<String, EntityGroup>();
    groupCache.put(Group.UNKNOWN_AUTHOR.getName(), gDefault);

    /* Group Input */
    int nextId = Group.UNKNOWN_AUTHOR.ordinal() + AUTHOR_ID_BEGIN;
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;
        IPerson author = news.getAuthor();
        EntityGroup group = gDefault;

        if (author != null) {
          String name = author.getName();
          if (!StringUtils.isSet(name))
            name = Group.UNKNOWN_AUTHOR.getName();

          group = groupCache.get(name);
          if (group == null) {
            group = new EntityGroup(nextId++, GROUP_CATEGORY_ID, name);
            groupCache.put(name, group);
          }
        }

        new EntityGroupItem(group, news);
      }
    }

    /* Select all that are non empty */
    return sort(maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(groupCache.values().toArray(new EntityGroup[groupCache.values().size()])))));
  }

  private List<EntityGroup> createStateGroups(Collection<INews> input) {

    /* Build Groups */
    EntityGroup gNew = new EntityGroup(Group.NEW.ordinal(), GROUP_CATEGORY_ID, Group.NEW.getName());
    EntityGroup gUpdated = new EntityGroup(Group.UPDATED.ordinal(), GROUP_CATEGORY_ID, Group.UPDATED.getName());
    EntityGroup gUnread = new EntityGroup(Group.UNREAD.ordinal(), GROUP_CATEGORY_ID, Group.UNREAD.getName());
    EntityGroup gRead = new EntityGroup(Group.READ.ordinal(), GROUP_CATEGORY_ID, Group.READ.getName());

    /* Group Input */
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;

        /* New */
        if (INews.State.NEW.equals(news.getState()))
          new EntityGroupItem(gNew, news);

        /* Updated */
        else if (INews.State.UPDATED.equals(news.getState()))
          new EntityGroupItem(gUpdated, news);

        /* Unread */
        else if (INews.State.UNREAD.equals(news.getState()))
          new EntityGroupItem(gUnread, news);

        /* Read */
        else if (INews.State.READ.equals(news.getState()))
          new EntityGroupItem(gRead, news);
      }
    }

    /* Select all that are non empty */
    return maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(new EntityGroup[] { gNew, gUpdated, gUnread, gRead })));
  }

  private List<EntityGroup> createDateGroups(Collection<INews> input) {

    /* Today */
    Calendar today = DateUtils.getToday();
    long todayMillis = today.getTimeInMillis();

    /* Yesterday */
    Date yesterday = new Date(todayMillis - DAY);

    /* Earlier this Week */
    today.set(Calendar.DAY_OF_WEEK, today.getFirstDayOfWeek());
    Date earlierThisWeek = today.getTime();

    /* Last Week */
    Date lastWeek = new Date(earlierThisWeek.getTime() - WEEK);

    /* Build Groups */
    EntityGroup gToday = new EntityGroup(Group.TODAY.ordinal(), GROUP_CATEGORY_ID, Group.TODAY.getName());
    EntityGroup gYesterday = new EntityGroup(Group.YESTERDAY.ordinal(), GROUP_CATEGORY_ID, Group.YESTERDAY.getName());
    EntityGroup gEarlierThisWeek = new EntityGroup(Group.EARLIER_THIS_WEEK.ordinal(), GROUP_CATEGORY_ID, Group.EARLIER_THIS_WEEK.getName());
    EntityGroup gLastWeek = new EntityGroup(Group.LAST_WEEK.ordinal(), GROUP_CATEGORY_ID, Group.LAST_WEEK.getName());
    EntityGroup gOlder = new EntityGroup(Group.OLDER.ordinal(), GROUP_CATEGORY_ID, Group.OLDER.getName());

    /* Group Input */
    for (Object object : input) {
      if (object instanceof INews) {
        INews news = (INews) object;
        Date date = DateUtils.getRecentDate(news);

        /* Feed was visited Today */
        if (date.getTime() >= todayMillis)
          new EntityGroupItem(gToday, news);

        /* Feed was visited Yesterday */
        else if (date.compareTo(yesterday) >= 0)
          new EntityGroupItem(gYesterday, news);

        /* Feed was visited Two Weeks Ago */
        else if (date.compareTo(earlierThisWeek) >= 0)
          new EntityGroupItem(gEarlierThisWeek, news);

        /* Feed was visited Last Week */
        else if (date.compareTo(lastWeek) >= 0)
          new EntityGroupItem(gLastWeek, news);

        /* Feed was visited more than a Week ago */
        else
          new EntityGroupItem(gOlder, news);
      }
    }

    /* Select all that are non empty */
    return maskEmpty(new ArrayList<EntityGroup>(Arrays.asList(new EntityGroup[] { gToday, gYesterday, gEarlierThisWeek, gLastWeek, gOlder })));
  }

  private List<EntityGroup> maskEmpty(List<EntityGroup> items) {
    List<EntityGroup> maskedItems = new ArrayList<EntityGroup>();
    for (EntityGroup item : items) {
      if (item.size() > 0)
        maskedItems.add(item);
    }

    return maskedItems;
  }

  private Collection<EntityGroup> sort(List<EntityGroup> items) {
    Set<EntityGroup> sortedItems = new TreeSet<EntityGroup>(new Comparator<EntityGroup>() {
      public int compare(EntityGroup o1, EntityGroup o2) {
        if (o1.getSortKey() != null && o2.getSortKey() != null) {
          if (o1.getSortKey().equals(o2.getSortKey()))
            return -1;

          return o1.getSortKey().compareTo(o2.getSortKey());
        }

        if (o1.getName().equalsIgnoreCase(o2.getName())) //Duplicate names are allowed!
          return -1;

        return o1.getName().compareToIgnoreCase(o2.getName());
      }
    });

    sortedItems.addAll(items);
    return sortedItems;
  }

  boolean isActive() {
    return fType != Type.NO_GROUPING;
  }
}
TOP

Related Classes of org.rssowl.ui.internal.editors.feed.NewsGrouping

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.