/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.ir.transform.expression; import gw.internal.gosu.parser.expressions.QueryExpression; import gw.internal.gosu.ir.transform.TopLevelTransformationContext; import gw.lang.ir.IRExpression; import gw.lang.reflect.IType; import gw.lang.reflect.TypeSystem; import gw.lang.parser.EvaluationException; import gw.lang.parser.expressions.IQueryExpressionEvaluator; import gw.lang.parser.statements.IFunctionStatement; import gw.config.CommonServices; import gw.lang.reflect.gs.ICompilableType; import java.util.Collections; import java.util.Map; import java.util.HashMap; /** */ public class QueryExpressionTransformer extends EvalBasedTransformer<QueryExpression> { public static final Map<String, QueryExpression> QUERY_EXPRESSIONS = Collections.synchronizedMap( new HashMap<String, QueryExpression>() ); private static final Class[] PARAM_TYPES = new Class[]{Object.class, Object[].class, IType[].class, IType.class, int.class, int.class, String.class}; public static IRExpression compile( TopLevelTransformationContext cc, QueryExpression expr ) { QueryExpressionTransformer compiler = new QueryExpressionTransformer( cc, expr ); return compiler.compile(); } private QueryExpressionTransformer( TopLevelTransformationContext cc, QueryExpression expr ) { super( cc, expr ); } protected IRExpression compile_impl() { String queryExprKey; synchronized( QUERY_EXPRESSIONS ) { queryExprKey = EvalExpressionTransformer.makeEvalKey( getGosuClass(), _expr().getLineNum(), _expr().getColumn(), _expr().toString() ); QUERY_EXPRESSIONS.put( queryExprKey, _expr() ); } IFunctionStatement fs = _expr().getLocation().getEnclosingFunctionStatement(); IRExpression compileAndRunEvalSource = callStaticMethod( QueryExpressionTransformer.class, "compileAndRunQuery", PARAM_TYPES, exprList( pushEnclosingContext(), pushCapturedSymbols( getGosuClass(), _expr().getCapturedForBytecode() ), pushEnclosingFunctionTypeParamsInArray( _expr() ), pushType( getGosuClass() ), pushConstant( _expr().getLineNum() ), pushConstant( _expr().getColumn() ), pushConstant( _expr().toString() ) ) ); return checkCast( TypeSystem.getByFullName( "gw.api.database.IQueryBeanResult", TypeSystem.getGlobalModule() ), compileAndRunEvalSource ); } public static Object compileAndRunQuery( Object outer, Object[] capturedValues, IType[] immediateFuncTypeParams, IType enclosingClass, int iLineNum, int iColumnNum, String exprText ) { String exprKey = EvalExpressionTransformer.makeEvalKey( enclosingClass, iLineNum, iColumnNum, exprText ); QueryExpression queryExpr = QUERY_EXPRESSIONS.get( exprKey ); if( queryExpr == null ) { if( enclosingClass instanceof ICompilableType ) { ((ICompilableType)enclosingClass).compile(); queryExpr = QUERY_EXPRESSIONS.get( exprKey ); } } IQueryExpressionEvaluator evaluator = CommonServices.getEntityAccess().getQueryExpressionEvaluator( queryExpr ); if( evaluator != null ) { return evaluator.evaluate( new Object[] {outer, capturedValues, immediateFuncTypeParams, enclosingClass} ); } throw new EvaluationException( "No query expression evaluator is defined." ); } public static void clearQueryExpressions() { QUERY_EXPRESSIONS.clear(); } }