@Override public void writeTo( WebView webView, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { try { if (!mediaType.equals(MediaType.APPLICATION_JSON_TYPE) && webContext.getTheme() != null && !webContext.getTheme().isValidDefinition()) { // Fail fast with invalid theme error page, so that the developer knows ASAP and can correct // it. writeHttpError("Invalid theme definition", entityStream); return; } Template masterTemplate = null; try { masterTemplate = themeFileResolver.getIndexTemplate(webContext.getRequest().getBreakpoint()); } catch (TemplateNotFoundException e) { if (!mediaType.equals(MediaType.APPLICATION_JSON_TYPE)) { // For JSON API calls, we don't care if the template is found or not. // For other calls, raise the exception throw e; } } Template template = null; String jsonContext = null; if (!mediaType.equals(MediaType.APPLICATION_JSON_TYPE)) { if (webView.model().isPresent()) { // Check for a model Optional<String> path = themeFileResolver.resolveModelPath(webView.model().get()); if (path.isPresent()) { try { template = themeFileResolver.getTemplate( path.get(), webContext.getRequest().getBreakpoint()); } catch (TemplateNotFoundException e) { // Keep going } } // else just fallback on the default model } if (template == null) { try { template = themeFileResolver.getTemplate( webView.template().toString(), webContext.getRequest().getBreakpoint()); } catch (TemplateNotFoundException e) { if (webView.hasOption(WebView.Option.FALLBACK_ON_DEFAULT_THEME)) { try { template = themeFileResolver.getTemplate( themeManager.getDefaultTheme(), webView.template().toString(), webContext.getRequest().getBreakpoint()); } catch (TemplateNotFoundException e1) { // continue } } if (template == null && webView.hasOption(WebView.Option.FALLBACK_ON_GLOBAL_TEMPLATES)) { template = themeFileResolver.getGlobalTemplate( webView.template().toString(), webContext.getRequest().getBreakpoint()); } } } } if (!mediaType.equals(MediaType.APPLICATION_JSON_TYPE) || httpHeaders.containsKey("X-Mayocat-Full-Context")) { if (template != null) { webView.data().put("templateContent", template.getId()); webView.data().put("template", FilenameUtils.getBaseName(webView.template().toString())); } for (WebDataSupplier supplier : dataSuppliers.values()) { supplier.supply(webView.data()); } } try { ObjectMapper mapper = new ObjectMapper(); if (mediaType.equals(MediaType.APPLICATION_JSON_TYPE)) { mapper.writeValue(entityStream, webView.data()); return; } if (template == null) { throw new TemplateNotFoundException(); } jsonContext = mapper.writeValueAsString(webView.data()); engine.get().register(template); engine.get().register(masterTemplate); String rendered = engine.get().render(masterTemplate.getId(), jsonContext); entityStream.write(rendered.getBytes()); } catch (JsonMappingException e) { this.logger.warn("Failed to serialize JSON context", e); writeDeveloperError(webView, e, entityStream); } catch (TemplateEngineException e) { writeDeveloperError(webView, e, entityStream); } } catch (TemplateNotFoundException e) { throw new WebApplicationException( Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Template not found : " + webView.template().toString()) .build()); } }