* org.rssowl.core.persist.IConditionalGet, boolean, boolean,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public final void handleFeedReload(final IBookMark bookMark, IFeed interpretedFeed, IConditionalGet conditionalGet, boolean deleteConditionalGet, boolean runRetention, final IProgressMonitor monitor) {
fWriteLock.lock();
MergeResult mergeResult = null;
try {
/* Resolve reloaded Feed */
IFeed feed = bookMark.getFeedLinkReference().resolve();
/* Feed could have been deleted meanwhile! */
if (feed == null)
return;
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
/* Copy over Properties to reloaded Feed to keep them */
Map<String, Serializable> feedProperties = feed.getProperties();
if (feedProperties != null) {
feedProperties.entrySet();
for (Map.Entry<String, Serializable> entry : feedProperties.entrySet())
interpretedFeed.setProperty(entry.getKey(), entry.getValue());
}
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
/* Create labels as necessary from Sync and assign to news */
boolean isSynced = SyncUtils.isSynchronized(bookMark);
if (isSynced) {
/* Determine those Labels the user has explicitly deleted and ignore */
String[] labelsToIgnore = Owl.getPreferenceService().getGlobalScope().getStrings(DefaultPreferences.DELETED_LABELS);
List<String> labelsToIgnoreList = (labelsToIgnore != null) ? new ArrayList<String>(labelsToIgnore.length) : Collections.<String> emptyList();
if (labelsToIgnore != null) {
for (String label : labelsToIgnore) {
labelsToIgnoreList.add(label);
}
}
/* Collect All Incoming Labels */
boolean hasLabels = false;
Set<String> incomingLabels = new HashSet<String>();
for (INews item : interpretedFeed.getNews()) {
Object labelsObj = item.getProperty(SyncUtils.GOOGLE_LABELS);
if (labelsObj != null && labelsObj instanceof String[]) {
String[] labels = (String[]) labelsObj;
for (String label : labels) {
if (!labelsToIgnoreList.contains(label))
incomingLabels.add(label);
}
hasLabels = true;
}
}
/* Determine the New Labels to Create */
if (!incomingLabels.isEmpty()) {
/* Existing Labels */
Collection<ILabel> existingLabels = DynamicDAO.loadAll(ILabel.class);
Map<String, ILabel> mapNameToLabel = new HashMap<String, ILabel>();
for (ILabel label : existingLabels) {
mapNameToLabel.put(label.getName(), label);
}
/* New Labels to Create */
Set<ILabel> labelsToCreate = new HashSet<ILabel>();
for (String incomingLabel : incomingLabels) {
if (!mapNameToLabel.containsKey(incomingLabel)) {
ILabel newLabel = Owl.getModelFactory().createLabel(null, incomingLabel);
newLabel.setColor("0,0,0"); //$NON-NLS-1$
newLabel.setOrder(mapNameToLabel.size());
mapNameToLabel.put(incomingLabel, newLabel);
labelsToCreate.add(newLabel);
}
}
/* Save new Labels */
if (!labelsToCreate.isEmpty())
DynamicDAO.saveAll(labelsToCreate);
/* Assign Labels to News */
for (INews item : interpretedFeed.getNews()) {
Object labelsObj = item.getProperty(SyncUtils.GOOGLE_LABELS);
if (labelsObj != null && labelsObj instanceof String[]) {
String[] labels = (String[]) labelsObj;
for (String labelName : labels) {
ILabel label = mapNameToLabel.get(labelName);
if (label != null)
item.addLabel(label);
}
}
item.removeProperty(SyncUtils.GOOGLE_LABELS);
}
}
/* Otherwise make sure to clean up properties for Labels */
else if (hasLabels) {
for (INews item : interpretedFeed.getNews()) {
item.removeProperty(SyncUtils.GOOGLE_LABELS);
}
}
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
}
/* Merge with existing */
mergeResult = feed.mergeAndCleanUp(interpretedFeed);
final List<INews> newNewsAdded = getNewNewsAdded(feed);
/* Now adjust News State based on Sync */
if (isSynced) {
for (INews item : newNewsAdded) {
/* News Marked Read */
if (item.getProperty(SyncUtils.GOOGLE_MARKED_READ) != null) {
item.setState(INews.State.READ);
item.removeProperty(SyncUtils.GOOGLE_MARKED_READ);
}
/* News Marked Unread */
else if (item.getProperty(SyncUtils.GOOGLE_MARKED_UNREAD) != null) {
item.setState(INews.State.UNREAD);
item.removeProperty(SyncUtils.GOOGLE_MARKED_UNREAD);
}
}
}
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
/* Update Date of last added news in Bookmark */
if (!newNewsAdded.isEmpty()) {
Date mostRecentDate = DateUtils.getRecentDate(newNewsAdded);
Date previousMostRecentDate = bookMark.getMostRecentNewsDate();
if (previousMostRecentDate == null || mostRecentDate.after(previousMostRecentDate)) {
bookMark.setMostRecentNewsDate(mostRecentDate);
fDb.set(bookMark);
}
}
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
/* Update state of added news if equivalent news already exists */
SafeRunner.run(new LoggingSafeRunnable() {
public void run() throws Exception { //See Bug 1216 (NPE in ModelSearchImpl.getCurrentSearcher)
if (Owl.getPreferenceService().getGlobalScope().getBoolean(DefaultPreferences.MARK_READ_DUPLICATES))
updateStateOfUnsavedNewNews(newNewsAdded, monitor);
}
});
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
/* Retention Policy */
final List<INews> deletedNews = runRetention ? RetentionStrategy.process(bookMark, feed) : Collections.<INews>emptyList();
for (INews news : deletedNews)
mergeResult.addUpdatedObject(news);
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
/* Set ID to News and handle Description entity */
IDGenerator generator = Owl.getPersistenceService().getIDGenerator();
for (INews news : newNewsAdded) {
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())
return;
long id;
if (generator instanceof DB4OIDGenerator)
id = ((DB4OIDGenerator) generator).getNext(false);
else
id = generator.getNext();
news.setId(id);
String description = ((News) news).getTransientDescription();
if (description != null) {
mergeResult.addUpdatedObject(new Description(news, description));
}
}
/* Return early on cancellation */
if (monitor.isCanceled() || Owl.isShuttingDown())