Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright 2004-2005 Graeme Rocher
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *      http://www.apache.org/licenses/LICENSE-2.0
    *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.codehaus.groovy.grails.web.mapping;
  
  
  import java.net.URI;
  import java.util.Arrays;
  import java.util.Deque;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import  javax.servlet.ServletContext;
  

A UrlMapping evaluator that evaluates Groovy scripts that are in the form:

 
 mappings {
    /$post/$year?/$month?/$day?" {
       controller = "blog"
       action = "show"
       constraints {
           year(matches:/\d{4}/)
           month(matches:/\d{2}/)
       }
    }
 }
 
 

Author(s):
Graeme Rocher
Since:
0.5
  
  
      public static final String ACTION_CREATE = "create";
      public static final String ACTION_INDEX = "index";
      public static final String ACTION_SHOW = "show";
      public static final String ACTION_EDIT = "edit";
      public static final String ACTION_UPDATE = "update";
      public static final String ACTION_DELETE = "delete";
      public static final String ACTION_SAVE = "save";
      private static final Log LOG = LogFactory.getLog(UrlMappingBuilder.class);
      private GroovyClassLoader classLoader = new GroovyClassLoader();
      private UrlMappingParser urlParser = new DefaultUrlMappingParser();
      private ServletContext servletContext;
      private static final String EXCEPTION = "exception";
      private static final String PARSE_REQUEST = "parseRequest";
     private static final String RESOURCE = "resource";
     private static final String RESOURCES = "resources";
 
     private WebApplicationContext applicationContext;


    

