package org.activityinfo.server.util.jaxrs; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.google.common.base.Charsets; import com.google.inject.Inject; import com.google.inject.Singleton; import com.sun.jersey.api.core.HttpContext; import com.sun.jersey.api.view.Viewable; import com.sun.jersey.spi.template.ViewProcessor; import freemarker.core.Environment; import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.ResourceBundleModel; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.activityinfo.server.branding.ScaffoldingDirective; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.ext.Provider; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Locale; import java.util.ResourceBundle; import java.util.logging.Logger; /** * Match a Viewable-named view with a Freemarker template. */ @Provider @Singleton public class FreemarkerViewProcessor implements ViewProcessor<Template> { private static final Logger LOGGER = Logger.getLogger(FreemarkerViewProcessor.class.getName()); private final Configuration templateConfig; private final javax.inject.Provider<Locale> localeProvider; private @Context HttpContext httpContext; private ScaffoldingDirective scaffoldingDirective; @Inject public FreemarkerViewProcessor(Configuration templateConfig, javax.inject.Provider<Locale> localeProvider, ScaffoldingDirective scaffoldingDirective) { super(); this.templateConfig = templateConfig; this.localeProvider = localeProvider; this.scaffoldingDirective = scaffoldingDirective; } @Override public Template resolve(String name) { try { if (name.startsWith("/")) { name = name.substring(1); } return templateConfig.getTemplate(name); } catch (IOException e) { throw new RuntimeException(e); } } @Override public void writeTo(Template t, Viewable viewable, OutputStream out) throws IOException { // ensure that we set an content type and charset if (httpContext != null) { Object ct = httpContext.getResponse().getHttpHeaders().getFirst(HttpHeaders.CONTENT_TYPE); if (ct == null || "".equals(ct)) { ct = "text/html; charset=UTF-8"; } else if (!String.valueOf(ct).contains("charset")) { ct = ct + "; charset=UTF-8"; } httpContext.getResponse().getHttpHeaders().putSingle(HttpHeaders.CONTENT_TYPE, ct); httpContext.getResponse().getHttpHeaders().putSingle(HttpHeaders.CONTENT_ENCODING, "UTF-8"); } Writer writer = new OutputStreamWriter(out, Charsets.UTF_8); try { Environment env = t.createProcessingEnvironment(viewable.getModel(), writer); env.setLocale(localeProvider.get()); env.setVariable("label", getResourceBundle(localeProvider.get())); env.setVariable("scaffolding", scaffoldingDirective); env.process(); writer.flush(); } catch (TemplateException e) { throw new RuntimeException(e); } } private ResourceBundleModel getResourceBundle(Locale locale) { return new freemarker.ext.beans.ResourceBundleModel(ResourceBundle.getBundle("template/page/Labels", locale), new BeansWrapper()); } }