001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.dbutils;
018:
019: import java.io.IOException;
020: import java.io.InputStream;
021: import java.util.HashMap;
022: import java.util.Map;
023: import java.util.Properties;
024:
025: /**
026: * <code>QueryLoader</code> is a registry for sets of queries so
027: * that multiple copies of the same queries aren't loaded into memory.
028: * This implementation loads properties files filled with query name to
029: * SQL mappings. This class is thread safe.
030: */
031: public class QueryLoader {
032:
033: /**
034: * The Singleton instance of this class.
035: */
036: private static final QueryLoader instance = new QueryLoader();
037:
038: /**
039: * Return an instance of this class.
040: * @return The Singleton instance.
041: */
042: public static QueryLoader instance() {
043: return instance;
044: }
045:
046: /**
047: * Maps query set names to Maps of their queries.
048: */
049: private Map queries = new HashMap();
050:
051: /**
052: * QueryLoader constructor.
053: */
054: protected QueryLoader() {
055: super ();
056: }
057:
058: /**
059: * Loads a Map of query names to SQL values. The Maps are cached so a
060: * subsequent request to load queries from the same path will return
061: * the cached Map.
062: *
063: * @param path The path that the ClassLoader will use to find the file.
064: * This is <strong>not</strong> a file system path. If you had a jarred
065: * Queries.properties file in the com.yourcorp.app.jdbc package you would
066: * pass "/com/yourcorp/app/jdbc/Queries.properties" to this method.
067: * @throws IOException if a file access error occurs
068: * @throws IllegalArgumentException if the ClassLoader can't find a file at
069: * the given path.
070: * @return Map of query names to SQL values
071: */
072: public synchronized Map load(String path) throws IOException {
073:
074: Map queryMap = (Map) this .queries.get(path);
075:
076: if (queryMap == null) {
077: queryMap = this .loadQueries(path);
078: this .queries.put(path, queryMap);
079: }
080:
081: return queryMap;
082: }
083:
084: /**
085: * Loads a set of named queries into a Map object. This implementation
086: * reads a properties file at the given path.
087: * @param path The path that the ClassLoader will use to find the file.
088: * @throws IOException if a file access error occurs
089: * @throws IllegalArgumentException if the ClassLoader can't find a file at
090: * the given path.
091: * @since DbUtils 1.1
092: * @return Map of query names to SQL values
093: */
094: protected Map loadQueries(String path) throws IOException {
095: InputStream in = getClass().getResourceAsStream(path);
096:
097: if (in == null) {
098: throw new IllegalArgumentException(path + " not found.");
099: }
100:
101: Properties props = new Properties();
102: props.load(in);
103:
104: // Copy to HashMap for better performance
105: return new HashMap(props);
106: }
107:
108: /**
109: * Removes the queries for the given path from the cache.
110: * @param path The path that the queries were loaded from.
111: */
112: public synchronized void unload(String path) {
113: this.queries.remove(path);
114: }
115:
116: }
|