001/* 
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.platform.rendering.fm;
023
024import java.io.File;
025import java.io.FileInputStream;
026import java.io.IOException;
027import java.io.InputStreamReader;
028import java.io.Reader;
029import java.net.MalformedURLException;
030import java.net.URL;
031
032import org.nuxeo.ecm.platform.rendering.api.ResourceLocator;
033
034import freemarker.cache.TemplateLoader;
035import freemarker.cache.URLTemplateLoader;
036
037/**
038 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
039 */
040public class ResourceTemplateLoader implements TemplateLoader {
041
042    protected ResourceLocator locator;
043
044    protected final MyURLTemplateLoader urlLoader;
045
046    protected final MyFileTemplateLoader fileLoader;
047
048    public ResourceTemplateLoader(ResourceLocator locator) {
049        this.locator = locator;
050        urlLoader = new MyURLTemplateLoader();
051        fileLoader = new MyFileTemplateLoader();
052    }
053
054    public void setLocator(ResourceLocator locator) {
055        this.locator = locator;
056    }
057
058    public ResourceLocator getLocator() {
059        return locator;
060    }
061
062    public void closeTemplateSource(Object templateSource) throws IOException {
063        if (templateSource instanceof File) {
064            fileLoader.closeTemplateSource(templateSource);
065        } else if (templateSource instanceof URL) {
066            urlLoader.closeTemplateSource(templateSource);
067        }
068    }
069
070    public Object findTemplateSource(String name) throws IOException {
071        if (name.startsWith("fs://")) { // hack for absolute paths - see
072                                        // FreemarkerEngine#render()
073            name = name.substring(5);
074        } else if (name.contains(":/")) {
075            return urlLoader.findTemplateSource(name);
076        }
077        Object obj = fileLoader.findTemplateSource(name);
078        if (obj != null) {
079            return obj;
080        }
081        return urlLoader.findTemplateSource(name);
082    }
083
084    public long getLastModified(Object templateSource) {
085        if (templateSource instanceof File) {
086            return fileLoader.getLastModified(templateSource);
087        } else {
088            return urlLoader.getLastModified(templateSource);
089        }
090    }
091
092    public Reader getReader(Object templateSource, String encoding) throws IOException {
093        if (templateSource instanceof File) {
094            return fileLoader.getReader(templateSource, encoding);
095        } else {
096            return urlLoader.getReader(templateSource, encoding);
097        }
098    }
099
100    class MyURLTemplateLoader extends URLTemplateLoader {
101        @Override
102        protected URL getURL(String arg0) {
103            if (locator != null) {
104                return locator.getResourceURL(arg0);
105            }
106            try {
107                return new URL(arg0);
108            } catch (MalformedURLException e) {
109                return null;
110            }
111        }
112    }
113
114    class MyFileTemplateLoader implements TemplateLoader {
115        public void closeTemplateSource(Object templateSource) throws IOException {
116            // do nothing
117        }
118
119        public Object findTemplateSource(String name) throws IOException {
120            if (locator != null) {
121                File file = locator.getResourceFile(name);
122                if (file != null) {
123                    return file.getCanonicalFile();
124                }
125            }
126            try {
127                File file = new File(name).getCanonicalFile();
128                if (file.isFile()) {
129                    return file;
130                }
131            } catch (IOException e) {
132                return null;
133            }
134            return null;
135        }
136
137        public long getLastModified(Object templateSource) {
138            try {
139                return ((File) templateSource).lastModified();
140            } catch (ClassCastException e) {
141                throw new IllegalArgumentException("templateSource is a: " + templateSource.getClass().getName());
142            }
143        }
144
145        public Reader getReader(Object templateSource, String encoding) throws IOException {
146            try {
147                return new InputStreamReader(new FileInputStream((File) templateSource), encoding);
148            } catch (ClassCastException e) {
149                throw new IllegalArgumentException("templateSource is a: " + templateSource.getClass().getName());
150            }
151        }
152
153    }
154
155}