/*
 * 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 org.apache.commons.dbutils2;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.InvalidPropertiesFormatException;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Pattern;

/**
 * <code>QueryLoader</code> is a registry for sets of queries so
 * that multiple copies of the same queries aren't loaded into memory.
 * This implementation loads properties files filled with query name to
 * SQL mappings.  This class is thread safe.
 */
public class QueryLoader {

    /**
     * The Singleton instance of this class.
     */
    private static final QueryLoader instance = new QueryLoader();

    /**
     * Matches .xml file extensions.
     */
    private static final Pattern dotXml = Pattern.compile(".+\\.[xX][mM][lL]");

    /**
     * Return an instance of this class.
     * 
     * @return The Singleton instance.
     */
    public static QueryLoader instance() {
        return instance;
    }

    /**
     * Maps query set names to Maps of their queries.
     */
    private final Map<String, Map<String, String>> queries = new HashMap<String, Map<String, String>>();

    /**
     * QueryLoader constructor.
     */
    protected QueryLoader() {
        super();
    }

    /**
     * Loads a Map of query names to SQL values.  The Maps are cached so a
     * subsequent request to load queries from the same path will return
     * the cached Map.  The properties file to load can be in either
     * line-oriented or XML format.  XML formatted properties files must use a
     * <code>.xml</code> file extension.
     *
     * @param path The path that the ClassLoader will use to find the file.
     * This is <strong>not</strong> a file system path.  If you had a jarred
     * Queries.properties file in the com.yourcorp.app.jdbc package you would
     * pass "/com/yourcorp/app/jdbc/Queries.properties" to this method.
     * @throws IOException if a file access error occurs
     * @throws IllegalArgumentException if the ClassLoader can't find a file at
     * the given path.
     * @throws InvalidPropertiesFormatException if the XML properties file is
     * invalid
     * @return Map of query names to SQL values
     * @see java.util.Properties
     */
    public synchronized Map<String, String> load(String path) throws IOException {

        Map<String, String> queryMap = this.queries.get(path);

        if (queryMap == null) {
            queryMap = this.loadQueries(path);
            this.queries.put(path, queryMap);
        }

        return queryMap;
    }

    /**
     * Loads a set of named queries into a Map object.  This implementation
     * reads a properties file at the given path.  The properties file can be
     * in either line-oriented or XML format.  XML formatted properties files
     * must use a <code>.xml</code> file extension.
     * 
     * @param path The path that the ClassLoader will use to find the file.
     * @throws IOException if a file access error occurs
     * @throws IllegalArgumentException if the ClassLoader can't find a file at
     * the given path.
     * @throws InvalidPropertiesFormatException if the XML properties file is
     * invalid
     * @since 1.1
     * @return Map of query names to SQL values
     * @see java.util.Properties
     */
    protected Map<String, String> loadQueries(String path) throws IOException {
        // Findbugs flags getClass().getResource as a bad practice; maybe we should change the API?
        final Properties props;
        try (InputStream in = getClass().getResourceAsStream(path)) {

            if (in == null) {
                throw new IllegalArgumentException(path + " not found.");
            }
            props = new Properties();
            if (dotXml.matcher(path).matches()) {
                props.loadFromXML(in);
            } else {
                props.load(in);
            }
        } finally {
            in.close();
        }

        // Copy to HashMap for better performance

        @SuppressWarnings({ "rawtypes", "unchecked" }) // load() always creates <String,String> entries
        HashMap<String, String> hashMap = new HashMap(props);
        return hashMap;
    }

    /**
     * Removes the queries for the given path from the cache.
     * 
     * @param path The path that the queries were loaded from.
     */
    public synchronized void unload(String path) {
        this.queries.remove(path);
    }

}
