001: /*
002: * The contents of this file are subject to the terms of the
003: * Common Development and Distribution License, Version 1.0 only
004: * (the "License"). You may not use this file except in compliance
005: * with the License. A copy of the license is available
006: * at http://www.opensource.org/licenses/cddl1.php
007: *
008: * See the License for the specific language governing permissions
009: * and limitations under the License.
010: *
011: * The Original Code is the nbdoclet.sf.net project.
012: * The Initial Developer of the Original Code is Petr Zajac.
013: * Portions created by Petr Zajac are Copyright (C) 2006.
014: * Portions created by Jaroslav Tulach are Copyright (C) 2006.
015: * Portions Copyrighted 2007 Sun Microsystems, Inc.
016: * All Rights Reserved.
017:
018: If you wish your version of this file to be governed by only the CDDL
019: or only the GPL Version 2, indicate your decision by adding
020: "[Contributor] elects to include this software in this distribution
021: under the [CDDL or GPL Version 2] license." If you do not indicate a
022: single choice of license, a recipient has the option to distribute
023: your version of this file under either the CDDL, the GPL Version 2 or
024: to extend the choice of license to its licensees as provided above.
025: However, if you add GPL Version 2 code and therefore, elected the GPL
026: Version 2 license, then the option applies only if the new code is
027: made subject to such option by the copyright holder.
028: */
029: package org.netbeans.libs.freemarker;
030:
031: import freemarker.cache.TemplateLoader;
032: import freemarker.core.Environment;
033: import freemarker.template.Configuration;
034: import freemarker.template.TemplateException;
035: import freemarker.template.TemplateExceptionHandler;
036: import freemarker.template.TemplateModel;
037: import freemarker.template.TemplateModelException;
038: import java.io.IOException;
039: import java.io.InputStreamReader;
040: import java.io.Reader;
041: import java.io.Writer;
042: import java.nio.charset.Charset;
043: import java.util.Enumeration;
044: import java.util.LinkedHashSet;
045: import java.util.Set;
046: import javax.script.Bindings;
047: import javax.script.ScriptContext;
048: import org.netbeans.api.queries.FileEncodingQuery;
049: import org.openide.filesystems.FileObject;
050: import org.openide.filesystems.FileStateInvalidException;
051: import org.openide.filesystems.Repository;
052: import org.openide.util.Exceptions;
053:
054: /**
055: * Velocity templates resource loader rewritten for Freemarker to
056: * access resources via FileSystem.
057: *
058: * @author Petr Zajac, adopted by Jaroslav Tulach
059: */
060:
061: final class RsrcLoader extends Configuration implements TemplateLoader,
062: TemplateExceptionHandler {
063: private FileObject fo;
064: private ScriptContext map;
065: private Bindings engineScope;
066:
067: RsrcLoader(FileObject fo, ScriptContext map) {
068: this .fo = fo;
069: this .map = map;
070: this .engineScope = map.getBindings(ScriptContext.ENGINE_SCOPE);
071: setTemplateLoader(this );
072: setTemplateExceptionHandler(this );
073: }
074:
075: public void handleTemplateException(TemplateException ex,
076: Environment env, Writer w) throws TemplateException {
077: try {
078: w.append(ex.getLocalizedMessage());
079: } catch (IOException e) {
080: Exceptions.printStackTrace(e);
081: }
082: }
083:
084: private FileObject getFile(String name) {
085: FileObject tmp = (getFolder() == null) ? null : getFolder()
086: .getFileObject(name);
087: return tmp;
088: }
089:
090: private FileObject getFolder() {
091: try {
092: return fo.getFileSystem().getRoot();
093: } catch (FileStateInvalidException ex) {
094: // ok
095: }
096: return Repository.getDefault().getDefaultFileSystem().getRoot();
097: }
098:
099: public Object findTemplateSource(String string) throws IOException {
100: FileObject tmp = getFile(string);
101: return tmp == null ? null : new Wrap(tmp);
102: }
103:
104: public long getLastModified(Object object) {
105: return ((Wrap) object).fo.lastModified().getTime();
106: }
107:
108: public Reader getReader(Object object, String encoding)
109: throws IOException {
110: Wrap w = (Wrap) object;
111: if (w.reader == null) {
112: Charset chset = FileEncodingQuery.getEncoding(w.fo);
113: w.reader = new InputStreamReader(w.fo.getInputStream(),
114: chset);
115: }
116: return w.reader;
117: }
118:
119: public void closeTemplateSource(Object object) throws IOException {
120: Wrap w = (Wrap) object;
121: if (w.reader != null) {
122: w.reader.close();
123: }
124: }
125:
126: public Object put(String string, Object object) {
127: assert false;
128: return null;
129: }
130:
131: @Override
132: public TemplateModel getSharedVariable(String string) {
133: Object value = map.getAttribute(string);
134: if (value == null) {
135: value = engineScope.get(string);
136: }
137: if (value == null && fo != null) {
138: value = fo.getAttribute(string);
139: }
140: try {
141: return getObjectWrapper().wrap(value);
142: } catch (TemplateModelException ex) {
143: Exceptions.printStackTrace(ex);
144: return null;
145: }
146: }
147:
148: @Override
149: public Set getSharedVariableNames() {
150: LinkedHashSet<String> keys = new LinkedHashSet<String>();
151:
152: if (map != null) {
153: keys.addAll(map.getBindings(map.ENGINE_SCOPE).keySet());
154: }
155:
156: if (fo != null) {
157: Enumeration<String> en = fo.getAttributes();
158: while (en.hasMoreElements()) {
159: keys.add(en.nextElement());
160: }
161: }
162:
163: return keys;
164: }
165:
166: private static final class Wrap {
167: public FileObject fo;
168: public Reader reader;
169:
170: public Wrap(FileObject fo) {
171: this .fo = fo;
172: }
173: } // end Wrap
174:
175: }
|