001: /*
002: * $Id: TypeUtils.java,v 1.7 2005/05/21 19:41:23 spal Exp $
003: * $Source: /cvsroot/sqlunit/sqlunit/src/net/sourceforge/sqlunit/utils/TypeUtils.java,v $
004: * SQLUnit - a test harness for unit testing database stored procedures.
005: * Copyright (C) 2003 The SQLUnit Team
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021: package net.sourceforge.sqlunit.utils;
022:
023: import java.math.BigDecimal;
024: import java.util.HashMap;
025:
026: import net.sourceforge.sqlunit.IType;
027: import net.sourceforge.sqlunit.SQLUnitException;
028: import net.sourceforge.sqlunit.SymbolTable;
029: import net.sourceforge.sqlunit.TypeFactory;
030: import net.sourceforge.sqlunit.TypeMapper;
031:
032: import org.apache.log4j.Logger;
033:
034: /**
035: * Provides commonly used functionality to convert between SQL, Java and
036: * XML data type names.
037: * @author Sujit Pal (spal@users.sourceforge.net)
038: * @version $Revision: 1.7 $
039: */
040: public final class TypeUtils {
041:
042: private static final Logger LOG = Logger.getLogger(TypeUtils.class);
043:
044: private static HashMap xmlToSqlMap = new HashMap();
045: private static HashMap sqlToXmlMap = new HashMap();
046: private static boolean mapCreated = false;
047:
048: /**
049: * Private Constructor. Cannot be instantiated.
050: */
051: private TypeUtils() {
052: // private constructor, cannot instantiate
053: }
054:
055: /**
056: * Returns the XML Type given the SQL Type Id. For example, return INTEGER
057: * when passed a value of java.sql.Types.INTEGER.
058: * @param sqlType a valid java.sql.Types value.
059: * @return the XML Type name.
060: * @exception SQLUnitException if the sqlType is invalid. Should never
061: * occur since we call this only when parsing a Result.
062: */
063: public static String getXmlTypeFromSqlType(final int sqlType)
064: throws SQLUnitException {
065: LOG.debug(">> getXmlTypeFromSqlType(" + sqlType + ")");
066: return TypeMapper.findNameById(sqlType);
067: }
068:
069: /**
070: * Returns the SQL Type given the XML Type name. For example, returns
071: * java.sql.Types.INTEGER when passed in the String INTEGER.
072: * @param xmlType a valid String corresponding to a java.sql.Type constant.
073: * @return the corresponding java.sql.Types constant value.
074: * @exception SQLUnitException if the xmlType is incorrectly specified.
075: */
076: public static int getSqlTypeFromXmlType(final String xmlType)
077: throws SQLUnitException {
078: LOG.debug(">> getSqlTypeFromXmlType(" + xmlType + ")");
079: return TypeMapper.findIdByName(xmlType);
080: }
081:
082: /**
083: * Converts a String representation of a specific xmlType to the
084: * corresponding Java object for use by PreparedStatement and its
085: * children. This is used to convert the input parameters for a
086: * Stored procedure from the String representation to the appropriate
087: * object representation.
088: * @param value the String representation of the value to convert.
089: * @param xmlType the XML Type of the target object.
090: * @return an Object of the required java type.
091: * @exception SQLUnitException if there was a problem converting.
092: */
093: public static Object convertToObject(final String value,
094: final String xmlType) throws SQLUnitException {
095: LOG.debug(">> convertToObject(" + value + "," + xmlType + ")");
096: if (value == null) {
097: return null;
098: }
099: if (SymbolTable.isVariableName(value)) {
100: return convertToObject(SymbolTable.getValue(value), xmlType);
101: } else {
102: IType type = TypeFactory.getInstance(xmlType);
103: return type.toObject(value);
104: }
105: }
106:
107: /**
108: * Converts an Object with the specified type to the corresponding
109: * String representation. Only a few types are given special treatment
110: * by SQLUnit.
111: * @param obj the Object to convert to a String.
112: * @param sqlType the type of the object as defined by java.sql.Types.
113: * @return a String representation of the object.
114: * @exception SQLUnitException if there was a problem during conversion.
115: */
116: public static String convertToString(final Object obj,
117: final int sqlType) throws SQLUnitException {
118: LOG.debug(">> convertToString(obj," + sqlType + ")");
119: if (obj == null) {
120: return "NULL";
121: }
122: IType type = TypeFactory.getInstance(sqlType);
123: return type.toString(obj);
124: }
125:
126: /**
127: * Convenience method to convert a String to an int, and replace
128: * with a default value if the conversion fails.
129: * @param s the String to convert to an int.
130: * @param def the default int value to use.
131: * @return the int after the conversion.
132: */
133: public static int convertStringToInt(final String s, final int def) {
134: LOG.debug(">> convertToInt(" + s + "," + def + ")");
135: int i = def;
136: try {
137: i = Integer.parseInt(s);
138: } catch (NumberFormatException e) {
139: // :IGNORE: reset to default
140: }
141: return i;
142: }
143:
144: /**
145: * Returns true if Java Support has been turned on.
146: * @return true if Java Support is turned on, else false.
147: */
148: public static boolean hasJavaObjectSupport() {
149: LOG.debug(">> hasJavaObjectSupport()");
150: String javaSupport = SymbolTable
151: .getValue(SymbolTable.JAVA_OBJECT_SUPPORT);
152: return (javaSupport != null && javaSupport.equals("on"));
153: }
154:
155: /**
156: * Computes the scale value of a value that maps to a BigDecimalType
157: * class by counting the number of digits after the decimal point.
158: * @param value the String value of a parameter that maps to the
159: * BigDecimalType object.
160: * @return the scale of this value.
161: */
162: public static int computeScale(String value) {
163: if (value == null) {
164: return 0;
165: }
166: int decpos = value.indexOf(".");
167: if (decpos > -1) {
168: return value.substring(decpos + 1).length();
169: } else {
170: return 0;
171: }
172: }
173:
174: /**
175: * Returns true if both String values resolve to BigDecimal objects
176: * with identical values and scale.
177: * @param bd1 the String value of a BigDecimal number.
178: * @param bd2 the String value of another BigDecimal number.
179: * @return true if the two numbers are equal.
180: */
181: public static boolean isValueOfBigDecimalEqual(String bd1,
182: String bd2) {
183: BigDecimal this BigDecimal = null;
184: BigDecimal thatBigDecimal = null;
185: if (!("NULL").equals(bd1)) {
186: this BigDecimal = new BigDecimal(bd1);
187: }
188: if (!("NULL").equals(bd2)) {
189: int scale = TypeUtils.computeScale(bd1);
190: thatBigDecimal = new BigDecimal(bd2).setScale(scale,
191: BigDecimal.ROUND_HALF_DOWN);
192: }
193: if (this BigDecimal == null) {
194: if (thatBigDecimal == null) {
195: return true;
196: } else {
197: return false;
198: }
199: } else {
200: return this BigDecimal.equals(thatBigDecimal);
201: }
202: }
203:
204: /**
205: * Returns true if either of the IType arguments contain null values.
206: * @param typeObj1 an IType object to compare.
207: * @param typeObj2 another IType object to compare.
208: * @return true if either of the IType objects contain null values.
209: */
210: public static boolean checkIfNull(IType typeObj1, IType typeObj2) {
211: Object value1 = null;
212: Object value2 = null;
213: if (typeObj1 != null) {
214: value1 = typeObj1.getValue();
215: }
216: if (typeObj2 != null) {
217: value2 = typeObj2.getValue();
218: }
219: return (value1 == null || value2 == null);
220: }
221:
222: /**
223: * Compares two IType object values, one or both of which is NULL.
224: * If both are null, then returns 0. If value of typeObj1 is NULL,
225: * then returns -1, else returns 1. We assume that the order of
226: * precedence in the comparison is that NULL is lesser of the two.
227: * @param typeObj1 an IType object to compare.
228: * @param typeObj2 another IType object to compare.
229: * @return true -1, 0, or 1, according as value of typeObj1 is less
230: * than, equal to or greater than typeObj2.
231: */
232: public static int compareNulls(IType typeObj1, IType typeObj2) {
233: Object value1 = null;
234: Object value2 = null;
235: if (typeObj1 != null) {
236: value1 = typeObj1.getValue();
237: }
238: if (typeObj2 != null) {
239: value2 = typeObj2.getValue();
240: }
241: if (value1 == null && value2 != null) {
242: return -1;
243: }
244: if (value1 != null && value2 == null) {
245: return 1;
246: }
247: // both null
248: return 0;
249: }
250: }
|