Package com.salas.bb.domain

Source Code of com.salas.bb.domain.QueryFeed

// 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: QueryFeed.java,v 1.47 2007/07/06 14:47:57 spyromus Exp $
//

package com.salas.bb.domain;

import EDU.oswego.cs.dl.util.concurrent.Mutex;
import EDU.oswego.cs.dl.util.concurrent.Sync;
import com.salas.bb.domain.querytypes.QueryType;
import com.salas.bb.utils.StringUtils;
import com.salas.bb.utils.i18n.Strings;
import com.salas.bb.utils.parser.Channel;
import com.salas.bb.views.feeds.IFeedDisplayConstants;

import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Query feed uses third-party services to get the list of articles. Each query feed has
* query type desriminator assigned. Using query type object feed can convert the query
* parameter and some other properties into the valid query URL which can be used
* to get the data from service.
*/
public class QueryFeed extends NetworkFeed
{
    private static final Logger LOG = Logger.getLogger(QueryFeed.class.getName());

    /** Query type property. */
    public static final String PROP_QUERY_TYPE = "queryType";
    /** Parameter property. */
    public static final String PROP_PARAMETER = "parameter";
    public static final String PROP_DEDUP_ENABLED = "dedupEnabled";
    public static final String PROP_DEDUP_FROM = "dedupFrom";
    public static final String PROP_DEDUP_TO = "dedupTo";

    private final Sync  syncParameterChange;

    private String      baseTitle;
    private String      title;
    private QueryType   queryType;
    private String      parameter;
    /** TRUE when deduplication functionality is enabled. */
    private boolean     dedupEnabled;
    /** The first word index to look for the match. */
    private int         dedupFrom;
    /** The last word index to look for the match. */
    private int         dedupTo;

    /**
     * Creates query feed.
     */
    public QueryFeed()
    {
        syncParameterChange = new Mutex();

        baseTitle = null;
        queryType = null;
        parameter = null;
        renderTitle();

        super.setCustomViewModeEnabled(true);

        dedupEnabled = false;
        dedupFrom = 0;
        dedupTo = 0;
    }

    /**
     * Returns reason for being invalid. Query feeds are always invalid when their type isn't
     * specified.
     *
     * @return reason.
     */
    public String getInvalidnessReason()
    {
        String reason = null;

        if (queryType == null) reason = Strings.message("feed.invalidness.reason.unsupported.query");
        if (reason == null) reason = super.getInvalidnessReason();

        return reason;
    }

    /**
     * Returns TRUE if this feed is updatable, meaning that it's not invalid for some reason and
     * it's proper time to call <code>update()</code> method. The behaviod may differ if the update
     * operation was called directly to this particular feed and not as a part of a bigger update
     * operation (update guide or update all).
     *
     * @param direct if TRUE then the update was requested directly (not through guide/set or by
     *               periodic check).
     */
    protected boolean isUpdatable(boolean direct)
    {
        return queryType != null && StringUtils.isNotEmpty(parameter) && super.isUpdatable(direct);
    }

    /**
     * Returns title of feed.
     *
     * @return title.
     */
    public String getTitle()
    {
        return title;
    }

    /**
     * Renders new title on type or title change. For now, all we do is to append "SmartFeed:" to the name.
     */
    private void renderTitle()
    {
        title = getBaseTitle();
    }

    /**
     * Returns title of feed.
     *
     * @return title.
     */
    public String getBaseTitle()
    {
        return baseTitle;
    }

    /**
     * Sets the title of the feed.
     *
     * @param aTitle title of the feed.
     */
    public void setBaseTitle(String aTitle)
    {
        String oldTitle = getTitle();
        baseTitle = aTitle;

        renderTitle();

        firePropertyChanged(PROP_TITLE, oldTitle, getTitle());
    }

    /**
     * Returns query type.
     *
     * @return query type.
     */
    public QueryType getQueryType()
    {
        return queryType;
    }

    /**
     * Sets new query type.
     *
     * @param aQueryType query type.
     */
    public void setQueryType(QueryType aQueryType)
    {
        int viewMode = aQueryType == null
            ? IFeedDisplayConstants.MODE_BRIEF : aQueryType.getPreferredViewMode();
        setCustomViewMode(viewMode);

        String oldTitle = getTitle();
        QueryType old = queryType;
        queryType = aQueryType;

        renderTitle();

        firePropertyChanged(PROP_QUERY_TYPE, old, queryType, true, false);
        firePropertyChanged(PROP_TITLE, oldTitle, getTitle());

        if (queryType != null) setType(queryType.getFeedType());
    }

    /**
     * Returns the query parameter.
     *
     * @return parameter.
     */
    public String getParameter()
    {
        return parameter;
    }

    /**
     * Sets the query parameter.
     *
     * @param aParameter parameter.
     */
    public void setParameter(String aParameter)
    {
        String old = parameter;
        parameter = aParameter;

        firePropertyChanged(PROP_PARAMETER, old, parameter, true, false);
    }

