Package org.rssowl.ui.internal.views.explorer

Source Code of org.rssowl.ui.internal.views.explorer.BookMarkGrouping

/*   **********************************************************************  **
**   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.views.explorer;

import org.eclipse.core.runtime.Assert;
import org.rssowl.core.persist.IBookMark;
import org.rssowl.core.persist.IEntity;
import org.rssowl.core.persist.IFolder;
import org.rssowl.core.persist.IMark;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.INewsBin;
import org.rssowl.core.persist.INewsMark;
import org.rssowl.core.persist.ISearchMark;
import org.rssowl.core.util.DateUtils;
import org.rssowl.ui.internal.EntityGroup;
import org.rssowl.ui.internal.EntityGroupItem;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
import java.util.List;

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

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

  /* Popularity Ratio */
  private static final float VERY_POPULAR_RATIO = 0.8f;
  private static final float POPULAR_RATIO = 0.5f;
  private static final float FAIRLY_POPULAR_RATIO = 0.2f;

  /* ID of Group Category */
  static final String GROUP_CATEGORY_ID = "org.rssowl.ui.internal.views.explorer.BookMarkGrouping"; //$NON-NLS-1$

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

    /** Grouping is Disabled */
    NO_GROUPING,

    /** Group by Last Visit Date */
    GROUP_BY_LAST_VISIT,

    /** Group by Popularity */
    GROUP_BY_POPULARITY,

    /** Group by Type */
    GROUP_BY_TYPE,

    /** Group by State */
    GROUP_BY_STATE
  }

  /** Valid Groups */
  public enum Group {

    /** Group: Visited Today */
    TODAY(Messages.BookMarkGrouping_TODAY),

    /** Group: Visited Yesterday */
    YESTERDAY(Messages.BookMarkGrouping_YESTERDAY),

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

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

    /** Group: Older */
    OLDER(Messages.BookMarkGrouping_MORE_THAN_WEEK),

    /** Group: Never Visited */
    NEVER(Messages.BookMarkGrouping_NEVER),

    /** Group: Very Popular */
    VERY_POPULAR(Messages.BookMarkGrouping_VERY_POPULAR),

    /** Group: Popular */
    POPULAR(Messages.BookMarkGrouping_POPULAR),

    /** Group: Fairly Popular */
    FAIRLY_POPULAR(Messages.BookMarkGrouping_FAILRY_POPULAR),

    /** Group: Unpopular */
    UNPOPULAR(Messages.BookMarkGrouping_UNPOPULAR),

    /** Group: Bins */
    BIN(Messages.BookMarkGrouping_NEWS_BINS),

    /** Group: Searches */
    SEARCH(Messages.BookMarkGrouping_SAVED_SEARCHES),

    /** Group: Bookmarks */
    BOOKMARK(Messages.BookMarkGrouping_BOOKMARKS),

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

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

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

    /** Group: Other */
    OTHER(Messages.BookMarkGrouping_OTHER);

    String fName;

    Group(String name) {
      fName = name;
    }

    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 new Grouping Type.
   */
  public void setType(Type type) {
    fType = type;
  }

  /**
   * 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 EntityGroup[] group(List<? extends IEntity> input) {
    Assert.isTrue(fType != Type.NO_GROUPING, "Grouping is not enabled!"); //$NON-NLS-1$

    /* Group by Last Visit Date */
    if (Type.GROUP_BY_LAST_VISIT == fType)
      return createLastVisitDateGroups(input);

    /* Group by Popularity */
    else if (Type.GROUP_BY_POPULARITY == fType)
      return createPopularityGroups(input);

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

    /* Group by Type */
    else if (Type.GROUP_BY_TYPE == fType)
      return createTypeGroups(input);

    /* Should not happen */
    return new EntityGroup[0];
  }

  /* Create the Group for the Type GROUP_BY_LAST_VISIT */
  private EntityGroup[] createLastVisitDateGroups(List<? extends IEntity> 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());
    EntityGroup gNever = new EntityGroup(Group.NEVER.ordinal(), GROUP_CATEGORY_ID, Group.NEVER.getName());

    /* Group Input */
    for (Object object : input) {
      if (object instanceof IMark) {
        IMark mark = (IMark) object;
        Date lastVisitDate = mark.getLastVisitDate();

        /* Feed was never visited */
        if (lastVisitDate == null)
          new EntityGroupItem(gNever, mark);

        /* Feed was visited Today */
        else if (lastVisitDate.getTime() >= todayMillis)
          new EntityGroupItem(gToday, mark);

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

        /* Feed was visited Earlier this Week */
        else if (lastVisitDate.compareTo(earlierThisWeek) >= 0)
          new EntityGroupItem(gEarlierThisWeek, mark);

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

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

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

  /* Create the Group for the Type GROUP_BY_POPULARITY */
  private EntityGroup[] createPopularityGroups(List<? extends IEntity> input) {

    /* Build Groups */
    EntityGroup gVeryPopular = new EntityGroup(Group.VERY_POPULAR.ordinal(), GROUP_CATEGORY_ID, Group.VERY_POPULAR.getName());
    EntityGroup gPopular = new EntityGroup(Group.POPULAR.ordinal(), GROUP_CATEGORY_ID, Group.POPULAR.getName());
    EntityGroup gFairlyPopular = new EntityGroup(Group.FAIRLY_POPULAR.ordinal(), GROUP_CATEGORY_ID, Group.FAIRLY_POPULAR.getName());
    EntityGroup gUnpopular = new EntityGroup(Group.UNPOPULAR.ordinal(), GROUP_CATEGORY_ID, Group.UNPOPULAR.getName());

    /* Get the Max. Popularity */
    float maxPopularity = -1;
    for (Object object : input) {
      if (object instanceof IMark) {
        IMark bookmark = (IMark) object;
        maxPopularity = Math.max(maxPopularity, bookmark.getPopularity());
      }
    }

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

        float popularity = bookmark.getPopularity();
        float ratio = maxPopularity > 0 ? popularity / maxPopularity : 0;

        /* Feed is Very Popular */
        if (ratio >= VERY_POPULAR_RATIO)
          new EntityGroupItem(gVeryPopular, bookmark);

        /* Feed is Popular */
        else if (ratio >= POPULAR_RATIO)
          new EntityGroupItem(gPopular, bookmark);

        /* Feed is Fairly Popular */
        else if (ratio >= FAIRLY_POPULAR_RATIO)
          new EntityGroupItem(gFairlyPopular, bookmark);

        /* Feed is Unpopular */
        else
          new EntityGroupItem(gUnpopular, bookmark);
      }
    }

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

  /* Create the Group for the Type GROUP_BY_TYPE */
  private EntityGroup[] createTypeGroups(List<? extends IEntity> input) {

    /* Build Groups */
    EntityGroup gBins = new EntityGroup(Group.BIN.ordinal(), GROUP_CATEGORY_ID, Group.BIN.getName());
    EntityGroup gSearches = new EntityGroup(Group.SEARCH.ordinal(), GROUP_CATEGORY_ID, Group.SEARCH.getName());
    EntityGroup gBookmarks = new EntityGroup(Group.BOOKMARK.ordinal(), GROUP_CATEGORY_ID, Group.BOOKMARK.getName());

    /* Group Input */
    for (Object object : input) {

      /* Bookmark */
      if (object instanceof IBookMark)
        new EntityGroupItem(gBookmarks, (IEntity) object);

      /* Bin */
      else if (object instanceof INewsBin)
        new EntityGroupItem(gBins, (IEntity) object);

      /* Saved Search */
      else if (object instanceof ISearchMark)
        new EntityGroupItem(gSearches, (IEntity) object);
    }

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

  /* Create the Group for the Type GROUP_BY_STATE */
  private EntityGroup[] createStateGroups(List<? extends IEntity> input) {

    /* Build Groups */
    EntityGroup gSticky = new EntityGroup(Group.STICKY.ordinal(), GROUP_CATEGORY_ID, Group.STICKY.getName());
    EntityGroup gNew = new EntityGroup(Group.NEW.ordinal(), GROUP_CATEGORY_ID, Group.NEW.getName());
    EntityGroup gUnread = new EntityGroup(Group.UNREAD.ordinal(), GROUP_CATEGORY_ID, Group.UNREAD.getName());
    EntityGroup gOther = new EntityGroup(Group.OTHER.ordinal(), GROUP_CATEGORY_ID, Group.OTHER.getName());

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

        /* Early exclude saved searches (buggy) */
        if (mark instanceof ISearchMark)
          new EntityGroupItem(gOther, mark);

        /* Contains Sticky */
        else if (mark instanceof IBookMark && ((IBookMark) mark).getStickyNewsCount() > 0)
          new EntityGroupItem(gSticky, mark);

        /* Contains New */
        else if (mark.getNewsCount(EnumSet.of(INews.State.NEW)) > 0)
          new EntityGroupItem(gNew, mark);

        /* Contains Unread */
        else if (mark.getNewsCount(EnumSet.of(INews.State.NEW, INews.State.UNREAD, INews.State.UPDATED)) > 0)
          new EntityGroupItem(gUnread, mark);

        /* Other */
        else
          new EntityGroupItem(gOther, mark);
      }
    }

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

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

    return maskedItems.toArray(new EntityGroup[maskedItems.size()]);
  }

  boolean needsRefresh(Class<? extends IEntity> entityClass) {

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

    /* Early handle News */
    if (entityClass.equals(INews.class))
      return fType == Type.GROUP_BY_STATE;

    /* Folder Event (e.g. Mark deleted) */
    if (entityClass.equals(IFolder.class))
      return true;

    /* Bookmark Event */
    if (IBookMark.class.isAssignableFrom(entityClass))
      return true;

    /* Searchmark Event */
    if (ISearchMark.class.isAssignableFrom(entityClass))
      return true;

    /* News Bin Event */
    if (INewsBin.class.isAssignableFrom(entityClass))
      return true;

    return false;
  }

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

Related Classes of org.rssowl.ui.internal.views.explorer.BookMarkGrouping

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.