Package com.salas.bb.persistence.backend

Source Code of com.salas.bb.persistence.backend.HsqlArticlesPM

// 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: HsqlArticlesPM.java,v 1.19 2008/02/27 08:35:59 spyromus Exp $
//

package com.salas.bb.persistence.backend;

import com.salas.bb.domain.IArticle;
import com.salas.bb.domain.IFeed;
import com.salas.bb.domain.IGuide;
import com.salas.bb.domain.StandardArticle;
import com.salas.bb.utils.i18n.Strings;

import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* HSQL articles persistence manager.
*/
final class HsqlArticlesPM
{
    private static final Logger LOG = Logger.getLogger(HsqlArticlesPM.class.getName());

    /** Persistence manager context. */
    private final HsqlPersistenceManager context;

    /** Unsupported article type. */
    private static final String MSG_UNSUPPORTED_TYPE = Strings.error("db.unsupported.article.type");
    /** Article is not in database yet. */
    private static final String MSG_NOT_IN_DB = Strings.error("db.article.is.not.in.database");
    /** Article parameter is NULL. */
    private static final String MSG_SHOULD_BE_SPECIFIED = Strings.error("unspecified.article");
    /** Article is already in database. */
    private static final String MSG_ALREADY_IN_DB = Strings.error("db.article.is.already.in.database");
    /** Article is not assigned to some feed. */
    private static final String MSG_NO_FEED = Strings.error("db.article.is.not.assigned.to.any.feed");
    /** The feed article is assigned to is transient. */
    private static final String MSG_TRANSIENT_FEED = Strings.error("db.article.is.assigned.to.transient.feed");

    /**
     * Created manager.
     *
     * @param aContext context to communicate to.
     */
    public HsqlArticlesPM(HsqlPersistenceManager aContext)
    {
        context = aContext;
    }

