Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2004-2005 the original author or authors.
   *
   * 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.metaclass;
 
 
 import java.io.File;
 import java.io.Writer;
 import java.util.Map;
 
 import  javax.servlet.http.HttpServletRequest;
 import  javax.servlet.http.HttpServletResponse;
 
Allows rendering of text, views, and templates to the response

Author(s):
Graeme Rocher
Since:
0.2
 
 @SuppressWarnings({"unchecked","rawtypes"})
     public static final String METHOD_SIGNATURE = "render";
     public static final Pattern METHOD_PATTERN = Pattern.compile('^' +  + '$');
 
     public static final String ARGUMENT_TEXT = "text";
     public static final String ARGUMENT_STATUS = "status";
     public static final String ARGUMENT_LAYOUT = "layout";
     public static final String ARGUMENT_CONTENT_TYPE = "contentType";
     public static final String ARGUMENT_ENCODING = "encoding";
     public static final String ARGUMENT_VIEW = "view";
     public static final String ARGUMENT_MODEL = "model";
     public static final String ARGUMENT_TEMPLATE = "template";
     public static final String ARGUMENT_CONTEXTPATH = "contextPath";
     public static final String ARGUMENT_BEAN = "bean";
     public static final String ARGUMENT_COLLECTION = "collection";
     public static final String ARGUMENT_BUILDER = "builder";
     public static final String ARGUMENT_VAR = "var";
    private static final String DEFAULT_ARGUMENT = "it";
    private static final String BUILDER_TYPE_JSON = "json";
    private static final String TEXT_HTML = "text/html";
    private static final String APPLICATION_XML = "application/xml";
    public static final String DISPOSITION_HEADER_PREFIX = "attachment;filename=";
    private String gspEncoding = ;
    private static final String DEFAULT_ENCODING = "utf-8";
    private Object ARGUMENT_PLUGIN = "plugin";
    private static final String ARGUMENT_FILE = "file";
    private static final String ARGUMENT_FILE_NAME = "fileName";
    private MimeUtility mimeUtility;
    public RenderDynamicMethod() {
        super();
    }
    public void setGspEncoding(String gspEncoding) {
        this. = gspEncoding;
    }
    @Override
    public Object invoke(Object targetString methodNameObject[] arguments) {
        if (arguments.length == 0) {
            throw new MissingMethodException(target.getClass(), arguments);
        }
        GrailsWebRequest webRequest = (GrailsWebRequest) RequestContextHolder.currentRequestAttributes();
        HttpServletResponse response = webRequest.getCurrentResponse();
        boolean renderView = true;
        GroovyObject controller = (GroovyObjecttarget;
        
        String explicitSiteMeshLayout = null;
        
        final Object renderArgument = arguments[0];
        if (renderArgument instanceof Converter<?>) {
            renderView = renderConverter((Converter<?>)renderArgumentresponse);
        } else if (renderArgument instanceof Writable) {
            applyContentType(responsenullrenderArgument);
            Writable writable = (Writable)renderArgument;
            renderView = renderWritable(writableresponse);
        } else if (renderArgument instanceof CharSequence) {
            applyContentType(responsenullrenderArgument);
            CharSequence text = (CharSequence)renderArgument;
            renderView = renderText(textresponse);
        }
        else {
            final Object renderObject = arguments[arguments.length - 1];
            if (renderArgument instanceof Closure) {
                setContentType(responsetrue);
                Closure closure = (ClosurerenderObject;
                renderView = renderMarkup(closureresponse);
            }
            else if (renderArgument instanceof Map) {
                Map argMap = (MaprenderArgument;
                
                if (argMap.containsKey()) {
                    explicitSiteMeshLayout = String.valueOf(argMap.get());
                }
                boolean statusSet = false;
                if (argMap.containsKey()) {
                    Object statusObj = argMap.get();
                    if (statusObj != null) {
                        try {
                            final int statusCode = statusObj instanceof Number ? ((Number)statusObj).intValue() : Integer.parseInt(statusObj.toString());
                            response.setStatus(statusCode);
                            statusSet = true;
                        }
                        catch (NumberFormatException e) {
                            throw new ControllerExecutionException(
                                    "Argument [status] of method [render] must be a valid integer.");
                        }
                    }
                }
                
                if (renderObject instanceof Writable) {
                    Writable writable = (WritablerenderObject;
                    applyContentType(responseargMaprenderObject);
                    renderView = renderWritable(writableresponse);
                } 
                else if (renderObject instanceof Closure) {
                    Closure callable = (ClosurerenderObject;
                    applyContentType(responseargMaprenderObject);
                    if (.equals(argMap.get()) || isJSONResponse(response)) {
                        renderView = renderJSON(callableresponse);
                    }
                    else {
                        renderView = renderMarkup(callableresponse);
                    }
                }
                else if (renderObject instanceof CharSequence) {
                    applyContentType(responseargMaprenderObject);
                    CharSequence text = (CharSequencerenderObject;
                    renderView = renderText(textresponse);
                }
                else if (argMap.containsKey()) {
                    Object textArg = argMap.get();
                    applyContentType(responseargMaptextArg);
                    if (textArg instanceof Writable) {
                        Writable writable = (WritabletextArg;
                        renderView = renderWritable(writableresponse);
                    } else {                    
                        CharSequence text = (textArg instanceof CharSequence) ? ((CharSequence)textArg) : textArg.toString();
                        renderView = renderText(textresponse);
                    }
                }
                else if (argMap.containsKey()) {
                    renderView(webRequestargMaptargetcontroller);
                }
                else if (argMap.containsKey()) {
                    applyContentType(responseargMapnullfalse);
                    renderView = renderTemplate(targetcontrollerwebRequestargMapexplicitSiteMeshLayout);
                }
                else if (argMap.containsKey()) {
                    renderView = false;
                    Object o = argMap.get();
                    Object fnO = argMap.get();
                    String fileName = fnO != null ? fnO.toString() : ((o instanceof File) ? ((File)o).getName(): null );
                    if (o != null) {
                        boolean hasContentType = applyContentType(responseargMapnullfalse);
                        if (fileName != null) {
                            if(!hasContentType) {
                                hasContentType = detectContentTypeFromFileName(webRequestresponseargMapfileName);
                            }
                            if (fnO != null) {
                                response.setHeader(. + fileName);
                            }
                        }
                        if (!hasContentType) {
                            throw new ControllerExecutionException(
                                    "Argument [file] of render method specified without valid [contentType] argument");
                        }
                        InputStream input = null;
                        try {
                            if (o instanceof File) {
                                File f = (Fileo;
                                input = GrailsIOUtils.openStream(f);
                            }
                            else if (o instanceof InputStream) {
                                input = (InputStreamo;
                            }
                            else if (o instanceof byte[]) {
                                input = new ByteArrayInputStream((byte[])o);
                            }
                            else {
                                input = GrailsIOUtils.openStream(new File(o.toString()));
                            }
                            IOUtils.copy(inputresponse.getOutputStream());
                        } catch (IOException e) {
                            throw new ControllerExecutionException(
                                    "I/O error copying file to response: " + e.getMessage(), e);
                        }
                        finally {
                            if (input != null) {
                                try {
                                    input.close();
                                } catch (IOException e) {
                                    // ignore
                                }
                            }
                        }
                    }
                }
                else if (statusSet) {
                    // GRAILS-6711 nothing to render, just setting status code, so don't render the map
                    renderView = false;
                }
                else {
                    Object object = renderArgument;
                    if (object instanceof JSONElement) {
                        renderView = renderJSON((JSONElement)objectresponse);
                    }
                    else{
                        try {
                            renderView = renderObject(objectresponse.getWriter());
                        }
                        catch (IOException e) {
                            // ignore
                        }
                    }
                }
            }
            else {
                throw new MissingMethodException(target.getClass(), arguments);
            }
        }
        applySiteMeshLayout(webRequest.getCurrentRequest(), renderViewexplicitSiteMeshLayout);
        webRequest.setRenderView(renderView);
        return null;
    }
    private void applySiteMeshLayout(HttpServletRequest requestboolean renderViewString explicitSiteMeshLayout) {
        if(explicitSiteMeshLayout == null && request.getAttribute(.) != null) {
            // layout has been set already
            return;
        }
        String siteMeshLayout = explicitSiteMeshLayout != null ? explicitSiteMeshLayout : (renderView ? null : .);
        if(siteMeshLayout != null) {
            request.setAttribute(.siteMeshLayout);
        }
    }
    private boolean renderConverter(Converter<?> converter, HttpServletResponse response) {
        converter.render(response);
        return false;
    }
    private String resolveContentTypeBySourceType(final Object renderArgumentString defaultEncoding) {
        return renderArgument instanceof GPathResult ?  : defaultEncoding;
    }
    
    private boolean applyContentType(HttpServletResponse responseMap argMapObject renderArgument) {
        return applyContentType(responseargMaprenderArgumenttrue);
    }
    private boolean applyContentType(HttpServletResponse responseMap argMapObject renderArgumentboolean useDefault) {
        boolean contentTypeIsDefault = true;
        String contentType = resolveContentTypeBySourceType(renderArgumentuseDefault ?  : null);
        String encoding = ;
        if (argMap != null) {
            if(argMap.containsKey()) {
                contentType = argMap.get().toString();
                contentTypeIsDefault = false;
            }
            if(argMap.containsKey()) {
                encoding = argMap.get().toString();
                contentTypeIsDefault = false;
            }
        }
        if(contentType != null) {
            setContentType(responsecontentTypeencodingcontentTypeIsDefault);
            return true;
        }
        return false;
    }
    private boolean renderJSON(JSONElement object, HttpServletResponse response) {
        response.setContentType(GrailsWebUtil.getContentType("application/json"));
        return renderWritable(objectresponse);
    }
    private boolean detectContentTypeFromFileName(GrailsWebRequest webRequest, HttpServletResponse responseMap argMapString fileName) {
        MimeUtility mimeUtility = lookupMimeUtility(webRequest);
        if (mimeUtility != null) {
            MimeType mimeType = mimeUtility.getMimeTypeForExtension(GrailsStringUtils.getFilenameExtension(fileName));
            if (mimeType != null) {
                String contentType = mimeType.getName();
                Object encodingObj = argMap.get();
                String encoding = encodingObj != null ? encodingObj.toString() : ;
                setContentType(responsecontentTypeencoding);
                return true;
            }
        }
        return false;
    }
    private MimeUtility lookupMimeUtility(GrailsWebRequest webRequest) {
        if ( == null) {
            ApplicationContext applicationContext = webRequest.getApplicationContext();
            if (applicationContext != null) {
                 = applicationContext.getBean("grailsMimeUtility"MimeUtility.class);
            }
        }
        return ;
    }
    
    private boolean renderTemplate(Object targetGroovyObject controllerGrailsWebRequest webRequest,
            Map argMapString explicitSiteMeshLayout) {
        boolean renderView;
        boolean hasModel = argMap.containsKey();
        Object modelObject = null;
        if(hasModel) {
            modelObject = argMap.get();
        }
        String templateName = argMap.get().toString();
        String contextPath = getContextPath(webRequestargMap);
        String var = null;
        if (argMap.containsKey()) {
            var = String.valueOf(argMap.get());
        }
        // get the template uri
        String templateUri = webRequest.getAttributes().getTemplateURI(controllertemplateName);
        // retrieve gsp engine
        ResourceAwareTemplateEngine engine = webRequest.getAttributes().getPagesTemplateEngine();
        try {
            Template t = engine.createTemplateForUri(new String[]{
                    GrailsResourceUtils.appendPiecesForUri(contextPathtemplateUri),
                    GrailsResourceUtils.appendPiecesForUri(contextPath"/grails-app/views/"templateUri)});
            if (t == null) {
                throw new ControllerExecutionException("Unable to load template for uri [" +
                        templateUri + "]. Template not found.");
            }
            if (t instanceof GroovyPageTemplate) {
                ((GroovyPageTemplate)t).setAllowSettingContentType(true);
            }
            
            GroovyPageView gspView = new GroovyPageView();
            gspView.setTemplate(t);
            try {
                gspView.afterPropertiesSet();
            } catch (Exception e) {
                throw new RuntimeException("Problem initializing view"e);
            }
            
            View view = gspView;            
            boolean renderWithLayout = (explicitSiteMeshLayout != null || webRequest.getCurrentRequest().getAttribute(.) != null);
            if(renderWithLayout) {
                applySiteMeshLayout(webRequest.getCurrentRequest(), falseexplicitSiteMeshLayout);
                try {
                    GroovyPageLayoutFinder groovyPageLayoutFinder = webRequest.getApplicationContext().getBean("groovyPageLayoutFinder"GroovyPageLayoutFinder.class);
                    view = new GrailsLayoutView(groovyPageLayoutFindergspView);
                } catch (NoSuchBeanDefinitionException e) {
                    // ignore
                }
            }
            Map binding = new HashMap();
            if (argMap.containsKey()) {
                Object bean = argMap.get();
                if (hasModel) {
                    if (modelObject instanceof Map) {
                        setTemplateModel(webRequestbinding, (MapmodelObject);
                    }
                }
                renderTemplateForBean(webRequestviewbindingbeanvar);
            }
            else if (argMap.containsKey()) {
                Object colObject = argMap.get();
                if (hasModel) {
                    if (modelObject instanceof Map) {
                        setTemplateModel(webRequestbinding, (Map)modelObject);
                    }
                }
                renderTemplateForCollection(webRequestviewbindingcolObjectvar);
            }
            else if (hasModel) {
                if (modelObject instanceof Map) {
                    setTemplateModel(webRequestbinding, (Map)modelObject);
                }
                renderViewForTemplate(webRequestviewbinding);
            }
            else {
                renderViewForTemplate(webRequestviewbinding);
            }
            renderView = false;
        }
        catch (GroovyRuntimeException gre) {
            throw new ControllerExecutionException("Error rendering template [" + templateName + "]: " + gre.getMessage(), gre);
        }
        catch (IOException ioex) {
            throw new ControllerExecutionException("I/O error executing render method for arguments [" + argMap + "]: " + ioex.getMessage(), ioex);
        }
        return renderView;
    }
    protected void renderViewForTemplate(GrailsWebRequest webRequestView viewMap binding) {
        try {
            view.render(bindingwebRequest.getCurrentRequest(), webRequest.getResponse());
        }
        catch (Exception e) {
            throw new ControllerExecutionException(e.getMessage(), e);
        }
    }
        if ( == null) {
            ApplicationContext applicationContext = webRequest.getApplicationContext();
            if (applicationContext != null) {
                 = applicationContext.getBeansOfType(ActionResultTransformer.class).values();
            }
            if ( == null) {
                 = Collections.emptyList();
            }
        }
        return ;
    }
    private void setTemplateModel(GrailsWebRequest webRequestMap bindingMap modelObject) {
        Map modelMap = modelObject;
        binding.putAll(modelMap);
    }
    private String getContextPath(GrailsWebRequest webRequestMap argMap) {
        Object cp = argMap.get();
        String contextPath = (cp != null ? cp.toString() : "");
        Object pluginName = argMap.get();
        if (pluginName != null) {
            ApplicationContext applicationContext = webRequest.getApplicationContext();
            GrailsPluginManager pluginManager = (GrailsPluginManagerapplicationContext.getBean(.);
            GrailsPlugin plugin = pluginManager.getGrailsPlugin(pluginName.toString());
            if (plugin != null && !plugin.isBasePlugin()) contextPath = plugin.getPluginPath();
        }
        return contextPath;
    }
    private void setContentType(HttpServletResponse responseString contentTypeString encoding) {
        setContentType(responsecontentTypeencodingfalse);
    }
    private void setContentType(HttpServletResponse responseString contentTypeString encodingboolean contentTypeIsDefault) {
        if (!contentTypeIsDefault || response.getContentType()==null) {
            response.setContentType(GrailsWebUtil.getContentType(contentTypeencoding));
        }
    }
    private boolean renderObject(Object objectWriter out) {
        boolean renderView;
        try {
            out.write(DefaultGroovyMethods.inspect(object));
            renderView = false;
        }
        catch (IOException e) {
            throw new ControllerExecutionException("I/O error obtaining response writer: " + e.getMessage(), e);
        }
        return renderView;
    }
    private void renderTemplateForCollection(GrailsWebRequest webRequestView viewMap bindingObject colObjectString varthrows IOException {
        if (colObject instanceof Iterable) {
            Iterable c = (IterablecolObject;
            for (Object o : c) {
                if (GrailsStringUtils.isBlank(var)) {
                    binding.put(o);
                }
                else {
                    binding.put(varo);
                }
                renderViewForTemplate(webRequestviewbinding);
            }
        }
        else {
            if (GrailsStringUtils.isBlank(var)) {
                binding.put(colObject);
            }
            else {
                binding.put(varcolObject);
            }
            renderViewForTemplate(webRequestviewbinding);
        }
    }
    private void renderTemplateForBean(GrailsWebRequest webRequestView viewMap bindingObject beanString varNamethrows IOException {
        if (GrailsStringUtils.isBlank(varName)) {
            binding.put(bean);
        }
        else {
            binding.put(varNamebean);
        }
        renderViewForTemplate(webRequestviewbinding);
    }
    private void renderView(GrailsWebRequest webRequestMap argMapObject targetGroovyObject controller) {
        String viewName = argMap.get().toString();
        String viewUri = webRequest.getAttributes().getNoSuffixViewURI((GroovyObjecttargetviewName);
        String contextPath = getContextPath(webRequestargMap);
        if(contextPath != null) {
            viewUri = contextPath + viewUri;
        }
        Object modelObject = argMap.get();
        if (modelObject != null) {
            modelObject = argMap.get();
            boolean isPromise = modelObject instanceof Promise;
            Collection<ActionResultTransformerresultTransformers = getActionResultTransformers(webRequest);
            for (ActionResultTransformer resultTransformer : resultTransformers) {
                modelObject = resultTransformer.transformActionResult(webRequest,viewUrimodelObject);
            }
            if (isPromisereturn;
        }
        
        applyContentType(webRequest.getCurrentResponse(), argMapnull);
        Map model;
        if (modelObject instanceof Map) {
            model = (MapmodelObject;
        }
        else {
            model = new HashMap();
        }
        controller.setProperty(.new ModelAndView(viewUrimodel));
    }
    private boolean renderJSON(Closure callable, HttpServletResponse response) {
        boolean renderView = true;
        JSONBuilder builder = new JSONBuilder();
        JSON json = builder.build(callable);
        json.render(response);
        renderView = false;
        return renderView;
    }
    private boolean renderMarkup(Closure closure, HttpServletResponse response) {
        StreamingMarkupBuilder b = new StreamingMarkupBuilder();
        b.setEncoding(response.getCharacterEncoding());
        Writable markup = (Writableb.bind(closure);
        return renderWritable(markupresponse);
    }
    private boolean renderText(CharSequence text, HttpServletResponse response) {
        try {
            PrintWriter writer = response.getWriter();
            return renderText(textwriter);
        }
        catch (IOException e) {
            throw new ControllerExecutionException(e.getMessage(), e);
        }
    }
    
    private boolean renderWritable(Writable writable, HttpServletResponse response) {
        try {
            PrintWriter writer = response.getWriter();
            writable.writeTo(writer);
            writer.flush();
        }
        catch (IOException e) {
            throw new ControllerExecutionException(e.getMessage(), e);
        }
        return false;
    }
    private boolean renderText(CharSequence textWriter writer) {
        try {
            if (writer instanceof PrintWriter) {
                ((PrintWriter)writer).print(text);
            }
            else {
                writer.write(text.toString());
            }
            writer.flush();
            return false;
        }
        catch (IOException e) {
            throw new ControllerExecutionException(e.getMessage(), e);
        }
    }
    private boolean isJSONResponse(HttpServletResponse response) {
        String contentType = response.getContentType();
        return contentType != null && (contentType.indexOf("application/json") > -1 ||
               contentType.indexOf("text/json") > -1);
    }
New to GrepCode? Check out our FAQ X