/* ===============================================================================
*
* Part of the InfoGlue Content Management Platform (www.infoglue.org)
*
* ===============================================================================
*
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2, as published by the
* Free Software Foundation. See the file LICENSE.html for more information.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, including 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.
*
* ===============================================================================
*
* $Id: ContentCategoryController.java,v 1.23 2010/09/07 08:05:43 mattias Exp $
*/
package org.infoglue.cms.controllers.kernel.impl.simple;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.exolab.castor.jdo.Database;
import org.exolab.castor.jdo.PersistenceException;
import org.infoglue.cms.entities.content.ContentCategory;
import org.infoglue.cms.entities.content.ContentCategoryVO;
import org.infoglue.cms.entities.content.ContentVersion;
import org.infoglue.cms.entities.content.ContentVersionVO;
import org.infoglue.cms.entities.content.impl.simple.ContentCategoryImpl;
import org.infoglue.cms.entities.content.impl.simple.ContentVersionImpl;
import org.infoglue.cms.entities.content.impl.simple.MediumContentCategoryImpl;
import org.infoglue.cms.entities.content.impl.simple.MediumContentVersionImpl;
import org.infoglue.cms.entities.kernel.BaseEntityVO;
import org.infoglue.cms.entities.management.Category;
import org.infoglue.cms.entities.management.CategoryVO;
import org.infoglue.cms.entities.management.impl.simple.CategoryImpl;
import org.infoglue.cms.exception.SystemException;
import org.infoglue.cms.security.InfoGluePrincipal;
import org.infoglue.cms.util.ConstraintExceptionBuffer;
import org.infoglue.deliver.util.CacheController;
import org.infoglue.deliver.util.Timer;
/**
* The ContentCategoryController manages all actions related to persistence
* and querying for ContentCategory relationships.
*
* TODO: When we convert have Hibernate manage all of these relationships, it will pull it
* TODO: all back with one query and be a helluva lot faster than this basic implementation
*
* @author Frank Febbraro (frank@phase2technology.com)
*/
public class ContentCategoryController extends BaseController
{
private final static Logger logger = Logger.getLogger(ContentCategoryController.class.getName());
private static final ContentCategoryController instance = new ContentCategoryController();
private static final String findByContentVersion = new StringBuffer("SELECT c ")
.append("FROM org.infoglue.cms.entities.content.impl.simple.MediumContentCategoryImpl c ")
.append("WHERE c.contentVersion.contentVersionId = $1").toString();
/*
private static final String findByContentVersionAttribute = new StringBuffer("SELECT c ")
.append("FROM org.infoglue.cms.entities.content.impl.simple.ContentCategoryImpl c ")
.append("WHERE c.attributeName = $1 ")
.append("AND c.contentVersion.contentVersionId = $2")
.append("ORDER BY c.category.name").toString();
*/
private static final String findByContentVersionAttributeSmall = new StringBuffer("SELECT c ")
.append("FROM org.infoglue.cms.entities.content.impl.simple.SmallContentCategoryImpl c ")
.append("WHERE c.attributeName = $1 ")
.append("AND c.contentVersionId = $2")
.append("ORDER BY c.contentCategoryId").toString();
private static final String findByCategory = new StringBuffer("SELECT c ")
.append("FROM org.infoglue.cms.entities.content.impl.simple.MediumContentCategoryImpl c ")
.append("WHERE c.category.categoryId = $1 ").toString();
public static ContentCategoryController getController()
{
return instance;
}
private ContentCategoryController() {}
/**
* Find a ContentCategory by it's identifier.
* @param id The id of the Category to find
* @return The CategoryVO identified by the provided id
* @throws SystemException If an error happens
*/
public ContentCategoryVO findById(Integer id) throws SystemException
{
return (ContentCategoryVO)getVOWithId(ContentCategoryImpl.class, id);
}
/**
* Find a List of ContentCategories for the specific attribute and Content Version.
* @param attribute The attribute name of the ContentCategory to find
* @param versionId The Content Version id of the ContentCategory to find
* @return A list of ContentCategoryVO that have the provided content version and attribute
* @throws SystemException If an error happens
*/
public List findByContentVersionAttribute(String attribute, Integer versionId) throws SystemException
{
/*
List params = new ArrayList();
params.add(attribute);
params.add(versionId);
return executeQuery(findByContentVersionAttribute, params);
*/
List contentCategoryVOList = new ArrayList();
Database db = CastorDatabaseService.getDatabase();
ConstraintExceptionBuffer ceb = new ConstraintExceptionBuffer();
beginTransaction(db);
try
{
List contentCategories = findByContentVersionAttribute(attribute, versionId, db, true);
if(contentCategories != null)
contentCategoryVOList = toVOList(contentCategories);
commitTransaction(db);
}
catch(Exception e)
{
//logger.error("An error occurred so we should not complete the transaction:" + e, e);
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
return contentCategoryVOList;
}
public List<ContentCategoryVO> findSmallByContentVersionAttributeReadOnly(String attribute, Integer versionId, Database db) throws SystemException
{
String key = "" + attribute + "_" + versionId;
List<ContentCategoryVO> contentCategories = (List<ContentCategoryVO>)CacheController.getCachedObjectFromAdvancedCache("contentCategoryCache", key);
if(contentCategories != null)
{
//logger.info("There was an cached contentVersionVO:" + contentVersionVO.getContentVersionId());
}
else
{
List params = new ArrayList();
params.add(attribute);
params.add(versionId);
List contentCategoryList = executeQueryReadOnly(findByContentVersionAttributeSmall, params, db);
if(contentCategoryList != null)
{
contentCategories = toVOList(contentCategoryList);
CacheController.cacheObjectInAdvancedCache("contentCategoryCache", key, contentCategories, new String[]{CacheController.getPooledString(2, versionId)}, true);
}
}
return contentCategories;
}
/**
* Find a List of ContentCategories for the specific attribute and Content Version.
* @param attribute The attribute name of the ContentCategory to find
* @param versionId The Content Version id of the ContentCategory to find
* @return A list of ContentCategoryVO that have the provided content version and attribute
* @throws SystemException If an error happens
*/
public List findByContentVersionAttribute(String attribute, Integer versionId, Database db, boolean readOnly) throws SystemException
{
return findByContentVersionAttribute(attribute, versionId, db);
}
public List findByContentVersionAttribute(String attribute, Integer versionId, Database db) throws SystemException
{
List contentCategoryList = new ArrayList();
//Timer t = new Timer();
//TODO - kan optimeras mycket
List contentCategories = findByContentVersionReadOnly(versionId, db);
//t.printElapsedTime("findByContentVersionReadOnly");
//t.printElapsedTime("contentCategories");
if(contentCategories != null)
{
Iterator contentCategoriesIterator = contentCategories.iterator();
while(contentCategoriesIterator.hasNext())
{
ContentCategory contentCategory = (ContentCategory)contentCategoriesIterator.next();
if(contentCategory.getAttributeName().equals(attribute))
{
contentCategoryList.add(contentCategory);
}
}
}
//t.printElapsedTime("Rest");
return contentCategoryList;
/*
List contentCategoryList = new ArrayList();
ContentVersion contentVersion = null;
if(readOnly)
contentVersion = ContentVersionController.getContentVersionController().getReadOnlyContentVersionWithId(versionId, db);
else
contentVersion = ContentVersionController.getContentVersionController().getContentVersionWithId(versionId, db);
Collection contentCategories = contentVersion.getContentCategories();
if(contentCategories != null)
{
Iterator contentCategoriesIterator = contentCategories.iterator();
while(contentCategoriesIterator.hasNext())
{
ContentCategory contentCategory = (ContentCategory)contentCategoriesIterator.next();
if(contentCategory.getAttributeName().equals(attribute))
{
contentCategoryList.add(contentCategory);
}
}
}
return contentCategoryList;
*/
}
/**
* Find a List of ContentCategories for the specific attribute and Content Version.
* @param attribute The attribute name of the ContentCategory to find
* @param versionId The Content Version id of the ContentCategory to find
* @return A list of ContentCategoryVO that have the provided content version and attribute
* @throws SystemException If an error happens
*/
public List findByContentVersionAttribute(String attribute, ContentVersion contentVersion, Database db) throws SystemException
{
List contentCategoryList = new ArrayList();
if(contentVersion != null)
{
Collection contentCategories = contentVersion.getContentCategories();
if(contentCategories != null)
{
Iterator contentCategoriesIterator = contentCategories.iterator();
while(contentCategoriesIterator.hasNext())
{
ContentCategory contentCategory = (ContentCategory)contentCategoriesIterator.next();
if(contentCategory.getAttributeName().equals(attribute))
{
contentCategoryList.add(contentCategory);
}
}
}
}
return contentCategoryList;
}
/**
* Find a List of ContentCategories for a Content Version.
* @param versionId The Content Version id of the ContentCategory to find
* @return A list of ContentCategoryVO that have the provided content version and attribute
* @throws SystemException If an error happens
*/
public List findByContentVersion(Integer versionId) throws SystemException
{
List params = new ArrayList();
params.add(versionId);
return executeQuery(findByContentVersion, params);
}
/**
* Find a List of ContentCategories for a Content Version.
* @param versionId The Content Version id of the ContentCategory to find
* @return A list of ContentCategoryVO that have the provided content version and attribute
* @throws SystemException If an error happens
*/
public List findByContentVersion(Integer versionId, Database db) throws SystemException
{
List params = new ArrayList();
params.add(versionId);
return executeQuery(findByContentVersion, params, db);
}
/**
* Find a List of ContentCategories for a Content Version.
* @param versionId The Content Version id of the ContentCategory to find
* @return A list of ContentCategoryVO that have the provided content version and attribute
* @throws SystemException If an error happens
*/
public List findByContentVersionReadOnly(Integer versionId, Database db) throws SystemException
{
List params = new ArrayList();
params.add(versionId);
return executeQueryReadOnly(findByContentVersion, params, db);
}
/**
* Find a List of ContentCategories for the specific attribute and Content Version.
* @param categoryId The Category id of the ContentCategory to find
* @return A list of ContentCategoryVO that have the provided category id
* @throws SystemException If an error happens
*/
public List findByCategory(Integer categoryId) throws SystemException
{
List params = new ArrayList();
params.add(categoryId);
return executeQuery(findByCategory, params);
}
/**
* Saves a ContentCategoryVO whether it is new or not.
* @param c The ContentCategoryVO to save
* @return The saved ContentCategoryVO
* @throws SystemException If an error happens
*/
public ContentCategoryVO save(ContentCategoryVO c, InfoGluePrincipal principal) throws SystemException
{
ContentVersionVO contentVersionVO = ContentVersionController.getContentVersionController().checkStateAndChangeIfNeeded(c.getContentVersionId(), principal);
c.setContentVersionId(contentVersionVO.getId());
return c.isUnsaved() ? create(c) : (ContentCategoryVO)updateEntity(ContentCategoryImpl.class, c);
}
/**
* Creates a ContentCategory from a ContentCategoryVO
*/
private ContentCategoryVO create(ContentCategoryVO c) throws SystemException
{
Database db = beginTransaction();
try
{
ContentCategory contentCategory = createWithDatabase(c, db);
commitTransaction(db);
return contentCategory.getValueObject();
}
catch (Exception e)
{
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
}
public ContentCategory createWithDatabase(ContentCategoryVO c, Database db) throws SystemException, PersistenceException
{
// Need this crappy hack to forge the relationship (castor completely sucks like this)
// TODO: When hibernate comes, just save the VOs and if it has a child VO with an id set
// TODO: it is used to make the relationship...ask me for clarification -frank
Category category = (Category)getObjectWithId(CategoryImpl.class, c.getCategory().getId(), db);
//ContentVersion contentVersion = (ContentVersion)getObjectWithId(ContentVersionImpl.class, c.getContentVersionId(), db);
ContentVersion contentVersion = ContentVersionController.getContentVersionController().getMediumContentVersionWithId(c.getContentVersionId(), db);
ContentCategory contentCategory = null;
List existingContentCategories = ContentCategoryController.getController().findByContentVersionAttribute(c.getAttributeName(), contentVersion.getContentVersionId(), db);
boolean exists = false;
Iterator existingContentCategoriesIterator = existingContentCategories.iterator();
while(existingContentCategoriesIterator.hasNext())
{
ContentCategory contentCategoryCandidate = (ContentCategory)existingContentCategoriesIterator.next();
if(contentCategoryCandidate.getCategoryId().equals(category.getId()))
{
exists = true;
contentCategory = contentCategoryCandidate;
logger.info("The category " + category.getName() + " was allready set on this version");
break;
}
}
if(!exists)
{
logger.info("Creating the category " + category.getName() + " as it was not set on this version");
contentCategory = new MediumContentCategoryImpl();
contentCategory.setValueObject(c);
contentCategory.setCategory((CategoryImpl)category);
contentCategory.setContentVersion((MediumContentVersionImpl)contentVersion);
db.create(contentCategory);
contentVersion.getContentCategories().add(contentCategory);
}
else
{
logger.info("Skipping the category " + category.getName() + " as it was allready set on this version");
}
return contentCategory;
}
/**
* Creates a number of ContentCategories from a list of categories and a contentVersion.
*/
public List create(List categoryVOList, ContentVersionVO contentVersionVO, String attributeName) throws SystemException
{
List contentCategoryVOList = new ArrayList();
Database db = beginTransaction();
try
{
Iterator categoryVOListIterator = categoryVOList.iterator();
while(categoryVOListIterator.hasNext())
{
CategoryVO categoryVO = (CategoryVO)categoryVOListIterator.next();
Category category = (Category)getObjectWithId(CategoryImpl.class, categoryVO.getId(), db);
ContentVersion contentVersion = (ContentVersion)getObjectWithId(ContentVersionImpl.class, contentVersionVO.getId(), db);
List existingContentCategories = ContentCategoryController.getController().findByContentVersionAttribute(attributeName, contentVersion.getContentVersionId(), db, true);
boolean exists = false;
Iterator existingContentCategoriesIterator = existingContentCategories.iterator();
while(existingContentCategoriesIterator.hasNext())
{
ContentCategory contentCategory = (ContentCategory)existingContentCategoriesIterator.next();
if(contentCategory.getCategoryId().equals(category.getId()))
{
exists = true;
logger.info("The category " + category.getName() + " was allready set on this version");
break;
}
}
if(!exists)
{
logger.info("Creating the category " + category.getName() + " as it was not set on this version");
ContentCategoryVO contentCategoryVO = new ContentCategoryVO();
contentCategoryVO.setAttributeName(attributeName);
contentCategoryVO.setContentVersionId(contentVersionVO.getId());
ContentCategory contentCategory = createWithDatabase(contentCategoryVO, category, contentVersion, db);
contentCategoryVOList.add(contentCategory.getValueObject());
}
else
{
logger.info("Skipping the category " + category.getName() + " as it was allready set on this version");
}
}
commitTransaction(db);
}
catch (Exception e)
{
rollbackTransaction(db);
throw new SystemException(e.getMessage());
}
return contentCategoryVOList;
}
/**
* Creates a number of ContentCategories from a list of categories and a contentVersion.
*/
public List create(List categoryList, ContentVersion contentVersion, String attributeName, Database db) throws SystemException, Exception
{
logger.info("Creating categories on " + contentVersion.getId() + " for attributeName:" + attributeName);
List contentCategoryList = new ArrayList();
Iterator categoryListIterator = categoryList.iterator();
while(categoryListIterator.hasNext())
{
Category category = (Category)categoryListIterator.next();
List existingContentCategories = ContentCategoryController.getController().findByContentVersionAttribute(attributeName, contentVersion.getContentVersionId(), db, true);
boolean exists = false;
Iterator existingContentCategoriesIterator = existingContentCategories.iterator();
while(existingContentCategoriesIterator.hasNext())
{
ContentCategory contentCategory = (ContentCategory)existingContentCategoriesIterator.next();
if(contentCategory.getCategoryId().equals(category.getId()))
{
exists = true;
logger.info("The category " + category.getName() + " was allready set on this version");
break;
}
}
if(!exists)
{
logger.info("Creating the category " + category.getName() + " as it was not set on this version");
ContentCategoryVO contentCategoryVO = new ContentCategoryVO();
contentCategoryVO.setAttributeName(attributeName);
contentCategoryVO.setContentVersionId(contentVersion.getId());
ContentCategory contentCategory = createWithDatabase(contentCategoryVO, category, contentVersion, db);
contentVersion.getContentCategories().add(contentCategory);
contentCategoryList.add(contentCategory);
}
else
{
logger.info("Skipping the category " + category.getName() + " as it was allready set on this version");
}
}
return contentCategoryList;
}
/**
* Creates a number of ContentCategories from a list of categories and a contentVersion.
*/
public List createMedium(List categoryList, ContentVersion contentVersion, String attributeName, Database db) throws SystemException, Exception
{
logger.info("Creating categories on " + contentVersion.getId() + " for attributeName:" + attributeName);
List contentCategoryList = new ArrayList();
Iterator categoryListIterator = categoryList.iterator();
while(categoryListIterator.hasNext())
{
Category category = (Category)categoryListIterator.next();
List existingContentCategories = ContentCategoryController.getController().findByContentVersionAttribute(attributeName, contentVersion.getContentVersionId(), db);
boolean exists = false;
Iterator existingContentCategoriesIterator = existingContentCategories.iterator();
while(existingContentCategoriesIterator.hasNext())
{
ContentCategory contentCategory = (ContentCategory)existingContentCategoriesIterator.next();
if(contentCategory.getCategoryId().equals(category.getId()))
{
exists = true;
logger.info("The category " + category.getName() + " was allready set on this version");
break;
}
}
if(!exists)
{
logger.info("Creating the category " + category.getName() + " as it was not set on this version");
ContentCategoryVO contentCategoryVO = new ContentCategoryVO();
contentCategoryVO.setAttributeName(attributeName);
contentCategoryVO.setContentVersionId(contentVersion.getId());
ContentCategory contentCategory = createMediumWithDatabase(contentCategoryVO, category, contentVersion, db);
contentVersion.getContentCategories().add(contentCategory);
contentCategoryList.add(contentCategory);
}
else
{
logger.info("Skipping the category " + category.getName() + " as it was allready set on this version");
}
}
return contentCategoryList;
}
public ContentCategory createWithDatabase(ContentCategoryVO c, Category category, ContentVersion contentVersion, Database db) throws SystemException, PersistenceException
{
ContentCategory contentCategory = new ContentCategoryImpl();
contentCategory.setValueObject(c);
contentCategory.setCategory((CategoryImpl)category);
contentCategory.setContentVersion((ContentVersionImpl)contentVersion);
db.create(contentCategory);
return contentCategory;
}
public ContentCategory createMediumWithDatabase(ContentCategoryVO c, Category category, ContentVersion contentVersion, Database db) throws SystemException, PersistenceException
{
ContentCategory contentCategory = new MediumContentCategoryImpl();
contentCategory.setValueObject(c);
contentCategory.setCategory((CategoryImpl)category);
contentCategory.setContentVersion((MediumContentVersionImpl)contentVersion);
db.create(contentCategory);
return contentCategory;
}
/**
* Deletes a ContentCategory
* @param id The id of the ContentCategory to delete
* @throws SystemException If an error happens
*/
public void delete(Integer id, InfoGluePrincipal principal) throws SystemException
{
Database db = beginTransaction();
try
{
ContentCategory contentCategory = (ContentCategory)getObjectWithId(MediumContentCategoryImpl.class, id, db);
MediumContentVersionImpl contentVersion = ContentVersionController.getContentVersionController().checkStateAndChangeIfNeeded(contentCategory.getContentVersionId(), principal, db);
//ContentCategory contentCategory = (ContentCategory)getObjectWithId(ContentCategoryImpl.class, id, db);
//ContentVersion contentVersion = (ContentVersion)getObjectWithId(ContentVersionImpl.class, contentCategory.getContentVersionId(), db);
Iterator contentCategoriesIterator = contentVersion.getContentCategories().iterator();
while(contentCategoriesIterator.hasNext())
{
MediumContentCategoryImpl currentContentCategory = (MediumContentCategoryImpl)contentCategoriesIterator.next();
ContentCategoryVO currentContentCategoryVO = currentContentCategory.getValueObject();
if(currentContentCategoryVO.getAttributeName().equals(contentCategory.getAttributeName()) && currentContentCategory.getCategory().getId().equals(contentCategory.getCategory().getId()))
{
contentCategoriesIterator.remove();
db.remove(currentContentCategory);
break;
}
}
//contentVersion.getContentCategories().remove(contentCategory);
//db.remove(contentCategory);
commitTransaction(db);
}
catch (Exception e)
{
rollbackTransaction(db);
e.printStackTrace();
throw new SystemException(e.getMessage());
}
//deleteEntity(ContentCategoryImpl.class, id);
}
/**
* Deletes all ContentCategories for a particular ContentVersion
* @param versionId The id of the ContentCategory to delete
* @throws SystemException If an error happens
*/
public void deleteByContentVersion(Integer versionId) throws SystemException
{
delete(findByContentVersion(versionId));
}
/**
* Deletes all ContentCategories for a particular ContentVersion
* @param versionId The id of the ContentCategory to delete
* @throws SystemException If an error happens
*/
public void deleteByContentVersion(ContentVersion contentVersion, Database db) throws SystemException, Exception
{
Iterator contentVersionIterator = contentVersion.getContentCategories().iterator();
while(contentVersionIterator.hasNext())
{
ContentCategory contentCategory = (ContentCategory)contentVersionIterator.next();
contentVersionIterator.remove();
db.remove(contentCategory);
}
}
/**
* Deletes all ContentCategories for a particular ContentVersion using the provided Database
* @param versionId The id of the ContentCategory to delete
* @param db The Database instance to use
* @throws SystemException If an error happens
*/
public void deleteByContentVersion(Integer versionId, Database db) throws SystemException
{
delete(findByContentVersion(versionId), db);
}
/**
* Deletes all ContentCategories for a particular Category
* @param categoryId The id of the ContentCategory to delete
* @throws SystemException If an error happens
*/
public void deleteByCategory(Integer categoryId) throws SystemException
{
delete(findByCategory(categoryId));
}
/**
* Deletes all ContentCategories for a particular Category using the provided Database
* @param categoryId The id of the Category to delete
* @param db The Database instance to use
* @throws SystemException If an error happens
*/
public void deleteByCategory(Integer categoryId, Database db) throws SystemException
{
delete(findByCategory(categoryId), db);
}
/**
* Deletes all content categories with a specific attribute for a specific content version within a single transaction
* @param attribute the desired attribute
* @param versionId the ID of the desired content version
* @throws SystemException if a database error occurs
*/
public void deleteByContentVersionAttribute(String attribute, Integer versionId) throws SystemException
{
delete(findByContentVersionAttribute(attribute, versionId));
}
/**
* Deletes all content categories with a specific attribute for a specific content version using the given database
* @param attribute the desired attribute
* @param versionId the ID of the desired content version
* @param db the database defining the transaction context for this delete
* @throws SystemException if a database error occurs
*/
public void deleteByContentVersionAttribute(String attribute, Integer versionId, Database db) throws SystemException
{
delete(findByContentVersionAttribute(attribute, versionId), db);
}
/**
* Deletes a collection of content categories within a single transaction
* @param contentCategories a collection of ContentCategoryVOs to delete
* @throws SystemException if a database error occurs
*/
private static void delete(Collection contentCategories) throws SystemException
{
Database db = beginTransaction();
try
{
delete(contentCategories, db);
commitTransaction(db);
}
catch (Exception e)
{
rollbackTransaction(db);
throw new SystemException(e);
}
}
/**
* Deletes a collection of content categories using the given database
* @param contentCategories a collection of ContentCategoryVOs to delete
* @param db the database to be used for the delete
* @throws SystemException if a database error occurs
*/
private static void delete(Collection contentCategories, Database db) throws SystemException
{
for (Iterator i = contentCategories.iterator(); i.hasNext();)
deleteEntity(ContentCategoryImpl.class, ((ContentCategoryVO)i.next()).getId(), db);
}
/**
* Implemented for BaseController
*/
public BaseEntityVO getNewVO()
{
return new ContentCategoryVO();
}
}