<commit_before>package org.apereo.portlet.soffit.renderer;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

import org.apereo.portlet.soffit.model.v1_0.SoffitRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
@RequestMapping("/soffit")
public class SoffitRendererController {

    private static final String VIEW_NOT_PROVIDED = SoffitRendererController.class.getName() + ".VIEW_NOT_PROVIDED";
    private static final String MODEL_NAME = "soffit";

    @Value("${soffit.renderer.viewsLocation:/WEB-INF/soffit/}")
    private String viewsLocation;
    private final Map<String,Map<String,String>> availableViews = new HashMap<>();

    final ObjectMapper objectMapper = new ObjectMapper();

    @Value("classpath:/soffit.properties")
    private Resource soffitPropertiesResource;

    private Map<String,String> soffitProperties = Collections.emptyMap();  // default

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @PostConstruct
    public void init() {
        Properties properties = new Properties();
        Map<String,String> map = new HashMap<>();
        try (final InputStream stream = soffitPropertiesResource.getInputStream()) {
            if (stream != null) {
                // A soffit.properties file was included, so we will use it
                logger.debug("File soffit.properties was provided");
                properties.load(stream);
                for (final String name : properties.stringPropertyNames()) {
                    map.put(name, properties.getProperty(name));
                }
            }
        } catch (IOException e) {
            logger.error("Classpath file soffit.properties was provided, but failed to load", e);
        }
        if (!map.isEmpty()) {
            soffitProperties = Collections.unmodifiableMap(map);
        }
        logger.debug("Initialized soffitProperties:  {}", soffitProperties);
    }

    @RequestMapping(value="/{module}", method=RequestMethod.POST)
    public ModelAndView render(final HttpServletRequest req, final @RequestBody String soffitJson,
            final @PathVariable String module) {

        logger.debug("Rendering for request URI '{}', soffitJson={}", req.getRequestURI(), soffitJson);

        try {
            final SoffitRequest soffit = objectMapper.readValue(soffitJson, SoffitRequest.class);
            final String viewName = selectView(req, module, soffit);
            return new ModelAndView(viewName.toString(), MODEL_NAME, soffit);
        } catch (IOException e) {
            throw new IllegalArgumentException("Request body was not JSON or was not a valid SoffitRequest", e);
        }

    }

    // TODO:  Not convinced we need this item at all
    @ModelAttribute("properties")
    public Map<String,String> getProperties() {
        return soffitProperties;
    }

    /*
     * Implementation
     */

    private String selectView(final HttpServletRequest req, final String module, final SoffitRequest soffit) {

        final StringBuilder modulePathBuilder = new StringBuilder().append(viewsLocation);
        if (!viewsLocation.endsWith("/")) {
            // Final slash in the configs is optional
            modulePathBuilder.append("/");
        }
        modulePathBuilder.append(module).append("/");
        final String modulePath = modulePathBuilder.toString();

        logger.debug("Calculated modulePath of '{}'", modulePath);

        @SuppressWarnings("unchecked")
        final Set<String> moduleResources = req.getSession().getServletContext().getResourcePaths(modulePath);

        // Narrow the choices based on PortletMode
        final String modeLowercase = soffit.getMode().toLowerCase();
        Map<String,String> viewsForMode = availableViews.get(modeLowercase);
        if (viewsForMode == null) {
            // First time for this PortletMode;  seed the Map
            viewsForMode = new HashMap<>();
            availableViews.put(modeLowercase, viewsForMode);
        }<commit_msg>Remove the soffit.properties concept;  we don't need it<commit_after>package org.apereo.portlet.soffit.renderer;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apereo.portlet.soffit.model.v1_0.SoffitRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
@RequestMapping("/soffit")
public class SoffitRendererController {

    private static final String VIEW_NOT_PROVIDED = SoffitRendererController.class.getName() + ".VIEW_NOT_PROVIDED";
    private static final String MODEL_NAME = "soffit";

    @Value("${soffit.renderer.viewsLocation:/WEB-INF/soffit/}")
    private String viewsLocation;
    private final Map<String,Map<String,String>> availableViews = new HashMap<>();

    final ObjectMapper objectMapper = new ObjectMapper();

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    @RequestMapping(value="/{module}", method=RequestMethod.POST)
    public ModelAndView render(final HttpServletRequest req, final @RequestBody String soffitJson,
            final @PathVariable String module) {

        logger.debug("Rendering for request URI '{}', soffitJson={}", req.getRequestURI(), soffitJson);

        try {
            final SoffitRequest soffit = objectMapper.readValue(soffitJson, SoffitRequest.class);
            final String viewName = selectView(req, module, soffit);
            return new ModelAndView(viewName.toString(), MODEL_NAME, soffit);
        } catch (IOException e) {
            throw new IllegalArgumentException("Request body was not JSON or was not a valid SoffitRequest", e);
        }

    }

    /*
     * Implementation
     */

    private String selectView(final HttpServletRequest req, final String module, final SoffitRequest soffit) {

        final StringBuilder modulePathBuilder = new StringBuilder().append(viewsLocation);
        if (!viewsLocation.endsWith("/")) {
            // Final slash in the configs is optional
            modulePathBuilder.append("/");
        }
        modulePathBuilder.append(module).append("/");
        final String modulePath = modulePathBuilder.toString();

        logger.debug("Calculated modulePath of '{}'", modulePath);

        @SuppressWarnings("unchecked")
        final Set<String> moduleResources = req.getSession().getServletContext().getResourcePaths(modulePath);

        // Narrow the choices based on PortletMode
        final String modeLowercase = soffit.getMode().toLowerCase();
        Map<String,String> viewsForMode = availableViews.get(modeLowercase);
        if (viewsForMode == null) {
            // First time for this PortletMode;  seed the Map
            viewsForMode = new HashMap<>();
            availableViews.put(modeLowercase, viewsForMode);
        }
{'fraction_non_alphanumeric': 0.1022656927076885, 'fraction_numerical': 0.0009904667574594528, 'mean_word_length': 3.5407532321528947, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '3753948', 'n_tokens_mistral': 2152, 'n_tokens_neox': 2109, 'n_words': 501}