/* ********************************************************************** ** ** 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.ui.internal; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.rssowl.core.Owl; import org.rssowl.core.persist.INews; import org.rssowl.core.persist.ISearchMark; import org.rssowl.core.persist.INews.State; import org.rssowl.core.persist.dao.DynamicDAO; import org.rssowl.core.persist.dao.ISearchMarkDAO; import org.rssowl.core.persist.event.SearchMarkEvent; import org.rssowl.core.persist.reference.NewsReference; import org.rssowl.core.persist.service.IModelSearch; import org.rssowl.core.persist.service.IndexListener; import org.rssowl.core.util.ISearchHit; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; /** * @author bpasero */ public class SavedSearchService { private static final int BATCH_INTERVAL = 500; private Job fBatchJob; private IndexListener fIndexListener; private AtomicBoolean fBatchInProcess = new AtomicBoolean(false); /** * */ public SavedSearchService() { fBatchJob = createBatchJob(); registerListeners(); updateSavedSearches(); } private Job createBatchJob() { return new Job("Batch Job") { @Override protected IStatus run(IProgressMonitor monitor) { updateSavedSearches(); fBatchInProcess.set(false); return Status.OK_STATUS; } }; } private void registerListeners() { fIndexListener = new IndexListener() { public void indexUpdated() { onIndexUpdated(); } }; Owl.getPersistenceService().getModelSearch().addIndexListener(fIndexListener); } private void unregisterListeners() { Owl.getPersistenceService().getModelSearch().removeIndexListener(fIndexListener); } private void onIndexUpdated() { /* Batch is in process - return */ if (fBatchInProcess.get()) return; /* Start a new Batch */ fBatchInProcess.set(true); fBatchJob.schedule(BATCH_INTERVAL); } private void updateSavedSearches() { IModelSearch modelSearch = Owl.getPersistenceService().getModelSearch(); Set searchMarks = Controller.getDefault().getCacheService().getSearchMarks(); Set events = new HashSet(searchMarks.size()); for (ISearchMark searchMark : searchMarks) { List> results = modelSearch.searchNews(searchMark.getSearchConditions(), searchMark.matchAllConditions()); List readNews = null; List unreadNews = null; List newNews = null; for (ISearchHit searchHit : results) { INews.State state = (State) searchHit.getData(INews.STATE); if (state == INews.State.READ) { if (readNews == null) readNews = new ArrayList(results.size() / 3); readNews.add(searchHit.getResult()); } else if (state == INews.State.UNREAD || state == INews.State.UPDATED) { if (unreadNews == null) unreadNews = new ArrayList(results.size() / 3); unreadNews.add(searchHit.getResult()); } else if (state == INews.State.NEW) { if (newNews == null) newNews = new ArrayList(results.size() / 3); newNews.add(searchHit.getResult()); } } searchMark.setResult(readNews, INews.State.READ); searchMark.setResult(unreadNews, INews.State.UNREAD); searchMark.setResult(newNews, INews.State.NEW); events.add(new SearchMarkEvent(searchMark, null, true)); } /* Notify Listeners (TODO Optimize if nothing changed!) */ DynamicDAO.getDAO(ISearchMarkDAO.class).fireResultsChanged(events); } /** * */ public void stopService() { unregisterListeners(); } }