use of org.codehaus.groovy.ast.expr.Expression in project groovy-core by groovy.
the class BindableASTTransformation method wrapSetterMethod.
/*
* Wrap an existing setter.
*/
private void wrapSetterMethod(ClassNode classNode, String propertyName) {
String getterName = "get" + MetaClassHelper.capitalize(propertyName);
MethodNode setter = classNode.getSetterMethod("set" + MetaClassHelper.capitalize(propertyName));
if (setter != null) {
// Get the existing code block
Statement code = setter.getCode();
Expression oldValue = varX("$oldValue");
Expression newValue = varX("$newValue");
BlockStatement block = new BlockStatement();
// create a local variable to hold the old value from the getter
block.addStatement(declS(oldValue, callThisX(getterName)));
// call the existing block, which will presumably set the value properly
block.addStatement(code);
// get the new value to emit in the event
block.addStatement(declS(newValue, callThisX(getterName)));
// add the firePropertyChange method call
block.addStatement(stmt(callThisX("firePropertyChange", args(constX(propertyName), oldValue, newValue))));
// replace the existing code block with our new one
setter.setCode(block);
}
}
use of org.codehaus.groovy.ast.expr.Expression in project grails-core by grails.
the class ControllerActionTransformer method getCodeToHandleAllowedMethods.
protected BlockStatement getCodeToHandleAllowedMethods(ClassNode controllerClass, String methodName) {
GrailsASTUtils.addEnhancedAnnotation(controllerClass, DefaultGrailsControllerClass.ALLOWED_HTTP_METHODS_PROPERTY);
final BlockStatement checkAllowedMethodsBlock = new BlockStatement();
final PropertyExpression requestPropertyExpression = new PropertyExpression(new VariableExpression("this"), "request");
final FieldNode allowedMethodsField = controllerClass.getField(DefaultGrailsControllerClass.ALLOWED_HTTP_METHODS_PROPERTY);
if (allowedMethodsField != null) {
final Expression initialAllowedMethodsExpression = allowedMethodsField.getInitialExpression();
if (initialAllowedMethodsExpression instanceof MapExpression) {
boolean actionIsRestricted = false;
final MapExpression allowedMethodsMapExpression = (MapExpression) initialAllowedMethodsExpression;
final List<MapEntryExpression> allowedMethodsMapEntryExpressions = allowedMethodsMapExpression.getMapEntryExpressions();
for (MapEntryExpression allowedMethodsMapEntryExpression : allowedMethodsMapEntryExpressions) {
final Expression allowedMethodsMapEntryKeyExpression = allowedMethodsMapEntryExpression.getKeyExpression();
if (allowedMethodsMapEntryKeyExpression instanceof ConstantExpression) {
final ConstantExpression allowedMethodsMapKeyConstantExpression = (ConstantExpression) allowedMethodsMapEntryKeyExpression;
final Object allowedMethodsMapKeyValue = allowedMethodsMapKeyConstantExpression.getValue();
if (methodName.equals(allowedMethodsMapKeyValue)) {
actionIsRestricted = true;
break;
}
}
}
if (actionIsRestricted) {
final PropertyExpression responsePropertyExpression = new PropertyExpression(new VariableExpression("this"), "response");
final ArgumentListExpression isAllowedArgumentList = new ArgumentListExpression();
isAllowedArgumentList.addExpression(new ConstantExpression(methodName));
isAllowedArgumentList.addExpression(new PropertyExpression(new VariableExpression("this"), "request"));
isAllowedArgumentList.addExpression(new PropertyExpression(new VariableExpression("this"), DefaultGrailsControllerClass.ALLOWED_HTTP_METHODS_PROPERTY));
final Expression isAllowedMethodCall = new StaticMethodCallExpression(ClassHelper.make(AllowedMethodsHelper.class), "isAllowed", isAllowedArgumentList);
final BooleanExpression isValidRequestMethod = new BooleanExpression(isAllowedMethodCall);
final MethodCallExpression sendErrorMethodCall = new MethodCallExpression(responsePropertyExpression, "sendError", new ConstantExpression(HttpServletResponse.SC_METHOD_NOT_ALLOWED));
final ReturnStatement returnStatement = new ReturnStatement(new ConstantExpression(null));
final BlockStatement blockToSendError = new BlockStatement();
blockToSendError.addStatement(new ExpressionStatement(sendErrorMethodCall));
blockToSendError.addStatement(returnStatement);
final IfStatement ifIsValidRequestMethodStatement = new IfStatement(isValidRequestMethod, new ExpressionStatement(new EmptyExpression()), blockToSendError);
checkAllowedMethodsBlock.addStatement(ifIsValidRequestMethodStatement);
}
}
}
final ArgumentListExpression argumentListExpression = new ArgumentListExpression();
argumentListExpression.addExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME));
argumentListExpression.addExpression(new ConstantExpression(methodName));
final Expression setAttributeMethodCall = new MethodCallExpression(requestPropertyExpression, "setAttribute", argumentListExpression);
final BlockStatement codeToExecuteIfAttributeIsNotSet = new BlockStatement();
codeToExecuteIfAttributeIsNotSet.addStatement(new ExpressionStatement(setAttributeMethodCall));
codeToExecuteIfAttributeIsNotSet.addStatement(checkAllowedMethodsBlock);
final BooleanExpression attributeIsSetBooleanExpression = new BooleanExpression(new MethodCallExpression(requestPropertyExpression, "getAttribute", new ArgumentListExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME))));
final Statement ifAttributeIsAlreadySetStatement = new IfStatement(attributeIsSetBooleanExpression, new EmptyStatement(), codeToExecuteIfAttributeIsNotSet);
final BlockStatement code = new BlockStatement();
code.addStatement(ifAttributeIsAlreadySetStatement);
return code;
}
use of org.codehaus.groovy.ast.expr.Expression in project grails-core by grails.
the class ControllerActionTransformer method initializeActionParameters.
protected BlockStatement initializeActionParameters(ClassNode classNode, ASTNode actionNode, String actionName, Parameter[] actionParameters, SourceUnit source, GeneratorContext context) {
BlockStatement wrapper = new BlockStatement();
ArgumentListExpression mapBindingResultConstructorArgs = new ArgumentListExpression();
mapBindingResultConstructorArgs.addExpression(new ConstructorCallExpression(new ClassNode(HashMap.class), EMPTY_TUPLE));
mapBindingResultConstructorArgs.addExpression(new ConstantExpression("controller"));
final Expression mapBindingResultConstructorCallExpression = new ConstructorCallExpression(new ClassNode(MapBindingResult.class), mapBindingResultConstructorArgs);
final Expression errorsAssignmentExpression = buildSetPropertyExpression(new VariableExpression("this", classNode), "errors", classNode, mapBindingResultConstructorCallExpression);
wrapper.addStatement(new ExpressionStatement(errorsAssignmentExpression));
if (actionParameters != null) {
for (Parameter param : actionParameters) {
initializeMethodParameter(classNode, wrapper, actionNode, actionName, param, source, context);
}
}
return wrapper;
}
use of org.codehaus.groovy.ast.expr.Expression in project grails-core by grails.
the class ControllerActionTransformer method wrapMethodBodyWithExceptionHandling.
/**
* This will wrap the method body in a try catch block which does something
* like this:
* <pre>
* try {
* // original method body here
* } catch (Exception $caughtException) {
* Method $method = getExceptionHandlerMethod($caughtException.getClass())
* if($method) {
* return $method.invoke(this, $caughtException)
* } else {
* throw $caughtException
* }
* }
* </pre>
* @param methodNode the method to add the try catch block to
*/
protected void wrapMethodBodyWithExceptionHandling(final ClassNode controllerClassNode, final MethodNode methodNode) {
final BlockStatement catchBlockCode = new BlockStatement();
final String caughtExceptionArgumentName = "$caughtException";
final Expression caughtExceptionVariableExpression = new VariableExpression(caughtExceptionArgumentName);
final Expression caughtExceptionTypeExpression = new PropertyExpression(caughtExceptionVariableExpression, "class");
final Expression thisExpression = new VariableExpression("this");
final MethodCallExpression getExceptionHandlerMethodCall = new MethodCallExpression(thisExpression, "getExceptionHandlerMethodFor", caughtExceptionTypeExpression);
applyDefaultMethodTarget(getExceptionHandlerMethodCall, controllerClassNode);
final ClassNode reflectMethodClassNode = new ClassNode(Method.class);
final String exceptionHandlerMethodVariableName = "$method";
final Expression exceptionHandlerMethodExpression = new VariableExpression(exceptionHandlerMethodVariableName, new ClassNode(Method.class));
final Expression declareExceptionHandlerMethod = new DeclarationExpression(new VariableExpression(exceptionHandlerMethodVariableName, reflectMethodClassNode), Token.newSymbol(Types.EQUALS, 0, 0), getExceptionHandlerMethodCall);
final ArgumentListExpression invokeArguments = new ArgumentListExpression();
invokeArguments.addExpression(thisExpression);
invokeArguments.addExpression(caughtExceptionVariableExpression);
final MethodCallExpression invokeExceptionHandlerMethodExpression = new MethodCallExpression(new VariableExpression(exceptionHandlerMethodVariableName), "invoke", invokeArguments);
applyDefaultMethodTarget(invokeExceptionHandlerMethodExpression, reflectMethodClassNode);
final Statement returnStatement = new ReturnStatement(invokeExceptionHandlerMethodExpression);
final Statement throwCaughtExceptionStatement = new ThrowStatement(caughtExceptionVariableExpression);
final Statement ifExceptionHandlerMethodExistsStatement = new IfStatement(new BooleanExpression(exceptionHandlerMethodExpression), returnStatement, throwCaughtExceptionStatement);
catchBlockCode.addStatement(new ExpressionStatement(declareExceptionHandlerMethod));
catchBlockCode.addStatement(ifExceptionHandlerMethodExistsStatement);
final CatchStatement catchStatement = new CatchStatement(new Parameter(new ClassNode(Exception.class), caughtExceptionArgumentName), catchBlockCode);
final Statement methodBody = methodNode.getCode();
BlockStatement tryBlock = new BlockStatement();
BlockStatement codeToHandleAllowedMethods = getCodeToHandleAllowedMethods(controllerClassNode, methodNode.getName());
tryBlock.addStatement(codeToHandleAllowedMethods);
tryBlock.addStatement(methodBody);
final TryCatchStatement tryCatchStatement = new TryCatchStatement(tryBlock, new EmptyStatement());
tryCatchStatement.addCatch(catchStatement);
final ArgumentListExpression argumentListExpression = new ArgumentListExpression();
argumentListExpression.addExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME));
final PropertyExpression requestPropertyExpression = new PropertyExpression(new VariableExpression("this"), "request");
final Expression removeAttributeMethodCall = new MethodCallExpression(requestPropertyExpression, "removeAttribute", argumentListExpression);
final Expression getAttributeMethodCall = new MethodCallExpression(requestPropertyExpression, "getAttribute", new ArgumentListExpression(new ConstantExpression(ALLOWED_METHODS_HANDLED_ATTRIBUTE_NAME)));
final VariableExpression attributeValueExpression = new VariableExpression("$allowed_methods_attribute_value", ClassHelper.make(Object.class));
final Expression initializeAttributeValue = new DeclarationExpression(attributeValueExpression, Token.newSymbol(Types.EQUALS, 0, 0), getAttributeMethodCall);
final Expression attributeValueMatchesMethodNameExpression = new BinaryExpression(new ConstantExpression(methodNode.getName()), Token.newSymbol(Types.COMPARE_EQUAL, 0, 0), attributeValueExpression);
final Statement ifAttributeValueMatchesMethodName = new IfStatement(new BooleanExpression(attributeValueMatchesMethodNameExpression), new ExpressionStatement(removeAttributeMethodCall), new EmptyStatement());
final BlockStatement blockToRemoveAttribute = new BlockStatement();
blockToRemoveAttribute.addStatement(new ExpressionStatement(initializeAttributeValue));
blockToRemoveAttribute.addStatement(ifAttributeValueMatchesMethodName);
final TryCatchStatement tryCatchToRemoveAttribute = new TryCatchStatement(blockToRemoveAttribute, new EmptyStatement());
tryCatchToRemoveAttribute.addCatch(new CatchStatement(new Parameter(ClassHelper.make(Exception.class), "$exceptionRemovingAttribute"), new EmptyStatement()));
tryCatchStatement.setFinallyStatement(tryCatchToRemoveAttribute);
methodNode.setCode(tryCatchStatement);
}
use of org.codehaus.groovy.ast.expr.Expression in project grails-core by grails.
the class ControllerActionTransformer method initializeAndValidateCommandObjectParameter.
protected void initializeAndValidateCommandObjectParameter(final BlockStatement wrapper, final ClassNode controllerNode, final ClassNode commandObjectNode, final ASTNode actionNode, final String actionName, final String paramName, final SourceUnit source, final GeneratorContext context) {
final DeclarationExpression declareCoExpression = new DeclarationExpression(new VariableExpression(paramName, commandObjectNode), Token.newSymbol(Types.EQUALS, 0, 0), new EmptyExpression());
wrapper.addStatement(new ExpressionStatement(declareCoExpression));
if (commandObjectNode.isInterface() || Modifier.isAbstract(commandObjectNode.getModifiers())) {
final String warningMessage = "The [" + actionName + "] action in [" + controllerNode.getName() + "] accepts a parameter of type [" + commandObjectNode.getName() + "]. Interface types and abstract class types are not supported as command objects. This parameter will be ignored.";
GrailsASTUtils.warning(source, actionNode, warningMessage);
} else {
initializeCommandObjectParameter(wrapper, commandObjectNode, paramName, source);
@SuppressWarnings("unchecked") boolean argumentIsValidateable = GrailsASTUtils.hasAnyAnnotations(commandObjectNode, grails.persistence.Entity.class, javax.persistence.Entity.class) || commandObjectNode.implementsInterface(ClassHelper.make(Validateable.class));
if (!argumentIsValidateable && commandObjectNode.isPrimaryClassNode()) {
final ModuleNode commandObjectModule = commandObjectNode.getModule();
if (commandObjectModule != null && this.compilationUnit != null) {
if (commandObjectModule == controllerNode.getModule() || doesModulePathIncludeSubstring(commandObjectModule, "grails-app" + File.separator + "controllers" + File.separator)) {
TraitInjectionUtils.injectTrait(compilationUnit, source, commandObjectNode, Validateable.class);
List<ConstructorNode> declaredConstructors = commandObjectNode.getDeclaredConstructors();
List<Statement> objectInitializerStatements = commandObjectNode.getObjectInitializerStatements();
if (declaredConstructors.isEmpty() && !objectInitializerStatements.isEmpty()) {
BlockStatement constructorLogic = new BlockStatement();
ConstructorNode constructorNode = new ConstructorNode(Modifier.PUBLIC, constructorLogic);
commandObjectNode.addConstructor(constructorNode);
constructorLogic.addStatements(objectInitializerStatements);
}
argumentIsValidateable = true;
} else if (doesModulePathIncludeSubstring(commandObjectModule, "grails-app" + File.separator + "domain" + File.separator)) {
argumentIsValidateable = true;
}
}
}
if (argumentIsValidateable) {
final MethodCallExpression validateMethodCallExpression = new MethodCallExpression(new VariableExpression(paramName), "validate", EMPTY_TUPLE);
final MethodNode validateMethod = commandObjectNode.getMethod("validate", new Parameter[0]);
if (validateMethod != null) {
validateMethodCallExpression.setMethodTarget(validateMethod);
}
final Statement ifCommandObjectIsNotNullThenValidate = new IfStatement(new BooleanExpression(new VariableExpression(paramName)), new ExpressionStatement(validateMethodCallExpression), new ExpressionStatement(new EmptyExpression()));
wrapper.addStatement(ifCommandObjectIsNotNullThenValidate);
} else {
// try to dynamically invoke the .validate() method if it is available at runtime...
final Expression respondsToValidateMethodCallExpression = new MethodCallExpression(new VariableExpression(paramName), "respondsTo", new ArgumentListExpression(new ConstantExpression("validate")));
final Expression validateMethodCallExpression = new MethodCallExpression(new VariableExpression(paramName), "validate", new ArgumentListExpression());
final Statement ifRespondsToValidateThenValidateStatement = new IfStatement(new BooleanExpression(respondsToValidateMethodCallExpression), new ExpressionStatement(validateMethodCallExpression), new ExpressionStatement(new EmptyExpression()));
final Statement ifCommandObjectIsNotNullThenValidate = new IfStatement(new BooleanExpression(new VariableExpression(paramName)), ifRespondsToValidateThenValidateStatement, new ExpressionStatement(new EmptyExpression()));
wrapper.addStatement(ifCommandObjectIsNotNullThenValidate);
final String warningMessage = "The [" + actionName + "] action accepts a parameter of type [" + commandObjectNode.getName() + "] which does not implement grails.validation.Validateable. Data binding will still be applied " + "to this command object but the instance will not be validateable.";
GrailsASTUtils.warning(source, actionNode, warningMessage);
}
if (GrailsASTUtils.isInnerClassNode(commandObjectNode)) {
final String warningMessage = "The [" + actionName + "] action accepts a parameter of type [" + commandObjectNode.getName() + "] which is an inner class. Command object classes should not be inner classes.";
GrailsASTUtils.warning(source, actionNode, warningMessage);
} else {
new DefaultASTDatabindingHelper().injectDatabindingCode(source, context, commandObjectNode);
}
}
}
Aggregations