001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * bstefanescu 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.webengine.model; 021 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024 025import java.io.IOException; 026import java.io.OutputStream; 027import java.io.OutputStreamWriter; 028import java.io.StringWriter; 029import java.io.Writer; 030import java.util.HashMap; 031import java.util.Map; 032import java.io.UnsupportedEncodingException; 033import java.net.SocketException; 034 035import org.nuxeo.common.utils.ExceptionUtils; 036import org.nuxeo.ecm.webengine.WebException; 037import org.nuxeo.ecm.webengine.scripting.ScriptFile; 038 039/** 040 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 041 */ 042public class Template { 043 044 private static final Log log = LogFactory.getLog(Template.class); 045 046 protected final Resource resource; 047 048 protected Map<String, Object> args; 049 050 protected ScriptFile script; 051 052 protected WebContext ctx; 053 054 protected Template(WebContext ctx, Resource resource, ScriptFile script) { 055 this.ctx = ctx; 056 this.resource = resource; 057 this.script = script; 058 if (this.ctx == null && this.resource != null) { 059 this.ctx = this.resource.getContext(); 060 } 061 } 062 063 public Template(WebContext ctx, String fileName) { 064 this(ctx, null, null); 065 resolve(fileName); 066 } 067 068 public Template(Resource resource, String fileName) { 069 this(resource.getContext(), resource, null); 070 resolve(fileName); 071 } 072 073 public Template(WebContext ctx, ScriptFile script) { 074 this(ctx, null, script); 075 } 076 077 public Template(Resource resource, ScriptFile script) { 078 this(resource.getContext(), resource, script); 079 } 080 081 public Template arg(String key, Object value) { 082 if (args == null) { 083 args = new HashMap<String, Object>(); 084 } 085 args.put(key, value); 086 return this; 087 } 088 089 public Template args(Map<String, Object> args) { 090 this.args = args; 091 return this; 092 } 093 094 public Map<String, Object> args() { 095 return args; 096 } 097 098 public Resource resource() { 099 return resource; 100 } 101 102 protected void resolve(String fileName) { 103 if (resource != null) { 104 script = resource.getType().getView(ctx.getModule(), fileName); 105 } else { 106 script = ctx.getModule().getFile(fileName); 107 } 108 } 109 110 public ScriptFile script() { 111 return script; 112 } 113 114 public void render(OutputStream out) throws WebException { 115 Writer w; 116 try { 117 w = new OutputStreamWriter(out, "UTF-8"); 118 } catch (UnsupportedEncodingException e) { 119 throw WebException.wrap("Failed to create output stream: unsupported encoding", e); 120 } 121 ctx.render(script(), args, w); 122 try { 123 w.flush(); 124 } catch (IOException e) { 125 if (ExceptionUtils.getRootCause(e) instanceof SocketException) { 126 log.debug("Output socket closed: failed to flush response"); 127 } else { 128 throw WebException.wrap("Failed to flush response", e); 129 } 130 } 131 } 132 133 public String render() { 134 StringWriter w = new StringWriter(); 135 ctx.render(script(), args, w); 136 w.flush(); 137 return w.getBuffer().toString(); 138 } 139 140}