<commit_before>package grails.plugin.scaffolding

import grails.codegen.model.ModelBuilder
import grails.io.IOUtils
import groovy.text.GStringTemplateEngine
import groovy.text.Template
import groovy.transform.CompileStatic
import org.grails.web.servlet.mvc.GrailsWebRequest
import org.grails.web.servlet.view.GroovyPageView
import org.grails.web.servlet.view.GroovyPageViewResolver
import org.springframework.context.ResourceLoaderAware
import org.springframework.core.io.ByteArrayResource
import org.springframework.core.io.Resource
import org.springframework.core.io.ResourceLoader
import org.springframework.core.io.UrlResource
import org.springframework.web.servlet.View

import java.util.concurrent.ConcurrentHashMap

/**
 * @author <NAME>
 * @since 3.1
 */
@CompileStatic
class ScaffoldingViewResolver extends GroovyPageViewResolver implements ResourceLoaderAware, ModelBuilder {

    ResourceLoader resourceLoader
    protected Map<String, View> generatedViewCache = new ConcurrentHashMap<>()

    @Override
    protected View loadView(String viewName, Locale locale) throws Exception {
        def view = super.loadView(viewName, locale)
        if(view == null) {
            view = generatedViewCache[viewName]
            if(view != null) {
                return view
            }
            else {
                def webR = GrailsWebRequest.lookup()
                def controllerClass = webR.controllerClass

                def scaffoldValue = controllerClass?.getPropertyValue("scaffold")
                if(scaffoldValue instanceof Class) {
                    def shortViewName = viewName.substring(viewName.lastIndexOf('/') + 1)
                    def url = IOUtils.findResourceRelativeToClass(controllerClass.clazz, "/META-INF/templates/scaffolding/${shortViewName}.gsp")
                    Resource res = url ? new UrlResource(url) : null
                    if(!res.exists()) {
                        res = resourceLoader.getResource("classpath:META-INF/templates/scaffolding/${shortViewName}.gsp")
                    }

                    if(res.exists()) {
                        def model = model((Class)scaffoldValue)
                        def viewGenerator = new GStringTemplateEngine()
                        Template t = viewGenerator.createTemplate(res.URL)

                        def contents = new StringWriter()
                        t.make(model.asMap()).writeTo(contents)
                        def template = templateEngine.createTemplate(new ByteArrayResource(contents.toString().bytes, "view:$viewName"))
                        view = new GroovyPageView()
                        view.setTemplate(template)
                        view.setTemplateEngine(templateEngine)
                        view.afterPropertiesSet()
                        return view
                    }
                    else {
                        return view<commit_msg>Use GSP engine encoding when reading template<commit_after>package grails.plugin.scaffolding

import grails.codegen.model.ModelBuilder
import grails.io.IOUtils
import groovy.text.GStringTemplateEngine
import groovy.text.Template
import groovy.transform.CompileStatic
import org.grails.buffer.*
import org.grails.web.servlet.mvc.GrailsWebRequest
import org.grails.web.servlet.view.GroovyPageView
import org.grails.web.servlet.view.GroovyPageViewResolver
import org.springframework.context.ResourceLoaderAware
import org.springframework.core.io.ByteArrayResource
import org.springframework.core.io.Resource
import org.springframework.core.io.ResourceLoader
import org.springframework.core.io.UrlResource
import org.springframework.web.servlet.View

import java.util.concurrent.ConcurrentHashMap

/**
 * @author <NAME>
 * @since 3.1
 */
@CompileStatic
class ScaffoldingViewResolver extends GroovyPageViewResolver implements ResourceLoaderAware, ModelBuilder {

    ResourceLoader resourceLoader
    protected Map<String, View> generatedViewCache = new ConcurrentHashMap<>()

    @Override
    protected View loadView(String viewName, Locale locale) throws Exception {
        def view = super.loadView(viewName, locale)
        if(view == null) {
            view = generatedViewCache[viewName]
            if(view != null) {
                return view
            }
            else {
                def webR = GrailsWebRequest.lookup()
                def controllerClass = webR.controllerClass

                def scaffoldValue = controllerClass?.getPropertyValue("scaffold")
                if(scaffoldValue instanceof Class) {
                    def shortViewName = viewName.substring(viewName.lastIndexOf('/') + 1)
                    def url = IOUtils.findResourceRelativeToClass(controllerClass.clazz, "/META-INF/templates/scaffolding/${shortViewName}.gsp")
                    Resource res = url ? new UrlResource(url) : null
                    if(!res.exists()) {
                        res = resourceLoader.getResource("classpath:META-INF/templates/scaffolding/${shortViewName}.gsp")
                    }

                    if(res.exists()) {
                        def model = model((Class)scaffoldValue)
                        def viewGenerator = new GStringTemplateEngine()
                        Template t = viewGenerator.createTemplate(res.URL)

                        def contents = new FastStringWriter()
                        t.make(model.asMap()).writeTo(contents)
                        
                        def template = templateEngine.createTemplate(new ByteArrayResource(contents.toString().getBytes(templateEngine.gspEncoding), "view:$viewName"))
                        view = new GroovyPageView()
                        view.setServletContext(getServletContext())
                        view.setTemplate(template)
                        view.setApplicationContext(getApplicationContext())
                        view.setTemplateEngine(templateEngine)
                        view.afterPropertiesSet()
                        generatedViewCache[viewName] = view
                        return view
                    }
                    else {
                        return view
{'fraction_non_alphanumeric': 0.08046913178042027, 'fraction_numerical': 0.0009773578758755497, 'mean_word_length': 2.186299948105864, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4941860', 'n_tokens_mistral': 1523, 'n_tokens_neox': 1438, 'n_words': 281}