    /**
     * Sets the options at once and updates the feed if necessary.
     *
     * @param dedupEnabled  deduplication enabled flag.
     * @param dedupFrom     the first dedup word.
     * @param dedupTo       the last dedup word.
     *
     * @return <code>TRUE</code> if changed and updated.
     */
    public boolean setDedupProperties(boolean dedupEnabled, int dedupFrom, int dedupTo)
    {
        boolean oldEnabled = isDedupEnabled();
        int oldFrom = getDedupFrom();
        int oldTo = getDedupTo();

        setDedupEnabled(dedupEnabled);
        setDedupFrom(dedupFrom);
        setDedupTo(dedupTo);

        return (oldEnabled != isDedupEnabled() ||
            oldFrom != getDedupFrom() ||
            oldTo != getDedupTo());
    }

    /**
     * Changes query parameter to something different and resets the feed statistics,
     * which will force it to be updated.
     *
     * @param aNewParameter new parameter.
     *
     * @return TRUE if parameter has been changed.
     */
    public boolean changeParameter(String aNewParameter)
    {
        boolean changed = false;
        try
        {
            syncParameterChange.acquire();
            try
            {
                if (parameter == null || !parameter.equals(aNewParameter))
                {
                    setParameter(aNewParameter);
                    clear(false);
                    resetFeedStatistics();

                    changed = true;
                }
            } finally
            {
                syncParameterChange.release();
            }
        } catch (InterruptedException e)
        {
            LOG.log(Level.SEVERE, Strings.error("interrupted"), e);
        }

        return changed;
    }

    /**
     * Reviews articles with dup-checking.
     */
    public void reviewArticles()
    {
        clear(true);
    }

    /**
     * Removes all articles.
     *
     * @param checkDup  <code>TRUE</code> to clear with dup-checking.
     */
    private void clear(boolean checkDup)
    {
        if (checkDup && !isDedupEnabled()) return;

        int count = getArticlesCount();
        for (int i = 0; i < count; i++)
        {
            IArticle article = getArticleAt(count - i - 1);
            if (!article.isPinned() && (!checkDup ||
                isDuplicate(article, getDedupFrom(), getDedupTo(), getArticlesList())))
            {
                removeArticle(article);
            }
        }
    }

    /**
     * Gets XML URL.
     *
     * @return URL.
     */
    public URL getXmlURL()
    {
        int limit = getPurgeLimitCombined();
        return queryType == null ? null : queryType.convertToURL(parameter, limit);
    }

    /**
     * Fetches the feed by some specific means.
     *
     * @return the feed or NULL if there was an error or no updates required.
     */
    protected Channel fetchFeed()
        throws IOException
    {
        Channel result = queryType.fetchFeed(this);

        if (result == null) result = super.fetchFeed();

        return result;
    }

    @Override
    public boolean insertArticle(int index, IArticle article)
    {
        if (queryType != null) article = queryType.beforeInsertArticle(index, article);

        return super.insertArticle(index, article);
    }

    /**
     * Returns simple match key, which can be used to detect similarity of feeds. For example, it's
     * XML URL for the direct feeds, query type + parameter for the query feeds, serialized search
     * criteria for the search feeds.
     *
     * @return match key.
     */
    public String getMatchKey()
    {
        return "QF" + (queryType == null ? "" : queryType.getType()) + " " + parameter;
    }

    /**
     * Returns <code>TRUE</code> if an article is duplicate of some other already registered.
     *
     * @param article article.
     *
     * @return <code>TRUE</code> if an article is duplicate of some other already registered.
     */
    protected boolean isDuplicate(IArticle article)
    {
        return dedupEnabled && isDuplicate(article, dedupFrom, dedupTo, Arrays.asList(getArticles()));
    }

    // ------------------------------------------------------------------------
    // Duplicates Checking
    // ------------------------------------------------------------------------

    /**
     * Returns <code>TRUE</code> if remove duplicates is enabled.
     *
     * @return <code>TRUE</code> if remove duplicates is enabled.
     */
    public boolean isDedupEnabled()
    {
        return dedupEnabled;
    }

    /**
     * Sets remove duplicates flag.
     *
     * @param flag <code>TRUE</code> if remove duplicates is enabled.
     */
    public void setDedupEnabled(boolean flag)
    {
        boolean old = dedupEnabled;
        if (old == flag) return;
        dedupEnabled = flag;

        firePropertyChanged(PROP_DEDUP_ENABLED, old, flag, true, false);
    }

    /**
     * Returns the first word to look for duplicates.
     *
     * @return word number.
     */
    public int getDedupFrom()
    {
        return dedupFrom;
    }

    /**
     * Sets the first word to look for duplicates.
     *
     * @param word number
     */
    public void setDedupFrom(int word)
    {
        int old = dedupFrom;
        dedupFrom = word;

        firePropertyChanged(PROP_DEDUP_FROM, old, word, true, false);
    }

    /**
     * Returns the last word to look for duplicates.
     *
     * @return word number.
     */
    public int getDedupTo()
    {
        return dedupTo;
    }

    /**
     * Sets the last word to look for duplicates.
     *
     * @param word number
     */
    public void setDedupTo(int word)
    {
        int old = dedupTo;
        dedupTo = word;

        firePropertyChanged(PROP_DEDUP_TO, old, word, true, false);
    }
}
TOP

Related Classes of com.salas.bb.domain.QueryFeed

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.