void render()

in grails-controllers/src/main/groovy/grails/artefact/controller/support/ResponseRenderer.groovy [223:440]


    void render(Map argMap) {
        GrailsWebRequest webRequest = (GrailsWebRequest)RequestContextHolder.currentRequestAttributes()
        HttpServletResponse response = webRequest.currentResponse
        String layoutArg = argMap[ARGUMENT_LAYOUT]?.toString() ?: null
        boolean statusSet = handleStatusArgument(argMap, webRequest, response)


        def applicationAttributes = webRequest.attributes
        if (argMap.containsKey(ARGUMENT_TEXT)) {
            def textArg = argMap[ARGUMENT_TEXT]
            applyContentType response, argMap, textArg
            if (textArg instanceof Writable) {
                renderWritable((Writable)textArg, response)
                webRequest.renderView = false
            } else {
                CharSequence text = (textArg instanceof CharSequence) ? ((CharSequence)textArg) : textArg.toString()
                render text
            }
            setLayout webRequest.currentRequest, layoutArg
        }
        else if (argMap.containsKey(ARGUMENT_VIEW)) {
            String viewName = argMap[ARGUMENT_VIEW].toString()
            String viewUri = applicationAttributes.getNoSuffixViewURI((GroovyObject)this, viewName)
            String contextPath = getContextPath(webRequest, argMap)
            if(contextPath) {
                viewUri = contextPath + viewUri
            }
            Object modelObject = argMap[ARGUMENT_MODEL]
            if (modelObject) {
                Collection<ActionResultTransformer> resultTransformers = actionResultTransformers
                for (ActionResultTransformer resultTransformer : resultTransformers) {
                    modelObject = resultTransformer.transformActionResult webRequest,viewUri, modelObject
                }
            }

            applyContentType webRequest.currentResponse, argMap, null, false

            Map model
            if (modelObject instanceof Map) {
                model = (Map) modelObject
            }
            else {
                model = [:]
            }

            ((GroovyObject)this).setProperty "modelAndView", new ModelAndView(viewUri, model)
            setLayout webRequest.currentRequest, layoutArg
        }
        else if (argMap.containsKey(ARGUMENT_TEMPLATE)) {
            applyContentType response, argMap, null, false
            webRequest.renderView = false
            boolean hasModel = argMap.containsKey(ARGUMENT_MODEL)
            def modelObject
            if(hasModel) {
                modelObject = argMap[ARGUMENT_MODEL]
            }
            String templateName = argMap[ARGUMENT_TEMPLATE].toString()
            String var
            if (argMap.containsKey(ARGUMENT_VAR)) {
                var = String.valueOf( argMap[ARGUMENT_VAR] )
            }

            // get the template uri
            String templateUri = applicationAttributes.getTemplateURI((GroovyObject)this, templateName, false)

            // retrieve view resolver
            def applicationContext = applicationAttributes.getApplicationContext()
            def viewResolver = applicationContext.getBean(CompositeViewResolver.BEAN_NAME, CompositeViewResolver)
            try {

                View view = viewResolver.resolveView(templateUri, webRequest.locale)
                if(view instanceof GroovyPageView) {
                    ((GroovyPageTemplate)((GroovyPageView)view).template).allowSettingContentType = true
                }
                if (view == null) {
                    throw new ControllerExecutionException("Unable to load template for uri [$templateUri]. Template not found.")
                }


                boolean renderWithLayout = (layoutArg || webRequest.getCurrentRequest().getAttribute(WebUtils.LAYOUT_ATTRIBUTE))
                // if automatic decoration occurred unwrap, since this is a partial

                if (renderWithLayout) {
                    setLayout webRequest.currentRequest, layoutArg
                }


                Map binding = [:]

                if (argMap.containsKey(ARGUMENT_BEAN)) {
                    Object bean = argMap[ARGUMENT_BEAN]
                    if (hasModel) {
                        if (modelObject instanceof Map) {
                            setTemplateModel webRequest, binding, (Map) modelObject
                        }
                    }
                    if (GrailsStringUtils.isBlank(var)) {
                        binding.put DEFAULT_ARGUMENT, bean
                    }
                    else {
                        binding.put var, bean
                    }
                    renderViewForTemplate webRequest, view, binding
                }
                else if (argMap.containsKey(ARGUMENT_COLLECTION)) {
                    Object colObject = argMap[ARGUMENT_COLLECTION]
                    if (hasModel) {
                        if (modelObject instanceof Map) {
                            setTemplateModel webRequest, binding, (Map)modelObject
                        }
                    }
                    renderTemplateForCollection webRequest, view, binding, colObject, var
                }
                else if (hasModel) {
                    if (modelObject instanceof Map) {
                        setTemplateModel webRequest, binding, (Map)modelObject
                    }
                    renderViewForTemplate webRequest, view, binding
                }
                else {
                    renderViewForTemplate webRequest, view, binding
                }
            }
            catch (GroovyRuntimeException gre) {
                throw new ControllerExecutionException("Error rendering template [$templateName]: ${gre.message}", gre)
            }
            catch (IOException ioex) {
                throw new ControllerExecutionException("I/O error executing render method for arguments [$argMap]: ${ioex.message}" , ioex)
            }
        }
        else if (argMap.containsKey(ARGUMENT_FILE)) {
            webRequest.renderView = false

            def o = argMap[ARGUMENT_FILE]
            def fnO = argMap[ARGUMENT_FILE_NAME]
            String fileName = fnO ? fnO.toString() : ((o instanceof File) ? ((File)o).name : null )
            if (o) {
                boolean hasContentType = applyContentType(response, argMap, null, false)
                if (fileName) {
                    if(!hasContentType) {
                        hasContentType = detectContentTypeFromFileName(webRequest, response, argMap, fileName)
                    }
                    if (fnO) {
                        response.setHeader HttpHeaders.CONTENT_DISPOSITION, "$DISPOSITION_HEADER_PREFIX\"$fileName\""
                    }
                }
                if (!hasContentType) {
                    throw new ControllerExecutionException(
                            "Argument [file] of render method specified without valid [contentType] argument")
                }

                InputStream input
                try {
                    if (o instanceof File) {
                        input = IOUtils.openStream(o)
                    }
                    else if (o instanceof InputStream) {
                        input = (InputStream)o
                    }
                    else if (o instanceof byte[]) {
                        input = new ByteArrayInputStream((byte[])o)
                    }
                    else {
                        input = IOUtils.openStream(new File(o.toString()))
                    }
                    SpringIOUtils.copy input, response.getOutputStream()
                } catch (IOException e) {
                    throw new ControllerExecutionException(
                            "I/O error copying file to response: ${e.message}", e)
                }
                finally {
                    if (input) {
                        try {
                            ((InputStream)input).close()
                        } catch (IOException e) {
                            // ignore
                        }
                    }
                }
            }
        }
        else if( !statusSet ) {
            webRequest.renderView = false
            if(argMap instanceof JSONElement) {
                response.contentType = GrailsWebUtil.getContentType(MimeType.JSON.name, DEFAULT_ENCODING)
                renderWritable( (JSONElement)argMap, response )
            }
            else {
                applyContentType response, argMap, argMap
                try {
                    response.writer.write argMap.inspect()
                }
                catch (IOException e) {
                    throw new ControllerExecutionException("I/O error obtaining response writer: ${e.message}", e)
                }
            }
        }
        else {
            // reached here so only the status was set, just send it back
            String message = argMap?.message?.toString()
            int statusCode = response.status
            if( message ) {
                response.sendError(statusCode, message  )
            }
            else {
                // if the status code is an error trigger the container
                // forwarding logic
                if(statusCode >= 300) {
                    response.sendError(statusCode)
                }
                else {
                    // otherwise just ensure the status is propagated to the client
                    response.setStatus(statusCode)
                    response.flushBuffer()
                }
            }
        }
    }