use of org.codehaus.groovy.ast.stmt.BlockStatement 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.stmt.BlockStatement 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.stmt.BlockStatement 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.stmt.BlockStatement in project grails-core by grails.
the class DefaultASTValidateableHelper method addValidateMethod.
protected void addValidateMethod(final ClassNode classNode) {
String fieldsToValidateParameterName = "$fieldsToValidate";
final MethodNode listArgValidateMethod = classNode.getMethod(VALIDATE_METHOD_NAME, new Parameter[] { new Parameter(new ClassNode(List.class), fieldsToValidateParameterName) });
if (listArgValidateMethod == null) {
final BlockStatement validateMethodCode = new BlockStatement();
final ArgumentListExpression validateInstanceArguments = new ArgumentListExpression();
validateInstanceArguments.addExpression(new VariableExpression("this"));
validateInstanceArguments.addExpression(new VariableExpression(fieldsToValidateParameterName, ClassHelper.LIST_TYPE));
final ClassNode validationSupportClassNode = ClassHelper.make(ValidationSupport.class);
final StaticMethodCallExpression invokeValidateInstanceExpression = new StaticMethodCallExpression(validationSupportClassNode, "validateInstance", validateInstanceArguments);
validateMethodCode.addStatement(new ExpressionStatement(invokeValidateInstanceExpression));
final Parameter fieldsToValidateParameter = new Parameter(new ClassNode(List.class), fieldsToValidateParameterName);
MethodNode methodNode = new MethodNode(VALIDATE_METHOD_NAME, Modifier.PUBLIC, ClassHelper.boolean_TYPE, new Parameter[] { fieldsToValidateParameter }, EMPTY_CLASS_ARRAY, validateMethodCode);
classNode.addMethod(methodNode);
AnnotatedNodeUtils.markAsGenerated(classNode, methodNode);
}
final MethodNode noArgValidateMethod = classNode.getMethod(VALIDATE_METHOD_NAME, ZERO_PARAMETERS);
if (noArgValidateMethod == null) {
final BlockStatement validateMethodCode = new BlockStatement();
final ArgumentListExpression validateInstanceArguments = new ArgumentListExpression();
validateInstanceArguments.addExpression(new CastExpression(new ClassNode(List.class), new ConstantExpression(null)));
final Expression callListArgValidateMethod = new MethodCallExpression(new VariableExpression("this"), VALIDATE_METHOD_NAME, validateInstanceArguments);
validateMethodCode.addStatement(new ReturnStatement(callListArgValidateMethod));
MethodNode methodNode = new MethodNode(VALIDATE_METHOD_NAME, Modifier.PUBLIC, ClassHelper.boolean_TYPE, ZERO_PARAMETERS, EMPTY_CLASS_ARRAY, validateMethodCode);
classNode.addMethod(methodNode);
AnnotatedNodeUtils.markAsGenerated(classNode, methodNode);
}
}
use of org.codehaus.groovy.ast.stmt.BlockStatement in project grails-core by grails.
the class DefaultASTValidateableHelper method addGetConstraintsMethod.
protected void addGetConstraintsMethod(final ClassNode classNode, boolean defaultNullable) {
final String getConstraintsMethodName = "getConstraints";
MethodNode getConstraintsMethod = classNode.getMethod(getConstraintsMethodName, ZERO_PARAMETERS);
if (getConstraintsMethod == null || !getConstraintsMethod.getDeclaringClass().equals(classNode)) {
final BooleanExpression isConstraintsPropertyNull = new BooleanExpression(new BinaryExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME), Token.newSymbol(Types.COMPARE_EQUAL, 0, 0), new ConstantExpression(null)));
final BlockStatement ifConstraintsPropertyIsNullBlockStatement = new BlockStatement();
final ArgumentListExpression getConstrainedPropertiesForClassArguments = new ArgumentListExpression();
getConstrainedPropertiesForClassArguments.addExpression(new VariableExpression("this"));
getConstrainedPropertiesForClassArguments.addExpression(new ConstantExpression(defaultNullable));
final Expression getConstraintsMethodCall = new StaticMethodCallExpression(ClassHelper.make(ValidationSupport.class), "getConstrainedPropertiesForClass", getConstrainedPropertiesForClassArguments);
final Expression initializeConstraintsFieldExpression = new BinaryExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME), Token.newSymbol(Types.EQUALS, 0, 0), getConstraintsMethodCall);
final Statement ifConstraintsPropertyIsNullStatement = new IfStatement(isConstraintsPropertyNull, ifConstraintsPropertyIsNullBlockStatement, new ExpressionStatement(new EmptyExpression()));
ifConstraintsPropertyIsNullBlockStatement.addStatement(new ExpressionStatement(initializeConstraintsFieldExpression));
if (!defaultNullable) {
final Map<String, ClassNode> propertiesToConstrain = getPropertiesToEnsureConstraintsFor(classNode);
for (final Map.Entry<String, ClassNode> entry : propertiesToConstrain.entrySet()) {
final String propertyName = entry.getKey();
final ClassNode propertyType = entry.getValue();
final String cpName = "$" + propertyName + "$constrainedProperty";
final ArgumentListExpression constrainedPropertyConstructorArgumentList = new ArgumentListExpression();
constrainedPropertyConstructorArgumentList.addExpression(new ClassExpression(classNode));
constrainedPropertyConstructorArgumentList.addExpression(new ConstantExpression(propertyName));
constrainedPropertyConstructorArgumentList.addExpression(new ClassExpression(propertyType));
final ConstructorCallExpression constrainedPropertyCtorCallExpression = new ConstructorCallExpression(new ClassNode(ConstrainedProperty.class), constrainedPropertyConstructorArgumentList);
final Expression declareConstrainedPropertyExpression = new DeclarationExpression(new VariableExpression(cpName, ClassHelper.OBJECT_TYPE), Token.newSymbol(Types.EQUALS, 0, 0), constrainedPropertyCtorCallExpression);
final ArgumentListExpression applyConstraintMethodArgumentList = new ArgumentListExpression();
applyConstraintMethodArgumentList.addExpression(new ConstantExpression(ConstrainedProperty.NULLABLE_CONSTRAINT));
applyConstraintMethodArgumentList.addExpression(new ConstantExpression(defaultNullable));
final Expression applyNullableConstraintMethodCallExpression = new MethodCallExpression(new VariableExpression(cpName), "applyConstraint", applyConstraintMethodArgumentList);
final ArgumentListExpression putMethodArgumentList = new ArgumentListExpression();
putMethodArgumentList.addExpression(new ConstantExpression(propertyName));
putMethodArgumentList.addExpression(new VariableExpression(cpName));
final MethodCallExpression addToConstraintsMapExpression = new MethodCallExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME), "put", putMethodArgumentList);
final BlockStatement addNullableConstraintBlock = new BlockStatement();
addNullableConstraintBlock.addStatement(new ExpressionStatement(declareConstrainedPropertyExpression));
addNullableConstraintBlock.addStatement(new ExpressionStatement(applyNullableConstraintMethodCallExpression));
addNullableConstraintBlock.addStatement(new ExpressionStatement(addToConstraintsMapExpression));
final Expression constraintsMapContainsKeyExpression = new MethodCallExpression(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME, ClassHelper.make(Map.class)), "containsKey", new ArgumentListExpression(new ConstantExpression(propertyName)));
final BooleanExpression ifPropertyIsAlreadyConstrainedExpression = new BooleanExpression(constraintsMapContainsKeyExpression);
final Statement ifPropertyIsAlreadyConstrainedStatement = new IfStatement(ifPropertyIsAlreadyConstrainedExpression, new ExpressionStatement(new EmptyExpression()), addNullableConstraintBlock);
ifConstraintsPropertyIsNullBlockStatement.addStatement(ifPropertyIsAlreadyConstrainedStatement);
}
}
final BlockStatement methodBlockStatement = new BlockStatement();
methodBlockStatement.addStatement(ifConstraintsPropertyIsNullStatement);
final Statement returnStatement = new ReturnStatement(new VariableExpression(CONSTRAINED_PROPERTIES_PROPERTY_NAME));
methodBlockStatement.addStatement(returnStatement);
final MethodNode methodNode = new MethodNode(getConstraintsMethodName, Modifier.STATIC | Modifier.PUBLIC, new ClassNode(Map.class), ZERO_PARAMETERS, null, methodBlockStatement);
if (classNode.redirect() == null) {
classNode.addMethod(methodNode);
AnnotatedNodeUtils.markAsGenerated(classNode, methodNode);
} else {
classNode.redirect().addMethod(methodNode);
AnnotatedNodeUtils.markAsGenerated(classNode.redirect(), methodNode);
}
}
}
Aggregations