final HttpServletResponse response)
throws Exception {
final ServletContext servletContext = getServletContext() ;
final String viewTemplateName = getTemplateName();
final TemplateEngine viewTemplateEngine = getTemplateEngine();
if (!viewTemplateEngine.isInitialized()) {
viewTemplateEngine.initialize();
}
if (viewTemplateName == null) {
throw new IllegalArgumentException("Property 'templateName' is required");
}
if (getLocale() == null) {
throw new IllegalArgumentException("Property 'locale' is required");
}
if (viewTemplateEngine == null) {
throw new IllegalArgumentException("Property 'templateEngine' is required");
}
final Map<String, Object> mergedModel = new HashMap<String, Object>(30);
final Map<String, Object> templateStaticVariables = getStaticVariables();
if (templateStaticVariables != null) {
mergedModel.putAll(templateStaticVariables);
}
if (pathVariablesSelector != null) {
@SuppressWarnings("unchecked")
final Map<String, Object> pathVars = (Map<String, Object>) request.getAttribute(pathVariablesSelector);
if (pathVars != null) {
mergedModel.putAll(pathVars);
}
}
if (model != null) {
mergedModel.putAll(model);
}
final ApplicationContext applicationContext = getApplicationContext();
final RequestContext requestContext =
new RequestContext(request, response, getServletContext(), mergedModel);
// For compatibility with ThymeleafView
addRequestContextAsVariable(mergedModel, SpringContextVariableNames.SPRING_REQUEST_CONTEXT, requestContext);
// For compatibility with AbstractTemplateView
addRequestContextAsVariable(mergedModel, AbstractTemplateView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE, requestContext);
// Expose Thymeleaf's own evaluation context as a model variable
final ConversionService conversionService =
(ConversionService) request.getAttribute(ConversionService.class.getName()); // might be null!
final ThymeleafEvaluationContext evaluationContext =
new ThymeleafEvaluationContext(applicationContext, conversionService);
mergedModel.put(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME, evaluationContext);
final SpringWebContext context =
new SpringWebContext(request, response, servletContext, getLocale(), mergedModel, getApplicationContext());
final String templateName;
final IFragmentSpec nameFragmentSpec;
if (!viewTemplateName.contains("::")) {
// No fragment specified at the template name
templateName = viewTemplateName;
nameFragmentSpec = null;
} else {
// Template name contains a fragment name, so we should parse it as such
final Configuration configuration = viewTemplateEngine.getConfiguration();
final ProcessingContext processingContext = new ProcessingContext(context);
final String dialectPrefix = getStandardDialectPrefix(configuration);
final StandardFragment fragment =
StandardFragmentProcessor.computeStandardFragmentSpec(
configuration, processingContext, viewTemplateName, dialectPrefix, StandardFragmentAttrProcessor.ATTR_NAME);
if (fragment == null) {
throw new IllegalArgumentException("Invalid template name specification: '" + viewTemplateName + "'");
}
templateName = fragment.getTemplateName();
nameFragmentSpec = fragment.getFragmentSpec();
final Map<String,Object> nameFragmentParameters = fragment.getParameters();
if (nameFragmentParameters != null) {
if (FragmentSelectionUtils.parameterNamesAreSynthetic(nameFragmentParameters.keySet())) {
// We cannot allow synthetic parameters because there is no way to specify them at the template
// engine execution!
throw new IllegalArgumentException(
"Parameters in a view specification must be named (non-synthetic): '" + viewTemplateName + "'");
}
context.setVariables(nameFragmentParameters);
}
}
final String templateContentType = getContentType();
final Locale templateLocale = getLocale();
final String templateCharacterEncoding = getCharacterEncoding();
IFragmentSpec templateFragmentSpec = fragmentSpecToRender;
final IFragmentSpec viewFragmentSpec = getFragmentSpec();
if (viewFragmentSpec != null) {
if (templateFragmentSpec == null) {
templateFragmentSpec = viewFragmentSpec;
} else {
templateFragmentSpec =
new ChainedFragmentSpec(viewFragmentSpec, templateFragmentSpec);
}
}
if (nameFragmentSpec != null) {
if (templateFragmentSpec == null) {
templateFragmentSpec = nameFragmentSpec;
} else {
templateFragmentSpec =
new ChainedFragmentSpec(nameFragmentSpec, templateFragmentSpec);
}
}
response.setLocale(templateLocale);
if (templateContentType != null) {
response.setContentType(templateContentType);
} else {
response.setContentType(DEFAULT_CONTENT_TYPE);
}
if (templateCharacterEncoding != null) {
response.setCharacterEncoding(templateCharacterEncoding);
}
viewTemplateEngine.process(templateName, context, templateFragmentSpec, response.getWriter());
}