295 lines
13 KiB
Java
Executable File
295 lines
13 KiB
Java
Executable File
/*
|
|
* Copyright (C) 2003-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.cms.search;
|
|
|
|
import java.text.DateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.List;
|
|
|
|
import com.arsdigita.categorization.Category;
|
|
import com.arsdigita.cms.ContentSection;
|
|
import com.arsdigita.cms.ContentType;
|
|
// import com.arsdigita.cms.search.ContentTypeFilterSpecification;
|
|
// import com.arsdigita.cms.search.ContentTypeFilterType;
|
|
import com.arsdigita.kernel.PartyCollection;
|
|
import com.arsdigita.persistence.DataQuery;
|
|
import com.arsdigita.persistence.Filter;
|
|
import com.arsdigita.search.FilterSpecification;
|
|
import com.arsdigita.search.FilterType;
|
|
import com.arsdigita.search.Search;
|
|
import com.arsdigita.search.filters.CategoryFilterSpecification;
|
|
import com.arsdigita.search.filters.DateRangeFilterSpecification;
|
|
import com.arsdigita.search.filters.PartyFilterSpecification;
|
|
import com.arsdigita.search.intermedia.BaseQueryEngine;
|
|
|
|
|
|
public class IntermediaQueryEngine extends BaseQueryEngine {
|
|
|
|
public IntermediaQueryEngine() {
|
|
addColumn("version", "i.version");
|
|
addColumn("launch_date", "p.launch_date");
|
|
addColumn("last_modified", "audited.last_modified" );
|
|
addColumn("modifying_user", "audited.modifying_user" );
|
|
addColumn("creation_date", "audited.creation_date" );
|
|
addColumn("creation_user", "audited.creation_user");
|
|
// cg column map has been switched round (map fields to aliases)
|
|
// allowing us to override the score field to include keyword/title score
|
|
if (ContentSection.getConfig().scoreKeywordsAndTitle()) {
|
|
addColumn(SCORE, "((score(1) * " + Search.getConfig().getXMLContentWeight() + ") +"
|
|
+ " (score(2) * " + Search.getConfig().getRawContentWeight() + ") +"
|
|
+ " (score(3) * " + ContentSection.getConfig().getKeywordSearchWeight() + ") +"
|
|
+ " (score(4) * " + ContentSection.getConfig().getTitleSearchWeight() + "))");
|
|
}
|
|
|
|
|
|
|
|
// XXX: I am going to hell for the line below. I console myself only
|
|
// because this is a hack to work around a terrible interface.
|
|
// This line replaces the existing hash entry for 'search_content' and
|
|
// abuses the alias to add a left outer join.
|
|
// mbooth@redhat.com 02/02/2005
|
|
//
|
|
// amended to include (other) outer joins, otherwise you
|
|
// can't search for anything other than cms items
|
|
// cg - 11/10/2005
|
|
//
|
|
// likewise going to hell. Seb - 30/11/2005
|
|
addTable( "search_content", "c left outer join cms_pages p on ( p.item_id = c.object_id )"
|
|
+ " left outer join cms_items i on (c.object_id = i.item_id )"
|
|
+ " left outer join acs_auditing audited on (c.object_id = audited.object_id)" );
|
|
}
|
|
|
|
protected String cleanSearchString(String terms) {
|
|
if (ContentSection.getConfig().scoreKeywordsAndTitle()) {
|
|
return PathSearchSpecification.cleanSearchString(terms, " AND ");
|
|
} else {
|
|
return super.cleanSearchString(terms);
|
|
}
|
|
}
|
|
|
|
protected String getContainsClause (String terms) {
|
|
if (ContentSection.getConfig().scoreKeywordsAndTitle()) {
|
|
return PathSearchSpecification.containsClause("c", terms, "1", "2", "3", "4") + "\n";
|
|
} else {
|
|
return super.getContainsClause(terms);
|
|
}
|
|
}
|
|
|
|
|
|
protected void addFilter(DataQuery query,
|
|
FilterSpecification filter) {
|
|
super.addFilter(query, filter);
|
|
|
|
FilterType type = filter.getType();
|
|
|
|
if (ContentTypeFilterType.KEY.equals(type.getKey())) {
|
|
addContentTypeFilter(query, (ContentTypeFilterSpecification)filter);
|
|
} else if (VersionFilterType.KEY.equals(type.getKey())) {
|
|
addVersionFilter(query, (VersionFilterSpecification)filter);
|
|
} else if (LaunchDateFilterType.KEY.equals(type.getKey())) {
|
|
//addColumn("p.launch_date", "launch_date");
|
|
//addTable("cms_pages", "p");
|
|
//addCondition("c.object_id = p.item_id");
|
|
addLaunchDateFilter(query, (DateRangeFilterSpecification)filter);
|
|
} else if (LastModifiedDateFilterType.KEY.equals(type.getKey())) {
|
|
addLastModifiedDateFilter(query, (DateRangeFilterSpecification)filter);
|
|
} else if (CreationDateFilterType.KEY.equals(type.getKey())) {
|
|
addCreationDateFilter(query, (DateRangeFilterSpecification)filter);
|
|
} else if (LastModifiedUserFilterType.KEY.equals(type.getKey())) {
|
|
addPartyFilter(query, (PartyFilterSpecification)filter,
|
|
"modifying_user");
|
|
} else if (CreationUserFilterType.KEY.equals(type.getKey())) {
|
|
addPartyFilter(query, (PartyFilterSpecification)filter,
|
|
"creation_user");
|
|
} else if (CMSContentSectionFilterType.KEY.equals(type.getKey())) {
|
|
addCMSContentSectionFilter(query, (CMSContentSectionFilterSpecification)filter);
|
|
}
|
|
}
|
|
|
|
protected void addCMSContentSectionFilter(DataQuery query,
|
|
CMSContentSectionFilterSpecification filter) {
|
|
if (filter.getSections() == null) {
|
|
return;
|
|
}
|
|
Filter f = null;
|
|
if (filter.isExclusion()) {
|
|
f = query.addNotInSubqueryFilter(
|
|
"object_id",
|
|
"com.arsdigita.cms.getContentSectionItems");
|
|
} else {
|
|
f = query.addInSubqueryFilter(
|
|
"object_id",
|
|
"com.arsdigita.cms.getContentSectionItems");
|
|
}
|
|
f.set("sectionName", Arrays.asList(filter.getSections()));
|
|
}
|
|
|
|
protected void addVersionFilter(DataQuery query,
|
|
VersionFilterSpecification filter) {
|
|
Filter f = query.addFilter("nvl(version,'" + filter.getVersion() + "') = :version");
|
|
f.set("version", filter.getVersion());
|
|
}
|
|
|
|
protected void addLaunchDateFilter(DataQuery query,
|
|
DateRangeFilterSpecification filter) {
|
|
addDateRangeFilter(query, filter, "launch_date");
|
|
}
|
|
|
|
protected void addLastModifiedDateFilter(DataQuery query,
|
|
DateRangeFilterSpecification filter) {
|
|
// TODO: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=113394
|
|
// this will not work until the above bug is fixed
|
|
addDateRangeFilter(query, filter, "last_modified");
|
|
}
|
|
|
|
protected void addCreationDateFilter(DataQuery query,
|
|
DateRangeFilterSpecification filter) {
|
|
// TODO: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=113394
|
|
// this will not work until the above bug is fixed
|
|
addDateRangeFilter(query, filter, "creation_date");
|
|
}
|
|
|
|
private void addDateRangeFilter(DataQuery query,
|
|
DateRangeFilterSpecification filter,
|
|
String columnName) {
|
|
Date start = filter.getStartDate();
|
|
Date end = filter.getEndDate();
|
|
// XXX The query should actually be the commented out code at the
|
|
// bottom of this method instead of the query that we are using
|
|
// we have to comment it out because of a bug with persistence
|
|
|
|
DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
|
|
|
|
if (start != null) {
|
|
Filter f = query.addFilter(columnName + " >= :" +
|
|
columnName + "StartDate");
|
|
// we truncate the value using java because we cannot do it
|
|
// using sql because of the persistence bug
|
|
Calendar startCal = GregorianCalendar.getInstance();
|
|
startCal.setTime(start);
|
|
/*
|
|
Calendar truncCal = GregorianCalendar.getInstance();
|
|
truncCal.set(Calendar.DAY_OF_YEAR, startCal.get(Calendar.DAY_OF_YEAR));
|
|
truncCal.set(Calendar.YEAR, startCal.get(Calendar.YEAR));
|
|
truncCal.set(Calendar.MINUTE, 0);
|
|
truncCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
truncCal.set(Calendar.SECOND, 0);
|
|
f.set(columnName + "StartDate", truncCal.getTime());
|
|
*/
|
|
startCal.set(Calendar.MINUTE, 0);
|
|
startCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
startCal.set(Calendar.SECOND, 0);
|
|
f.set(columnName + "StartDate", startCal.getTime());
|
|
}
|
|
if (end != null) {
|
|
Filter f = query.addFilter(columnName + " < :" +
|
|
columnName + "EndDate");
|
|
// we truncate the value using java because we cannot do it
|
|
// using sql because of the persistence bug
|
|
Calendar endCal = GregorianCalendar.getInstance();
|
|
endCal.setTime(end);
|
|
endCal.set(Calendar.MINUTE, 0);
|
|
endCal.set(Calendar.HOUR_OF_DAY, 0);
|
|
endCal.set(Calendar.SECOND, 0);
|
|
f.set(columnName + "EndDate", endCal.getTime());
|
|
}
|
|
|
|
/*
|
|
DateFormat format = new SimpleDateFormat("MM/dd/yyyy");
|
|
|
|
if (start != null) {
|
|
// XXX persistence bug - can't deal with functions on fields
|
|
Filter f = query.addFilter("trunc(" + columnName + ") >= to_date('" +
|
|
format.format(start) +
|
|
"','MM/DD/YYYY')");
|
|
}
|
|
if (end != null) {
|
|
// XXX persistence bug - can't deal with functions on fields
|
|
Filter f = query.addFilter("trunc(" + columnName + ") <= to_date('" +
|
|
format.format(end) +
|
|
"','MM/DD/YYYY')");
|
|
}
|
|
*/
|
|
}
|
|
|
|
protected void addPartyFilter(DataQuery query,
|
|
PartyFilterSpecification filter,
|
|
String columnName) {
|
|
PartyCollection parties = filter.getParties();
|
|
if (parties == null) {
|
|
return;
|
|
}
|
|
List partyIDs = new ArrayList();
|
|
while (parties.next()) {
|
|
partyIDs.add(parties.getID());
|
|
}
|
|
|
|
if (partyIDs.size() == 0) {
|
|
// no parties match so we make sure to return no results
|
|
query.addFilter("1=2");
|
|
} else {
|
|
Filter f = query.addFilter(columnName + " in :" +
|
|
columnName + "parties");
|
|
f.set(columnName + "parties", partyIDs);
|
|
}
|
|
}
|
|
|
|
protected void addContentTypeFilter(DataQuery query,
|
|
ContentTypeFilterSpecification filter) {
|
|
List l = new ArrayList();
|
|
ContentType[] types = filter.getTypes();
|
|
if (types == null || types.length == 0) {
|
|
return;
|
|
}
|
|
|
|
for (int i = 0 ; i < types.length ; i++) {
|
|
ContentType type = types[i];
|
|
l.add(type.getAssociatedObjectType());
|
|
}
|
|
Filter f = query.addFilter("object_type in :types");
|
|
f.set("types", l);
|
|
}
|
|
|
|
// Override to use query that takes account of bundles :-(
|
|
protected void addCategoryFilter(DataQuery query,
|
|
CategoryFilterSpecification filter) {
|
|
Category[] categories = filter.getCategories();
|
|
if (categories != null && categories.length > 0) {
|
|
List ids = new ArrayList();
|
|
for (int i = 0 ; i < categories.length ; i++) {
|
|
ids.add(categories[i].getID());
|
|
}
|
|
|
|
Filter f = query.addInSubqueryFilter(
|
|
"object_id",
|
|
"id",
|
|
"com.arsdigita.cms.searchCategoryObjects");
|
|
|
|
f.set("ids", ids);
|
|
f.set("pathLimit", new Integer(filter.isDescending() ? 999999 : 0));
|
|
}
|
|
}
|
|
|
|
}
|