/*==========================================================================*\
| $Id: AdvancedQueryAssistant.java,v 1.1 2010/05/11 14:51:59 aallowat Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2006-2008 Virginia Tech
|
| This file is part of Web-CAT.
|
| Web-CAT is free software; you can redistribute it and/or modify
| it under the terms of the GNU Affero General Public License as published
| by the Free Software Foundation; either version 3 of the License, or
| (at your option) any later version.
|
| Web-CAT 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 Affero General Public License
| along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package org.webcat.core.objectquery;
import org.json.JSONException;
import org.json.JSONObject;
import org.webcat.core.KeyPathParser;
import org.webcat.core.WCComponent;
import org.webcat.ui.generators.JavascriptGenerator;
import org.webcat.ui.util.ComponentIDGenerator;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WORequest;
import com.webobjects.appserver.WOResponse;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableArray;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation.NSTimestamp;
//-------------------------------------------------------------------------
/**
* Provides an interface for incrementally building an advanced query
* by adding/combining key/value qualifiers of various kinds.
*
* @author aallowat
* @version $Id: AdvancedQueryAssistant.java,v 1.1 2010/05/11 14:51:59 aallowat Exp $
*/
public class AdvancedQueryAssistant
extends WCComponent
{
//~ Constructor ...........................................................
// ----------------------------------------------------------
/**
* Creates a new object.
* @param context The page's context
*/
public AdvancedQueryAssistant(WOContext context)
{
super(context);
}
//~ KVC Attributes (must be public) .......................................
public String objectType;
public AdvancedQueryModel model;
/* Repetition variables */
public AdvancedQueryCriterion criterion;
public int comparandType;
public Class<?> castType;
public int index;
public ComponentIDGenerator idFor;
//~ Methods ...............................................................
// ----------------------------------------------------------
@Override
public void appendToResponse(WOResponse response, WOContext context)
{
idFor = new ComponentIDGenerator(this);
super.appendToResponse(response, context);
}
// ----------------------------------------------------------
public void takeValuesFromRequest(WORequest request, WOContext context)
{
/* for(String key : request.formValues().keySet())
{
System.out.println(key + " = " + request.formValues().objectForKey(key));
}
System.out.println("-----------");*/
super.takeValuesFromRequest(request, context);
}
// ----------------------------------------------------------
public String contentAssistActionURL()
{
NSMutableDictionary<String, Object> queryParameters =
new NSMutableDictionary<String, Object>();
queryParameters.setObjectForKey(Integer.toString(256 * 256 + 256),
"designerVersion");
return context().directActionURLForActionNamed(
"contentAssist/entityDescriptions", queryParameters);
}
// ----------------------------------------------------------
public JSONObject contentAssistDataStoreQuery()
{
JSONObject query = new JSONObject();
try
{
query.put("rootType", objectType);
}
catch (JSONException e)
{
// Do nothing.
}
return query;
}
// ----------------------------------------------------------
public String currentKeyPath()
{
String keypath = criterion.keyPath();
if (keypath == null)
{
return "";
}
else
{
return keypath;
}
}
// ----------------------------------------------------------
public void immediatelySetKeyPathAtIndex(String value, int index)
{
AdvancedQueryCriterion criterion =
model.criteria().objectAtIndex(index);
criterion.setKeyPath(value);
if (criterion.comparison() == null)
{
criterion.setComparison(
comparisonsForCurrentKeyPath().objectAtIndex(0));
}
}
// ----------------------------------------------------------
public void setCurrentKeyPath(String value)
{
immediatelySetKeyPathAtIndex(value, index);
}
// ----------------------------------------------------------
public boolean isCurrentKeyPathValid()
{
String keypath = currentKeyPath();
KeyPathParser kpp = new KeyPathParser(objectType, keypath);
return (kpp.theClass() != null);
}
// ----------------------------------------------------------
public boolean doesCurrentKeyPathNeedCast()
{
KeyPathParser kpp = new KeyPathParser(objectType, currentKeyPath());
return (kpp.theClass() == Object.class);
}
// ----------------------------------------------------------
public NSArray<Class<?>> castTypes()
{
return new NSArray<Class<?>>(new Class<?>[] {
String.class,
Integer.class,
Double.class,
Boolean.class,
NSTimestamp.class
});
}
// ----------------------------------------------------------
public Class<?> currentCastType()
{
if (criterion.castType() == null)
{
return String.class;
}
else
{
return criterion.castType();
}
}
// ----------------------------------------------------------
public void immediatelySetCastTypeAtIndex(int castTypeIndex, int index)
{
AdvancedQueryCriterion criterion =
model.criteria().objectAtIndex(index);
criterion.setCastType(castTypes().objectAtIndex(castTypeIndex));
}
// ----------------------------------------------------------
public void setCurrentCastType(Class<?> value)
{
if (value == null)
{
criterion.setCastType(String.class);
}
else
{
criterion.setCastType(value);
}
}
// ----------------------------------------------------------
public String displayStringForCastType()
{
Class<?> type = castType;
if (type == String.class)
{
return "string";
}
else if (type == Integer.class)
{
return "integer";
}
else if (type == Double.class)
{
return "float";
}
else if (type == Boolean.class)
{
return "boolean";
}
else if (type == NSTimestamp.class)
{
return "timestamp";
}
else
{
return "";
}
}
// ----------------------------------------------------------
public NSArray<AdvancedQueryComparison> comparisonsForCurrentKeyPath()
{
String keypath = currentKeyPath();
return comparisonsForKeyPath(keypath, criterion.castType());
}
// ----------------------------------------------------------
public NSArray<AdvancedQueryComparison> comparisonsForKeyPath(
String keypath, Class<?> castType)
{
KeyPathParser kpp = new KeyPathParser(objectType, keypath);
Class<?> klass = kpp.theClass();
if (klass == Object.class)
{
return AdvancedQueryComparison.comparisonsForType(castType);
}
else
{
return AdvancedQueryComparison.comparisonsForType(klass);
}
}
// ----------------------------------------------------------
public NSArray<Integer> validComparandTypesForCurrentComparison()
{
NSMutableArray<Integer> comparands = new NSMutableArray<Integer>();
comparands.addObject(AdvancedQueryCriterion.COMPARAND_LITERAL);
AdvancedQueryComparison comparison = criterion.comparison();
if (comparison != null && comparison.doesSupportKeyPaths())
{
comparands.addObject(AdvancedQueryCriterion.COMPARAND_KEYPATH);
}
return comparands;
}
// ----------------------------------------------------------
public AdvancedQueryComparison currentComparison()
{
return criterion.comparison();
}
// ----------------------------------------------------------
public void immediatelySetComparisonAtIndex(int comparisonIndex,
int castTypeIndex, int index)
{
AdvancedQueryCriterion criterion =
model.criteria().objectAtIndex(index);
Class<?> castType = castTypes().objectAtIndex(castTypeIndex);
AdvancedQueryComparison comparison =
comparisonsForKeyPath(criterion.keyPath(), castType).objectAtIndex(
comparisonIndex);
setComparisonForCriterion(comparison, criterion);
}
// ----------------------------------------------------------
public void setCurrentComparison(AdvancedQueryComparison comparison)
{
setComparisonForCriterion(comparison, criterion);
}
// ----------------------------------------------------------
public void setComparisonForCriterion(AdvancedQueryComparison comparison,
AdvancedQueryCriterion criterion)
{
/*
* If the keypath operand support for either the old or the new
* comparison differ, we reset the comparand back to LITERAL so that
* it doesn't cause problems later.
*/
if (comparison == null)
{
comparison = comparisonsForCurrentKeyPath().objectAtIndex(0);
}
if (criterion.comparison() == null
|| criterion.comparison().doesSupportKeyPaths() !=
comparison.doesSupportKeyPaths())
{
criterion.setComparandType(
AdvancedQueryCriterion.COMPARAND_LITERAL);
criterion.setValue(null);
}
criterion.setComparison(comparison);
}
// ----------------------------------------------------------
public boolean doesCurrentComparisonHaveSecondOperand()
{
return currentComparison().hasSecondOperand();
}
// ----------------------------------------------------------
public Integer currentComparandType()
{
return criterion.comparandType();
}
// ----------------------------------------------------------
public void immediatelySetComparandTypeAtIndex(int comparandType, int index)
{
AdvancedQueryCriterion criterion =
model.criteria().objectAtIndex(index);
setComparandTypeForCriterion(comparandType, criterion);
}
// ----------------------------------------------------------
public void setCurrentComparandType(Integer type)
{
setComparandTypeForCriterion(type, criterion);
}
// ----------------------------------------------------------
public void setComparandTypeForCriterion(Integer type,
AdvancedQueryCriterion criterion)
{
if (type == null)
{
criterion.setComparandType(
AdvancedQueryCriterion.COMPARAND_LITERAL);
}
else
{
criterion.setComparandType(type);
}
}
// ----------------------------------------------------------
public boolean doesCurrentCriterionUseComparand()
{
return currentComparison().doesSupportKeyPaths();
}
// ----------------------------------------------------------
public String displayStringForComparandType()
{
if (comparandType == AdvancedQueryCriterion.COMPARAND_LITERAL)
{
if (doesCurrentComparisonSupportMultipleValues())
{
return "values";
}
else
{
return "value";
}
}
else
{
return "key path";
}
}
// ----------------------------------------------------------
public boolean doesCurrentComparisonSupportMultipleValues()
{
return currentComparison().doesSupportMultipleValues();
}
// ----------------------------------------------------------
public Class<?> typeOfCurrentKeyPath()
{
String keypath = currentKeyPath();
KeyPathParser kpp = new KeyPathParser(objectType, keypath);
Class<?> klass = kpp.theClass();
if (klass != null && klass != Object.class)
{
return klass;
}
else
{
return currentCastType();
}
}
// ----------------------------------------------------------
public boolean isCurrentCriterionOperandSimple()
{
return (currentComparandType() !=
AdvancedQueryCriterion.COMPARAND_KEYPATH)
&& (currentComparison() != AdvancedQueryComparison.IS_BETWEEN)
&& (currentComparison() != AdvancedQueryComparison.IS_NOT_BETWEEN);
}
// ----------------------------------------------------------
public boolean isCurrentCriterionOperandKeyPath()
{
return currentComparandType() ==
AdvancedQueryCriterion.COMPARAND_KEYPATH;
}
// ----------------------------------------------------------
public boolean isCurrentCriterionOperandBetween()
{
return (currentComparison() == AdvancedQueryComparison.IS_BETWEEN)
|| (currentComparison() == AdvancedQueryComparison.IS_NOT_BETWEEN);
}
// ----------------------------------------------------------
public Object currentRepresentedValue()
{
return criterion.value();
}
// ----------------------------------------------------------
public void setCurrentRepresentedValue(Object value)
{
criterion.setValue(value);
}
// ----------------------------------------------------------
public Object minimumValueOfCurrentRepresentedValue()
{
if (criterion.value() instanceof NSDictionary)
{
return ((NSDictionary<String, Object>)criterion.value())
.objectForKey("minimumValue");
}
else
{
return null;
}
}
public void setMinimumValueOfCurrentRepresentedValue(Object value)
{
if (value == null)
{
return;
}
if (criterion.value() instanceof NSMutableDictionary)
{
((NSMutableDictionary<String, Object>)criterion.value())
.setObjectForKey(value, "minimumValue");
}
else
{
NSMutableDictionary<String, Object> dict =
new NSMutableDictionary<String, Object>();
dict.setObjectForKey(value, "minimumValue");
criterion.setValue(dict);
}
}
// ----------------------------------------------------------
public Object maximumValueOfCurrentRepresentedValue()
{
if (criterion.value() instanceof NSDictionary)
{
return ((NSDictionary<String, Object>)criterion.value())
.objectForKey("maximumValue");
}
else
{
return null;
}
}
// ----------------------------------------------------------
public void setMaximumValueOfCurrentRepresentedValue(Object value)
{
if (value == null)
{
return;
}
if (criterion.value() instanceof NSMutableDictionary)
{
((NSMutableDictionary<String, Object>)criterion.value())
.setObjectForKey(value, "maximumValue");
}
else
{
NSMutableDictionary<String, Object> dict =
new NSMutableDictionary<String, Object>();
dict.setObjectForKey(value, "maximumValue");
criterion.setValue(dict);
}
}
// ----------------------------------------------------------
public JavascriptGenerator addCriterion()
{
model.insertNewCriterionAtIndex(index + 1);
return new JavascriptGenerator()
.refresh((String) idFor.valueForKey("criteriaContainer"));
}
// ----------------------------------------------------------
public JavascriptGenerator removeCriterion()
{
model.removeCriterionAtIndex(index);
return new JavascriptGenerator()
.refresh((String) idFor.valueForKey("criteriaContainer"));
}
}