/*
* SmartGWT (GWT for SmartClient)
* Copyright 2008 and beyond, Isomorphic Software, Inc.
*
* SmartGWT is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 3
* as published by the Free Software Foundation. SmartGWT is also
* available under typical commercial license terms - see
* http://smartclient.com/license
*
* This software 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.
*/
package com.smartgwt.client.data;
import com.google.gwt.core.client.JavaScriptObject;
import com.smartgwt.client.core.DataClass;
import com.smartgwt.client.core.RefDataClass;
import com.smartgwt.client.util.JSOHelper;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Criteria for selecting only a matching set of records from a DataSource. Criteria can be applied on the client and
* server. Unless configured otherwise, criteria will generally be applied client-side by {@link
* com.smartgwt.client.data.ResultSet}s via {@link com.smartgwt.client.data.ResultSet#applyFilter ResultSet.applyFilter}.
* <P> Client- and server-side systems built into Smart GWT understand two criteria formats by default: simple key-value
* pairs (Criteria) or the {@link com.smartgwt.client.data.AdvancedCriteria} format. <P> <P> Use {@link
* com.smartgwt.client.data.DataSource#combineCriteria DataSource.combineCriteria} to combine two Criteria objects
* (including Criteria and AdvancedCriteria) or {@link com.smartgwt.client.data.DataSource#convertCriteria
* DataSource.convertCriteria} to convert simple Criteria to the AdvancedCriteria format. <P> When sent to the Smart GWT
* server, the Java representation of the criteria is described {@link com.smartgwt.client.rpc.RPCRequest#getData here}.
* When sent to other servers, the {@link com.smartgwt.client.types.DSProtocol operationBinding.dataProtocol} affects the
* format.
*/
public class Criteria extends DataClass {
public Criteria() {
}
public Criteria(String field, String value) {
this();
addCriteria(field, value);
}
public Criteria(JavaScriptObject jsObj) {
super(jsObj);
}
public native static Criteria getOrCreateRef(JavaScriptObject jsObj) /*-{
if (jsObj == null) return null;
var instance = jsObj["__ref"];
if (instance == null) {
return @com.smartgwt.client.data.Criteria::new(Lcom/google/gwt/core/client/JavaScriptObject;)(jsObj);
} else {
return instance;
}
}-*/;
// The addCriteria() APIs are simply convenience wrappers for JSOHelper routines
// that take the associated type of argument. At the JSOHelper level, there may
// not be an exact match, resulting in Integer, Float, or Double matching Number.
// However, the APIs here can't removed to match as they've already been exposed.
public void addCriteria(String field, String value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Boolean value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Integer value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Long value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Float value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Double value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Date value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, String[] value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Boolean[] value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Integer[] value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Long[] value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Float[] value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Double[] value) {
JSOHelper.setAttribute(jsObj, field, value);
}
public void addCriteria(String field, Object value) {
if (value == null) return;
if (value instanceof String) {
addCriteria(field, (String) value);
} else if (value instanceof Number) {
if (value instanceof Integer) {
addCriteria(field, (Integer) value);
} else if (value instanceof Long) {
addCriteria(field, (Long) value);
} else if (value instanceof Float) {
addCriteria(field, (Float) value);
} else if (value instanceof Double) {
addCriteria(field, (Double) value);
}
} else if (value instanceof Boolean) {
addCriteria(field, (Boolean) value);
} else if (value.getClass().isArray()) {
if (value instanceof String[]) {
addCriteria(field, (String[]) value);
} else if (value instanceof Boolean[]) {
addCriteria(field, (Boolean[]) value);
} else if (value instanceof Integer[]) {
addCriteria(field, (Integer[]) value);
} else if (value instanceof Long[]) {
addCriteria(field, (Long[]) value);
} else if (value instanceof Float[]) {
addCriteria(field, (Float[]) value);
} else if (value instanceof Double[]) {
addCriteria(field, (Double[]) value);
}
} else if (value instanceof Date) {
addCriteria(field, (Date) value);
}
}
/**
* Adds the criteria from the passed criteria object.
*
* @param otherCriteria the passed criteria object
*/
public void addCriteria(Criteria otherCriteria) {
if (otherCriteria instanceof AdvancedCriteria || otherCriteria instanceof Criterion) {
throw new IllegalArgumentException("Cannot add a Criterion or AdvancedCriteria to simple Criteria. " +
"Use Criteria.asAdvancedCriteria() to convert to AdvancedCriteria");
}
Map otherMap = otherCriteria.getValues();
Set otherKeys = otherMap.keySet();
for (Iterator i=otherKeys.iterator(); i.hasNext(); ) {
String field = (String) i.next();
Object value = otherMap.get(field);
JSOHelper.setAttribute(jsObj, field, value);
}
}
/**
* Return the criteria values as a name-value Map.
*
* @return the criteria values as a Map
*/
public Map getValues() {
return JSOHelper.convertToMap(jsObj);
}
public static Criteria[] convertToCriteriaArray(JavaScriptObject nativeArray) {
if (nativeArray == null) {
return new Criteria[]{};
}
if (JSOHelper.isArray(nativeArray)) {
JavaScriptObject[] criteriasJS = JSOHelper.toArray(nativeArray);
Criteria[] objects = new Criteria[criteriasJS.length];
for (int i = 0; i < criteriasJS.length; i++) {
JavaScriptObject criteriaJS = criteriasJS[i];
Criteria obj = new Criteria(criteriaJS);
objects[i] = obj;
}
return objects;
} else {
Criteria[] ret = new Criteria[1];
ret[0] = new Criteria(nativeArray);
return ret;
}
}
/**
* Does this represent an underlying AdvancedCriteria object in JavaScript?
* @return
*/
public boolean isAdvanced() {
return ("AdvancedCriteria".equals(getAttributeAsString("_constructor")));
}
/**
* Returns an AdvancedCriteria derived from this Criteria object.
* @return
*/
public AdvancedCriteria asAdvancedCriteria() {
if (isAdvanced()) return new AdvancedCriteria(this.getJsObj());
else {
return new AdvancedCriteria(convertToAdvancedCriteria(this.getJsObj()));
}
}
private native JavaScriptObject convertToAdvancedCriteria(JavaScriptObject simpleCriteria) /*-{
return $wnd.isc.DataSource.convertCriteria(simpleCriteria);
}-*/;
}