001/* 002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * bstefanescu 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.webengine.model; 023 024import org.apache.commons.logging.Log; 025import org.apache.commons.logging.LogFactory; 026 027import java.io.IOException; 028import java.io.OutputStream; 029import java.io.OutputStreamWriter; 030import java.io.StringWriter; 031import java.io.Writer; 032import java.util.HashMap; 033import java.util.Map; 034import java.io.UnsupportedEncodingException; 035import java.net.SocketException; 036 037import org.nuxeo.common.utils.ExceptionUtils; 038import org.nuxeo.ecm.webengine.WebException; 039import org.nuxeo.ecm.webengine.scripting.ScriptFile; 040 041/** 042 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 043 */ 044public class Template { 045 046 private static final Log log = LogFactory.getLog(Template.class); 047 048 protected final Resource resource; 049 050 protected Map<String, Object> args; 051 052 protected ScriptFile script; 053 054 protected WebContext ctx; 055 056 protected Template(WebContext ctx, Resource resource, ScriptFile script) { 057 this.ctx = ctx; 058 this.resource = resource; 059 this.script = script; 060 if (this.ctx == null && this.resource != null) { 061 this.ctx = this.resource.getContext(); 062 } 063 } 064 065 public Template(WebContext ctx, String fileName) { 066 this(ctx, null, null); 067 resolve(fileName); 068 } 069 070 public Template(Resource resource, String fileName) { 071 this(resource.getContext(), resource, null); 072 resolve(fileName); 073 } 074 075 public Template(WebContext ctx, ScriptFile script) { 076 this(ctx, null, script); 077 } 078 079 public Template(Resource resource, ScriptFile script) { 080 this(resource.getContext(), resource, script); 081 } 082 083 public Template arg(String key, Object value) { 084 if (args == null) { 085 args = new HashMap<String, Object>(); 086 } 087 args.put(key, value); 088 return this; 089 } 090 091 public Template args(Map<String, Object> args) { 092 this.args = args; 093 return this; 094 } 095 096 public Map<String, Object> args() { 097 return args; 098 } 099 100 public Resource resource() { 101 return resource; 102 } 103 104 protected void resolve(String fileName) { 105 if (resource != null) { 106 script = resource.getType().getView(ctx.getModule(), fileName); 107 } else { 108 script = ctx.getModule().getFile(fileName); 109 } 110 } 111 112 public ScriptFile script() { 113 return script; 114 } 115 116 public void render(OutputStream out) throws WebException { 117 Writer w; 118 try { 119 w = new OutputStreamWriter(out, "UTF-8"); 120 } catch (UnsupportedEncodingException e) { 121 throw WebException.wrap("Failed to create output stream: unsupported encoding", e); 122 } 123 ctx.render(script(), args, w); 124 try { 125 w.flush(); 126 } catch (IOException e) { 127 if (ExceptionUtils.getRootCause(e) instanceof SocketException) { 128 log.debug("Output socket closed: failed to flush response"); 129 } else { 130 throw WebException.wrap("Failed to flush response", e); 131 } 132 } 133 } 134 135 public String render() { 136 StringWriter w = new StringWriter(); 137 ctx.render(script(), args, w); 138 w.flush(); 139 return w.getBuffer().toString(); 140 } 141 142}