//--------------------------------------------------------------------------
// Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the Drew Davidson nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//--------------------------------------------------------------------------
package ariba.util.expr;
import ariba.util.fieldtype.TypeInfo;
import ariba.util.fieldvalue.OrderedList;
import java.util.*;
/**
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
*/
class ASTProject extends SimpleNode implements Symbol
{
public static final String CollectMethod = "collect";
public static final String FindAllMethod = "findAll";
public static final String FindMethod = "find";
public static final String SumMethod = "sum";
public static final String AvgMethod = "avg";
public static final String MinMethod = "min";
public static final String MaxMethod = "max";
private String methodName;
public ASTProject(int id) {
super(id);
}
public ASTProject(ExprParser p, int id) {
super(p, id);
}
public String getMethodName ()
{
return methodName;
}
/** Called from parser action. */
void setMethodName( String methodName ) {
this.methodName = methodName;
}
protected Object getValueBody( ExprContext context, Object source ) throws ExprException
{
// Eventually we need to generalize to apply via classextension...
Node expr = children[0];
OrderedList listInterface = OrderedList.get(source);
Iterator e = listInterface.elements(source);
if (methodName.equals("collect")) return collect(e, expr, context, source);
else if (methodName.equals("findAll")) return findAll(e, expr, context, source);
else if (methodName.equals("find")) return find(e, expr, context, source);
else if (methodName.equals("sum")) return sum(e, expr, context, source);
else if (methodName.equals("avg")) return avg(e, expr, context, source);
else if (methodName.equals("min")) return min(e, expr, context, source);
else if (methodName.equals("max")) return max(e, expr, context, source);
return null;
}
protected Object collect(Iterator e, Node expr, ExprContext context, Object source) throws ExprException
{
List answer = new ArrayList();
while (e.hasNext()) {
answer.add( expr.getValue(context, e.next()) );
}
return answer;
}
protected Object findAll(Iterator e, Node expr, ExprContext context, Object source) throws ExprException
{
List answer = new ArrayList();
while (e.hasNext()) {
Object next = e.next();
if ( ExprOps.booleanValue(expr.getValue(context, next)) ) answer.add(next);
}
return answer;
}
protected Object find(Iterator e, Node expr, ExprContext context, Object source) throws ExprException
{
List answer = new ArrayList();
while (e.hasNext()) {
Object next = e.next();
if ( ExprOps.booleanValue(expr.getValue(context, next)) ) return next;
}
return null;
}
protected Object sum(Iterator e, Node expr, ExprContext context, Object source) throws ExprException
{
Object result = null;
while (e.hasNext()) {
Object value = expr.getValue(context, e.next());
TypeInfo valueInfo = getTypeInfo();
result = ExprOps.add(
result, value, null, valueInfo != null? valueInfo.getName(): null);
}
return result;
}
protected Object avg(Iterator e, Node expr, ExprContext context, Object source) throws ExprException
{
Object result = new Integer(0);
String resultType = Integer.class.getName();
int count = 0;
while (e.hasNext()) {
Object value = expr.getValue(context, e.next());
TypeInfo valueInfo = expr.getTypeInfo();
result = ExprOps.add(
result,
value,
resultType,
valueInfo != null? valueInfo.getName(): null);
resultType = result != null? result.getClass().getName(): null;
count++;
}
return ExprOps.divide(result, new Integer(count), resultType);
}
protected Object min(Iterator e, Node expr, ExprContext context, Object source) throws ExprException
{
Object result = null;
while (e.hasNext()) {
Object value = expr.getValue(context, e.next());
if (result == null || (ExprOps.compareWithConversion(value, result) < 0)) result = value;
}
return result;
}
protected Object max(Iterator e, Node expr, ExprContext context, Object source) throws ExprException
{
Object result = null;
while (e.hasNext()) {
Object value = expr.getValue(context, e.next());
if (result == null || (ExprOps.compareWithConversion(value, result) > 0)) result = value;
}
return result;
}
public String toString()
{
return methodName + "{ " + children[0] + " }";
}
public void accept (ASTNodeVisitor visitor)
{
visitor.visit(this);
}
public String getName ()
{
return methodName;
}
}