Java tutorial
/** * Copyright 2012 MegaFon * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ru.histone.spring.mvc; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.ApplicationContextException; import org.springframework.web.servlet.view.AbstractTemplateView; import ru.histone.GlobalProperty; import ru.histone.Histone; import ru.histone.HistoneException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.util.Locale; import java.util.Map; public class HistoneView extends AbstractTemplateView { private Histone histone; public Histone getHistone() { return histone; } public void setHistone(Histone histone) { this.histone = histone; } /** * Invoked on startup. Looks for a single VelocityConfig bean to * find the relevant VelocityEngine for this factory. */ @Override protected void initApplicationContext() throws BeansException { super.initApplicationContext(); if (getHistone() == null) { // No explicit Histone: try to autodetect one. setHistone(autodetectHistone()); } } private Histone autodetectHistone() throws BeansException { try { HistoneConfig histoneConfig = BeanFactoryUtils.beanOfTypeIncludingAncestors(getApplicationContext(), HistoneConfig.class, true, false); return histoneConfig.getHistone(); } catch (NoSuchBeanDefinitionException ex) { throw new ApplicationContextException( "Must define a single HistoneConfig bean in this web application context " + "(may be inherited): HistoneConfigurer is the usual implementation. " + "This bean may be given any name.", ex); } } @Override public boolean checkResource(Locale locale) throws Exception { try { Reader content = new InputStreamReader(getServletContext().getResourceAsStream(getUrl())); if (content == null) { throw new FileNotFoundException("Can't find view file"); } getHistone().setGlobalProperty(GlobalProperty.BASE_URI, "webapp:" + getUrl()); getHistone().evaluate(content); return true; } catch (FileNotFoundException ex) { if (logger.isDebugEnabled()) { logger.debug("No Histone view found for URL: " + getUrl()); } return false; } catch (HistoneException ex) { throw new ApplicationContextException("Failed to parse Histone template for URL [" + getUrl() + "]", ex); } catch (IOException ex) { throw new ApplicationContextException("Could not load Histone template for URL [" + getUrl() + "]", ex); } } @Override protected void renderMergedTemplateModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { ObjectMapper jackson = new ObjectMapper(); ObjectNode context = jackson.createObjectNode(); for (Map.Entry<String, Object> entry : model.entrySet()) { if (entry.getKey().startsWith("context.")) { String key = entry.getKey().substring(8); Object val = entry.getValue(); if (val instanceof JsonNode) { context.put(key, (JsonNode) val); } else { JsonNode jsonVal = jackson.valueToTree(val); context.put(key, jsonVal); } } } response.setCharacterEncoding("UTF-8"); Reader content = new InputStreamReader(getServletContext().getResourceAsStream(getUrl()), "UTF-8"); getHistone().setGlobalProperty(GlobalProperty.BASE_URI, "webapp:" + getUrl()); String result = getHistone().evaluate(getUrl(), content, context); response.getOutputStream().write(result.getBytes("UTF-8")); } }