Package org.rssowl.ui.internal

Source Code of org.rssowl.ui.internal.FolderNewsMark$FolderNewsMarkReference

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

import org.rssowl.core.internal.persist.Mark;
import org.rssowl.core.internal.persist.NewsContainer;
import org.rssowl.core.persist.IBookMark;
import org.rssowl.core.persist.IFolder;
import org.rssowl.core.persist.IFolderChild;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.INewsBin;
import org.rssowl.core.persist.INewsMark;
import org.rssowl.core.persist.INews.State;
import org.rssowl.core.persist.reference.FeedLinkReference;
import org.rssowl.core.persist.reference.ModelReference;
import org.rssowl.core.persist.reference.NewsReference;
import org.rssowl.core.persist.service.PersistenceException;

import java.io.Serializable;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* An internal subclass of {@link Mark} that implements {@link INewsMark} to
* provide the news of all bookmarks, bins and saved searches inside a folder.
* The {@link FolderNewsMark} is created dynamically whenever a folder is opened
* in the feedview and is never persisted to the DB.
* <p>
* TODO This class is not very good in terms of performance because it has to
* load all news of the folder on the fly to produce the news container. When then
* opened from the feedview, these news get resolved again and thereby twice.
* </p>
*
* @author bpasero
*/
@SuppressWarnings("restriction")
public class FolderNewsMark extends Mark implements INewsMark {
  private NewsContainer fNewsContainer;
  private final IFolder fFolder;

  /**
   * Internal implementation of the <code>ModelReference</code> for the internal
   * Type <code>FolderNewsMark</code>.
   *
   * @author bpasero
   */
  public static final class FolderNewsMarkReference extends ModelReference {

    /**
     * @param id
     */
    public FolderNewsMarkReference(long id) {
      super(id, FolderNewsMark.class);
    }

    @Override
    public IFolder resolve() throws PersistenceException {
      throw new UnsupportedOperationException();
    }
  }

  /**
   * @param folder
   */
  public FolderNewsMark(IFolder folder) {
    super(folder.getId(), folder.getParent(), folder.getName());
    fFolder = folder;
    fNewsContainer = new NewsContainer(Collections.<INews.State, Boolean> emptyMap());
    fillNews(folder);
  }

  private void fillNews(IFolder folder) {
    List<IFolderChild> children = folder.getChildren();
    for (IFolderChild child : children) {
      if (child instanceof INewsMark) {
        INewsMark newsmark = (INewsMark) child;
        List<INews> news = newsmark.getNews(INews.State.getVisible());
        for (INews newsitem : news) {
          if (newsitem != null && newsitem.getId() != null)
            fNewsContainer.addNews(newsitem);
        }
      }

      /* Recursively treat Folders */
      if (child instanceof IFolder)
        fillNews((IFolder) child);
    }
  }

  /**
   * @return the {@link IFolder} that serves as input to this {@link INewsMark}.
   */
  public IFolder getFolder() {
    return fFolder;
  }

  /*
   * @see org.rssowl.core.internal.persist.AbstractEntity#setProperty(java.lang.String, java.io.Serializable)
   */
  @Override
  public synchronized void setProperty(String key, Serializable value) {
    fFolder.setProperty(key, value);
  }

  /*
   * @see org.rssowl.core.internal.persist.Mark#getName()
   */
  @Override
  public synchronized String getName() {
    return fFolder.getName();
  }

  /*
   * @see org.rssowl.core.internal.persist.AbstractEntity#getProperties()
   */
  @Override
  public synchronized Map<String, Serializable> getProperties() {
    return fFolder.getProperties();
  }

  /*
   * @see org.rssowl.core.internal.persist.AbstractEntity#getProperty(java.lang.String)
   */
  @Override
  public synchronized Object getProperty(String key) {
    return fFolder.getProperty(key);
  }

  /*
   * @see org.rssowl.core.internal.persist.Mark#getParent()
   */
  /*
   * @see org.rssowl.core.internal.persist.Mark#getParent()
   */
  @Override
  public synchronized IFolder getParent() {
    return fFolder.getParent();
  }

  /**
   * @param news
   * @return <code>true</code> if the given News belongs to any
   * {@link IBookMark} or {@link INewsBin} of the given {@link IFolder}.
   */
  public boolean isRelatedTo(INews news) {

    /* Might be contained */
    if (containsNews(news))
      return true;

    FeedLinkReference feedRef = news.getFeedReference();
    return isRelatedTo(fFolder, news, feedRef);
  }

  private boolean isRelatedTo(IFolder folder, INews news, FeedLinkReference ref) {
    List<IFolderChild> children = folder.getChildren();

    for (IFolderChild child : children) {

      /* Check contained in Folder */
      if (child instanceof IFolder && isRelatedTo((IFolder) child, news, ref))
        return true;

      /* News could be part of the Feed (but is no copy) */
      else if (news.getParentId() == 0 && child instanceof IBookMark) {
        IBookMark bookmark = (IBookMark) child;
        if (bookmark.getFeedLinkReference().equals(ref))
          return true;
      }

      /* News could be part of Bin (and is a copy) */
      else if (news.getParentId() != 0 && child instanceof INewsBin) {
        INewsBin bin = (INewsBin) child;
        if (bin.getId() == news.getParentId())
          return true;
      }
    }

    return false;
  }

  /*
   * @see org.rssowl.core.persist.INewsMark#containsNews(org.rssowl.core.persist.INews)
   */
  public synchronized boolean containsNews(INews news) {
    return fNewsContainer.containsNews(news);
  }

  /*
   * @see org.rssowl.core.persist.INewsMark#getNews()
   */
  public synchronized List<INews> getNews() {
    return getNews(EnumSet.allOf(INews.State.class));
  }

  /*
   * @see org.rssowl.core.persist.INewsMark#getNews(java.util.Set)
   */
  public List<INews> getNews(Set<State> states) {
    List<NewsReference> newsRefs;
    synchronized (this) {
      newsRefs = fNewsContainer.getNews(states);
    }
    return getNews(newsRefs);
  }

  /*
   * @see org.rssowl.core.persist.INewsMark#getNewsCount(java.util.Set)
   */
  public synchronized int getNewsCount(Set<State> states) {
    return fNewsContainer.getNewsCount(states);
  }

  /*
   * @see org.rssowl.core.persist.INewsMark#getNewsRefs()
   */
  public synchronized List<NewsReference> getNewsRefs() {
    return fNewsContainer.getNews();
  }

  /*
   * @see org.rssowl.core.persist.INewsMark#getNewsRefs(java.util.Set)
   */
  public synchronized List<NewsReference> getNewsRefs(Set<State> states) {
    return fNewsContainer.getNews(states);
  }

  /*
   * @see org.rssowl.core.persist.INewsMark#isGetNewsRefsEfficient()
   */
  public boolean isGetNewsRefsEfficient() {
    return false;
  }

  /*
   * @see org.rssowl.core.persist.IEntity#toReference()
   */
  public ModelReference toReference() {
    return new FolderNewsMarkReference(getId());
  }
}
TOP

Related Classes of org.rssowl.ui.internal.FolderNewsMark$FolderNewsMarkReference

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.