001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.webengine.jaxrs.views; 013 014import java.io.File; 015import java.io.IOException; 016import java.io.OutputStream; 017import java.io.OutputStreamWriter; 018import java.io.Writer; 019import java.net.MalformedURLException; 020import java.net.URL; 021import java.util.HashMap; 022import java.util.Map; 023 024import org.nuxeo.ecm.platform.rendering.api.RenderingException; 025import org.nuxeo.ecm.platform.rendering.api.ResourceLocator; 026import org.nuxeo.ecm.platform.rendering.fm.FreemarkerEngine; 027import org.osgi.framework.Bundle; 028 029/** 030 * Template for compatibility with Nuxeo WebEngine 031 * 032 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 033 */ 034public class TemplateView { 035 036 private static final FreemarkerEngine engine = new FreemarkerEngine(null, new Locator()); 037 038 private static final Map<String, TemplateView> locators = new HashMap<String, TemplateView>(); 039 040 public static URL resolveFile(File file) throws ViewNotFoundException { 041 if (!file.isFile()) { 042 throw new ViewNotFoundException(null, null, file.getAbsolutePath()); 043 } 044 try { 045 return file.toURI().toURL(); 046 } catch (MalformedURLException e) { 047 throw new ViewNotFoundException(e, null, file.getAbsolutePath()); 048 } 049 } 050 051 public static URL resolveResource(Object owner, String name) throws ViewNotFoundException { 052 URL url = owner.getClass().getResource(name); 053 if (url == null) { 054 throw new ViewNotFoundException(null, owner, name); 055 } 056 return url; 057 } 058 059 public static URL resolveResourceFromBundle(Bundle bundle, String name) throws ViewNotFoundException { 060 URL url = bundle.getEntry(name); 061 if (url == null) { 062 throw new ViewNotFoundException(null, bundle, name); 063 } 064 return url; 065 } 066 067 private static URL resolveResource(Bundle bundle, Object owner, String name) throws ViewNotFoundException { 068 return bundle != null ? resolveResourceFromBundle(bundle, name) : resolveResource(owner, name); 069 } 070 071 protected Object owner; 072 073 protected final URL url; 074 075 protected final Map<String, Object> vars; 076 077 public TemplateView(String name) { 078 this(null, null, name); 079 } 080 081 public TemplateView(Object owner, String name) { 082 this(null, owner, name); 083 } 084 085 public TemplateView(Bundle bundle, Object owner, String name) { 086 this(owner, resolveResource(bundle, owner, name)); 087 } 088 089 public TemplateView(File file) { 090 this(null, file); 091 } 092 093 public TemplateView(Object owner, File file) { 094 this(owner, resolveFile(file)); 095 } 096 097 public TemplateView(URL url) { 098 this(null, url); 099 } 100 101 public TemplateView(Object owner, URL url) { 102 vars = new HashMap<String, Object>(); 103 this.url = url; 104 if (owner != null) { 105 forObject(owner); 106 } 107 } 108 109 public TemplateView forObject(Object owner) { 110 this.owner = owner; 111 vars.put("This", owner); 112 return this; 113 } 114 115 public URL getUrl() { 116 return url; 117 } 118 119 public Object getOwner() { 120 return owner; 121 } 122 123 public TemplateView arg(String key, Object value) { 124 vars.put(key, value); 125 return this; 126 } 127 128 public void render(Writer writer) throws RenderingException, IOException { 129 String id = addLocator(this); 130 try { 131 engine.render(id, vars, writer); 132 writer.flush(); 133 } finally { 134 removeLocator(id); 135 } 136 } 137 138 public void render(OutputStream out) throws RenderingException, IOException { 139 render(new OutputStreamWriter(out, "UTF-8")); 140 } 141 142 private static synchronized String addLocator(TemplateView view) { 143 String locatorId = "view:/" + view.getUrl().toExternalForm(); 144 locators.put(locatorId, view); 145 return locatorId; 146 } 147 148 private static synchronized void removeLocator(String id) { 149 locators.remove(id); 150 } 151 152 private static synchronized TemplateView getLocator(String id) { 153 return locators.get(id); 154 } 155 156 static class Locator implements ResourceLocator { 157 @Override 158 public File getResourceFile(String key) { 159 return null; 160 } 161 162 @Override 163 public URL getResourceURL(String key) { 164 TemplateView view = getLocator(key); 165 if (view != null) { 166 return view.getUrl(); 167 } 168 return null; 169 } 170 } 171 172}