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 */
017package org.nuxeo.ecm.webengine.model.view;
018
019import java.io.IOException;
020import java.io.OutputStream;
021import java.io.OutputStreamWriter;
022import java.io.StringWriter;
023import java.io.Writer;
024import java.net.URL;
025import java.util.HashMap;
026import java.util.Map;
027
028import org.nuxeo.ecm.platform.rendering.api.RenderingException;
029import org.nuxeo.ecm.platform.web.common.vh.VirtualHostHelper;
030import org.nuxeo.ecm.webengine.WebEngine;
031import org.nuxeo.ecm.webengine.WebException;
032import org.nuxeo.ecm.webengine.model.WebContext;
033import org.nuxeo.ecm.webengine.model.exceptions.WebResourceNotFoundException;
034import org.nuxeo.runtime.api.Framework;
035
036/**
037 * A view to be used by regular JAX-RS resources to be able to use freemarker templates.
038 *
039 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
040 */
041public class TemplateView {
042
043    protected URL url;
044
045    protected WebContext ctx;
046
047    protected Object target;
048
049    protected Map<String, Object> bindings;
050
051    public static URL findTemplate(Object owner, String name) {
052        URL url = owner.getClass().getResource(name);
053        if (url == null) {
054            url = Framework.getResourceLoader().getResource(name);
055            if (url == null) {
056                throw new WebResourceNotFoundException("View not found: " + name + " for object " + owner);
057            }
058        }
059        return url;
060    }
061
062    public TemplateView(Object owner, String name) {
063        this(WebEngine.getActiveContext(), owner, name);
064    }
065
066    public TemplateView(WebContext ctx, Object owner, String name) {
067        this(ctx, owner, findTemplate(owner, name));
068    }
069
070    public TemplateView(Object owner, URL url) {
071        this(WebEngine.getActiveContext(), owner, url);
072    }
073
074    public TemplateView(WebContext ctx, Object owner, URL url) {
075        if (ctx == null) {
076            throw new WebException("Not in WebEngine context");
077        }
078        this.ctx = ctx;
079        this.target = owner;
080        this.url = url;
081        bindings = new HashMap<String, Object>();
082        bindings.put("This", target);
083        bindings.put("Context", ctx);
084        bindings.put("Engine", ctx.getEngine());
085        bindings.put("basePath", ctx.getBasePath());
086        bindings.put("contextPath", VirtualHostHelper.getContextPathProperty());
087    }
088
089    public WebContext getContext() {
090        return ctx;
091    }
092
093    public TemplateView arg(String key, Object value) {
094        bindings.put(key, value);
095        return this;
096    }
097
098    public TemplateView args(Map<String, Object> args) {
099        bindings.putAll(args);
100        return this;
101    }
102
103    public void render(Writer writer) {
104        try {
105            ctx.getEngine().getRendering().render(url.toExternalForm(), bindings, writer);
106        } catch (RenderingException e) {
107            throw WebException.wrap(e);
108        }
109    }
110
111    public void render(OutputStream out) {
112        Writer writer = new OutputStreamWriter(out);
113        try {
114            render(writer);
115        } finally {
116            try {
117                writer.flush();
118            } catch (IOException e) {
119                throw WebException.wrap(e);
120            }
121        }
122    }
123
124    public String getString() {
125        StringWriter writer = new StringWriter();
126        render(writer);
127        return writer.toString();
128    }
129
130}