// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: ShowFeedPropertiesAction.java,v 1.35 2008/02/15 14:50:25 spyromus Exp $
//
package com.salas.bb.core.actions.feed;
import com.salas.bb.core.GlobalController;
import com.salas.bb.core.GlobalModel;
import com.salas.bb.dialogs.DirectFeedPropertiesDialog;
import com.salas.bb.dialogs.QueryFeedPropertiesDialog;
import com.salas.bb.dialogs.SearchFeedPropertiesDialog;
import com.salas.bb.discovery.MDDiscoveryRequest;
import com.salas.bb.domain.*;
import com.salas.bb.domain.query.articles.Query;
import com.salas.bb.domain.querytypes.QueryType;
import com.salas.bb.service.ServerService;
import com.salas.bb.utils.ThreadedAction;
import com.salas.bb.utils.i18n.Strings;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.net.URL;
/**
* Shows properties of the feed.
*
* Action is enabled/disabled by <code>ActionsManager</code>.
*/
public class ShowFeedPropertiesAction extends ThreadedAction
{
private static ShowFeedPropertiesAction instance;
/**
* Hidden constructor of singleton class.
*/
protected ShowFeedPropertiesAction()
{
setEnabled(false);
}
/**
* Returns initialized instance.
*
* @return instance of action.
*/
public static synchronized ShowFeedPropertiesAction getInstance()
{
if (instance == null) instance = new ShowFeedPropertiesAction();
return instance;
}
/**
* Invoked before forking the thread.
*
* @return <code>TRUE</code> to continue with action.
*/
protected boolean beforeFork()
{
return GlobalModel.SINGLETON.getSelectedFeed() != null;
}
/**
* Actual action.
*
* @param event original event object.
*/
protected void doAction(ActionEvent event)
{
IFeed feed = getFeed();
if (feed != null)
{
if (feed instanceof DirectFeed)
{
showDirectFeedProperties((DirectFeed)feed);
} else if (feed instanceof QueryFeed)
{
showQueryFeedProperties((QueryFeed)feed);
} else if (feed instanceof SearchFeed)
{
showSearchFeedProperties((SearchFeed)feed);
}
}
}
/**
* Returns a feed to show the dialog for.
*
* @return feed.
*/
protected IFeed getFeed()
{
GlobalModel model = GlobalModel.SINGLETON;
return model.getSelectedFeed();
}
/**
* Shows properties dialog for a given serach feed.
*
* @param searchFeed serach feed.
*/
private void showSearchFeedProperties(final SearchFeed searchFeed)
{
GlobalController controller = GlobalController.SINGLETON;
SearchFeedPropertiesDialog dialog =
new SearchFeedPropertiesDialog(searchFeed, controller.getMainFrame());
int articlesLimit = searchFeed.getArticlesLimit();
String title = searchFeed.getBaseTitle();
Query query = searchFeed.getQuery();
boolean dedupEnabled = searchFeed.isDedupEnabled();
int dedupFrom = searchFeed.getDedupFrom();
int dedupTo = searchFeed.getDedupTo();
if (dialog.open(title, query, articlesLimit, dedupEnabled, dedupFrom, dedupTo))
{
final String feedTitle = dialog.getFeedTitle();
final Query feedSearchQuery = dialog.getFeedSearchQuery();
final int feedArticlesLimit = dialog.getFeedArticlesLimit();
final boolean feedDedupEnabled = dialog.isDedupEnabled();
final int feedDedupFrom = dialog.getDedupFrom();
final int feedDedupTo = dialog.getDedupTo();
new SetSearchFeedProperties(searchFeed, feedTitle,
feedSearchQuery, feedArticlesLimit,
feedDedupEnabled, feedDedupFrom, feedDedupTo).start();
}
}
/**
* Shows properties dialog for the query feed. The dialog allows to modify some of the
* fields and after the changes confirmed they will be moved to the feed object.
*
* @param feed feed to watch and change.
*/
private void showQueryFeedProperties(QueryFeed feed)
{
GlobalController controller = GlobalController.SINGLETON;
QueryFeedPropertiesDialog dialog =
new QueryFeedPropertiesDialog(feed, controller.getMainFrame());
// Read-in the properties
String title = feed.getBaseTitle();
QueryType queryType = feed.getQueryType();
int purgeLimit = feed.getPurgeLimit();
String parameter = feed.getParameter();
boolean dedupEnabled = feed.isDedupEnabled();
int dedupFrom = feed.getDedupFrom();
int dedupTo = feed.getDedupTo();
// Show dialog and check if something has been changed and accepted
if (queryType == null)
{
JOptionPane.showMessageDialog(controller.getMainFrame(),
Strings.message("show.feed.properties.dialog.text.unsupported.type"),
Strings.message("show.feed.properties.dialog.title"),
JOptionPane.INFORMATION_MESSAGE);
} else if (dialog.open(title, queryType, purgeLimit, parameter, dedupEnabled, dedupFrom, dedupTo))
{
// Accepted
feed.setBaseTitle(dialog.getFeedTitle());
feed.setPurgeLimit(dialog.getFeedArticlesLimit());
boolean dedupChanged = feed.setDedupProperties(dialog.isDedupEnabled(),
dialog.getDedupFrom(), dialog.getDedupTo());
boolean paramChanged = feed.changeParameter(dialog.getFeedParameter());
if (paramChanged) controller.getPoller().update(feed, true, true); else
if (dedupChanged) feed.reviewArticles();
}
}
/**
* Shows the properties of regular direct feed. By its nature, feed can be in resolved,
* unresolved and invalid states. Depending on this the dialog will have different
* fields enabled for modification. When the feed isn't resolved, it's possible to specify
* (or "suggest") the correct XML URL by hand, when it's resolved it's possible to change
* some other properties (general fields, like title, description and author, as well as
* community fields). The changed properties are moved back to the feed object.
*
* @param aFeed feed object to change.
*/
private void showDirectFeedProperties(final DirectFeed aFeed)
{
GlobalController controller = GlobalController.SINGLETON;
boolean badFeed = aFeed.isInvalid() && !aFeed.isInitialized();
// Record current XML URL
URL xmlURL = badFeed ? aFeed.getXmlURL() : null;
// Show dialog
DirectFeedPropertiesDialog dialog =
new DirectFeedPropertiesDialog(controller.getMainFrame(), aFeed);
dialog.open();
// Compare new XML URL to that
URL newXmlURL = aFeed.getXmlURL();
boolean xmlUrlChanged = (xmlURL == null
? newXmlURL != null
: !xmlURL.toString().equals(newXmlURL.toString()));
// If the feed is bad (is not initialized even once) and URL changed
// then we remove it and add new feed with the given XML URL
if (badFeed && xmlUrlChanged)
{
aFeed.setXmlURL(null);
GuidesSet set = controller.getModel().getGuidesSet();
DirectFeed existingFeed = set.findDirectFeed(newXmlURL);
if (existingFeed != null)
{
GuidesSet.replaceFeed(aFeed, existingFeed);
} else
{
aFeed.setXmlURL(newXmlURL);
FeedMetaDataHolder holder = aFeed.getMetaDataHolder();
// XML URL has changed -- suggest XML URL if it's not local
if (xmlURL != null && !MDDiscoveryRequest.isLocalURL(newXmlURL))
{
ServerService.metaSuggestFeedUrl(xmlURL.toString(), newXmlURL.toString());
}
// set newly discovered URL and mark the data as no longer invalid
holder.setXmlURL(newXmlURL);
holder.setInvalid(false);
controller.updateIfDiscovered(aFeed);
}
}
}
/**
* Simple thread setting the search feed properties to avoid UI locking.
*/
private static class SetSearchFeedProperties extends Thread
{
private final SearchFeed searchFeed;
private final String feedTitle;
private final Query feedSearchQuery;
private final int feedArticlesLimit;
private final boolean dedupEnabled;
private final int dedupFrom;
private final int dedupTo;
/**
* Creates thread.
*
* @param aSearchFeed search feed to update.
* @param aFeedTitle new feed title.
* @param aFeedSearchQuery new query.
* @param aFeedArticlesLimit new articles limit.
* @param aDedupEnabled new remove duplicates flag.
* @param aDedupFrom new index of the first dedup word.
* @param aDedupTo new index of the last dedup word.
*/
public SetSearchFeedProperties(SearchFeed aSearchFeed, String aFeedTitle,
Query aFeedSearchQuery, int aFeedArticlesLimit,
boolean aDedupEnabled, int aDedupFrom, int aDedupTo)
{
searchFeed = aSearchFeed;
feedTitle = aFeedTitle;
feedSearchQuery = aFeedSearchQuery;
feedArticlesLimit = aFeedArticlesLimit;
dedupEnabled = aDedupEnabled;
dedupFrom = aDedupFrom;
dedupTo = aDedupTo;
}
/** Invoked during thread run. */
public void run()
{
searchFeed.setBaseTitle(feedTitle);
searchFeed.setArticlesLimit(feedArticlesLimit);
searchFeed.setDedupProperties(dedupEnabled, dedupFrom, dedupTo, false);
searchFeed.setQuery(feedSearchQuery);
}
}
}