Deprecated:
Used DefaultUrLMappingsEvaluator(ApplicationContext) instead
Parameters:
servletContext The servlet context
 
     @Deprecated
     public DefaultUrlMappingEvaluator(ServletContext servletContext) {
         this. = servletContext;
     }
 
     public DefaultUrlMappingEvaluator(WebApplicationContext applicationContext) {
         if (applicationContext != null) {
             this. = applicationContext.getServletContext();
         }
         this. = applicationContext;
     }
 
     @SuppressWarnings({ "rawtypes""unchecked" })
     public List evaluateMappings(Resource resource) {
         InputStream inputStream = null;
         try {
             inputStream = resource.getInputStream();
             return evaluateMappings(.parseClass(IOGroovyMethods.getText(inputStream)));
         }
         catch (IOException e) {
             throw new UrlMappingException("Unable to read mapping file [" + resource.getFilename() + "]: " + e.getMessage(), e);
         }
         finally {
             IOUtils.closeQuietly(inputStream);
         }
     }
 
     @SuppressWarnings({"unchecked","rawtypes"})
     public List<UrlMappingevaluateMappings(Class theClass) {
         GroovyObject obj = (GroovyObject) BeanUtils.instantiateClass(theClass);
 
         if (obj instanceof Script) {
             Script script = (Scriptobj;
             Binding b = new Binding();
 
             MappingCapturingClosure closure = new MappingCapturingClosure(script);
             b.setVariable("mappings"closure);
             script.setBinding(b);
 
             script.run();
 
             Closure mappings = closure.getMappings();
 
             Binding binding = script.getBinding();
             return evaluateMappings(scriptmappingsbinding);
         }
 
         throw new UrlMappingException("Unable to configure URL mappings for class [" + theClass +
                 "]. A URL mapping must be an instance of groovy.lang.Script.");
     }
 
     private List<UrlMappingevaluateMappings(GroovyObject goClosure<?> mappingsBinding binding) {
         UrlMappingBuilder builder = new UrlMappingBuilder(binding);
         mappings.setDelegate(builder);
         mappings.call();
         builder.urlDefiningMode = false;
 
 
         return builder.getUrlMappings();
     }
 
     @SuppressWarnings("rawtypes")
     public List<UrlMappingevaluateMappings(Closure closure) {
         UrlMappingBuilder builder = new UrlMappingBuilder(null);
         closure.setDelegate(builder);
         closure.setResolveStrategy(.);
         if (closure.getParameterTypes().length == 0) {
             closure.call();
         }
         else {
             closure.call();
         }
         builder.urlDefiningMode = false;
         configureUrlMappingDynamicObjects(closure);
         return builder.getUrlMappings();
     }
 
     private void configureUrlMappingDynamicObjects(Object object) {
         if ( != null) {
             WebMetaUtils.registerCommonWebProperties(GrailsMetaClassUtils.getExpandoMetaClass(object.getClass()), null);
         }
     }
 
     public void setClassLoader(ClassLoader classLoader) {
         Assert.isInstanceOf(GroovyClassLoader.classclassLoader,
                "Property [classLoader] must be an instance of GroovyClassLoader");
         this. = (GroovyClassLoaderclassLoader;
     }
 
     public void setPluginManager(GrailsPluginManager pluginManager) {
         this. = pluginManager;
     }

    
A Closure that captures a call to a method that accepts a single closure
 
     @SuppressWarnings("rawtypes")
     class MappingCapturingClosure extends Closure {
 
         private static final long serialVersionUID = 2108155626252742722L;
         private Closure<?> mappings;
 
         public Closure<?> getMappings() {
             return ;
         }
 
         public MappingCapturingClosure(Object o) {
             super(o);
         }
 
         @Override
         public Object call(Object... args) {
             if (args.length > 0 && (args[0] instanceof Closure)) {
                  = (Closure<?>) args[0];
             }
             return null;
         }
     }

    

A modal builder that constructs a UrlMapping instances by executing a closure. The class overrides getProperty(name) and allows the substitution of GString values with the * wildcard.

invokeMethod(methodName, args) is also overriden for the creation of each UrlMapping instance

 
     @SuppressWarnings("rawtypes")
     class UrlMappingBuilder extends GroovyObjectSupport {
         private static final String CAPTURING_WILD_CARD = .;
         private static final String SLASH = "/";
         private static final String CONSTRAINTS = "constraints";
 
 
 
         private boolean urlDefiningMode = true;
         private List<UrlMappingurlMappings = new ArrayList<UrlMapping>();
         private Map<StringObjectparameterValues = new HashMap<StringObject>();
         private Binding binding;
         private Object actionName = null;
         private Object pluginName = null;
         private Object namespace = null;
         private Object controllerName = null;
         private Object viewName = null;
         private String httpMethod;
         private ServletContext sc;
         private Object exception;
         private Object parseRequest;
         private Object uri;
         private Object redirectInfo;
         private Deque<ParentResourceparentResources = new ArrayDeque<ParentResource>();
 
         public UrlMappingBuilder(Binding binding, ServletContext servletContext) {
             this. = binding;
              = servletContext;
         }
 
         public List<UrlMappinggetUrlMappings() {
             return ;
         }
 
         public ServletContext getServletContext() {
             return ;
         }
 
         public ApplicationContext getApplicationContext() {
             return WebApplicationContextUtils.getRequiredWebApplicationContext();
         }
 
         public GrailsApplication getGrailsApplication() {
         }
 
         @Override
         public Object getProperty(String name) {
             if () {
                 getCurrentConstraints().add(new ConstrainedProperty(UrlMapping.classnameString.class));
                 return ;
             }
             return super.getProperty(name);
         }
 
         public Object getException() {
             return ;
         }
 
         public void setException(Object exception) {
             this. = exception;
         }
 
         public Object getUri() {
             return ;
         }
 
         public void setUri(Object uri) {
             this. = uri;
         }
 
         public void setAction(Object action) {
              = action;
         }
 
         public Object getAction() {
             return ;
         }
 
         public void setController(Object controller) {
              = controller;
         }
 
         public Object getController() {
             return ;
         }
 
         public void setRedirectInfo(Object redirectInfo) {
             this. = redirectInfo;
         }
 
         public Object getRedirectInfo() {
             return ;
         }
 
         public void setPlugin(Object plugin) {
              = plugin;
         }
 
         public Object getPlugin() {
             return ;
         }
 
         public void setNamespace(Object namespace) {
             this. = namespace;
         }
 
         public Object getNamespace() {
             return ;
         }
 
         public Object getView() {
             return ;
         }
 
         public void setView(String viewName) {
             this. = viewName;
         }
 
         public void name(Map<StringUrlMappingm) {
             for (Map.Entry<StringUrlMappingentrym.entrySet()) {
                 entry.getValue().setMappingName(entry.getKey());
             }
         }

        
Define a group

Parameters:
uri The URI
mappings The mappings
 
         public void group(String uriClosure mappings) {
 
             try {
                 .push(new ParentResource(nulluri,true));
                 mappings.call();
             } finally {
                 .pop();
             }
         }
 
         @Override
         public Object invokeMethod(String methodNameObject arg) {
             if ( == null) {
                 return invokeMethodClosure(methodNamearg);
             }
             return invokeMethodScript(methodNamearg);
         }
 
         private Object invokeMethodScript(String methodNameObject arg) {
             return _invoke(methodNameargnull);
         }
 
         private Object invokeMethodClosure(String methodNameObject arg) {
             return _invoke(methodNameargthis);
         }
 
         void propertyMissing(String nameObject value) {
             .put(namevalue);
         }
 
         Object propertyMissing(String name) {
             return .get(name);
         }
 
         private Object _invoke(String methodNameObject argObject delegate) {
             Object[] args = (Object[]) arg;
             String mappedURI = establishFullURI(methodName);
             final boolean isResponseCode = isResponseCode(mappedURI);
             if (mappedURI.startsWith() || isResponseCode) {
                 // Create a new parameter map for this mapping.
                  = new HashMap<StringObject>();
                 Map variables =  != null ? .getVariables() : null;
                 try {
                      = false;
                     args = args != null && args.length > 0 ? args : new Object[]{.};
                     if (args[0] instanceof Closure) {
                         UrlMappingData urlData = createUrlMappingData(mappedURIisResponseCode);
 
                         Closure callable = (Closureargs[0];
                         if (delegate != null) {
                             callable.setDelegate(delegate);
                         }
                         callable.call();
 
                         Object controllerName;
                         Object actionName;
                         Object pluginName;
                         String httpMethod = null;
                         String version = null;
                         Object namespace;
                         Object viewName;
                         Object uri;
                         Object redirectInfo = null;
 
                         if ( != null) {
                             controllerName = variables.get(.);
                             actionName = variables.get(.);
                             viewName = variables.get(.);
                             uri = variables.get(.);
                             pluginName = variables.get(.);
                             namespace = variables.get(.);
                             if (variables.containsKey(.)) {
                                 httpMethod = variables.get(.).toString();
                             }
 
                         } else {
                             controllerName = this.;
                             redirectInfo = this.;
                             actionName = this.;
                             pluginName = this.;
                             namespace = this.;
                             viewName = this.;
                             uri = this.;
                             httpMethod = this.;
                         }
 
                         ConstrainedProperty[] constraints = getCurrentConstraints().toArray(new ConstrainedProperty[getCurrentConstraints().size()]);
                         UrlMapping urlMapping;
                         if (uri != null) {
                             try {
                                 urlMapping = new RegexUrlMapping(urlDatanew URI(uri.toString()), constraints);
                             } catch (URISyntaxException e) {
                                 throw new UrlMappingException("Cannot map to invalid URI: " + e.getMessage(), e);
                             }
                         } else {
                             urlMapping = createURLMapping(urlDataisResponseCoderedirectInfocontrollerNameactionNamenamespacepluginNameviewNamehttpMethodversion,constraints);
                         }
 
                         if ( != null) {
                             Map bindingVariables = variables;
                             Object parse = getParseRequest(.bindingVariables);
                             if (parse instanceof Boolean) {
                                 urlMapping.setParseRequest((Booleanparse);
                             }
                         }
                         configureUrlMapping(urlMapping);
                         return urlMapping;
                     }
 
                     if (args[0] instanceof Map) {
                         Map namedArguments = (Mapargs[0];
                         String uri = mappedURI;
                         String version = null;
 
                         if (namedArguments.containsKey(.)) {
                             version = namedArguments.get(.).toString();
                         }
                         if (namedArguments.containsKey(.)) {
                              = namedArguments.get(.).toString();
                         }
 
                         UrlMappingData urlData = createUrlMappingData(uriisResponseCode);
 
                         if (namedArguments.containsKey()) {
                             Object controller = namedArguments.get();
                             String controllerName = controller.toString();
                             .push(new ParentResource(controllerNameurigetCurrentConstraints(), true));
                             try {
                                 invokeLastArgumentIfClosure(args);
                             } finally {
                                 .pop();
                             }
                             if (controller != null) {
 
                                 createSingleResourceRestfulMappings(controllerNameversionurlDatagetCurrentConstraints(), calculateIncludes(namedArguments));
                             }
                         } else if (namedArguments.containsKey()) {
                             Object controller = namedArguments.get();
                             String controllerName = controller.toString();
                             .push(new ParentResource(controllerNameurigetCurrentConstraints(), false));
                             try {
                                 invokeLastArgumentIfClosure(args);
                             } finally {
                                 .pop();
                             }
                             if (controller != null) {
                                 createResourceRestfulMappings(controllerName,version,urlDatagetCurrentConstraints(), calculateIncludes(namedArguments));
                             }
                         } else {
 
                             invokeLastArgumentIfClosure(args);
                             UrlMapping urlMapping = getURLMappingForNamedArgs(namedArgumentsurlDatamappedURIisResponseCode);
                             configureUrlMapping(urlMapping);
                             return urlMapping;
                         }
                     }
                     return null;
                 } finally {
                     if ( != null) {
                         variables.clear();
                     } else {
                          = null;
                          = null;
                          = null;
                          = null;
                          = null;
                          = null;
                     }
                     if (.isEmpty()) {
                         .clear();
                          = true;
                     }
                 }
             } else if (! && .equals(mappedURI)) {
                 ConstrainedPropertyBuilder builder = new ConstrainedPropertyBuilder(this);
                 if (args.length > 0 && (args[0] instanceof Closure)) {
 
                     Closure callable = (Closureargs[0];
                     callable.setDelegate(builder);
                     for (ConstrainedProperty constrainedProperty : getCurrentConstraints()) {
                         builder.getConstrainedProperties().put(constrainedProperty.getPropertyName(), constrainedProperty);
                     }
                     callable.call();
                 }
                 return builder.getConstrainedProperties();
             } else {
                 return super.invokeMethod(mappedURIarg);
             }
         }
 
 
         private List<StringcalculateIncludes(Map namedArgumentsList<StringdefaultResourcesIncludes) {
             List<Stringincludes = new ArrayList<String>(defaultResourcesIncludes);
 
             Object excludesObject = namedArguments.get("excludes");
             if (excludesObject != null ) {
                 if (excludesObject instanceof List) {
 
                     List excludeList = (ListexcludesObject;
                     for (Object exc : excludeList) {
                         if (exc != null) {
                             String excStr = exc.toString().toLowerCase();
                             includes.remove(excStr);
                         }
                     }
                 }
                 else {
                     includes.remove(excludesObject.toString());
                 }
             }
             Object includesObject = namedArguments.get("includes");
             if (includesObject != null) {
                 if (includesObject instanceof List) {
 
                     List includeList = (ListincludesObject;
                     includes.clear();
                     for (Object inc : includeList) {
                         if (inc != null) {
                             String incStr = inc.toString().toLowerCase();
                             includes.add(incStr);
                         }
                     }
                 }
                 else {
                     includes.clear();
                     includes.add(includesObject.toString());
                 }
             }
             return includes;
         }
 
         private String establishFullURI(String uri) {
             if (.isEmpty()) {
                 return uri;
             }
 
             StringBuilder uriBuilder = new StringBuilder();
             ParentResource parentResource = .peek();
             if (parentResource.isSingle) {
                 uriBuilder.append(parentResource.uri);
             }
             else {
                 if (parentResource.controllerName != null) {
                     uriBuilder.append(parentResource.uri).append().append();
                     getCurrentConstraints().add(new ConstrainedProperty(UrlMapping.classparentResource.controllerName + "Id"String.class));
                 }
             }
 
             uriBuilder.append(uri);
             return uriBuilder.toString();
         }
 
         private void invokeLastArgumentIfClosure(Object[] args) {
             if (args.length > 1 && args[1] instanceof Closure) {
                 ((Closureargs[1]).call();
             }
         }
 
         protected void createResourceRestfulMappings(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraintsList<Stringincludes) {
             ConstrainedProperty[] constraintArray = previousConstraints.toArray(new ConstrainedProperty[previousConstraints.size()]);
 
             if (includes.contains()) {
                 // GET /$controller -> action:'index'
                 UrlMapping listUrlMapping = createIndexActionResourcesRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(listUrlMapping);
             }
 
             if (includes.contains()) {
                 // GET /$controller/create -> action:'create'
                 UrlMapping createUrlMapping = createCreateActionResourcesRestfulMapping(controllerNamepluginName,namespaceversionurlDataconstraintArray);
                 configureUrlMapping(createUrlMapping);
             }
 
             if (includes.contains()) {
                 // POST /$controller -> action:'save'
                 UrlMapping saveUrlMapping = createSaveActionResourcesRestfulMapping(controllerNamepluginNamenamespace,versionurlDatapreviousConstraints);
                 configureUrlMapping(saveUrlMapping);
             }
 
             if (includes.contains()) {
                 // GET /$controller/$id -> action:'show'
                 UrlMapping showUrlMapping = createShowActionResourcesRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(showUrlMapping);
             }
 
             if (includes.contains()) {
                 // GET /$controller/$id/edit -> action:'edit'
                 UrlMapping editUrlMapping = createEditActionResourcesRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(editUrlMapping);
             }
 
             if (includes.contains()) {
                 // PUT /$controller/$id -> action:'update'
                 UrlMapping updateUrlMapping = createUpdateActionResourcesRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(updateUrlMapping);
             }
 
             if (includes.contains()) {
                 // DELETE /$controller/$id -> action:'delete'
                 UrlMapping deleteUrlMapping = createDeleteActionResourcesRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(deleteUrlMapping);
             }
         }
 
         protected UrlMapping createDeleteActionResourcesRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraints) {
             UrlMappingData deleteUrlMappingData = createRelativeUrlDataWithIdAndFormat(urlData);
             List<ConstrainedPropertydeleteUrlMappingConstraints = createConstraintsWithIdAndFormat(previousConstraints);
 
             return new RegexUrlMapping(deleteUrlMappingData,controllerNamenamespacepluginNamenull..toString(), version,deleteUrlMappingConstraints.toArray(new ConstrainedProperty[deleteUrlMappingConstraints.size()]) , );
         }
 
         protected UrlMapping createUpdateActionResourcesRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraints) {
             UrlMappingData updateUrlMappingData = createRelativeUrlDataWithIdAndFormat(urlData);
             List<ConstrainedPropertyupdateUrlMappingConstraints = createConstraintsWithIdAndFormat(previousConstraints);
 
             return new RegexUrlMapping(updateUrlMappingData,controllerName,  namespacepluginNamenull..toString(),version,updateUrlMappingConstraints.toArray(new ConstrainedProperty[updateUrlMappingConstraints.size()]) , );
         }
 
         protected UrlMapping createEditActionResourcesRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraints) {
             UrlMappingData editUrlMappingData = urlData.createRelative('/' +  + "/edit");
             List<ConstrainedPropertyeditUrlMappingConstraints = new ArrayList<ConstrainedProperty>(previousConstraints);
             editUrlMappingConstraints.add(new ConstrainedProperty(UrlMapping.class"id"String.class));
 
             return new RegexUrlMapping(editUrlMappingData,controllerNamenamespacepluginNamenull..toString(), version,editUrlMappingConstraints.toArray(new ConstrainedProperty[editUrlMappingConstraints.size()]) , );
         }
 
         protected UrlMapping createShowActionResourcesRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraints) {
             UrlMappingData showUrlMappingData = createRelativeUrlDataWithIdAndFormat(urlData);
             List<ConstrainedPropertyshowUrlMappingConstraints = createConstraintsWithIdAndFormat(previousConstraints);
 
             return new RegexUrlMapping(showUrlMappingData,controllerNamenamespacepluginNamenull..toString(), version,showUrlMappingConstraints.toArray(new ConstrainedProperty[showUrlMappingConstraints.size()]) , );
         }
 
         private List<ConstrainedPropertycreateConstraintsWithIdAndFormat(List<ConstrainedPropertypreviousConstraints) {
             List<ConstrainedPropertyshowUrlMappingConstraints = new ArrayList<ConstrainedProperty>(previousConstraints);
             showUrlMappingConstraints.add(new ConstrainedProperty(UrlMapping.class"id"String.class));
             ConstrainedProperty cp = new ConstrainedProperty(UrlMapping.class"format"String.class);
             cp.setNullable(true);
             showUrlMappingConstraints.add(cp);
             return showUrlMappingConstraints;
         }
 
             return urlData.createRelative('/' +  + . + .);
         }
         private UrlMappingData createFormatOnlyUrlMappingData(UrlMappingData urlData) {
             return urlData.createRelative(. + .);
         }
 
 
         protected UrlMapping createSaveActionResourcesRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertyconstraints) {
             UrlMappingData saveActionUrlMappingData = urlData.createRelative(. + .);
             List<ConstrainedPropertysaveUrlMappingConstraints = createFormatOnlyConstraints(constraints);
 
             return new RegexUrlMapping(saveActionUrlMappingData,controllerNamenamespacepluginNamenull..toString(),version,saveUrlMappingConstraints.toArray(new ConstrainedProperty[saveUrlMappingConstraints.size()]), );
         }
 
         protected UrlMapping createCreateActionResourcesRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataConstrainedProperty[] constraintArray) {
             UrlMappingData createMappingData = urlData.createRelative("/create");
             return new RegexUrlMapping(createMappingData,controllerNamenamespacepluginNamenull..toString(), version,constraintArray);
         }
 
         protected UrlMapping createIndexActionResourcesRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertyconstraints) {
             UrlMappingData indexActionUrlMappingData = urlData.createRelative(. + .);
             List<ConstrainedPropertyindexUrlMappingConstraints = createFormatOnlyConstraints(constraints);
 
             return new RegexUrlMapping(indexActionUrlMappingDatacontrollerNamenamespacepluginNamenull..toString(), version,indexUrlMappingConstraints.toArray(new ConstrainedProperty[indexUrlMappingConstraints.size()]), );
         }
 
         private List<ConstrainedPropertycreateFormatOnlyConstraints(List<ConstrainedPropertyconstraints) {
             List<ConstrainedPropertyindexUrlMappingConstraints = new ArrayList<ConstrainedProperty>(constraints);
             ConstrainedProperty cp = new ConstrainedProperty(UrlMapping.class"format"String.class);
             cp.setNullable(true);
             indexUrlMappingConstraints.add(cp);
             return indexUrlMappingConstraints;
         }

        
Takes a controller and creates the necessary URL mappings for a singular RESTful resource

Parameters:
controllerName The controller name
pluginName The name of the plugin
namespace
version
urlData The urlData instance
previousConstraints Any constraints
includes
 
         protected void createSingleResourceRestfulMappings(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraintsList<Stringincludes) {
 
             ConstrainedProperty[] constraintArray = previousConstraints.toArray(new ConstrainedProperty[previousConstraints.size()]);
 
             if (includes.contains()) {
                 // GET /$controller/create -> action: 'create'
                 UrlMapping createUrlMapping = createCreateActionResourcesRestfulMapping(controllerNamepluginNamenamespace,versionurlDataconstraintArray);
                 configureUrlMapping(createUrlMapping);
             }
 
             if (includes.contains()) {
                 // POST /$controller -> action:'save'
                 UrlMapping saveUrlMapping = createSaveActionResourcesRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(saveUrlMapping);
             }
 
             if (includes.contains()) {
                 // GET /$controller -> action:'show'
                 UrlMapping showUrlMapping = createShowActionResourceRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(showUrlMapping);
             }
 
             if (includes.contains()) {
                 // GET /$controller/edit -> action:'edit'
                 UrlMapping editUrlMapping = createEditctionResourceRestfulMapping(controllerNamepluginNamenamespace,version,urlDataconstraintArray);
                 configureUrlMapping(editUrlMapping);
             }
 
             if (includes.contains()) {
                 // PUT /$controller -> action:'update'
                 UrlMapping updateUrlMapping = createUpdateActionResourceRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(updateUrlMapping);
             }
 
             if (includes.contains()) {
                 // DELETE /$controller -> action:'delete'
                 UrlMapping deleteUrlMapping = createDeleteActionResourceRestfulMapping(controllerNamepluginNamenamespace,version,urlDatapreviousConstraints);
                 configureUrlMapping(deleteUrlMapping);
             }
         }
 
         protected UrlMapping createDeleteActionResourceRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraints) {
             UrlMappingData deleteUrlMappingData = createFormatOnlyUrlMappingData(urlData);
             List<ConstrainedPropertydeleteUrlMappingConstraints = createFormatOnlyConstraints(previousConstraints);
 
             return new RegexUrlMapping(deleteUrlMappingData,controllerNamenullpluginNamenull..toString(), versiondeleteUrlMappingConstraints.toArray(new ConstrainedProperty[deleteUrlMappingConstraints.size()]) , );
         }
 
         protected UrlMapping createUpdateActionResourceRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraints) {
             UrlMappingData updateUrlMappingData = createFormatOnlyUrlMappingData(urlData);
             List<ConstrainedPropertyupdateUrlMappingConstraints = createFormatOnlyConstraints(previousConstraints);
 
             return new RegexUrlMapping(updateUrlMappingData,controllerNamenullpluginNamenull..toString(),versionupdateUrlMappingConstraints.toArray(new ConstrainedProperty[updateUrlMappingConstraints.size()]) , );
         }
 
         protected UrlMapping createEditctionResourceRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataConstrainedProperty[] constraintArray) {
             UrlMappingData editMappingData = urlData.createRelative("/edit");
             return new RegexUrlMapping(editMappingData,controllerName,nullpluginNamenull..toString(),versionconstraintArray);
         }
 
         protected UrlMapping createShowActionResourceRestfulMapping(String controllerNameObject pluginNameObject namespaceString versionUrlMappingData urlDataList<ConstrainedPropertypreviousConstraints) {
             UrlMappingData showUrlMappingData = createFormatOnlyUrlMappingData(urlData);
             List<ConstrainedPropertyshowUrlMappingConstraints = createFormatOnlyConstraints(previousConstraints);
 
             return new RegexUrlMapping(showUrlMappingData,controllerName,nullpluginNamenull..toString(), versionshowUrlMappingConstraints.toArray(new ConstrainedProperty[showUrlMappingConstraints.size()]) , );
         }
 
         @SuppressWarnings("unchecked")
         private void configureUrlMapping(UrlMapping urlMapping) {
             if ( != null) {
                 Map<StringObjectvars = .getVariables();
                 for (String key : vars.keySet()) {
                     if (isNotCoreMappingKey(key)) {
                         .put(keyvars.get(key));
                     }
                 }
 
                 .getVariables().clear();
             }
 
             // Add the controller and action to the params map if
             // they are set. This ensures consistency of behaviour
             // for the application, i.e. "controller" and "action"
             // parameters will always be available to it.
             if (urlMapping.getControllerName() != null) {
                 .put("controller"urlMapping.getControllerName());
             }
             if (urlMapping.getActionName() != null) {
                 .put("action"urlMapping.getActionName());
             }
 
             urlMapping.setParameterValues();
             .add(urlMapping);
         }
 
         private boolean isNotCoreMappingKey(Object key) {
             return !..equals(key) &&
                    !..equals(key) &&
                    !..equals(key);
         }
 
         private UrlMappingData createUrlMappingData(String methodNameboolean responseCode) {
             if (!responseCode) {
                 return .parse(methodName);
             }
 
             return new ResponseCodeMappingData(methodName);
         }
 
         private boolean isResponseCode(String s) {
             for (int count = s.length(), i = 0; i < counti++) {
                 if (!Character.isDigit(s.charAt(i))) return false;
             }
 
             return true;
         }
 
         private UrlMapping getURLMappingForNamedArgs(Map namedArguments,
                 UrlMappingData urlDataString mappingboolean isResponseCode) {
             Object controllerName;
             Object actionName;
             final Map bindingVariables =  != null ? .getVariables() : null;
             controllerName = getControllerName(namedArgumentsbindingVariables);
             actionName = getActionName(namedArgumentsbindingVariables);
             Object pluginName = getPluginName(namedArgumentsbindingVariables);
             Object httpMethod = getHttpMethod(namedArgumentsbindingVariables);
             Object version = getVersion(namedArgumentsbindingVariables);
             Object namespace = getNamespace(namedArgumentsbindingVariables);
             Object redirectInfo = getRedirectInfo(namedArgumentsbindingVariables);
 
             Object viewName = getViewName(namedArgumentsbindingVariables);
             if (actionName != null && viewName != null) {
                 viewName = null;
                 .warn("Both [action] and [view] specified in URL mapping [" + mapping + "]. The action takes precendence!");
             }
 
             Object uri = getURI(namedArgumentsbindingVariables);
             ConstrainedProperty[] constraints = getCurrentConstraints().toArray(new ConstrainedProperty[getCurrentConstraints().size()]);
 
             UrlMapping urlMapping;
             if (uri != null) {
                 try {
                     urlMapping = new RegexUrlMapping(urlDatanew URI(uri.toString()), constraints);
                 }
                 catch (URISyntaxException e) {
                     throw new UrlMappingException("Cannot map to invalid URI: " + e.getMessage(), e);
                 }
             }
             else {
                 urlMapping = createURLMapping(urlDataisResponseCoderedirectInfocontrollerNameactionNamenamespacepluginNameviewNamehttpMethod != null ? httpMethod.toString() : nullversion != null ? version.toString() : nullconstraints);
             }
 
             Object exceptionArg = getException(namedArgumentsbindingVariables);
 
             if (isResponseCode && exceptionArg != null) {
                 if (exceptionArg instanceof Class) {
                     Class exClass = (ClassexceptionArg;
                     if (Throwable.class.isAssignableFrom(exClass)) {
                         ((ResponseCodeUrlMapping)urlMapping).setExceptionType(exClass);
                     }
                     else {
                         .error("URL mapping argument [exception] with value ["exceptionArg +"] must be a subclass of java.lang.Throwable");
                     }
                 }
                 else {
                     .error("URL mapping argument [exception] with value [" + exceptionArg + "] must&n