/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package freemarker.cache;

import java.io.IOException;
import java.io.Reader;

import freemarker.template.Configuration;
import freemarker.template.TemplateNotFoundException;

/**
 * FreeMarker loads template "files" through objects that implement this interface,
 * thus the templates need not be real files, and can come from any kind of data source
 * (like classpath, servlet context, database, etc). While FreeMarker provides a few
 * {@link TemplateLoader} implementations out-of-the-box, it's normal for embedding
 * frameworks to use their own implementations.
 * 
 * <p>To set the {@link TemplateLoader} used by FreeMaker, use
 * {@link Configuration#setTemplateLoader(TemplateLoader)}.
 * 
 * <p>Implementations of this interface should be thread-safe.
 * 
 * <p>Implementations should override {@link Object#toString()} to show information about from where the
 * {@link TemplateLoader} loads the templates. For example, for a template loader that loads template from database
 * table {@code toString} could return something like
 * {@code "MyDatabaseTemplateLoader(user=\"cms\", table=\"mail_templates\")"}. This string will be shown in
 * {@link TemplateNotFoundException} exception messages, next to the template name.
 * 
 * <p>For those who has to dig deeper, note that the {@link TemplateLoader} is actually stored inside
 * the {@link TemplateCache} of the {@link Configuration}, and is normally only accessed directly
 * by the {@link TemplateCache}, and templates are get via the {@link TemplateCache} API-s.
 */
public interface TemplateLoader {
	
    /**
     * Finds the template in the backing storage and returns an object that identifies the storage location where the
     * template can be loaded from. See the return value for more information.
     *
     * @param name
     *            The name of the template, already localized and normalized by the
     *            {@link freemarker.cache.TemplateCache cache}. It is completely up to the loader implementation to
     *            interpret the name, however it should expect to receive hierarchical paths where path components are
     *            separated by a slash (not backslash). Backslashes (or any other OS specific separator character) are
     *            not considered as separators by FreeMarker, and thus they will not be replaced with slash before
     *            passing to this method, so it's up to the template loader to handle them (say, be throwing and
     *            exception that tells the user that the path (s)he has entered is invalid, as (s)he must use slash --
     *            typical mistake of Windows users). The passed names are always considered relative to some
     *            loader-defined root location (often referred as the "template root directory"), and will never start
     *            with a slash, nor will they contain a path component consisting of either a single or a double dot --
     *            these are all resolved by the template cache before passing the name to the loader. As a side effect,
     *            paths that trivially reach outside template root directory, such as <tt>../my.ftl</tt>, will be
     *            rejected by the template cache, so they never reach the template loader. Note again, that if the path
     *            uses backslash as path separator instead of slash as (the template loader should not accept that), the
     *            normalization will not properly happen, as FreeMarker (the cache) recognizes only the slashes as
     *            separators.
     *
     * @return An object representing the template source, which can be supplied in subsequent calls to
     *         {@link #getLastModified(Object)} and {@link #getReader(Object, String)}, when those are called on the
     *         same {@link TemplateLoader}. {@code null} must be returned if the source for the template doesn't exist;
     *         don't throw exception then! The exact type of this object is up to the {@link TemplateLoader}
     *         implementation. As this object is possibly used as hash key in caches, and is surly compared with another
     *         template source for equality, <b>it must have a proper {@link Object#equals(Object)} and
     *         {@link Object#hashCode()}) implementation</b>. Especially, template sources that refer to the same
     *         physical source must be equivalent, otherwise template caching can become inefficient. This is only
     *         expected from {@link Object#equals(Object)} when the compared template sources came from the same
     *         {@link TemplateLoader} instance. Also, it must not influence the equality if the source is open or
     *         closed ({@link #closeTemplateSource(Object)}). 
     * 
     * @throws IOException
     *             When an error occurs that makes it impossible to find out if the template exists, or to access the
     *             existing template. Don't throw exception if the template doesn't exist, instead return with
     *             {@code null} then!
     */
    public Object findTemplateSource(String name)
    throws IOException;
        
    /**
     * Returns the time of last modification of the specified template source. This method is called after
     * <code>findTemplateSource()</code>.
     * 
     * @param templateSource
     *            an object representing a template source, obtained through a prior call to
     *            {@link #findTemplateSource(String)}. This must be an object on which
     *            {@link TemplateLoader#closeTemplateSource(Object)} wasn't applied yet.
     * @return the time of last modification of the specified template source, or -1 if the time is not known.
     */
    public long getLastModified(Object templateSource);
    
    /**
     * Returns the character stream of a template represented by the specified template source. This method is possibly
     * called for multiple times for the same template source object, and it must always return a {@link Reader} that
     * reads the template from its beginning. Before this method is called for the second time (or later), its caller
     * must close the previously returned {@link Reader}, and it must not use it anymore. That is, this method is not
     * required to support multiple concurrent readers for the same source {@code templateSource} object.
     * 
     * <p>
     * Typically, this method is called if the template is missing from the cache, or if after calling
     * {@link #findTemplateSource(String)} and {@link #getLastModified(Object)} it was determined that the cached copy
     * of the template is stale. Then, if it turns out that the {@code encoding} parameter used doesn't match the actual
     * template content (based on the {@code #ftl encoding=...} header), this method will be called for a second time
     * with the correct {@code encoding} parameter value.
     * 
     * @param templateSource
     *            an object representing a template source, obtained through a prior call to
     *            {@link #findTemplateSource(String)}. This must be an object on which
     *            {@link TemplateLoader#closeTemplateSource(Object)} wasn't applied yet.
     * @param encoding
     *            the character encoding used to translate source bytes to characters. Some loaders may not have access
     *            to the byte representation of the template stream, and instead directly obtain a character stream.
     *            These loaders should ignore the encoding parameter.
     * 
     * @return A {@link Reader} representing the template character stream. It's the responsibility of the caller (which
     *         is {@link TemplateCache} usually) to {@code close()} it. The {@link Reader} is not required to work after
     *         the {@code templateSource} was closed ({@link #closeTemplateSource(Object)}).
     * 
     * @throws IOException
     *             if an I/O error occurs while accessing the stream.
     */
    public Reader getReader(Object templateSource, String encoding)
    throws IOException;
    
    /**
     * Closes the template source, releasing any resources held that are only required for reading the template and/or
     * its metadata. This is the last method that is called by the {@link TemplateCache} for a template source, except
     * that {@link Object#equals(Object)} is might called later too. {@link TemplateCache} ensures that this method will
     * be called on every object that is returned from {@link #findTemplateSource(String)}.
     * 
     * @param templateSource
     *            the template source that should be closed.
     */
    public void closeTemplateSource(Object templateSource)
    throws IOException;
}
