private internalRespond()

in grails-rest-transforms/src/main/groovy/grails/artefact/controller/RestResponder.groovy [127:225]


    private internalRespond(value, Map args=[:]) {
        Integer statusCode
        if (args.status) {
            final statusValue = args.status
            if (statusValue instanceof Number) {
                statusCode = statusValue.intValue()
            } else {
                if (statusValue instanceof HttpStatus) {
                    statusCode = ((HttpStatus)statusValue).value()
                } else {
                    statusCode = statusValue.toString().toInteger()
                }
            }
        }
        if (value == null) {
            return callRender([status:statusCode ?: 404 ])
        }

        if (proxyHandler != null) {
            value = proxyHandler.unwrapIfProxy(value)
        }

        final webRequest = ((Controller)this).getWebRequest()
        List<String> formats = calculateFormats(webRequest.actionName, value, args)
        final response = webRequest.getCurrentResponse()
        MimeType[] mimeTypes = getResponseFormat(response)
        def registry = rendererRegistry
        if (registry == null) {
            registry = new DefaultRendererRegistry()
            registry.initialize()
        }

        Renderer renderer = null

        for(MimeType mimeType in mimeTypes) {
            if (mimeType == MimeType.ALL && formats) {
                final allMimeTypes = MimeType.getConfiguredMimeTypes()
                final firstFormat = formats[0]
                mimeType = allMimeTypes.find { MimeType mt -> mt.extension == firstFormat}
                if(mimeType) {
                    webRequest.currentRequest.setAttribute(GrailsApplicationAttributes.RESPONSE_MIME_TYPE, mimeType)
                }
            }

            if (mimeType && formats.contains(mimeType.extension)) {
                Errors errors = value.hasProperty(GormProperties.ERRORS) ? getDomainErrors(value) : null


                if (errors && errors.hasErrors()) {
                    def target = errors instanceof BeanPropertyBindingResult ? errors.getTarget() : null
                    if (proxyHandler != null && target != null) {
                        target = proxyHandler.unwrapIfProxy(target)
                    }
                    Renderer<Errors> errorsRenderer = registry.findContainerRenderer(mimeType, Errors.class, target)
                    if (errorsRenderer) {
                        final context = new ServletRenderContext(webRequest, [model: args.model])
                        if (args.view) {
                            context.viewName = args.view as String
                        }
                        if(statusCode != null) {
                            context.setStatus(HttpStatus.valueOf(statusCode))
                        }
                        errorsRenderer.render(errors, context)
                        if(context.wasWrittenTo() && !response.isCommitted()) {
                            response.flushBuffer()
                        }
                        return
                    }

                    return callRender([status: statusCode ?: 404 ])
                }

                final valueType = value.getClass()
                if (registry.isContainerType(valueType)) {
                    renderer = registry.findContainerRenderer(mimeType, valueType, value)
                    if (renderer == null) {
                        renderer = registry.findRenderer(mimeType, value)
                    }
                } else {
                    renderer = registry.findRenderer(mimeType, value)
                }
            }

            if(renderer) break
        }

        if (renderer) {
            final context = new ServletRenderContext(webRequest, args)
            if(statusCode != null) {
                context.setStatus(HttpStatus.valueOf(statusCode))
            }
            renderer.render(value, context)
            if(context.wasWrittenTo() && !response.isCommitted()) {
                response.flushBuffer()
            }
            return
        }
        callRender([status: statusCode ?: HttpStatus.NOT_ACCEPTABLE.value() ])
    }