1 /***
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Exoffice Technologies. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Exoffice Technologies. Exolab is a registered
23 * trademark of Exoffice Technologies.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2001-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: TypeSet.java,v 1.6 2003/08/07 13:33:11 tanderson Exp $
44 */
45
46 package org.exolab.jms.tools.db;
47
48 import java.sql.Connection;
49 import java.sql.ResultSet;
50 import java.sql.SQLException;
51 import java.util.ArrayList;
52 import java.util.HashMap;
53 import java.util.Iterator;
54
55 import org.apache.commons.logging.Log;
56 import org.apache.commons.logging.LogFactory;
57
58 import org.exolab.jms.persistence.PersistenceException;
59 import org.exolab.jms.persistence.SQLHelper;
60
61
62 /***
63 * A helper class for managing the set of types supported by an RDBMS
64 *
65 * @version $Revision: 1.6 $ $Date: 2003/08/07 13:33:11 $
66 * @author <a href="mailto:tima@intalio.com">Tim Anderson</a>
67 */
68 class TypeSet {
69
70 /***
71 * A map of type identifiers to an ArrayList of corresponding RDBMS types
72 */
73 private HashMap _types = new HashMap();
74
75 /***
76 * The logger
77 */
78 private static final Log _log = LogFactory.getLog(TypeSet.class);
79
80
81 /***
82 * Construct a new instance
83 *
84 * @param connection the database connection to obtain meta-data from
85 * @throws PersistenceException if meta-data cannot be accessed
86 */
87 public TypeSet(Connection connection) throws PersistenceException {
88 ResultSet set = null;
89 try {
90 set = connection.getMetaData().getTypeInfo();
91 while (set.next()) {
92 int type = set.getInt("DATA_TYPE");
93 String name = set.getString("TYPE_NAME");
94 long precision = set.getLong("PRECISION");
95 String createParams = set.getString("CREATE_PARAMS");
96
97 Descriptor descriptor = Descriptor.getDescriptor(type);
98 if (descriptor != null) {
99 addType(type, name, precision, createParams);
100 } else {
101 _log.debug(
102 "TypeSet: skipping unknown type, type id=" + type
103 + ", name=" + name + ", precision=" + precision
104 + ", create params=" + createParams);
105 }
106 }
107 } catch (SQLException exception) {
108 throw new PersistenceException(
109 "Failed to get type meta-data", exception);
110 } finally {
111 SQLHelper.close(set);
112 }
113 }
114
115 /***
116 * Return the closest type matching the requested type id and precision
117 *
118 * @param type the type identifier
119 * @param precision the requested precision
120 * @return the closest matching type, or null if none exists
121 */
122 public Type getType(int type, long precision) {
123 Type result = null;
124 ArrayList types = (ArrayList) _types.get(new Integer(type));
125 if (types != null) {
126 Iterator iter = types.iterator();
127 while (iter.hasNext()) {
128 Type option = (Type) iter.next();
129 if (precision == -1 && (option.getPrecision() != -1 &&
130 option.getParameters())) {
131 // no precision was requested, but the type requires
132 // parameters
133 result = new Type(type, option.getName(),
134 option.getPrecision(),
135 option.getParameters());
136 break;
137 } else if (precision <= option.getPrecision()) {
138 // use the requested precision
139 result = new Type(type, option.getName(), precision,
140 option.getParameters());
141 break;
142 } else {
143 _log.debug("TypeSet: requested type=" + type
144 + " exceeds precision for supported " + option);
145 }
146 }
147 } else {
148 _log.debug("TypeSet: no types matching type id=" + type
149 + ", type=" + Descriptor.getDescriptor(type).getName());
150 }
151 return result;
152 }
153
154 /***
155 * Return the near type matching the supplied type id and precision.
156 * This should only be invoked if the requested precision exceeds that
157 * supported by the database.
158 *
159 * @param type the type identifier
160 * @return the type, or null, if none exists
161 */
162 public Type getNearestType(int type, long precision) {
163 Type result = null;
164 ArrayList types = (ArrayList) _types.get(new Integer(type));
165 if (types != null) {
166 Iterator iter = types.iterator();
167 Type nearest = null;
168 while (iter.hasNext()) {
169 Type option = (Type) iter.next();
170 if (precision <= option.getPrecision()) {
171 // use the requested precision
172 result = new Type(type, option.getName(), precision,
173 option.getParameters());
174 break;
175 } else {
176 nearest = option;
177 }
178 }
179 if (result == null && nearest != null) {
180 // use the closest precision
181 result = new Type(type, nearest.getName(),
182 nearest.getPrecision(),
183 nearest.getParameters());
184 _log.warn(
185 "TypeSet: requested type=" + type + ", precision="
186 + precision + " exceeds precision supported by database. "
187 + "Falling back to " + nearest);
188 }
189 } else {
190 _log.debug("TypeSet: no types matching type id=" + type
191 + ", type=" + Descriptor.getDescriptor(type).getName());
192 }
193 return result;
194 }
195
196 /***
197 * Returns true if the type is supported
198 *
199 * @param type the type identifier
200 * @return <code>true</code> if the type is supported
201 */
202 public boolean exists(int type) {
203 return _types.containsKey(new Integer(type));
204 }
205
206
207 private void addType(int type, String name, long precision,
208 String createParams) {
209 Descriptor descriptor = Descriptor.getDescriptor(type);
210 boolean parameters = false;
211 if (createParams != null && createParams.trim().length() != 0) {
212 parameters = true;
213 }
214
215 Integer key = new Integer(type);
216 ArrayList types = (ArrayList) _types.get(key);
217 if (types == null) {
218 types = new ArrayList();
219 _types.put(key, types);
220 }
221
222 _log.debug("TypeSet: type id=" + type
223 + ", type=" + descriptor.getName()
224 + ", name=" + name
225 + ", precision=" + precision
226 + ", createParams=" + createParams);
227 types.add(new Type(type, name, precision, parameters));
228 }
229
230 } //-- TypeSet
This page was automatically generated by Maven