/* ********************************************************************** **
** 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.core.internal.persist.dao;
import org.eclipse.core.runtime.Assert;
import org.rssowl.core.internal.persist.service.DBHelper;
import org.rssowl.core.internal.persist.service.DatabaseEvent;
import org.rssowl.core.persist.IFeed;
import org.rssowl.core.persist.INews;
import org.rssowl.core.persist.NewsCounter;
import org.rssowl.core.persist.NewsCounterItem;
import org.rssowl.core.persist.dao.INewsCounterDAO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
/**
* A data-access-object for <code>NewsCounter</code>.
*
* @author Ismael Juma (ismael@juma.me.uk)
*/
public final class NewsCounterDAOImpl extends AbstractPersistableDAO<NewsCounter> implements INewsCounterDAO {
private volatile NewsCounter fNewsCounter;
/** Default constructor using the specific IPersistable for this DAO */
public NewsCounterDAOImpl() {
super(NewsCounter.class, true);
}
/*
* @see
* org.rssowl.core.internal.persist.dao.AbstractPersistableDAO#onDatabaseOpened
* (org.rssowl.core.internal.persist.service.DatabaseEvent)
*/
@Override
protected void onDatabaseOpened(DatabaseEvent event) {
super.onDatabaseOpened(event);
NewsCounter newsCounter = doLoad();
if (newsCounter == null) {
newsCounter = doCountAll();
save(newsCounter);
}
fNewsCounter = newsCounter;
}
private NewsCounter doLoad() {
Collection<NewsCounter> counters = super.loadAll();
Assert.isLegal(counters.size() <= 1, "There shouldn't be more than 1 NewsCounter, size: " + counters.size()); //$NON-NLS-1$
for (NewsCounter newsCounter : counters) {
return newsCounter; //Return the first one since we assert that we don't have more than one
}
return null;
}
/*
* @see
* org.rssowl.core.internal.persist.dao.AbstractPersistableDAO#onDatabaseClosed
* (org.rssowl.core.internal.persist.service.DatabaseEvent)
*/
@Override
protected void onDatabaseClosed(DatabaseEvent event) {
super.onDatabaseClosed(event);
fNewsCounter = null;
}
/*
* @see org.rssowl.core.persist.dao.INewsCounterDAO#delete()
*/
public final void delete() {
super.delete(load());
}
/*
* @see
* org.rssowl.core.internal.persist.dao.AbstractPersistableDAO#preCommit()
*/
@Override
protected void preCommit() {
//Do nothing
}
private NewsCounter doCountAll() {
NewsCounter newsCounter = new NewsCounter();
Collection<IFeed> feeds = DBHelper.loadAllFeeds(fDb);
for (IFeed feed : feeds)
newsCounter.put(feed.getLink().toString(), doCount(feed));
return newsCounter;
}
private NewsCounterItem doCount(IFeed feed) {
NewsCounterItem counterItem = new NewsCounterItem();
List<INews> newsList = feed.getVisibleNews();
for (INews news : newsList) {
if (EnumSet.of(INews.State.NEW, INews.State.UNREAD, INews.State.UPDATED).contains(news.getState()))
counterItem.incrementUnreadCounter();
if (INews.State.NEW.equals(news.getState()))
counterItem.incrementNewCounter();
if (news.isFlagged())
counterItem.incrementStickyCounter();
}
return counterItem;
}
/*
* @see
* org.rssowl.core.internal.persist.dao.AbstractPersistableDAO#delete(org.
* rssowl.core.persist.IPersistable)
*/
@Override
public final void delete(NewsCounter newsCounter) {
if (!newsCounter.equals(load()))
throw new IllegalArgumentException("Only a single newsCounter should be used. " + "Trying to delete a non-existent one."); //$NON-NLS-1$ //$NON-NLS-2$
super.delete(newsCounter);
}
/*
* @see org.rssowl.core.internal.persist.dao.AbstractPersistableDAO#loadAll()
*/
@Override
public Collection<NewsCounter> loadAll() {
List<NewsCounter> newsCounters = new ArrayList<NewsCounter>(1);
newsCounters.add(load());
return newsCounters;
}
/*
* @see org.rssowl.core.persist.dao.INewsCounterDAO#load()
*/
public final NewsCounter load() {
return fNewsCounter;
}
/*
* @see
* org.rssowl.core.internal.persist.dao.AbstractPersistableDAO#saveAll(java
* .util.Collection)
*/
@Override
public final void saveAll(Collection<NewsCounter> entities) {
if (entities.size() > 1) {
throw new IllegalArgumentException("Only a single newsCounter can be stored"); //$NON-NLS-1$
}
super.saveAll(entities);
}
/*
* @see
* org.rssowl.core.internal.persist.dao.AbstractPersistableDAO#doSave(org.
* rssowl.core.persist.IPersistable)
*/
@Override
protected final void doSave(NewsCounter entity) {
if (!fDb.ext().isStored(entity) && (load() != null))
throw new IllegalArgumentException("Only a single newsCounter can be stored"); //$NON-NLS-1$
super.doSave(entity);
}
/*
* @see org.rssowl.core.persist.dao.INewsCounterDAO#save()
*/
public void save() {
Assert.isNotNull(fNewsCounter, "fNewsCounter"); //$NON-NLS-1$
fDb.ext().set(fNewsCounter, Integer.MAX_VALUE);
}
}