Package org.rssowl.core.model.internal.types

Source Code of org.rssowl.core.model.internal.types.Feed

/*   **********************************************************************  **
**   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.core.model.internal.types;

import org.eclipse.core.runtime.Assert;
import org.rssowl.core.internal.persist.ComplexMergeResult;
import org.rssowl.core.internal.persist.MergeResult;
import org.rssowl.core.model.types.ICategory;
import org.rssowl.core.model.types.IFeed;
import org.rssowl.core.model.types.IImage;
import org.rssowl.core.model.types.INews;
import org.rssowl.core.model.types.IPerson;
import org.rssowl.core.persist.ICloud;
import org.rssowl.core.persist.ITextInput;
import org.rssowl.core.util.MergeUtils;

import java.net.URI;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;

/**
* A Feed is the container of <code>News</code>. There can only be one Feed
* that matches a certain Link. A Feed is created whenever a
* <code>BookMark</code> was created on a Link that is not yet present as a
* Feed in the database.
*
* @author bpasero
*/
public class Feed extends AbstractEntity implements IFeed {
  /* Attributes */
  private String fTitle;
  private Date fPublishDate;
  private String fDescription;
  private String fHomepage;

  private String fLanguage;
  private String fCopyright;

  private String fDocs;

  private String fGenerator;
  private Date fLastBuildDate;
  private String fWebmaster;
  private Date fLastModifiedDate;
  private int fTTL;
  private String fFormat;
 
  private String fBaseUri;

  private transient URI fLink;
  private String fLinkText;

  private IImage fImage;
 
  private IPerson fAuthor;

  private List<INews> fNews;

  private List<ICategory> fCategories;

  /**
   * Creates a new Element of the type Feed. A Feed is visually represented in
   * the GUI by a relation of one to many to Elements of the type
   * <code>BookMark</code>. The id property of the created object will be
   * IExtendableType.NO_ID.
   *
   * @param link The unique Link of this Feed pointing to the location to
   * retrieve <code>News</code>
   */
  public Feed(URI link) {
    this(null, link);
  }

  /**
   * Creates a new Element of the type Feed. A Feed is visually represented in
   * the GUI by a relation of one to many to Elements of the type
   * <code>BookMark</code>
   *
   * @param id The unique id of this Feed.
   * @param link The unique Link of this Feed pointing to the location to
   * retrieve <code>News</code>
   */
  public Feed(Long id, URI link) {
    super(id);
    Assert.isNotNull(link, "The type Feed requires a Link that is not NULL"); //$NON-NLS-1$
    fLink = link;
    fLinkText = link.toString();
    fNews = new ArrayList<INews>();
  }

