|
21 | 21 | import static org.codehaus.groovy.grails.compiler.injection.GrailsASTUtils.buildGetPropertyExpression; |
22 | 22 | import static org.codehaus.groovy.grails.compiler.injection.GrailsASTUtils.buildSetPropertyExpression; |
23 | 23 | import grails.artefact.Artefact; |
| 24 | +import grails.transaction.Transactional; |
24 | 25 | import grails.util.BuildSettings; |
25 | 26 | import grails.util.CollectionUtils; |
26 | 27 | import grails.validation.ASTValidateableHelper; |
|
86 | 87 | import org.codehaus.groovy.grails.compiler.injection.AstTransformer; |
87 | 88 | import org.codehaus.groovy.grails.compiler.injection.GrailsASTUtils; |
88 | 89 | import org.codehaus.groovy.grails.compiler.injection.GrailsArtefactClassInjector; |
| 90 | +import org.codehaus.groovy.grails.transaction.transform.TransactionalTransform; |
89 | 91 | import org.codehaus.groovy.grails.web.binding.DefaultASTDatabindingHelper; |
90 | 92 | import org.codehaus.groovy.grails.web.controllers.DefaultControllerExceptionHandlerMetaData; |
91 | 93 | import org.codehaus.groovy.grails.web.util.TypeConvertingMap; |
92 | 94 | import org.codehaus.groovy.runtime.DefaultGroovyMethods; |
93 | 95 | import org.codehaus.groovy.syntax.Token; |
94 | 96 | import org.codehaus.groovy.syntax.Types; |
| 97 | +import org.springframework.transaction.TransactionStatus; |
95 | 98 | import org.springframework.validation.Errors; |
96 | 99 | import org.springframework.validation.MapBindingResult; |
97 | 100 |
|
@@ -357,6 +360,7 @@ private MethodNode convertToMethodAction(ClassNode classNode, MethodNode methodN |
357 | 360 |
|
358 | 361 | MethodNode method = null; |
359 | 362 | if (methodNode.getParameters().length > 0) { |
| 363 | + populateMethodWithCommandObjectInitializationCode(classNode, methodNode, source, context); |
360 | 364 | final BlockStatement methodCode = new BlockStatement(); |
361 | 365 |
|
362 | 366 | final BlockStatement codeToHandleAllowedMethods = getCodeToHandleAllowedMethods(classNode, methodNode.getName()); |
@@ -385,6 +389,54 @@ private MethodNode convertToMethodAction(ClassNode classNode, MethodNode methodN |
385 | 389 | return method; |
386 | 390 | } |
387 | 391 |
|
| 392 | + protected void populateMethodWithCommandObjectInitializationCode(final ClassNode classNode, |
| 393 | + final MethodNode methodNode, |
| 394 | + final SourceUnit source, |
| 395 | + final GeneratorContext context) { |
| 396 | + final MethodNode methodToUse = getMethodToIncludeCommandObjectInitializationCode(methodNode); |
| 397 | + final BlockStatement newCodeForExistingMethod = new BlockStatement(); |
| 398 | + final BlockStatement codeToInitializeCommandObjects = getCodeToInitializeCommandObjects(methodToUse, methodToUse.getName(), methodToUse.getParameters(), classNode, source, context); |
| 399 | + newCodeForExistingMethod.addStatement(codeToInitializeCommandObjects); |
| 400 | + newCodeForExistingMethod.addStatement(methodToUse.getCode()); |
| 401 | + methodToUse.setCode(newCodeForExistingMethod); |
| 402 | + } |
| 403 | + |
| 404 | + protected MethodNode getMethodToIncludeCommandObjectInitializationCode(final MethodNode methodNode) { |
| 405 | + MethodNode node = methodNode; |
| 406 | + if(GrailsASTUtils.hasAnnotation(methodNode, Transactional.class)) { |
| 407 | + final ClassNode declaringClass = methodNode.getDeclaringClass(); |
| 408 | + final String txHandlingMethodName = TransactionalTransform.getTransactionHandlingMethodName(methodNode); |
| 409 | + final Parameter[] originalMethodParameters = methodNode.getParameters(); |
| 410 | + final Parameter[] txHandlingMethodParams = new Parameter[originalMethodParameters.length + 1]; |
| 411 | + System.arraycopy(originalMethodParameters, 0, txHandlingMethodParams, 0, originalMethodParameters.length); |
| 412 | + txHandlingMethodParams[txHandlingMethodParams.length-1] = new Parameter(ClassHelper.make(TransactionStatus.class), "transactionStatus"); |
| 413 | + if(declaringClass.hasMethod(txHandlingMethodName, txHandlingMethodParams)) { |
| 414 | + node = declaringClass.getMethod(txHandlingMethodName, txHandlingMethodParams); |
| 415 | + } |
| 416 | + } |
| 417 | + return node; |
| 418 | + } |
| 419 | + |
| 420 | + protected BlockStatement getCodeToInitializeCommandObjects(final ASTNode actionNode, |
| 421 | + final String actionName, |
| 422 | + final Parameter[] parameters, |
| 423 | + final ClassNode controllerNode, |
| 424 | + final SourceUnit source, |
| 425 | + final GeneratorContext context) { |
| 426 | + final BlockStatement body = new BlockStatement(); |
| 427 | + for(Parameter p : parameters) { |
| 428 | + final String paramName = p.getName(); |
| 429 | + final ClassNode paramTypeClassNode = p.getType(); |
| 430 | + if (!(PRIMITIVE_CLASS_NODES.contains(paramTypeClassNode) || |
| 431 | + TYPE_WRAPPER_CLASS_TO_CONVERSION_METHOD_NAME.containsKey(paramTypeClassNode)) && |
| 432 | + !paramTypeClassNode.equals(new ClassNode(String.class)) && |
| 433 | + !paramTypeClassNode.equals(OBJECT_CLASS)) { |
| 434 | + initializeAndValidateCommandObjectParameter(body, controllerNode, paramTypeClassNode, actionNode, actionName, paramName, source, context); |
| 435 | + } |
| 436 | + } |
| 437 | + return body; |
| 438 | + } |
| 439 | + |
388 | 440 | private Statement addOriginalMethodCall(MethodNode methodNode, BlockStatement blockStatement) { |
389 | 441 |
|
390 | 442 | if (blockStatement == null) { |
@@ -438,7 +490,16 @@ protected void addMethodToInvokeClosure(ClassNode controllerClassNode, |
438 | 490 |
|
439 | 491 | MethodNode method = controllerClassNode.getMethod(closureProperty.getName(), ZERO_PARAMETERS); |
440 | 492 | if (method == null || !method.getDeclaringClass().equals(controllerClassNode)) { |
441 | | - ClosureExpression closureExpression = (ClosureExpression) closureProperty.getInitialExpression(); |
| 493 | + final ClosureExpression closureExpression = (ClosureExpression) closureProperty.getInitialExpression(); |
| 494 | + final BlockStatement newClosureCode = new BlockStatement(); |
| 495 | + final Statement originalClosureCode = closureExpression.getCode(); |
| 496 | + final BlockStatement codeToInitializeCommandObjects = getCodeToInitializeCommandObjects(closureProperty, closureProperty.getName(), closureExpression.getParameters(), controllerClassNode, source, context); |
| 497 | + |
| 498 | + newClosureCode.addStatement(codeToInitializeCommandObjects); |
| 499 | + newClosureCode.addStatement(originalClosureCode); |
| 500 | + |
| 501 | + closureExpression.setCode(newClosureCode); |
| 502 | + |
442 | 503 | final Parameter[] parameters = closureExpression.getParameters(); |
443 | 504 | final BlockStatement newMethodCode = initializeActionParameters( |
444 | 505 | controllerClassNode, closureProperty, closureProperty.getName(), |
@@ -705,18 +766,16 @@ protected void initializeMethodParameter(final ClassNode classNode, final BlockS |
705 | 766 | } else if (paramTypeClassNode.equals(new ClassNode(String.class))) { |
706 | 767 | initializeStringParameter(classNode, wrapper, param, requestParameterName); |
707 | 768 | } else if (!paramTypeClassNode.equals(OBJECT_CLASS)) { |
708 | | - initializeAndValidateCommandObjectParameter(wrapper, classNode, paramTypeClassNode, |
709 | | - actionNode, actionName, paramName, source, context); |
| 769 | + final DeclarationExpression declareCoExpression = new DeclarationExpression( |
| 770 | + new VariableExpression(paramName, paramTypeClassNode), Token.newSymbol(Types.EQUALS, 0, 0), new ConstantExpression(null)); |
| 771 | + wrapper.addStatement(new ExpressionStatement(declareCoExpression)); |
710 | 772 | } |
711 | 773 | } |
712 | 774 |
|
713 | 775 | protected void initializeAndValidateCommandObjectParameter(final BlockStatement wrapper, |
714 | 776 | final ClassNode controllerNode, final ClassNode commandObjectNode, |
715 | 777 | final ASTNode actionNode, final String actionName, final String paramName, |
716 | 778 | final SourceUnit source, final GeneratorContext context) { |
717 | | - final DeclarationExpression declareCoExpression = new DeclarationExpression( |
718 | | - new VariableExpression(paramName, commandObjectNode), Token.newSymbol(Types.EQUALS, 0, 0), new EmptyExpression()); |
719 | | - wrapper.addStatement(new ExpressionStatement(declareCoExpression)); |
720 | 779 |
|
721 | 780 | if(commandObjectNode.isInterface() || Modifier.isAbstract(commandObjectNode.getModifiers())) { |
722 | 781 | final String warningMessage = "The [" + actionName + "] action in [" + |
@@ -754,10 +813,12 @@ protected void initializeAndValidateCommandObjectParameter(final BlockStatement |
754 | 813 | if (argumentIsValidateable) { |
755 | 814 | final MethodCallExpression validateMethodCallExpression = |
756 | 815 | new MethodCallExpression(new VariableExpression(paramName), "validate", EMPTY_TUPLE); |
| 816 | + |
757 | 817 | final MethodNode validateMethod = |
758 | 818 | commandObjectNode.getMethod("validate", new Parameter[0]); |
759 | 819 | if (validateMethod != null) { |
760 | 820 | validateMethodCallExpression.setMethodTarget(validateMethod); |
| 821 | + validateMethodCallExpression.setImplicitThis(false); |
761 | 822 | } |
762 | 823 | final Statement ifCommandObjectIsNotNullThenValidate = new IfStatement(new BooleanExpression(new VariableExpression(paramName)), new ExpressionStatement(validateMethodCallExpression), new ExpressionStatement(new EmptyExpression())); |
763 | 824 | wrapper.addStatement(ifCommandObjectIsNotNullThenValidate); |
@@ -804,8 +865,10 @@ protected void initializeCommandObjectParameter(final BlockStatement wrapper, |
804 | 865 | applyDefaultMethodTarget(initializeCommandObjectMethodCall, commandObjectNode); |
805 | 866 |
|
806 | 867 | final Expression assignCommandObjectToParameter = new BinaryExpression(new VariableExpression(paramName), Token.newSymbol(Types.EQUALS, 0, 0), initializeCommandObjectMethodCall); |
807 | | - |
808 | | - wrapper.addStatement(new ExpressionStatement(assignCommandObjectToParameter)); |
| 868 | + |
| 869 | + final BinaryExpression isParamNullExression = new BinaryExpression(new VariableExpression(paramName), Token.newSymbol(Types.COMPARE_EQUAL, 0, 0), new ConstantExpression(null)); |
| 870 | + final Statement initializeCommandObjectIfNull = new IfStatement(new BooleanExpression(isParamNullExression), new ExpressionStatement(assignCommandObjectToParameter), new EmptyStatement()); |
| 871 | + wrapper.addStatement(initializeCommandObjectIfNull); |
809 | 872 | } |
810 | 873 |
|
811 | 874 | /** |
|
0 commit comments