/*
 * @(#)ResourceLoader.java				Wed May 30, 2012 10:06 PM
 *
 * Copyright 2012 Radeon Systems
 *
 *    Licensed 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 com.radeonsys.data.querystore.support.loader;

import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;

import com.google.common.io.InputSupplier;

/**
 * A component that is capable of loading resources from a location.
 *
 * <p>It provides two main methods. The {@link #getReadableResource(String)} method returns a factory that provides 
 * a {@link Reader} over the resource. This operation is optimized to read contents off a resource containing 
 * text content.
 *
 * <p>The other method {@link #getBinaryResource(String)} returns a factory that provides a {@link InputStream} over
 * the resource. This operation is optimized to read contents off a resource containing binary content.</p>
 *
 * @see Reader
 * @see Charset
 * @see InputStream
 * @see InputSupplier
 * @see AbstractResourceLoader
 * 
 * @author  oddjobsman at radeonsys dot com
 * @since 1.0
 */
public interface ResourceLoader {

    /**
     * Returns a factory that provides a {@link Reader} over the resource at the specified location.
     *
     * <p>This method uses the default encoding set for this Java environment or the underlying 
     * operating system.</p>
     *
     * @param resourceLocation  the location of the resource that is required
     *
     * @return  reference to an instance of {@link InputSupplier} which supplies
     *          instances of {@link Reader} over the contents of the resource
     *
     * @throws  ResourceNotFoundException
     *          if no resource could be found at the specified location
     *
     */
    InputSupplier<? extends Reader> getReadableResource(String resourceLocation);

    /**
     * Returns a factory that provides a {@link Reader} over the resource at the specified location 
     * using the specified character set to decode the contents of the resource.
     *
     * @param resourceLocation  the location of the resource that is required
     * @param charset           reference to an instance of {@link Charset} that represents the
     *                          character set used to decode the contents of the resource
     *
     * @return  reference to an instance of {@link InputSupplier} which supplies
     *          instances of {@link Reader} over the contents of the resource
     *
     * @throws  ResourceNotFoundException
     *          if no resource could be found at the specified location
     *
     */
    InputSupplier<? extends Reader> getReadableResource(String resourceLocation, Charset charset);

    /**
     * Returns a factory that provides a {@link InputStream} over the resource at the specified 
     * location.
     *
     * <p>This method is optional and implementations are not required to implement
     * this method if they choose to. In case this method is not implemented, a
     * {@link UnsupportedOperationException} must be thrown</p>
     *
     * @param resourceLocation  the location of the resource that is required
     *
     * @return  reference to an instance of {@link InputSupplier} which supplies
     *          instances of {@link InputStream} over the contents of the resource
     *
     * @throws  ResourceNotFoundException
     *          if no resource could be found at the specified location
     * @throws  UnsupportedOperationException
     *          if the implementation does not support this operation
     */
    InputSupplier<? extends InputStream> getBinaryResource(String resourceLocation);

}