    /**
     * Inserts the article in database.
     *
     * @param article article to insert.
     *
     * @throws NullPointerException if article isn't specified.
     * @throws IllegalStateException if article is already in database, or
     *                               article isn't assigned to feed, or
     *                               feed this article is assigned to is transient.
     * @throws IllegalArgumentException if article is of unsupported type.
     * @throws SQLException if database operation fails.
     */
    public void insertArticle(IArticle article)
        throws SQLException
    {
        if (article == null) throw new NullPointerException(MSG_SHOULD_BE_SPECIFIED);
        if (article.getID() != -1L) throw new IllegalStateException(MSG_ALREADY_IN_DB);

        IFeed feed = article.getFeed();
        if (feed == null) throw new IllegalStateException(MSG_NO_FEED);
        if (feed.getID() == -1L) throw new IllegalStateException(MSG_TRANSIENT_FEED);
        if (!(article instanceof StandardArticle))
            throw new IllegalArgumentException(MSG_UNSUPPORTED_TYPE);

        StandardArticle standardArticle = (StandardArticle)article;
        PreparedStatement stmt = context.getPreparedStatement(
            "INSERT INTO ARTICLES (AUTHOR, TEXT, PLAINTEXT, SIMPLEMATCHKEY, PUBLICATIONDATE, TITLE, " +
                "SUBJECT, READ, PINNED, LINK, FEEDID) " +
            "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

        try
        {
            stmt.setString(1, standardArticle.getAuthor());
            stmt.setString(2, standardArticle.getText());
            stmt.setString(3, standardArticle.getPlainText());
            stmt.setString(4, standardArticle.getSimpleMatchKey());
            Date publicationDate = standardArticle.getPublicationDate();
            stmt.setLong(5, publicationDate == null ? -1L : publicationDate.getTime());
            stmt.setString(6, standardArticle.getTitle());
            stmt.setString(7, standardArticle.getSubject());
            stmt.setBoolean(8, standardArticle.isRead());
            stmt.setBoolean(9, standardArticle.isPinned());
            URL link = standardArticle.getLink();
            stmt.setString(10, link == null ? null : link.toString());
            stmt.setLong(11, feed.getID());
            stmt.executeUpdate();

            // Get ID
            long id = context.getInsertedID();
            article.setID(id);

            // Add a properties record
            stmt = context.getPreparedStatement(
                "INSERT INTO ARTICLE_PROPERTIES (ARTICLEID, POSITIVE_SENTIMENTS, NEGATIVE_SENTIMENTS) " +
                "VALUES (?, ?, ?)");
            stmt.setLong(1, id);
            stmt.setInt(2, article.getPositiveSentimentsCount());
            stmt.setInt(3, article.getNegativeSentimentsCount());
            stmt.executeUpdate();
        } finally
        {
            stmt.close();
        }
    }

    /**
     * Removes article from database.
     *
     * @param article article to remove.
     *
     * @throws NullPointerException if article isn't specified.
     * @throws IllegalStateException if article is not in database.
     * @throws SQLException if database operation fails.
     */
    public void removeArticle(IArticle article)
        throws SQLException
    {
        if (article == null) throw new NullPointerException(MSG_SHOULD_BE_SPECIFIED);
        if (article.getID() == -1L)
        {
            LOG.log(Level.SEVERE, MessageFormat.format(Strings.error("0.title.1"),
                MSG_NOT_IN_DB, article.getTitle()), new Exception("Dump"));

            return;
        }

        PreparedStatement stmt = context.getPreparedStatement("DELETE FROM ARTICLES WHERE ID=?");
        try
        {
            stmt.setLong(1, article.getID());

            int rows = stmt.executeUpdate();
            if (rows == 0)
            {
                IFeed feed = article.getFeed();
                IGuide guide = null;
                if (feed != null)
                {
                    IGuide[] guides = feed.getParentGuides();
                    guide = guides.length == 0 ? null : guides[0];
                }
                String feedId = feed == null ? "no feed" : Long.toString(feed.getID());
                String guideId = guide == null ? "no guide" : Long.toString(guide.getID());

                throw new SQLException(MessageFormat.format(
                    Strings.error("db.hsql.removed.0.rows.for.articleid.0.feedid.1.guideid.2"),
                    article.getID(), feedId, guideId));
            }

            article.setID(-1L);
        } finally
        {
            stmt.close();
        }
    }

    /**
     * Updates article in database.
     *
     * @param article article to update.
     *
     * @throws NullPointerException if article isn't specified.
     * @throws IllegalArgumentException if article is of unsupported type.
     * @throws SQLException if database operation fails.
     */
    public void updateArticle(IArticle article)
        throws SQLException
    {
        if (!checkArticle(article)) return;

        // NOTE: We intentionally don't update text and plaintext fields because
        // a) they never change
        // b) there's the deadlock between LazyArticle.getPlainText() and AbstractArticle.setRead()
        //    being called from different threads
        StandardArticle standardArticle = (StandardArticle)article;
        PreparedStatement stmt = context.getPreparedStatement("UPDATE ARTICLES SET " +
            "AUTHOR=?, SIMPLEMATCHKEY=?, PUBLICATIONDATE=?, TITLE=?, SUBJECT=?, READ=?," +
            "PINNED=?, LINK=? WHERE ID=?");

        try
        {
            stmt.setString(1, standardArticle.getAuthor());
            stmt.setString(2, standardArticle.getSimpleMatchKey());
            Date publicationDate = standardArticle.getPublicationDate();
            stmt.setLong(3, publicationDate == null ? -1L : publicationDate.getTime());
            stmt.setString(4, standardArticle.getTitle());
            stmt.setString(5, standardArticle.getSubject());
            stmt.setBoolean(6, standardArticle.isRead());
            stmt.setBoolean(7, standardArticle.isPinned());
            URL link = standardArticle.getLink();
            stmt.setString(8, link == null ? null : link.toString());
            stmt.setLong(9, article.getID());

            int rows = stmt.executeUpdate();
            if (rows == 0)
            {
                IFeed feed = article.getFeed();
                IGuide[] guides = feed.getParentGuides();
                IGuide guide = guides.length == 0 ? null : guides[0];
                String feedId = feed == null ? "no feed" : Long.toString(feed.getID());
                String guideId = guide == null ? "no guide" : Long.toString(guide.getID());

                LOG.log(Level.SEVERE, MessageFormat.format(
                    Strings.error("db.hsql.updated.0.rows.for.articleid.0.feedid.1.guideid.2"),
                    article.getID(), feedId, guideId));
            }
        } finally
        {
            stmt.close();
        }
    }

    /**
     * Updates article in database.
     *
     * @param article article to update.
     *
     * @throws NullPointerException if article isn't specified.
     * @throws IllegalArgumentException if article is of unsupported type.
     * @throws SQLException if database operation fails.
     */
    public void updateArticleProperties(IArticle article)
        throws SQLException
    {
        if (!checkArticle(article)) return;

        PreparedStatement stmt = context.getPreparedStatement("UPDATE ARTICLE_PROPERTIES SET " +
            "POSITIVE_SENTIMENTS = ?, NEGATIVE_SENTIMENTS = ? " +
            "WHERE ARTICLEID = ?");
        try
        {
            stmt.setInt(1, article.getPositiveSentimentsCount());
            stmt.setInt(2, article.getNegativeSentimentsCount());
            stmt.setLong(3, article.getID());
            stmt.executeUpdate();
        } finally
        {
            stmt.close();
        }
    }

    /**
     * Checks an article for being present, being of a valid type etc.
     *
     * @param article article.
     *
     * @return TRUE if all well.
     *
     * @throws NullPointerException if article isn't specified.
     * @throws IllegalArgumentException if article is of unsupported type.
     * @throws SQLException if database operation fails.
     */
    private static boolean checkArticle(IArticle article)
    {
        if (article == null) throw new NullPointerException(MSG_SHOULD_BE_SPECIFIED);
        if (!(article instanceof StandardArticle)) throw new IllegalArgumentException(MSG_UNSUPPORTED_TYPE);
        if (article.getID() == -1L)
        {
            LOG.log(Level.SEVERE, MessageFormat.format(Strings.error("0.title.1"),
                MSG_NOT_IN_DB, article.getTitle()), new Exception("Dump"));
            return false;
        }

        return true;
    }
}
TOP

Related Classes of com.salas.bb.persistence.backend.HsqlArticlesPM

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.