Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: tombujok/grails-core
...
head fork: tombujok/grails-core
Checking mergeability… Don’t worry, you can still create the pull request.
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
View
39 ...gs/src/main/groovy/org/codehaus/groovy/grails/web/mapping/DefaultUrlMappingEvaluator.java
@@ -284,7 +284,7 @@ public GrailsApplication getGrailsApplication() {
@Override
public Object getProperty(String name) {
if (urlDefiningMode) {
- getCurrentConstraints().add(new ConstrainedProperty(UrlMapping.class, name, String.class));
+ getParentConstraints().add(new ConstrainedProperty(UrlMapping.class, name, String.class));
return CAPTURING_WILD_CARD;
}
return super.getProperty(name);
@@ -402,7 +402,12 @@ Object propertyMissing(String name) {
private Object _invoke(String methodName, Object arg, Object delegate) {
Object[] args = (Object[]) arg;
- String mappedURI = establishFullURI(methodName);
+ List<ConstrainedProperty> currentConstraints = new ArrayList<ConstrainedProperty>();
+ List<ConstrainedProperty> parentConstraints = getParentConstraints();
+ if(parentConstraints != null) {
+ currentConstraints.addAll(parentConstraints);
+ }
+ String mappedURI = establishFullURI(methodName, currentConstraints);
final boolean isResponseCode = isResponseCode(mappedURI);
if (mappedURI.startsWith(SLASH) || isResponseCode) {
// Create a new parameter map for this mapping.
@@ -452,7 +457,7 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
httpMethod = this.httpMethod;
}
- ConstrainedProperty[] constraints = getCurrentConstraints().toArray(new ConstrainedProperty[getCurrentConstraints().size()]);
+ ConstrainedProperty[] constraints = currentConstraints.toArray(new ConstrainedProperty[currentConstraints.size()]);
UrlMapping urlMapping;
if (uri != null) {
try {
@@ -492,7 +497,7 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
if (namedArguments.containsKey(RESOURCE)) {
Object controller = namedArguments.get(RESOURCE);
String controllerName = controller.toString();
- parentResources.push(new ParentResource(controllerName, uri, getCurrentConstraints(), true));
+ parentResources.push(new ParentResource(controllerName, uri, currentConstraints, true));
try {
invokeLastArgumentIfClosure(args);
} finally {
@@ -500,24 +505,24 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
}
if (controller != null) {
- createSingleResourceRestfulMappings(controllerName, pluginName, namespace, version, urlData, getCurrentConstraints(), calculateIncludes(namedArguments, DEFAULT_RESOURCE_INCLUDES));
+ createSingleResourceRestfulMappings(controllerName, pluginName, namespace, version, urlData, currentConstraints, calculateIncludes(namedArguments, DEFAULT_RESOURCE_INCLUDES));
}
} else if (namedArguments.containsKey(RESOURCES)) {
Object controller = namedArguments.get(RESOURCES);
String controllerName = controller.toString();
- parentResources.push(new ParentResource(controllerName, uri, getCurrentConstraints(), false));
+ parentResources.push(new ParentResource(controllerName, uri, currentConstraints, false));
try {
invokeLastArgumentIfClosure(args);
} finally {
parentResources.pop();
}
if (controller != null) {
- createResourceRestfulMappings(controllerName, pluginName, namespace,version,urlData, getCurrentConstraints(), calculateIncludes(namedArguments, DEFAULT_RESOURCES_INCLUDES));
+ createResourceRestfulMappings(controllerName, pluginName, namespace,version,urlData, currentConstraints, calculateIncludes(namedArguments, DEFAULT_RESOURCES_INCLUDES));
}
} else {
invokeLastArgumentIfClosure(args);
- UrlMapping urlMapping = getURLMappingForNamedArgs(namedArguments, urlData, mappedURI, isResponseCode);
+ UrlMapping urlMapping = getURLMappingForNamedArgs(namedArguments, urlData, mappedURI, isResponseCode, currentConstraints);
configureUrlMapping(urlMapping);
return urlMapping;
}
@@ -545,7 +550,7 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
Closure callable = (Closure) args[0];
callable.setDelegate(builder);
- for (ConstrainedProperty constrainedProperty : getCurrentConstraints()) {
+ for (ConstrainedProperty constrainedProperty : currentConstraints) {
builder.getConstrainedProperties().put(constrainedProperty.getPropertyName(), constrainedProperty);
}
callable.call();
@@ -597,7 +602,7 @@ private Object _invoke(String methodName, Object arg, Object delegate) {
return includes;
}
- private String establishFullURI(String uri) {
+ private String establishFullURI(String uri, List<ConstrainedProperty> currentConstraints) {
if (parentResources.isEmpty()) {
return uri;
}
@@ -610,7 +615,7 @@ private String establishFullURI(String uri) {
else {
if (parentResource.controllerName != null) {
uriBuilder.append(parentResource.uri).append(SLASH).append(CAPTURING_WILD_CARD);
- getCurrentConstraints().add(new ConstrainedProperty(UrlMapping.class, parentResource.controllerName + "Id", String.class));
+ currentConstraints.add(new ConstrainedProperty(UrlMapping.class, parentResource.controllerName + "Id", String.class));
}
}
@@ -872,7 +877,7 @@ private boolean isResponseCode(String s) {
}
private UrlMapping getURLMappingForNamedArgs(Map namedArguments,
- UrlMappingData urlData, String mapping, boolean isResponseCode) {
+ UrlMappingData urlData, String mapping, boolean isResponseCode, List<ConstrainedProperty> currentConstraints) {
Object controllerName;
Object actionName;
final Map bindingVariables = binding != null ? binding.getVariables() : null;
@@ -891,7 +896,7 @@ private UrlMapping getURLMappingForNamedArgs(Map namedArguments,
}
Object uri = getURI(namedArguments, bindingVariables);
- ConstrainedProperty[] constraints = getCurrentConstraints().toArray(new ConstrainedProperty[getCurrentConstraints().size()]);
+ ConstrainedProperty[] constraints = currentConstraints.toArray(new ConstrainedProperty[currentConstraints.size()]);
UrlMapping urlMapping;
if (uri != null) {
@@ -995,10 +1000,10 @@ private UrlMapping createURLMapping(UrlMappingData urlData, boolean isResponseCo
return new ResponseCodeUrlMapping(urlData, controllerName, actionName, namespace, pluginName, viewName,
null, sc);
}
-
- public List<ConstrainedProperty> getCurrentConstraints() {
- ParentResource parentResource = parentResources.peek();
- return parentResource == null ? previousConstraints : parentResource.constraints;
+
+ public List<ConstrainedProperty> getParentConstraints() {
+ ParentResource parentResource = parentResources.peek();
+ return parentResource == null ? previousConstraints : parentResource.constraints;
}
class ParentResource {
View
82 .../src/test/groovy/org/codehaus/groovy/grails/web/mapping/RestfulResourceMappingSpec.groovy
@@ -1,16 +1,96 @@
package org.codehaus.groovy.grails.web.mapping
+import static org.springframework.http.HttpMethod.*
import grails.web.CamelCaseUrlConverter
+
import org.springframework.http.HttpMethod
import org.springframework.mock.web.MockServletContext
+
+import spock.lang.Issue
import spock.lang.Specification
-import static org.springframework.http.HttpMethod.*
/**
* @author Graeme Rocher
*/
class RestfulResourceMappingSpec extends Specification{
+ @Issue('GRAILS-10835')
+ void 'Test multiple nested mappings have correct constrained properties'() {
+ given: 'A resource mapping with 2 immediate child mappings'
+ def urlMappingsHolder = getUrlMappingsHolder {
+ "/books"(resources: "book") {
+ '/sellers'(resources:'seller') {
+ '/locations'(resources: 'location')
+ }
+ '/authors'(resources:'author')
+ '/titles'(resources:'title')
+ }
+ }
+
+ when: 'The URL mappings are obtained'
+ def urlMappings = urlMappingsHolder.urlMappings
+ def bookMappings = urlMappings.findAll { it.controllerName == 'book' }
+ def authorMappings = urlMappings.findAll { it.controllerName == 'author' }
+ def titleMappings = urlMappings.findAll { it.controllerName == 'title' }
+ def sellersMappings = urlMappings.findAll { it.controllerName == 'seller' }
+ def locationsMappings = urlMappings.findAll { it.controllerName == 'location' }
+
+ then: 'There are 21 mappings'
+ urlMappings.size() == 35
+
+ and: 'Each controller has 7 mappings'
+ bookMappings.size() == 7
+ authorMappings.size() == 7
+ titleMappings.size() == 7
+ sellersMappings.size() == 7
+ locationsMappings.size() == 7
+
+ and: 'the book mappings have the expected constrained properties'
+ bookMappings.find { it.actionName == 'index' }.constraints*.propertyName == ['format']
+ bookMappings.find { it.actionName == 'create' }.constraints*.propertyName == []
+ bookMappings.find { it.actionName == 'save' }.constraints*.propertyName == ['format']
+ bookMappings.find { it.actionName == 'show' }.constraints*.propertyName == ['id', 'format']
+ bookMappings.find { it.actionName == 'edit' }.constraints*.propertyName == ['id']
+ bookMappings.find { it.actionName == 'update' }.constraints*.propertyName == ['id', 'format']
+ bookMappings.find { it.actionName == 'delete' }.constraints*.propertyName == ['id', 'format']
+
+ and: 'the author mappings have the expected constrained properties'
+ authorMappings.find { it.actionName == 'index' }.constraints*.propertyName == ['bookId', 'format']
+ authorMappings.find { it.actionName == 'create' }.constraints*.propertyName == ['bookId']
+ authorMappings.find { it.actionName == 'save' }.constraints*.propertyName == ['bookId', 'format']
+ authorMappings.find { it.actionName == 'show' }.constraints*.propertyName == ['bookId', 'id', 'format']
+ authorMappings.find { it.actionName == 'edit' }.constraints*.propertyName == ['bookId', 'id']
+ authorMappings.find { it.actionName == 'update' }.constraints*.propertyName == ['bookId', 'id', 'format']
+ authorMappings.find { it.actionName == 'delete' }.constraints*.propertyName == ['bookId', 'id', 'format']
+
+ and: 'the title mappings have the expected constrained properties'
+ titleMappings.find { it.actionName == 'index' }.constraints*.propertyName == ['bookId', 'format']
+ titleMappings.find { it.actionName == 'create' }.constraints*.propertyName == ['bookId']
+ titleMappings.find { it.actionName == 'save' }.constraints*.propertyName == ['bookId', 'format']
+ titleMappings.find { it.actionName == 'show' }.constraints*.propertyName == ['bookId', 'id', 'format']
+ titleMappings.find { it.actionName == 'edit' }.constraints*.propertyName == ['bookId', 'id']
+ titleMappings.find { it.actionName == 'update' }.constraints*.propertyName == ['bookId', 'id', 'format']
+ titleMappings.find { it.actionName == 'delete' }.constraints*.propertyName == ['bookId', 'id', 'format']
+
+ and: 'the seller mappings have the expected constrained properties'
+ sellersMappings.find { it.actionName == 'index' }.constraints*.propertyName == ['bookId', 'format']
+ sellersMappings.find { it.actionName == 'create' }.constraints*.propertyName == ['bookId']
+ sellersMappings.find { it.actionName == 'save' }.constraints*.propertyName == ['bookId', 'format']
+ sellersMappings.find { it.actionName == 'show' }.constraints*.propertyName == ['bookId', 'id', 'format']
+ sellersMappings.find { it.actionName == 'edit' }.constraints*.propertyName == ['bookId', 'id']
+ sellersMappings.find { it.actionName == 'update' }.constraints*.propertyName == ['bookId', 'id', 'format']
+ sellersMappings.find { it.actionName == 'delete' }.constraints*.propertyName == ['bookId', 'id', 'format']
+
+ and: 'the location mappings have the expected constrained properties'
+ locationsMappings.find { it.actionName == 'index' }.constraints*.propertyName == ['bookId', 'sellerId', 'format']
+ locationsMappings.find { it.actionName == 'create' }.constraints*.propertyName == ['bookId', 'sellerId']
+ locationsMappings.find { it.actionName == 'save' }.constraints*.propertyName == ['bookId', 'sellerId', 'format']
+ locationsMappings.find { it.actionName == 'show' }.constraints*.propertyName == ['bookId', 'sellerId', 'id', 'format']
+ locationsMappings.find { it.actionName == 'edit' }.constraints*.propertyName == ['bookId', 'sellerId', 'id']
+ locationsMappings.find { it.actionName == 'update' }.constraints*.propertyName == ['bookId', 'sellerId', 'id', 'format']
+ locationsMappings.find { it.actionName == 'delete' }.constraints*.propertyName == ['bookId', 'sellerId', 'id', 'format']
+ }
+
void "Test that URL mappings with resources 3 levels deep works"() {
given:"A resources definition with nested URL mappings"
def urlMappingsHolder = getUrlMappingsHolder {

No commit comments for this range

Something went wrong with that request. Please try again.