/* * ContentPeer.java * * This work 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 work 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 * * Copyright (c) 2004 Per Cederberg. All rights reserved. */ package org.liquidsite.core.data; import java.util.ArrayList; import org.liquidsite.util.db.DatabaseQuery; /** * A content database peer. This class contains static methods that * handles all accesses to the LS_CONTENT table. * * @author Per Cederberg, <per at percederberg dot net> * @version 1.0 */ public class ContentPeer extends AbstractPeer { /** * The content peer instance. */ private static final ContentPeer PEER = new ContentPeer(); /** * The latest content status flag. This flag is set on content * objects that are the latest revision, including unpublished or * working revisions. */ public static final int LATEST_STATUS = 1; /** * The published content status flag. This flag is set on content * objects that are the latest published revision, not including * working revisions. */ public static final int PUBLISHED_STATUS = 2; /** * Returns the number of content objects matching the specified * query. * * @param src the data source to use * @param query the content query to use * * @return the number of matching content objects * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static int doCountByQuery(DataSource src, ContentQuery query) throws DataObjectException { return (int) PEER.count(src, query.createCountQuery()); } /** * Returns a list of all content object revisions with the * specified id. * * @param src the data source to use * @param id the content id * * @return the list of content objects found * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static ArrayList doSelectById(DataSource src, int id) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.select.id"); query.addParameter(id); return PEER.selectList(src, query); } /** * Returns the content object with the specified id and revision. * * @param src the data source to use * @param id the content id * @param revision the content revision * * @return the content found, or * null if no matching content existed * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static ContentData doSelectByRevision(DataSource src, int id, int revision) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.select.revision"); query.addParameter(id); query.addParameter(revision); return (ContentData) PEER.select(src, query); } /** * Returns the content object with the specified id and highest * revision. A flag can be set to regard the revision number zero * (0) as the highest one. * * @param src the data source to use * @param id the content id * @param maxIsZero the revision zero is max flag * * @return the content found, or * null if no matching content existed * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static ContentData doSelectByMaxRevision(DataSource src, int id, boolean maxIsZero) throws DataObjectException { DatabaseQuery query; ContentData data; if (maxIsZero) { data = doSelectByRevision(src, id, 0); if (data != null) { return data; } } query = new DatabaseQuery("content.select.id"); query.addParameter(id); return (ContentData) PEER.select(src, query); } /** * Returns the content object with the specified parent and name. * If multiple objects should match, any one of them can be * returned. Matches of old revisions of content objects will be * discarded, and only the highest revision of a matching object * is returned. A flag can be set to regard the revision number * zero (0) as the highest one. * * @param src the data source to use * @param domain the domain name * @param parent the parent content id * @param name the content name * @param maxIsZero the revision zero is max flag * * @return the content found, or * null if no matching content existed * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static ContentData doSelectByName(DataSource src, String domain, int parent, String name, boolean maxIsZero) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.select.name"); query.addParameter(domain); query.addParameter(parent); query.addParameter(name); if (maxIsZero) { query.addParameter(LATEST_STATUS); } else { query.addParameter(PUBLISHED_STATUS); } return (ContentData) PEER.select(src, query); } /** * Returns a list of content objects matching the specified query. * * @param src the data source to use * @param query the content query to use * * @return a list of all matching content objects * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static ArrayList doSelectByQuery(DataSource src, ContentQuery query) throws DataObjectException { return PEER.selectList(src, query.createSelectQuery()); } /** * Inserts a new content object into the data source. This method * will assign a new content id if it is set to zero (0). * * @param src the data source to use * @param data the content data object * * @throws DataObjectException if the data source couldn't be * accessed properly * * @see #doStatusUpdate */ public static synchronized void doInsert(DataSource src, ContentData data) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.insert"); if (data.getInt(ContentData.ID) <= 0) { data.setInt(ContentData.ID, getNewId(src)); } query.addParameter(data.getString(ContentData.DOMAIN)); query.addParameter(data.getInt(ContentData.ID)); query.addParameter(data.getInt(ContentData.REVISION)); query.addParameter(data.getInt(ContentData.CATEGORY)); query.addParameter(data.getString(ContentData.NAME)); query.addParameter(data.getInt(ContentData.PARENT)); query.addParameter(data.getDate(ContentData.ONLINE)); query.addParameter(data.getDate(ContentData.OFFLINE)); query.addParameter(data.getDate(ContentData.MODIFIED)); query.addParameter(data.getString(ContentData.AUTHOR)); query.addParameter(data.getString(ContentData.COMMENT)); PEER.insert(src, query); } /** * Updates a content object in the data source. * * @param src the data source to use * @param data the content data object * * @throws DataObjectException if the data source couldn't be * accessed properly * * @see #doStatusUpdate */ public static void doUpdate(DataSource src, ContentData data) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.update"); query.addParameter(data.getString(ContentData.NAME)); query.addParameter(data.getInt(ContentData.PARENT)); query.addParameter(data.getDate(ContentData.ONLINE)); query.addParameter(data.getDate(ContentData.OFFLINE)); query.addParameter(data.getDate(ContentData.MODIFIED)); query.addParameter(data.getString(ContentData.AUTHOR)); query.addParameter(data.getString(ContentData.COMMENT)); query.addParameter(data.getInt(ContentData.ID)); query.addParameter(data.getInt(ContentData.REVISION)); PEER.update(src, query); } /** * Deletes a content object from the data source. This method * will delete all revisions, as well as related attributes, * permissions and locks. Note, however, that it will NOT delete * referenced child objects. * * @param src the data source to use * @param data the content data object * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static void doDelete(DataSource src, ContentData data) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.delete"); String domain = data.getString(ContentData.DOMAIN); int id = data.getInt(ContentData.ID); query.addParameter(id); PEER.delete(src, query); AttributePeer.doDeleteContent(src, id); PermissionPeer.doDelete(src, domain, id); LockPeer.doDeleteContent(src, id); } /** * Deletes all content objects in a domain from the data source. * This method also deletes all attributes, permissions and locks * in the domain. * * @param src the data source to use * @param domain the domain name * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static void doDeleteDomain(DataSource src, String domain) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.delete.domain"); query.addParameter(domain); PEER.delete(src, query); AttributePeer.doDeleteDomain(src, domain); PermissionPeer.doDeleteDomain(src, domain); LockPeer.doDeleteDomain(src, domain); } /** * Deletes a content object revision from the data source. This * method also deletes all related attributes. * * @param src the data source to use * @param id the content identifier * @param revision the content revision * * @throws DataObjectException if the data source couldn't be * accessed properly * * @see #doStatusUpdate */ public static void doDeleteRevision(DataSource src, int id, int revision) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.delete.revision"); query.addParameter(id); query.addParameter(revision); PEER.delete(src, query); AttributePeer.doDeleteRevision(src, id, revision); } /** * Updates the status flags for all content object revisions. * This method will read the data source to extract the latest * revisions, clear any previous status flags, and then set the * new flags. This method also updates the status flags in * related attributes. When finished inserting, updating or * deleting in the content and attribute tables, this method * should always be called. * * @param src the data source to use * @param id the content identifier * * @throws DataObjectException if the data source couldn't be * accessed properly */ public static void doStatusUpdate(DataSource src, int id) throws DataObjectException { DatabaseQuery query; int min; int max; query = new DatabaseQuery("content.select.revision.min"); query.addParameter(id); min = (int) PEER.count(src, query); query = new DatabaseQuery("content.select.revision.max"); query.addParameter(id); max = (int) PEER.count(src, query); doStatusClear(src, id); if (max > 0) { doStatusSet(src, id, max, PUBLISHED_STATUS); } if (min > 0) { doStatusSet(src, id, max, LATEST_STATUS); } else { doStatusSet(src, id, min, LATEST_STATUS); } } /** * Clears the status flags for all content object revisions. This * method also clears the status flags in related attributes. * * @param src the data source to use * @param id the content identifier * * @throws DataObjectException if the data source couldn't be * accessed properly */ private static void doStatusClear(DataSource src, int id) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.status.clear"); query.addParameter(id); PEER.update(src, query); } /** * Sets a status flag bit for a content object revision. The bit * flag will be added to the status flags without clearing any * other bit flag (logical OR). This method also sets the same bit * in related attributes. * * @param src the data source to use * @param id the content identifier * @param revision the content revision * @param flag the bit flag to set * * @throws DataObjectException if the data source couldn't be * accessed properly */ private static void doStatusSet(DataSource src, int id, int revision, int flag) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.status.set"); query.addParameter(flag); query.addParameter(id); query.addParameter(revision); PEER.update(src, query); } /** * Returns a new unique content identifier. This method will * search the data source for the maximum content identifier * currently used and add one to it. * * @param src the data source to use * * @return the new unique content identifier * * @throws DataObjectException if the data source couldn't be * accessed properly */ private static int getNewId(DataSource src) throws DataObjectException { DatabaseQuery query = new DatabaseQuery("content.select.id.max"); return (int) PEER.count(src, query) + 1; } /** * Creates a new content database peer. */ private ContentPeer() { super("content"); } /** * Returns a new instance of the data object. * * @return a new instance of the data object */ protected AbstractData getDataObject() { return new ContentData(); } }