335 lines
12 KiB
Java
Executable File
335 lines
12 KiB
Java
Executable File
/*
|
|
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation; either version 2.1 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
package com.arsdigita.navigation;
|
|
|
|
import com.arsdigita.bebop.PageState;
|
|
import com.arsdigita.categorization.Category;
|
|
|
|
|
|
import com.arsdigita.kernel.ACSObject;
|
|
import com.arsdigita.kernel.Kernel;
|
|
import com.arsdigita.kernel.Party;
|
|
|
|
import com.arsdigita.kernel.permissions.PermissionService;
|
|
import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
|
|
|
|
import com.arsdigita.persistence.DataCollection;
|
|
import com.arsdigita.persistence.Filter;
|
|
import com.arsdigita.persistence.SessionManager;
|
|
|
|
import com.arsdigita.persistence.metadata.ObjectType;
|
|
import com.arsdigita.persistence.metadata.Property;
|
|
|
|
import com.arsdigita.util.Assert;
|
|
import com.arsdigita.util.LockableImpl;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.Iterator;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
/**
|
|
* A class for building up a definition of parameters to
|
|
* later use for a DataCollection of ACSObjects.
|
|
*/
|
|
public class DataCollectionDefinition extends LockableImpl {
|
|
|
|
private static Logger s_log = Logger.getLogger(
|
|
DataCollectionDefinition.class);
|
|
private String m_objectType = ACSObject.BASE_DATA_OBJECT_TYPE;
|
|
private String m_specificObjectType = null;
|
|
private boolean m_filterCategory = true;
|
|
private boolean m_descendCategories = false;
|
|
private boolean m_excludeIndexObjects = true;
|
|
private boolean m_checkPermissions = false;
|
|
private boolean m_blackListTypes = false;
|
|
private ArrayList m_ordering = new ArrayList();
|
|
private ArrayList m_excludedTypes = new ArrayList();
|
|
private ArrayList m_properties = new ArrayList();
|
|
private String m_dateAttribute = null;
|
|
|
|
public final void setObjectType(String objectType) {
|
|
Assert.isUnlocked(this);
|
|
m_objectType = objectType;
|
|
validateObjectType(objectType);
|
|
}
|
|
|
|
public final void setSpecificObjectType(String specificObjectType) {
|
|
Assert.isUnlocked(this);
|
|
|
|
if (specificObjectType != null) {
|
|
validateObjectType(specificObjectType);
|
|
}
|
|
m_specificObjectType = specificObjectType;
|
|
}
|
|
|
|
public final void excludeSpecificObjectType(String specificObjectType) {
|
|
Assert.isUnlocked(this);
|
|
|
|
m_excludedTypes.add(specificObjectType);
|
|
}
|
|
|
|
public void setDateAttribute(DataCollectionRenderer renderer) {
|
|
|
|
// Stop here, if the set object type is invalid a.k.a. not installed
|
|
if(this.hasInvalidObjectType()) {
|
|
return;
|
|
}
|
|
|
|
ObjectType type = SessionManager.getMetadataRoot().getObjectType(
|
|
m_objectType);
|
|
s_log.debug("set date attribute for collection of " + type.
|
|
getQualifiedName());
|
|
if (s_log.isDebugEnabled()) {
|
|
Iterator properties = type.getProperties();
|
|
while (properties.hasNext()) {
|
|
Property prop = (Property) properties.next();
|
|
s_log.debug("object has property " + prop.getName()
|
|
+ " of class " + prop.getJavaClass().getName());
|
|
}
|
|
}
|
|
Iterator it = (renderer.getAttributes().iterator());
|
|
while (it.hasNext()) {
|
|
String attribute = (String) it.next();
|
|
s_log.debug("renderer is rendering attribute: " + attribute);
|
|
Property property = type.getProperty(attribute);
|
|
s_log.debug("property of object: " + property);
|
|
if (property != null) {
|
|
s_log.debug("Property class is " + property.getJavaClass().
|
|
getName());
|
|
}
|
|
if (property != null && property.getJavaClass().getName().equals(Date.class.
|
|
getName())) {
|
|
m_dateAttribute = attribute;
|
|
// if more than one date attribute is specified for the type included in this
|
|
// definition, then we cannot determine in the code which is to be used as the
|
|
// basis for ordering in XSL - therefore return the first encountered date.
|
|
// User can control which of the dates is used as basis for sorting by specifying
|
|
// that date attribute first in the navigation jsp
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private final void validateObjectType(String objectType) {
|
|
ObjectType type = SessionManager.getMetadataRoot().getObjectType(
|
|
objectType);
|
|
|
|
// WTF: I don't need an exception if the requested objecttype doesn't exists
|
|
// That will only ruin your website
|
|
//Assert.exists(type, ObjectType.class);
|
|
if(type == null) {
|
|
m_objectType = "";
|
|
} else {
|
|
validateObjectType(type);
|
|
}
|
|
}
|
|
|
|
public boolean hasInvalidObjectType() {
|
|
return m_objectType.isEmpty();
|
|
}
|
|
|
|
protected void validateObjectType(ObjectType type) {
|
|
// Nada
|
|
}
|
|
|
|
public final void setFilterCategory(boolean filterCategory) {
|
|
Assert.isUnlocked(this);
|
|
m_filterCategory = filterCategory;
|
|
}
|
|
|
|
public final boolean getDescendCategories() {
|
|
return m_descendCategories;
|
|
}
|
|
|
|
public final void setDescendCategories(boolean descendCategories) {
|
|
Assert.isUnlocked(this);
|
|
m_descendCategories = descendCategories;
|
|
}
|
|
|
|
public final void setExcludeIndexObjects(boolean excludeIndexObjects) {
|
|
Assert.isUnlocked(this);
|
|
m_excludeIndexObjects = excludeIndexObjects;
|
|
}
|
|
|
|
public final void setCheckPermissions(boolean checkPermissions) {
|
|
Assert.isUnlocked(this);
|
|
m_checkPermissions = checkPermissions;
|
|
}
|
|
|
|
/**
|
|
* Activates a filter for content types which are blacklisted
|
|
* in the AtoZ module.
|
|
*/
|
|
public void setBlackListTypes(boolean blackListTypes) {
|
|
Assert.isUnlocked(this);
|
|
m_blackListTypes = blackListTypes;
|
|
}
|
|
|
|
public final void addOrder(String order) {
|
|
Assert.isUnlocked(this);
|
|
if(s_log.isDebugEnabled()) {
|
|
s_log.debug(String.format("Adding order '%s' to current list of "
|
|
+ "order attributes: ", order));
|
|
for(Object orderAttr : m_ordering) {
|
|
s_log.debug(String.format("\t%s", orderAttr));
|
|
}
|
|
}
|
|
m_ordering.add(order);
|
|
}
|
|
|
|
public final void addProperty(DataCollectionProperty property) {
|
|
Assert.isUnlocked(this);
|
|
m_properties.add(property);
|
|
}
|
|
|
|
/**
|
|
* Get a collection of objects from the database defined by model or
|
|
* null if the requested object type is invalid
|
|
*
|
|
* @param model
|
|
* @return data collection or null
|
|
*/
|
|
public final DataCollection getDataCollection(NavigationModel model) {
|
|
Assert.isLocked(this);
|
|
|
|
// Stop here, if the set object type is invalid a.k.a. not installed
|
|
if(this.hasInvalidObjectType()) {
|
|
return null;
|
|
}
|
|
|
|
DataCollection objects = SessionManager.getSession().retrieve(
|
|
m_objectType);
|
|
|
|
applyFilters(objects, model);
|
|
|
|
Iterator properties = m_properties.iterator();
|
|
while (properties.hasNext()) {
|
|
DataCollectionProperty property = (DataCollectionProperty) properties.
|
|
next();
|
|
property.addProperty(objects);
|
|
}
|
|
|
|
if (model.getCategory() != null) {
|
|
// for date ordered categories, if pagination occurs, we need to ensure
|
|
// that primary ordering is the date attribute included in the renderer
|
|
// if there is one
|
|
if (s_log.isDebugEnabled()) {
|
|
s_log.debug("Category is " + model.getCategory().getID() + ": " + model.
|
|
getCategory().getName());
|
|
s_log.debug("getting data collection. Is category date ordered? "
|
|
+ Navigation.getConfig().isDateOrderedCategory(model.
|
|
getCategory(), PageState.getPageState())
|
|
+ " date attribute has been set to "
|
|
+ m_dateAttribute);
|
|
}
|
|
if (Navigation.getConfig().isDateOrderedCategory(model.getCategory(), PageState.
|
|
getPageState()) && m_dateAttribute != null) {
|
|
objects.addOrder(m_dateAttribute + " desc");
|
|
}
|
|
}
|
|
|
|
if (m_ordering.size() > 0) {
|
|
Iterator orders = m_ordering.iterator();
|
|
while (orders.hasNext()) {
|
|
objects.addOrder((String) orders.next());
|
|
}
|
|
} else {
|
|
objects.addOrder("id desc");
|
|
}
|
|
|
|
return objects;
|
|
}
|
|
|
|
/** Can be overridden to extract differently the category to inspect. */
|
|
protected Category getCategory(NavigationModel model) {
|
|
return model.getCategory();
|
|
}
|
|
|
|
protected void applyFilters(DataCollection objects,
|
|
NavigationModel model) {
|
|
if (m_specificObjectType != null) {
|
|
objects.addEqualsFilter(ACSObject.OBJECT_TYPE, m_specificObjectType);
|
|
}
|
|
|
|
Iterator excludedTypes = m_excludedTypes.iterator();
|
|
while (excludedTypes.hasNext()) {
|
|
String excludedType = excludedTypes.next().toString();
|
|
objects.addFilter(ACSObject.OBJECT_TYPE + " != '" + excludedType
|
|
+ "'");
|
|
}
|
|
|
|
if (m_blackListTypes) {
|
|
objects.addNotInSubqueryFilter(ACSObject.OBJECT_TYPE,
|
|
"com.arsdigita.navigation.blackListTypes");
|
|
}
|
|
|
|
Category cat = getCategory(model);
|
|
if (m_filterCategory && cat != null) {
|
|
if (m_descendCategories) {
|
|
Filter children = objects.addInSubqueryFilter(
|
|
getCategorizedObjectPath("id"),
|
|
"com.arsdigita.categorization.objectIDsInSubtree");
|
|
children.set("categoryID", cat.getID());
|
|
|
|
if (m_excludeIndexObjects) {
|
|
Filter moreChildren =
|
|
objects.addNotInSubqueryFilter(
|
|
getCategorizedObjectPath("id"),
|
|
"com.arsdigita.categorization.liveIndexItemsInSubtree");
|
|
moreChildren.set("categoryID", cat.getID());
|
|
}
|
|
} else {
|
|
objects.addEqualsFilter(
|
|
getCategorizedObjectPath("categories.id"),
|
|
cat.getID());
|
|
|
|
if (m_excludeIndexObjects) {
|
|
Filter moreChildren =
|
|
objects.addNotInSubqueryFilter(
|
|
getCategorizedObjectPath("id"),
|
|
"com.arsdigita.categorization.liveIndexItemsInCategory");
|
|
moreChildren.set("categoryID", cat.getID());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_checkPermissions) {
|
|
// allow subclasses to override the permission check
|
|
checkPermissions(objects);
|
|
}
|
|
}
|
|
|
|
protected void checkPermissions(DataCollection objects) {
|
|
Party party = Kernel.getContext().getParty();
|
|
if (party == null) {
|
|
party = Kernel.getPublicUser();
|
|
}
|
|
|
|
PermissionService.filterObjects(
|
|
objects,
|
|
PrivilegeDescriptor.READ,
|
|
party.getOID());
|
|
}
|
|
|
|
protected String getCategorizedObjectPath(String fragment) {
|
|
return fragment;
|
|
}
|
|
}
|