1/*
2 * Copyright (C) 2010 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.clearsilver.jsilver.compatibility;
18
19import com.google.clearsilver.jsilver.TemplateRenderer;
20import com.google.clearsilver.jsilver.template.Template;
21import com.google.clearsilver.jsilver.data.Data;
22import com.google.clearsilver.jsilver.exceptions.JSilverException;
23import com.google.clearsilver.jsilver.resourceloader.ResourceLoader;
24
25import org.clearsilver.CS;
26import org.clearsilver.CSFileLoader;
27import org.clearsilver.ClearsilverFactory;
28import org.clearsilver.HDF;
29import org.clearsilver.jni.JniClearsilverFactory;
30
31import java.io.FileNotFoundException;
32import java.io.IOException;
33import java.io.Reader;
34
35/**
36 * A {@link TemplateRenderer} implemented using ClearSilver itself.
37 */
38public class ClearsilverRenderer implements TemplateRenderer {
39  private final ClearsilverFactory factory;
40  private final ResourceLoader defaultResourceLoader;
41
42  /**
43   * Creates an implementation using the provided ClearSilver factory and JSilver resource loader.
44   */
45  public ClearsilverRenderer(ClearsilverFactory factory, ResourceLoader resourceLoader) {
46    this.factory = factory;
47    this.defaultResourceLoader = resourceLoader;
48  }
49
50  /**
51   * Creates a JSilver implementation using the JNI ClearSilver factory and provided JSilver
52   * resource loader.
53   */
54  public ClearsilverRenderer(ResourceLoader resourceLoader) {
55    this(new JniClearsilverFactory(), resourceLoader);
56  }
57
58  @Override
59  public void render(String templateName, Data data, Appendable output,
60      final ResourceLoader resourceLoader) throws IOException, JSilverException {
61    CSFileLoader fileLoader = new CSFileLoader() {
62      @Override
63      public String load(HDF hdf, String filename) throws IOException {
64        return loadResource(filename, resourceLoader);
65      }
66    };
67
68    HDF hdf = factory.newHdf();
69    try {
70      // Copy the Data into the HDF.
71      hdf.readString(data.toString());
72
73      CS cs = factory.newCs(hdf);
74      try {
75        cs.setFileLoader(fileLoader);
76        cs.parseFile(templateName);
77        output.append(cs.render());
78      } finally {
79        cs.close();
80      }
81    } finally {
82      hdf.close();
83    }
84  }
85
86  @Override
87  public void render(String templateName, Data data, Appendable output) throws IOException,
88      JSilverException {
89    render(templateName, data, output, defaultResourceLoader);
90  }
91
92  @Override
93  public String render(String templateName, Data data) throws IOException, JSilverException {
94    Appendable output = new StringBuilder(8192);
95    render(templateName, data, output);
96    return output.toString();
97  }
98
99  @Override
100  public void render(Template template, Data data, Appendable output, ResourceLoader resourceLoader)
101      throws IOException, JSilverException {
102    throw new UnsupportedOperationException("ClearsilverRenderer only expects "
103        + "template names, not Templates");
104  }
105
106  @Override
107  public void render(Template template, Data data, Appendable output) throws IOException,
108      JSilverException {
109    render(template, data, output, defaultResourceLoader);
110  }
111
112  @Override
113  public String render(Template template, Data data) throws IOException, JSilverException {
114    Appendable output = new StringBuilder(8192);
115    render(template, data, output);
116    return output.toString();
117  }
118
119  @Override
120  public void renderFromContent(String content, Data data, Appendable output) throws IOException,
121      JSilverException {
122    throw new UnsupportedOperationException();
123  }
124
125  @Override
126  public String renderFromContent(String content, Data data) throws IOException, JSilverException {
127    Appendable output = new StringBuilder(8192);
128    renderFromContent(content, data, output);
129    return output.toString();
130  }
131
132  /**
133   * @return the contents of a resource, or null if the resource was not found.
134   */
135  private String loadResource(String filename, ResourceLoader resourceLoader) throws IOException {
136    Reader reader = resourceLoader.open(filename);
137    if (reader == null) {
138      throw new FileNotFoundException(filename);
139    }
140    StringBuilder sb = new StringBuilder();
141    char buf[] = new char[4096];
142    int count;
143    while ((count = reader.read(buf)) != -1) {
144      sb.append(buf, 0, count);
145    }
146    return sb.toString();
147  }
148}
149