  /**
   * Default constructor for deserialization
   */
  protected Feed() {
  // As per javadoc
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#addNews(org.rssowl.core.model.types.INews)
   */
  public synchronized void addNews(INews news) {
    Assert.isNotNull(news, "Exception adding NULL as News into Feed"); //$NON-NLS-1$

    /* Rule: Child needs to know about its new parent already! */
    Assert.isTrue(fLinkText.equals(news.getFeedReference().getLink().toString()), "The News has a different Feed set!"); //$NON-NLS-1$

    fNews.add(news);
  }

  private int findNews(List<INews> newsList, INews news) {
    for (int i = 0, c = newsList.size(); i < c; ++i) {
      if (news.isEquivalent(newsList.get(i)))
        return i;
    }

    return -1;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getNews()
   */
  public synchronized List<INews> getNews() {
    return Collections.unmodifiableList(fNews);
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getLink()
   */
  public synchronized URI getLink() {
    if (fLink == null && fLinkText != null)
      fLink = createURI(fLinkText);
   
    return fLink;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getCopyright()
   */
  public synchronized String getCopyright() {
    return fCopyright;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setCopyright(java.lang.String)
   */
  public synchronized void setCopyright(String copyright) {
    fCopyright = copyright;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getDescription()
   */
  public synchronized String getDescription() {
    return fDescription;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setDescription(java.lang.String)
   */
  public synchronized void setDescription(String description) {
    fDescription = description;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getDocs()
   */
  public synchronized URI getDocs() {
    return createURI(fDocs);
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setDocs(java.lang.String)
   */
  public synchronized void setDocs(URI docs) {
    fDocs = getURIText(docs);
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getFormat()
   */
  public synchronized String getFormat() {
    return fFormat;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setFormat(java.lang.String)
   */
  public synchronized void setFormat(String format) {
    fFormat = format;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getGenerator()
   */
  public synchronized String getGenerator() {
    return fGenerator;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setGenerator(java.lang.String)
   */
  public synchronized void setGenerator(String generator) {
    fGenerator = generator;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getHomepage()
   */
  public synchronized URI getHomepage() {
    return createURI(fHomepage);
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setHomepage(java.lang.String)
   */
  public synchronized void setHomepage(URI homepage) {
    fHomepage = getURIText(homepage);
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getLanguage()
   */
  public synchronized String getLanguage() {
    return fLanguage;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setLanguage(java.lang.String)
   */
  public synchronized void setLanguage(String language) {
    fLanguage = language;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getLastBuildDate()
   */
  public synchronized Date getLastBuildDate() {
    return fLastBuildDate;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setLastBuildDate(java.util.Date)
   */
  public synchronized void setLastBuildDate(Date lastBuildDate) {
    fLastBuildDate = lastBuildDate;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getAuthor()
   */
  public synchronized IPerson getAuthor() {
    return fAuthor;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setAuthor(org.rssowl.core.model.types.IPerson)
   */
  public synchronized void setAuthor(IPerson author) {
    fAuthor = author;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getPublishDate()
   */
  public synchronized Date getPublishDate() {
    return fPublishDate;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setPublishDate(java.util.Date)
   */
  public synchronized void setPublishDate(Date publishDate) {
    fPublishDate = publishDate;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getTitle()
   */
  public synchronized String getTitle() {
    return fTitle;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setTitle(java.lang.String)
   */
  public synchronized void setTitle(String title) {
    fTitle = title;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getVisibleNews()
   */
  public synchronized List<INews> getVisibleNews() {
    List<INews> newsList = new ArrayList<INews>();
    for (INews news : fNews) {
      if (news.isVisible())
        newsList.add(news);
    }
    return newsList;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getNewsByStates(java.util.EnumSet)
   */
  public synchronized List<INews> getNewsByStates(EnumSet<INews.State> states) {
    List<INews> newsList = new ArrayList<INews>();
    for (INews news : fNews) {
      for (INews.State state : states) {
        if (news.getState() == state) {
          newsList.add(news);
          break;
        }
      }
    }
    return newsList;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getTTL()
   */
  public synchronized int getTTL() {
    return fTTL;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setTTL(int)
   */
  public synchronized void setTTL(int ttl) {
    fTTL = ttl;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getWebmaster()
   */
  public synchronized String getWebmaster() {
    return fWebmaster;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setWebmaster(java.lang.String)
   */
  public synchronized void setWebmaster(String webmaster) {
    fWebmaster = webmaster;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setImage(org.rssowl.core.model.types.IImage)
   */
  public synchronized void setImage(IImage image) {
    fImage = image;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#addCategory(org.rssowl.core.model.types.ICategory)
   */
  public synchronized void addCategory(ICategory category) {
    if (fCategories == null)
      fCategories = new ArrayList<ICategory>();

    fCategories.add(category);
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setLastModifiedDate(java.util.Date)
   */
  public synchronized void setLastModifiedDate(Date lastModifiedDate) {
    fLastModifiedDate = lastModifiedDate;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getLastModificationDate()
   */
  public synchronized Date getLastModifiedDate() {
    return fLastModifiedDate;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#setBase(java.net.URI)
   */
  public synchronized void setBase(URI baseUri) {
    fBaseUri = getURIText(baseUri);
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getBase()
   */
  public synchronized URI getBase() {
    return createURI(fBaseUri);
  }

  /**
   * Compare the given type with this type for identity.
   *
   * @param feed to be compared.
   * @return whether this object and <code>feed</code> are identical. It
   * compares all the fields.
   */
  public synchronized boolean isIdentical(IFeed feed) {
    if (this == feed)
      return true;

    if (!(feed instanceof Feed))
      return false;

    Feed f = (Feed) feed;

    return getId() == f.getId() && (fAuthor == null ? f.fAuthor == null : fAuthor.equals(f.fAuthor))
        && (fCategories == null ? f.fCategories == null : fCategories.equals(f.fCategories))
        && (fCopyright == null ? f.fCopyright == null : fCopyright.equals(f.fCopyright))
        && (fDescription == null ? f.fDescription == null : fDescription.equals(f.fDescription))
        && (getDocs() == null ? f.getDocs() == null : getDocs().equals(f.getDocs()))
        && (fFormat == null ? f.fFormat == null : fFormat.equals(f.fFormat))
        && (fGenerator == null ? f.fGenerator == null : fGenerator.equals(f.fGenerator))
        && (getHomepage() == null ? f.getHomepage() == null : getHomepage().equals(f.getHomepage()))
        && (getBase() == null ? f.getBase() == null : getBase().equals(f.getBase()))
        && (fImage == null ? f.fImage == null : fImage.equals(f.fImage))
        && (fLanguage == null ? f.fLanguage == null : fLanguage.equals(f.fLanguage))
        && (fLastBuildDate == null ? f.fLastBuildDate == null : fLastBuildDate.equals(f.fLastBuildDate))
        && (fLastModifiedDate == null ? f.fLastModifiedDate == null : fLastModifiedDate.equals(f.fLastModifiedDate))
        && (getLink() == null ? f.getLink() == null : getLink().toString().equals(f.getLink() != null ? f.getLink().toString() : null))
        && (fNews == null ? f.fNews == null : new HashSet<INews>(fNews).equals(new HashSet<INews>(f.fNews)))
        && (fPublishDate == null ? f.fPublishDate == null : fPublishDate.equals(f.fPublishDate))
        && (fTitle == null ? f.fTitle == null : fTitle.equals(f.fTitle))
        && fTTL == f.fTTL
        && (fWebmaster == null ? f.fWebmaster == null : fWebmaster.equals(f.fWebmaster))
        && (getProperties() == null ? f.getProperties() == null : getProperties().equals(f.getProperties()));
  }

  @SuppressWarnings("nls")
  @Override
  public synchronized String toString() {
    StringBuilder str = new StringBuilder();

    str.append("\n\n\n****************************** Feed ******************************");
    str.append("\nID: ").append(getId());
    str.append("\nLink: ").append(getLink());
    if (getTitle() != null)
      str.append("\nTitle: ").append(getTitle());

    return str.toString();
  }

  /**
   * Returns a String describing the state of this Entity.
   *
   * @return A String describing the state of this Entity.
   */
  @SuppressWarnings("nls")
  public synchronized String toLongString() {
    StringBuilder str = new StringBuilder();

    str.append("\n\n\n****************************** Feed ******************************");
    str.append("\nID: ").append(getId());
    str.append("\nFormat: ").append(getFormat());
    str.append("\nLink: ").append(getLink());
    if (getBase() != null)
      str.append("\nBase URI: ").append(getBase());
    if (getTitle() != null)
      str.append("\nTitle: ").append(getTitle());
    if (getDescription() != null)
      str.append("\nDescription: ").append(getDescription());
    if (getHomepage() != null)
      str.append("\nHomepage: ").append(getHomepage());
    if (getLanguage() != null)
      str.append("\nLanguage: ").append(getLanguage());
    if (getImage() != null)
      str.append("\nImage: ").append(getImage());
    if (getCopyright() != null)
      str.append("\nCopyright: ").append(getCopyright());
    if (getPublishDate() != null)
      str.append("\nPublish Date: ").append(DateFormat.getDateTimeInstance().format(getPublishDate()));
    if (getLastBuildDate() != null)
      str.append("\nLast Build: ").append(DateFormat.getDateTimeInstance().format(getLastBuildDate()));
    if (getLastModifiedDate() != null)
      str.append("\nLast Modified: ").append(DateFormat.getDateTimeInstance().format(getLastModifiedDate()));
    str.append("\nCategories: ").append(getCategories());
    if (getGenerator() != null)
      str.append("\nGenerator: ").append(getGenerator());
    if (getTTL() != 0)
      str.append("\nTTL: ").append(getTTL());
    if (getDocs() != null)
      str.append("\nDocs: ").append(getDocs());
    if (getAuthor() != null)
      str.append("\nAuthor: ").append(getAuthor());
    if (getWebmaster() != null)
      str.append("\nWebmaster: ").append(getWebmaster());
    str.append("\nProperties: ").append(getProperties());
    str.append("\n\nNews: ").append(getNews());

    str.append("\n******************\n");

    return str.toString();
  }

  /**
   * This type is not handled by the Application! Use Properties instead.
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void setRating(String rating) {}

  /**
   * This type is not handled by the Application! Use Properties instead.
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void setTextInput(ITextInput input) {}

  /**
   * This type is not handled by the Application! Use Properties instead.
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void addHourToSkip(int hour) {}

  /**
   * This type is not handled by the Application! Use Properties instead.
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void addDayToSkip(int day) {}

  /**
   * This type is not handled by the Application! Use Properties instead.
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void setCloud(ICloud cloud) {}

  /**
   * This type is not handled by the Application! Use Properties instead.
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public ICloud getCloud() {
    return null;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getImage()
   */
  public synchronized IImage getImage() {
    return fImage;
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public String getRating() {
    return null;
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public int[] getDaysToSkip() {
    return null;
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public int[] getHoursToSkip() {
    return null;
  }

  /*
   * @see org.rssowl.core.model.types.IFeed#getCategories()
   */
  public synchronized List<ICategory> getCategories() {
    if (fCategories == null)
      return Collections.emptyList();

    return Collections.unmodifiableList(fCategories);
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public ITextInput getTextInput() {
    return null;
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void setUpdateBase(Date updateBase) {}

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public Date getUpdateBase() {
    return null;
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public int getUpdateFrequency() {
    return 0;
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void setUpdateFrequency(int updateFrequency) {}

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public int getUpdatePeriod() {
    return 0;
  }

  /**
   * This type is not handled by the Application! Use Properties instead
   * <p>
   * The Methods <code>setProperty()</code> and <code>getProperty()</code>
   * allows to store and retrieve extensible Data that is not part of this Types
   * model.
   * </p>
   */
  public void setUpdatePeriod(int updatePeriod) {}

  public MergeResult mergeAndCleanUp(IFeed objectToMerge) {
    return merge(objectToMerge, true);
  }

  private MergeResult merge(IFeed objectToMerge, boolean cleanUp) {
    Assert.isLegal(getLink().toString().equals(objectToMerge.getLink().toString()),
        "Only feeds with the same link can be merged."); //$NON-NLS-1$
   
    MergeResult result = new MergeResult();
    boolean updated = processListMergeResult(result, mergeNews(objectToMerge.getNews(), cleanUp));
    updated |= processListMergeResult(result, mergeCategories(objectToMerge.getCategories()));
    updated |= processListMergeResult(result, mergeAuthor(objectToMerge.getAuthor()));
    updated |= processListMergeResult(result, mergeImage(objectToMerge.getImage()));
    updated |= !simpleFieldsEqual(objectToMerge);

    setBase(objectToMerge.getBase());
    fCopyright = objectToMerge.getCopyright();
    fDescription = objectToMerge.getDescription();
    setDocs(objectToMerge.getDocs());
    fFormat = objectToMerge.getFormat();
    fGenerator = objectToMerge.getGenerator();
    setHomepage(objectToMerge.getHomepage());
    fLanguage = objectToMerge.getLanguage();
    fLastBuildDate = objectToMerge.getLastBuildDate();
    fLastModifiedDate = objectToMerge.getLastModifiedDate();
    fPublishDate = objectToMerge.getPublishDate();
    fTitle = objectToMerge.getTitle();
    fTTL = objectToMerge.getTTL();
    fWebmaster = objectToMerge.getWebmaster();
   
    ComplexMergeResult<?> propertiesResult = MergeUtils.mergeProperties(this, objectToMerge);
    if (updated || propertiesResult.isStructuralChange()) {
      result.addUpdatedObject(this);
      result.addAll(propertiesResult);
    }
    return result;
  }

  private boolean simpleFieldsEqual(IFeed feed) {
    return MergeUtils.equals(getBase(), feed.getBase()) &&
        MergeUtils.equals(fCopyright, feed.getCopyright()) &&
        MergeUtils.equals(fDescription, feed.getDescription()) &&
        MergeUtils.equals(getDocs(), feed.getDocs()) &&
        MergeUtils.equals(fFormat, feed.getFormat()) &&
        MergeUtils.equals(fGenerator, feed.getGenerator()) &&
        MergeUtils.equals(getHomepage(), feed.getHomepage()) &&
        MergeUtils.equals(fLanguage, feed.getLanguage()) &&
        MergeUtils.equals(fLastBuildDate, feed.getLastBuildDate()) &&
        MergeUtils.equals(fLastModifiedDate, feed.getLastModifiedDate()) &&
        MergeUtils.equals(fPublishDate, feed.getPublishDate()) &&
        MergeUtils.equals(fTitle, feed.getTitle()) &&
        MergeUtils.equals(fTTL, feed.getTTL()) &&
        MergeUtils.equals(fWebmaster, feed.getWebmaster());
  }

  public synchronized MergeResult merge(IFeed objectToMerge) {
    Assert.isNotNull(objectToMerge);
    return merge(objectToMerge, false);
  }

  private ComplexMergeResult<IPerson> mergeAuthor(IPerson author) {
    ComplexMergeResult<IPerson> mergeResult = MergeUtils.merge(getAuthor(), author);
    fAuthor = mergeResult.getMergedObject();
    return mergeResult;
  }

  private ComplexMergeResult<List<ICategory>> mergeCategories(List<ICategory> categories) {
    Comparator<ICategory> comparator = new Comparator<ICategory>() {

      public int compare(ICategory o1, ICategory o2) {
        if (o1.getName() == null ? o2.getName() == null : o1.getName().equals(o2.getName())) {
          return 0;
        }
        return -1;
      }
     
    };
    ComplexMergeResult<List<ICategory>> mergeResult = MergeUtils.merge(fCategories, categories, comparator, null);
    fCategories = mergeResult.getMergedObject();
    return mergeResult;
  }

  private ComplexMergeResult<IImage> mergeImage(IImage image) {
    ComplexMergeResult<IImage> mergeResult = MergeUtils.merge(getImage(), image);
    fImage = mergeResult.getMergedObject();
    return mergeResult;
  }

  private ComplexMergeResult<List<INews>> mergeNews(List<INews> newsList, boolean cleanUp) {
    List<INews> newsListCopy = copyWithoutDuplicates(newsList);
    List<Integer> newsToCleanUp = null;
    if (cleanUp) {
      newsToCleanUp = new ArrayList<Integer>(fNews.size() / 2);
    }
    ComplexMergeResult<List<INews>> mergeResult = ComplexMergeResult.create(newsListCopy);
    for (int i = 0, c = fNews.size(); i < c; ++i) {
      INews existingNews = fNews.get(i);
      int existingNewsIndex = findNews(newsListCopy, existingNews);

      if (existingNewsIndex > -1) {
        mergeResult.addAll(existingNews.merge(newsListCopy.get(existingNewsIndex)));
        newsListCopy.remove(existingNewsIndex);
      } else if ((newsToCleanUp != null) && (existingNews.getState() == INews.State.DELETED))
        newsToCleanUp.add(Integer.valueOf(i));
   
    }
    if (newsToCleanUp != null) {
      for (int i = newsToCleanUp.size() - 1; i >= 0; --i) {
        INews news = fNews.remove(newsToCleanUp.get(i).intValue());
        mergeResult.addRemovedObject(news);
        mergeResult.setStructuralChange(true);
      }
     
    }
    for (INews news : newsListCopy) {
      news.setParent(this);
      fNews.add(news);
      mergeResult.setStructuralChange(true);
      mergeResult.addUpdatedObject(news);
    }
    return mergeResult;
  }
 
  private List<INews> copyWithoutDuplicates(List<INews> newsList) {
    List<INews> newsListCopy = new ArrayList<INews>(newsList.size());
    for (INews outerNews : newsList) {
      boolean containsNews = false;
      for (INews innerNews : newsListCopy) {
        if (innerNews.isEquivalent(outerNews)) {
          containsNews = true;
          break;
        }
      }
      if (!containsNews)
        newsListCopy.add(outerNews);
    }
    return newsListCopy;
  }

  public synchronized boolean removeNews(INews news) {
    return fNews.remove(news);
  }
}
TOP

Related Classes of org.rssowl.core.model.internal.types.Feed

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.