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 *
012 * $Id$
013 */
014
015package org.nuxeo.ecm.platform.rendering.fm;
016
017import java.io.File;
018import java.io.FileInputStream;
019import java.io.IOException;
020import java.io.InputStreamReader;
021import java.io.Reader;
022import java.net.MalformedURLException;
023import java.net.URL;
024
025import org.nuxeo.ecm.platform.rendering.api.ResourceLocator;
026
027import freemarker.cache.TemplateLoader;
028import freemarker.cache.URLTemplateLoader;
029
030/**
031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
032 */
033public class ResourceTemplateLoader implements TemplateLoader {
034
035    protected ResourceLocator locator;
036
037    protected final MyURLTemplateLoader urlLoader;
038
039    protected final MyFileTemplateLoader fileLoader;
040
041    public ResourceTemplateLoader(ResourceLocator locator) {
042        this.locator = locator;
043        urlLoader = new MyURLTemplateLoader();
044        fileLoader = new MyFileTemplateLoader();
045    }
046
047    public void setLocator(ResourceLocator locator) {
048        this.locator = locator;
049    }
050
051    public ResourceLocator getLocator() {
052        return locator;
053    }
054
055    public void closeTemplateSource(Object templateSource) throws IOException {
056        if (templateSource instanceof File) {
057            fileLoader.closeTemplateSource(templateSource);
058        } else if (templateSource instanceof URL) {
059            urlLoader.closeTemplateSource(templateSource);
060        }
061    }
062
063    public Object findTemplateSource(String name) throws IOException {
064        if (name.startsWith("fs://")) { // hack for absolute paths - see
065                                        // FreemarkerEngine#render()
066            name = name.substring(5);
067        } else if (name.contains(":/")) {
068            return urlLoader.findTemplateSource(name);
069        }
070        Object obj = fileLoader.findTemplateSource(name);
071        if (obj != null) {
072            return obj;
073        }
074        return urlLoader.findTemplateSource(name);
075    }
076
077    public long getLastModified(Object templateSource) {
078        if (templateSource instanceof File) {
079            return fileLoader.getLastModified(templateSource);
080        } else {
081            return urlLoader.getLastModified(templateSource);
082        }
083    }
084
085    public Reader getReader(Object templateSource, String encoding) throws IOException {
086        if (templateSource instanceof File) {
087            return fileLoader.getReader(templateSource, encoding);
088        } else {
089            return urlLoader.getReader(templateSource, encoding);
090        }
091    }
092
093    class MyURLTemplateLoader extends URLTemplateLoader {
094        @Override
095        protected URL getURL(String arg0) {
096            if (locator != null) {
097                return locator.getResourceURL(arg0);
098            }
099            try {
100                return new URL(arg0);
101            } catch (MalformedURLException e) {
102                return null;
103            }
104        }
105    }
106
107    class MyFileTemplateLoader implements TemplateLoader {
108        public void closeTemplateSource(Object templateSource) throws IOException {
109            // do nothing
110        }
111
112        public Object findTemplateSource(String name) throws IOException {
113            if (locator != null) {
114                File file = locator.getResourceFile(name);
115                if (file != null) {
116                    return file.getCanonicalFile();
117                }
118            }
119            try {
120                File file = new File(name).getCanonicalFile();
121                if (file.isFile()) {
122                    return file;
123                }
124            } catch (IOException e) {
125                return null;
126            }
127            return null;
128        }
129
130        public long getLastModified(Object templateSource) {
131            try {
132                return ((File) templateSource).lastModified();
133            } catch (ClassCastException e) {
134                throw new IllegalArgumentException("templateSource is a: " + templateSource.getClass().getName());
135            }
136        }
137
138        public Reader getReader(Object templateSource, String encoding) throws IOException {
139            try {
140                return new InputStreamReader(new FileInputStream((File) templateSource), encoding);
141            } catch (ClassCastException e) {
142                throw new IllegalArgumentException("templateSource is a: " + templateSource.getClass().getName());
143            }
144        }
145
146    }
147
148}