1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.dbutils;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.HashMap;
22 import java.util.Map;
23 import java.util.Properties;
24
25 /**
26 * <code>QueryLoader</code> is a registry for sets of queries so
27 * that multiple copies of the same queries aren't loaded into memory.
28 * This implementation loads properties files filled with query name to
29 * SQL mappings. This class is thread safe.
30 */
31 public class QueryLoader {
32
33 /**
34 * The Singleton instance of this class.
35 */
36 private static final QueryLoader instance = new QueryLoader();
37
38 /**
39 * Return an instance of this class.
40 * @return The Singleton instance.
41 */
42 public static QueryLoader instance() {
43 return instance;
44 }
45
46 /**
47 * Maps query set names to Maps of their queries.
48 */
49 private final Map queries = new HashMap();
50
51 /**
52 * QueryLoader constructor.
53 */
54 protected QueryLoader() {
55 super();
56 }
57
58 /**
59 * Loads a Map of query names to SQL values. The Maps are cached so a
60 * subsequent request to load queries from the same path will return
61 * the cached Map.
62 *
63 * @param path The path that the ClassLoader will use to find the file.
64 * This is <strong>not</strong> a file system path. If you had a jarred
65 * Queries.properties file in the com.yourcorp.app.jdbc package you would
66 * pass "/com/yourcorp/app/jdbc/Queries.properties" to this method.
67 * @throws IOException if a file access error occurs
68 * @throws IllegalArgumentException if the ClassLoader can't find a file at
69 * the given path.
70 * @return Map of query names to SQL values
71 */
72 public synchronized Map load(String path) throws IOException {
73
74 Map queryMap = (Map) this.queries.get(path);
75
76 if (queryMap == null) {
77 queryMap = this.loadQueries(path);
78 this.queries.put(path, queryMap);
79 }
80
81 return queryMap;
82 }
83
84 /**
85 * Loads a set of named queries into a Map object. This implementation
86 * reads a properties file at the given path.
87 * @param path The path that the ClassLoader will use to find the file.
88 * @throws IOException if a file access error occurs
89 * @throws IllegalArgumentException if the ClassLoader can't find a file at
90 * the given path.
91 * @since DbUtils 1.1
92 * @return Map of query names to SQL values
93 */
94 protected Map loadQueries(String path) throws IOException {
95 InputStream in = getClass().getResourceAsStream(path);
96
97 if (in == null) {
98 throw new IllegalArgumentException(path + " not found.");
99 }
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 }