/** * Constructor for use as a bean. * @see #setUrl */ public ScriptTemplateView() { setContentType(null); }
protected ScriptEngine getEngine() { if (Boolean.FALSE.equals(this.sharedEngine)) { Map<Object, ScriptEngine> engines = enginesHolder.get(); if (engines == null) { engines = new HashMap<>(4); enginesHolder.set(engines); } Assert.state(this.engineName != null, "No engine name specified"); Object engineKey = (!ObjectUtils.isEmpty(this.scripts) ? new EngineKey(this.engineName, this.scripts) : this.engineName); ScriptEngine engine = engines.get(engineKey); if (engine == null) { engine = createEngineFromName(this.engineName); engines.put(engineKey, engine); } return engine; } else { // Simply return the configured ScriptEngine... Assert.state(this.engine != null, "No shared engine available"); return this.engine; } }
@Override public boolean checkResource(Locale locale) throws Exception { String url = getUrl(); Assert.state(url != null, "'url' not set"); return (getResource(url) != null); }
protected ScriptEngine createEngineFromName(String engineName) { ScriptEngineManager scriptEngineManager = this.scriptEngineManager; if (scriptEngineManager == null) { scriptEngineManager = new ScriptEngineManager(obtainApplicationContext().getClassLoader()); this.scriptEngineManager = scriptEngineManager; } ScriptEngine engine = StandardScriptUtils.retrieveEngineByName(scriptEngineManager, engineName); loadScripts(engine); return engine; }
super.initApplicationContext(context); ScriptTemplateConfig viewConfig = autodetectViewConfig(); if (this.engine == null && viewConfig.getEngine() != null) { setEngine(viewConfig.getEngine()); this.renderFunction = viewConfig.getRenderFunction(); if (this.getContentType() == null) { setContentType(viewConfig.getContentType() != null ? viewConfig.getContentType() : DEFAULT_CONTENT_TYPE); setResourceLoaderPath(resourceLoaderPath != null ? resourceLoaderPath : DEFAULT_RESOURCE_LOADER_PATH); loadScripts(this.engine); setEngine(createEngineFromName(this.engineName));
@Test // SPR-13379 public void contentType() throws Exception { MockServletContext servletContext = new MockServletContext(); this.wac.setServletContext(servletContext); this.wac.refresh(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); MockHttpServletResponse response = new MockHttpServletResponse(); Map<String, Object> model = new HashMap<>(); this.view.setEngine(mock(InvocableScriptEngine.class)); this.view.setRenderFunction("render"); this.view.setResourceLoaderPath("classpath:org/springframework/web/servlet/view/script/"); this.view.setUrl("empty.txt"); this.view.setApplicationContext(this.wac); this.view.render(model, request, response); assertEquals(MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8, response.getHeader(HttpHeaders.CONTENT_TYPE)); response = new MockHttpServletResponse(); this.view.setContentType(MediaType.TEXT_PLAIN_VALUE); this.view.render(model, request, response); assertEquals(MediaType.TEXT_PLAIN_VALUE + ";charset=" + StandardCharsets.UTF_8, response.getHeader(HttpHeaders.CONTENT_TYPE)); response = new MockHttpServletResponse(); this.view.setCharset(StandardCharsets.ISO_8859_1); this.view.render(model, request, response); assertEquals(MediaType.TEXT_PLAIN_VALUE + ";charset=" + StandardCharsets.ISO_8859_1, response.getHeader(HttpHeaders.CONTENT_TYPE)); }
@Test public void missingTemplate() throws Exception { MockServletContext servletContext = new MockServletContext(); this.wac.setServletContext(servletContext); this.wac.refresh(); this.view.setResourceLoaderPath("classpath:org/springframework/web/servlet/view/script/"); this.view.setUrl("missing.txt"); this.view.setEngine(mock(InvocableScriptEngine.class)); this.configurer.setRenderFunction("render"); this.view.setApplicationContext(this.wac); assertFalse(this.view.checkResource(Locale.ENGLISH)); }
@Test // SPR-14210 public void resourceLoaderPath() throws Exception { MockServletContext servletContext = new MockServletContext(); this.wac.setServletContext(servletContext); this.wac.refresh(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.wac); MockHttpServletResponse response = new MockHttpServletResponse(); Map<String, Object> model = new HashMap<>(); InvocableScriptEngine engine = mock(InvocableScriptEngine.class); when(engine.invokeFunction(any(), any(), any(), any())).thenReturn("foo"); this.view.setEngine(engine); this.view.setRenderFunction("render"); this.view.setApplicationContext(this.wac); this.view.setUrl("org/springframework/web/servlet/view/script/empty.txt"); this.view.render(model, request, response); assertEquals("foo", response.getContentAsString()); response = new MockHttpServletResponse(); this.view.setResourceLoaderPath("classpath:org/springframework/web/servlet/view/script/"); this.view.setUrl("empty.txt"); this.view.render(model, request, response); assertEquals("foo", response.getContentAsString()); response = new MockHttpServletResponse(); this.view.setResourceLoaderPath("classpath:org/springframework/web/servlet/view/script"); this.view.setUrl("empty.txt"); this.view.render(model, request, response); assertEquals("foo", response.getContentAsString()); }
ScriptEngine engine = getEngine(); String url = getUrl(); Assert.state(url != null, "'url' not set"); String template = getTemplate(url); return getTemplate(path); RenderingContext context = new RenderingContext(obtainApplicationContext(), locale, templateLoader, url);
@Test public void customEngineAndRenderFunction() throws Exception { ScriptEngine engine = mock(InvocableScriptEngine.class); given(engine.get("key")).willReturn("value"); this.view.setEngine(engine); this.view.setRenderFunction("render"); this.view.setApplicationContext(this.wac); engine = this.view.getEngine(); assertNotNull(engine); assertEquals("value", engine.get("key")); DirectFieldAccessor accessor = new DirectFieldAccessor(this.view); assertNull(accessor.getPropertyValue("renderObject")); assertEquals("render", accessor.getPropertyValue("renderFunction")); assertEquals(StandardCharsets.UTF_8, accessor.getPropertyValue("charset")); }
@Test public void nonSharedEngine() throws Exception { int iterations = 20; this.view.setEngineName("nashorn"); this.view.setRenderFunction("render"); this.view.setSharedEngine(false); this.view.setApplicationContext(this.wac); ExecutorService executor = Executors.newFixedThreadPool(4); List<Future<Boolean>> results = new ArrayList<>(); for (int i = 0; i < iterations; i++) { results.add(executor.submit(() -> view.getEngine() != null)); } assertEquals(iterations, results.size()); for (int i = 0; i < iterations; i++) { assertTrue(results.get(i).get()); } executor.shutdown(); }
@Test public void engineSetterAndNonSharedEngine() { this.view.setEngine(mock(InvocableScriptEngine.class)); this.view.setRenderFunction("render"); this.view.setSharedEngine(false); this.expectedException.expect(IllegalArgumentException.class); this.view.setApplicationContext(this.wac); this.expectedException.expectMessage(contains("sharedEngine")); }
@Test public void engineAndEngineNameBothDefined() { this.view.setEngine(mock(InvocableScriptEngine.class)); this.view.setEngineName("test"); this.view.setRenderFunction("render"); this.expectedException.expect(IllegalArgumentException.class); this.view.setApplicationContext(this.wac); this.expectedException.expectMessage(contains("'engine' or 'engineName'")); }
@Test public void nonInvocableScriptEngineWithRenderFunction() throws Exception { this.view.setEngine(mock(ScriptEngine.class)); this.view.setRenderFunction("render"); this.expectedException.expect(IllegalArgumentException.class); this.view.setApplicationContext(this.wac); }
protected String getTemplate(String path) throws IOException { Resource resource = getResource(path); if (resource == null) { throw new IllegalStateException("Template resource [" + path + "] not found"); } InputStreamReader reader = (this.charset != null ? new InputStreamReader(resource.getInputStream(), this.charset) : new InputStreamReader(resource.getInputStream())); return FileCopyUtils.copyToString(reader); }
@Test public void nonInvocableScriptEngine() throws Exception { this.view.setEngine(mock(ScriptEngine.class)); this.view.setApplicationContext(this.wac); }
protected ScriptEngine createEngineFromName() { if (this.scriptEngineManager == null) { this.scriptEngineManager = new ScriptEngineManager(getApplicationContext().getClassLoader()); } ScriptEngine engine = StandardScriptUtils.retrieveEngineByName(this.scriptEngineManager, this.engineName); loadScripts(engine); return engine; }
@Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { try { ScriptEngine engine = getEngine(); Invocable invocable = (Invocable) engine; String url = getUrl(); String template = getTemplate(url); Object html; if (this.renderObject != null) { Object thiz = engine.eval(this.renderObject); html = invocable.invokeMethod(thiz, this.renderFunction, template, model, url); } else { html = invocable.invokeFunction(this.renderFunction, template, model, url); } response.getWriter().write(String.valueOf(html)); } catch (ScriptException ex) { throw new ServletException("Failed to render script template", new StandardScriptEvalException(ex)); } }
super.initApplicationContext(context); ScriptTemplateConfig viewConfig = autodetectViewConfig(); if (this.engine == null && viewConfig.getEngine() != null) { setEngine(viewConfig.getEngine()); this.renderFunction = viewConfig.getRenderFunction(); if (this.getContentType() == null) { setContentType(viewConfig.getContentType() != null ? viewConfig.getContentType() : DEFAULT_CONTENT_TYPE); setResourceLoaderPath(resourceLoaderPath != null ? resourceLoaderPath : DEFAULT_RESOURCE_LOADER_PATH); loadScripts(this.engine); setEngine(createEngineFromName(this.engineName));
ScriptEngine engine = getEngine(); String url = getUrl(); Assert.state(url != null, "'url' not set"); String template = getTemplate(url); return getTemplate(path); RenderingContext context = new RenderingContext(obtainApplicationContext(), locale, templateLoader, url);