00001
00025 package org.objectweb.jonas_ejb.lib;
00026
00027 import java.util.Map;
00028 import java.util.Stack;
00029
00030 import org.objectweb.jonas_ejb.deployment.ejbql.ASTAggregateSelectExpression;
00031 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCmpPathExpression;
00032 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEJBQL;
00033 import org.objectweb.jonas_ejb.deployment.ejbql.ASTIdentificationVariable;
00034 import org.objectweb.jonas_ejb.deployment.ejbql.ASTPath;
00035 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSelectClause;
00036 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSelectExpression;
00037 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSingleValuedCmrPathExpression;
00038 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSingleValuedPathExpression;
00039 import org.objectweb.jonas_ejb.deployment.ejbql.EJBQLConstants;
00040 import org.objectweb.jonas_ejb.deployment.ejbql.SimpleNode;
00041 import org.objectweb.jorm.type.api.PType;
00042 import org.objectweb.jorm.type.api.PTypeSpace;
00043 import org.objectweb.medor.api.Field;
00044 import org.objectweb.medor.filter.api.AggregateOperator;
00045 import org.objectweb.medor.filter.lib.Avg;
00046 import org.objectweb.medor.filter.lib.BasicFieldOperand;
00047 import org.objectweb.medor.filter.lib.Count;
00048 import org.objectweb.medor.filter.lib.Max;
00049 import org.objectweb.medor.filter.lib.Min;
00050 import org.objectweb.medor.filter.lib.Sum;
00051 import org.objectweb.medor.query.api.QueryTree;
00052 import org.objectweb.medor.query.api.QueryTreeField;
00053 import org.objectweb.medor.query.lib.Nest;
00054 import org.objectweb.medor.query.lib.SelectProject;
00055
00063 public class EjbqlSelectVisitor extends EjbqlAbstractVisitor {
00064
00065 Map fields;
00066 AggregateOperator aggregateOp = null;
00067 QueryTree qt;
00068
00074 public EjbqlSelectVisitor(ASTEJBQL ejbql, Map _fields, SelectProject sp) throws Exception {
00075 this.qt = sp;
00076 fields = _fields;
00077 visit(ejbql);
00078 }
00079
00084 public QueryTree getQueryTree() {
00085 return qt;
00086 }
00087
00092 public Object visit(ASTSelectClause node, Object data) {
00093 visit((SimpleNode) node, data);
00094 try {
00095 boolean distinct = node.distinct;
00096 qt.setDistinct(distinct);
00097 SelectProject sp = (SelectProject) qt;
00098 QueryTreeField qtf = (QueryTreeField) fields.get((String) ((Stack) data).pop());
00099 QueryTreeField qtf2 = sp.addPropagatedField(qtf.getName(), qtf.getType(), new QueryTreeField[] {qtf});
00100
00101
00102 if (aggregateOp != null) {
00103 Nest n = new Nest(new QueryTreeField[] {qtf2}, "grouped_fields", new QueryTreeField[0], "aggregate_node");
00104 PType type = null;
00105 if (aggregateOp instanceof Sum) {
00106 if (qtf.getType().equals(PTypeSpace.FLOAT) || qtf.getType().equals(PTypeSpace.DOUBLE)) {
00107 type = PTypeSpace.DOUBLE;
00108 } else if (qtf.getType().equals(PTypeSpace.BIGINTEGER)) {
00109 type = PTypeSpace.BIGINTEGER;
00110 } else if (qtf.getType().equals(PTypeSpace.BIGDECIMAL)) {
00111 type = PTypeSpace.BIGDECIMAL;
00112 } else {
00113 type = PTypeSpace.LONG;
00114 }
00115 } else if ((aggregateOp instanceof Max) || (aggregateOp instanceof Min)) {
00116 type = qtf.getType();
00117 } else if (aggregateOp instanceof Avg) {
00118 type = PTypeSpace.DOUBLE;
00119 } else if (aggregateOp instanceof Count) {
00120 type = PTypeSpace.LONG;
00121 }
00122
00123 aggregateOp.setExpression(0, new BasicFieldOperand(qtf2));
00124 n.addCalculatedField("calculed_field", type, aggregateOp);
00125 qt = n;
00126 }
00127 } catch (Exception e) {
00128 throw new VisitorException(e);
00129 }
00130 return null;
00131 }
00132
00136 public Object visit(ASTSelectExpression node, Object data) {
00137 return visit((SimpleNode) node, data);
00138 }
00139
00143 public Object visit(ASTAggregateSelectExpression node, Object data) {
00144 visit((SimpleNode) node, data);
00145 Stack s = (Stack) data;
00146 int operator = ((Integer) node.ops.get(0)).intValue();
00147 boolean distinct = node.distinct;
00148 Field field = (Field) fields.get((String) s.peek());
00149 BasicFieldOperand fieldOp = new BasicFieldOperand(field);
00150 switch (operator) {
00151 case EJBQLConstants.AVG:
00152 aggregateOp = new Avg(fieldOp, distinct);
00153 break;
00154 case EJBQLConstants.COUNT:
00155 aggregateOp = new Count(fieldOp, distinct);
00156 break;
00157 case EJBQLConstants.MAX:
00158 aggregateOp = new Max(fieldOp, distinct);
00159 break;
00160 case EJBQLConstants.MIN:
00161 aggregateOp = new Min(fieldOp, distinct);
00162 break;
00163 case EJBQLConstants.SUM:
00164 aggregateOp = new Sum(fieldOp, distinct);
00165 break;
00166 default:
00167 throw new Error("AggregateOperator '" + operator + "' unknown");
00168 }
00169 return null;
00170 }
00171
00175 public Object visit(ASTCmpPathExpression node, Object data) {
00176 return visit((SimpleNode) node, data);
00177 }
00178
00182 public Object visit(ASTSingleValuedCmrPathExpression node, Object data) {
00183 return visit((SimpleNode) node, data);
00184 }
00185
00189 public Object visit(ASTSingleValuedPathExpression node, Object data) {
00190 return visit((SimpleNode) node, data);
00191 }
00192
00196 public Object visit(ASTIdentificationVariable node, Object data) {
00197 ((Stack) data).push((String) node.value + "." + Field.PNAMENAME);
00198 return null;
00199 }
00200
00204 public Object visit(ASTPath node, Object data) {
00205 ((Stack) data).push(node.value);
00206 return null;
00207 }
00208 }