0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package com.sun.rave.web.ui.util;
0042:
0043: import java.io.ByteArrayInputStream;
0044: import java.io.IOException;
0045: import java.math.BigDecimal;
0046: import java.util.HashMap;
0047: import java.util.Map;
0048:
0049: /**
0050: * Provides an efficient and robust mechanism for converting an object
0051: * to a different type. For example, one can convert a <code>String</code> to
0052: * an <code>Integer</code> using the <code>TypeConverter</code> like this:
0053: *
0054: * <pre>
0055: * Integer i = (Integer) TypeConverter.asType(Integer.class, "123");
0056: * </pre>
0057: *
0058: * or using the shortcut method:
0059: *
0060: * <pre>
0061: * int i = TypeConverter.asInt("123");
0062: * </pre>
0063: *
0064: * The <code>TypeConverter</code> comes ready to convert all the primitive
0065: * types, plus a few more like <code>java.sql.Date</code> and <code>
0066: * java.math.BigDecimal</code>.<p>
0067: *
0068: * The conversion process has been optimized so that it is now a constant
0069: * time operation (aside from the conversion itself, which may vary).
0070: * Because of this optimization, it is possible to register classes that
0071: * implement the new <code>TypeConversion</code> interface for conversion
0072: * to a custom type. For example, this means that you can define a class to
0073: * convert arbitrary objects to type <code>Foo</code>, and register it for
0074: * use throughout the VM:
0075: *
0076: * <pre>
0077: * TypeConversion fooConversion = new FooTypeConversion();
0078: * TypeConverter.registerTypeConversion(Foo.class, fooConversion);
0079: * ...
0080: * Bar bar = new Bar();
0081: * Foo foo = (Foo) TypeConverter.asType(Foo.class, bar);
0082: * ...
0083: * String s = "bar";
0084: * Foo foo = (Foo) TypeConverter.asType(Foo.class, s);
0085: * </pre>
0086: *
0087: * The TypeConverter allows specification of an arbitrary <i>type key</i> in
0088: * the <code>registerTypeConversion()</code> and <code>asType()</code> methods,
0089: * so one can simultaneously register a conversion object under a <code>
0090: * Class</code> object, a class name, and a logical type name. For example,
0091: * the following are valid ways of converting a string to an <code>int</code>
0092: * using <code>TypeConverter</code>:
0093: *
0094: * <pre>
0095: * Integer i = (Integer) TypeConverter.asType(Integer.class, "123");
0096: * Integer i = (Integer) TypeConverter.asType("java.lang.Integer", "123");
0097: * Integer i = (Integer) TypeConverter.asType(TypeConverter.TYPE_INT, "123");
0098: * Integer i = (Integer) TypeConverter.asType(TypeConverter.TYPE_INTEGER, "123");
0099: * Integer i = (Integer) TypeConverter.asType("int", "123");
0100: * Integer i = (Integer) TypeConverter.asType("integer", "123");
0101: * int i = TypeConverter.asInt("123");
0102: * </pre>
0103: *
0104: * Default type conversions have been registered under the following keys:
0105: *
0106: * <pre>
0107: * Classes:
0108: * java.lang.Object
0109: * java.lang.String
0110: * java.lang.Integer
0111: * java.lang.Integer.TYPE (int)
0112: * java.lang.Double
0113: * java.lang.Double.TYPE (double)
0114: * java.lang.Boolean
0115: * java.lang.Boolean.TYPE (boolean)
0116: * java.lang.Long
0117: * java.lang.Long.TYPE (long)
0118: * java.lang.Float
0119: * java.lang.Float.TYPE (float)
0120: * java.lang.Short
0121: * java.lang.Short.TYPE (short)
0122: * java.lang.Byte
0123: * java.lang.Byte.TYPE (byte)
0124: * java.lang.Character
0125: * java.lang.Character.TYPE (char)
0126: * java.math.BigDecimal
0127: * java.sql.Date
0128: * java.sql.Time
0129: * java.sql.Timestamp
0130: *
0131: * Class name strings:
0132: * "java.lang.Object"
0133: * "java.lang.String"
0134: * "java.lang.Integer"
0135: * "java.lang.Double"
0136: * "java.lang.Boolean"
0137: * "java.lang.Long"
0138: * "java.lang.Float"
0139: * "java.lang.Short"
0140: * "java.lang.Byte"
0141: * "java.lang.Character"
0142: * "java.math.BigDecimal"
0143: * "java.sql.Date"
0144: * "java.sql.Time"
0145: * "java.sql.Timestamp"
0146: *
0147: * Logical type name string constants:
0148: * TypeConverter.TYPE_UNKNOWN ("null")
0149: * TypeConverter.TYPE_OBJECT ("object")
0150: * TypeConverter.TYPE_STRING ("string")
0151: * TypeConverter.TYPE_INT ("int")
0152: * TypeConverter.TYPE_INTEGER ("integer")
0153: * TypeConverter.TYPE_DOUBLE ("double")
0154: * TypeConverter.TYPE_BOOLEAN ("boolean")
0155: * TypeConverter.TYPE_LONG ("long")
0156: * TypeConverter.TYPE_FLOAT ("float")
0157: * TypeConverter.TYPE_SHORT ("short")
0158: * TypeConverter.TYPE_BYTE ("byte")
0159: * TypeConverter.TYPE_CHAR ("char")
0160: * TypeConverter.TYPE_CHARACTER ("character")
0161: * TypeConverter.TYPE_BIG_DECIMAL ("bigdecimal")
0162: * TypeConverter.TYPE_SQL_DATE ("sqldate")
0163: * TypeConverter.TYPE_SQL_TIME ("sqltime")
0164: * TypeConverter.TYPE_SQL_TIMESTAMP ("sqltimestamp")
0165: * </pre>
0166: *
0167: * The <code>TypeConverter</code> treats type keys of type <code>Class</code>
0168: * slightly differently than other keys. If the provided value is already of
0169: * the type specified by the type key class, it is returned without a
0170: * conversion taking place. For example, a value of type <code>MySub</code>
0171: * that extends the class <code>MySuper</code> would not be converted in the
0172: * following situation because it is already of the necessary type:
0173: *
0174: * <pre>
0175: * MySub o = (MySub) TypeConverter.asType(MySuper.class, mySub);
0176: * </pre>
0177: *
0178: * Be warned that although the type conversion infrastructure in this class
0179: * is desgned to add only minimal overhead to the conversion process, conversion
0180: * of an object to another type is a potentially expensive operation and should
0181: * be used with discretion.
0182: *
0183: * @see TypeConversion
0184: * @author Todd Fast, todd.fast@sun.com
0185: * @author Mike Frisino, michael.frisino@sun.com
0186: * @author Ken Paulsen, ken.paulsen@sun.com (stripped down)
0187: */
0188: public class TypeConverter extends Object {
0189:
0190: /**
0191: * Cannot instantiate
0192: */
0193: private TypeConverter() {
0194: super ();
0195: }
0196:
0197: /**
0198: * Return the map of type conversion objects. The keys for the values
0199: * in this map may be arbitrary objects, but the values are of type
0200: * <code>TypeConversion</code>.
0201: */
0202: public static Map getTypeConversions() {
0203: return typeConversions;
0204: }
0205:
0206: /**
0207: * Register a type conversion object under the specified key. This
0208: * method can be used by developers to register custom type conversion
0209: * objects.
0210: */
0211: public static void registerTypeConversion(Object key,
0212: TypeConversion conversion) {
0213: typeConversions.put(key, conversion);
0214: }
0215:
0216: /**
0217: * <p> Convert an object to the type specified by the provided type key.
0218: * A type conversion object must have been previously registered
0219: * under the provided key in order for the conversion to succeed (with
0220: * one exception, see below).</p>
0221: *
0222: * <p> Note, this method treats type keys of type <code>Class</code>
0223: * differently than other type keys. That is, this method will check
0224: * if the provided value is the same as or a subclass of the specified
0225: * class. If it is, this method returns the value object immediately
0226: * without attempting to convert its type. One exception to this
0227: * rule is if the provided type key is <code>Object.class</code>, in
0228: * which case the conversion is attempted anyway. The reason for this
0229: * deviation is that this key may have special meaning based on the
0230: * type of the provided value. For example, if the provided value is
0231: * a byte array, the <code>ObjectTypeConversion</code> class assumes
0232: * it is a serialized object and attempts to deserialize it. Because
0233: * all objects, including arrays, are of type <code>Object</code>,
0234: * this conversion would never be attempted without this special
0235: * handling. (Note that the default conversion for type key <code>
0236: * Object.class</code> is to simply return the original object.)</p>
0237: *
0238: * @param typeKey The key under which the desired type conversion object
0239: * has been previously registered. Most commonly, this key
0240: * should be a <code>Class</code> object, a class name
0241: * string, or a logical type string represented by the
0242: * various <code>TYPE_*</code> constants defined in this
0243: * class.
0244: *
0245: * @param value The value to convert to the specified target type
0246: *
0247: * @return The converted value object, or <code>null</code> if the
0248: * original value is <code>null</code>
0249: */
0250: public static Object asType(Object typeKey, Object value) {
0251: if (value == null) {
0252: return null;
0253: }
0254:
0255: /*
0256: System.out.println("COERCE_TYPE: Coercing ("+value+
0257: ")\n\tfrom "+value.getClass().getName()+
0258: "\n\tto "+typeKey+"\n");
0259: */
0260:
0261: if (typeKey == null) {
0262: return value;
0263: }
0264:
0265: // Check if the provided value is already of the target type
0266: if (typeKey instanceof Class
0267: && ((Class) typeKey) != Object.class) {
0268: if (((Class) typeKey).isInstance(value)) {
0269: return value;
0270: }
0271: }
0272:
0273: // Find the type conversion object
0274: TypeConversion conversion = (TypeConversion) typeConversions
0275: .get(typeKey);
0276:
0277: // Convert the value
0278: if (conversion != null) {
0279: return conversion.convertValue(value);
0280: } else {
0281: throw new IllegalArgumentException(
0282: "Could not find type conversion for " + "type \""
0283: + typeKey + "\" (value = \"" + value + "\"");
0284: }
0285: }
0286:
0287: /**
0288: *
0289: */
0290: public static byte asByte(Object value) {
0291: return asByte(value, (byte) 0);
0292: }
0293:
0294: /**
0295: *
0296: */
0297: public static byte asByte(Object value, byte defaultValue) {
0298: value = asType(Byte.class, value);
0299: if (value != null) {
0300: return ((Byte) value).byteValue();
0301: }
0302: return defaultValue;
0303: }
0304:
0305: /**
0306: *
0307: */
0308: public static short asShort(Object value) {
0309: return asShort(value, (short) 0);
0310: }
0311:
0312: /**
0313: *
0314: */
0315: public static short asShort(Object value, short defaultValue) {
0316: value = asType(Short.class, value);
0317: if (value != null) {
0318: return ((Short) value).shortValue();
0319: }
0320: return defaultValue;
0321: }
0322:
0323: /**
0324: *
0325: */
0326: public static int asInt(Object value) {
0327: return asInt(value, 0);
0328: }
0329:
0330: /**
0331: *
0332: */
0333: public static int asInt(Object value, int defaultValue) {
0334: value = asType(Integer.class, value);
0335: if (value != null) {
0336: return ((Integer) value).intValue();
0337: }
0338: return defaultValue;
0339: }
0340:
0341: /**
0342: *
0343: */
0344: public static long asLong(Object value) {
0345: return asLong(value, 0L);
0346: }
0347:
0348: /**
0349: *
0350: */
0351: public static long asLong(Object value, long defaultValue) {
0352: value = asType(Long.class, value);
0353: if (value != null) {
0354: return ((Long) value).longValue();
0355: }
0356: return defaultValue;
0357: }
0358:
0359: /**
0360: *
0361: */
0362: public static float asFloat(Object value) {
0363: return asFloat(value, 0F);
0364: }
0365:
0366: /**
0367: *
0368: */
0369: public static float asFloat(Object value, float defaultValue) {
0370: value = asType(Float.class, value);
0371: if (value != null) {
0372: return ((Float) value).floatValue();
0373: }
0374: return defaultValue;
0375: }
0376:
0377: /**
0378: *
0379: */
0380: public static double asDouble(Object value) {
0381: return asDouble(value, 0D);
0382: }
0383:
0384: /**
0385: *
0386: */
0387: public static double asDouble(Object value, double defaultValue) {
0388: value = asType(Double.class, value);
0389: if (value != null) {
0390: return ((Double) value).doubleValue();
0391: }
0392: return defaultValue;
0393: }
0394:
0395: /**
0396: *
0397: */
0398: public static char asChar(Object value) {
0399: return asChar(value, (char) 0);
0400: }
0401:
0402: /**
0403: *
0404: */
0405: public static char asChar(Object value, char defaultValue) {
0406: value = asType(Character.class, value);
0407: if (value != null) {
0408: return ((Character) value).charValue();
0409: }
0410: return defaultValue;
0411: }
0412:
0413: /**
0414: *
0415: */
0416: public static boolean asBoolean(Object value) {
0417: return asBoolean(value, false);
0418: }
0419:
0420: /**
0421: *
0422: */
0423: public static boolean asBoolean(Object value, boolean defaultValue) {
0424: value = asType(Boolean.class, value);
0425: if (value != null) {
0426: return ((Boolean) value).booleanValue();
0427: }
0428: return defaultValue;
0429: }
0430:
0431: /**
0432: *
0433: */
0434: public static String asString(Object value) {
0435: return (String) asType(String.class, value);
0436: }
0437:
0438: /**
0439: *
0440: */
0441: public static String asString(Object value, String defaultValue) {
0442: value = asType(String.class, value);
0443: if (value != null) {
0444: return (String) value;
0445: }
0446: return defaultValue;
0447: }
0448:
0449: ////////////////////////////////////////////////////////////////////////////////
0450: // Inner classes
0451: ////////////////////////////////////////////////////////////////////////////////
0452:
0453: /**
0454: *
0455: */
0456: public static class UnknownTypeConversion implements TypeConversion {
0457: /**
0458: *
0459: */
0460: public Object convertValue(Object value) {
0461: return value;
0462: }
0463: }
0464:
0465: /**
0466: *
0467: */
0468: public static class StringTypeConversion implements TypeConversion {
0469: /**
0470: *
0471: */
0472: public Object convertValue(Object value) {
0473: if (value == null) {
0474: return null;
0475: }
0476:
0477: if (value.getClass().isArray()) {
0478: // This is a byte array; we can convert it to a string
0479: if (value.getClass().getComponentType() == Byte.TYPE) {
0480: value = new String((byte[]) value);
0481: } else if (value.getClass().getComponentType() == Character.TYPE) {
0482: value = new String((char[]) value);
0483: }
0484: } else if (!(value instanceof String)) {
0485: value = value.toString();
0486: }
0487: return value;
0488: }
0489: }
0490:
0491: /**
0492: *
0493: */
0494: public static class IntegerTypeConversion implements TypeConversion {
0495: /**
0496: *
0497: */
0498: public Object convertValue(Object value) {
0499: if (value == null) {
0500: return null;
0501: }
0502:
0503: if (!(value instanceof Integer)) {
0504: String v = value.toString();
0505: if (v.trim().length() == 0) {
0506: value = null;
0507: } else {
0508: value = new Integer(v);
0509: }
0510: }
0511:
0512: return value;
0513: }
0514: }
0515:
0516: /**
0517: *
0518: *
0519: */
0520: public static class DoubleTypeConversion implements TypeConversion {
0521: /**
0522: *
0523: *
0524: */
0525: public Object convertValue(Object value) {
0526: if (value == null) {
0527: return null;
0528: }
0529:
0530: if (!(value instanceof Double)) {
0531: String v = value.toString();
0532: if (v.trim().length() == 0) {
0533: value = null;
0534: } else {
0535: value = new Double(v);
0536: }
0537: }
0538:
0539: return value;
0540: }
0541: }
0542:
0543: /**
0544: *
0545: */
0546: public static class BooleanTypeConversion implements TypeConversion {
0547: /**
0548: *
0549: */
0550: public Object convertValue(Object value) {
0551: if (value == null) {
0552: return null;
0553: }
0554:
0555: if (!(value instanceof Boolean)) {
0556: String v = value.toString();
0557: if (v.trim().length() == 0) {
0558: value = null;
0559: } else {
0560: value = Boolean.valueOf(v);
0561: }
0562: }
0563:
0564: return value;
0565: }
0566: }
0567:
0568: /**
0569: *
0570: */
0571: public static class LongTypeConversion implements TypeConversion {
0572: /**
0573: *
0574: */
0575: public Object convertValue(Object value) {
0576: if (value == null) {
0577: return null;
0578: }
0579:
0580: if (!(value instanceof Long)) {
0581: String v = value.toString();
0582: if (v.trim().length() == 0) {
0583: value = null;
0584: } else {
0585: value = new Long(v);
0586: }
0587: }
0588:
0589: return value;
0590: }
0591: }
0592:
0593: /**
0594: *
0595: */
0596: public static class FloatTypeConversion implements TypeConversion {
0597: /**
0598: *
0599: */
0600: public Object convertValue(Object value) {
0601: if (value == null) {
0602: return null;
0603: }
0604:
0605: if (!(value instanceof Float)) {
0606: String v = value.toString();
0607: if (v.trim().length() == 0) {
0608: value = null;
0609: } else {
0610: value = new Float(v);
0611: }
0612: }
0613:
0614: return value;
0615: }
0616: }
0617:
0618: /**
0619: *
0620: */
0621: public static class ShortTypeConversion implements TypeConversion {
0622: /**
0623: *
0624: */
0625: public Object convertValue(Object value) {
0626: if (value == null) {
0627: return null;
0628: }
0629:
0630: if (!(value instanceof Short)) {
0631: String v = value.toString();
0632: if (v.trim().length() == 0) {
0633: value = null;
0634: } else {
0635: value = new Short(v);
0636: }
0637: }
0638:
0639: return value;
0640: }
0641: }
0642:
0643: /**
0644: *
0645: */
0646: public static class BigDecimalTypeConversion implements
0647: TypeConversion {
0648: /**
0649: *
0650: */
0651: public Object convertValue(Object value) {
0652: if (value == null) {
0653: return null;
0654: }
0655:
0656: if (!(value instanceof BigDecimal)) {
0657: String v = value.toString();
0658: if (v.trim().length() == 0) {
0659: value = null;
0660: } else {
0661: value = new BigDecimal(v);
0662: }
0663: }
0664:
0665: return value;
0666: }
0667: }
0668:
0669: /**
0670: *
0671: */
0672: public static class ByteTypeConversion implements TypeConversion {
0673: /**
0674: *
0675: */
0676: public Object convertValue(Object value) {
0677: if (value == null) {
0678: return null;
0679: }
0680:
0681: if (!(value instanceof Byte)) {
0682: String v = value.toString();
0683: if (v.trim().length() == 0) {
0684: value = null;
0685: } else {
0686: value = new Byte(v);
0687: }
0688: }
0689:
0690: return value;
0691: }
0692: }
0693:
0694: /**
0695: *
0696: */
0697: public static class CharacterTypeConversion implements
0698: TypeConversion {
0699: /**
0700: *
0701: */
0702: public Object convertValue(Object value) {
0703: if (value == null) {
0704: return null;
0705: }
0706:
0707: if (!(value instanceof Character)) {
0708: String v = value.toString();
0709: if (v.trim().length() == 0) {
0710: value = null;
0711: } else {
0712: value = new Character(v.charAt(0));
0713: }
0714: }
0715:
0716: return value;
0717: }
0718: }
0719:
0720: /**
0721: *
0722: */
0723: public static class SqlDateTypeConversion implements TypeConversion {
0724: /**
0725: *
0726: */
0727: public Object convertValue(Object value) {
0728: if (value == null) {
0729: return null;
0730: }
0731:
0732: if (!(value instanceof java.sql.Date)) {
0733: String v = value.toString();
0734: if (v.trim().length() == 0) {
0735: value = null;
0736: } else {
0737: // Value must be in the "yyyy-mm-dd" format
0738: value = java.sql.Date.valueOf(v);
0739: }
0740: }
0741:
0742: return value;
0743: }
0744: }
0745:
0746: /**
0747: *
0748: */
0749: public static class SqlTimeTypeConversion implements TypeConversion {
0750: /**
0751: *
0752: */
0753: public Object convertValue(Object value) {
0754: if (value == null) {
0755: return null;
0756: }
0757:
0758: if (!(value instanceof java.sql.Time)) {
0759: String v = value.toString();
0760: if (v.trim().length() == 0) {
0761: value = null;
0762: } else {
0763: // Value must be in the "hh:mm:ss" format
0764: value = java.sql.Time.valueOf(v);
0765: }
0766: }
0767:
0768: return value;
0769: }
0770: }
0771:
0772: /**
0773: *
0774: */
0775: public static class SqlTimestampTypeConversion implements
0776: TypeConversion {
0777: /**
0778: *
0779: */
0780: public Object convertValue(Object value) {
0781: if (value == null) {
0782: return null;
0783: }
0784:
0785: if (!(value instanceof java.sql.Timestamp)) {
0786: String v = value.toString();
0787: if (v.trim().length() == 0) {
0788: value = null;
0789: } else {
0790: // Value must be in the "yyyy-mm-dd hh:mm:ss.fffffffff"
0791: // format
0792: value = java.sql.Timestamp.valueOf(v);
0793: }
0794: }
0795:
0796: return value;
0797: }
0798: }
0799:
0800: /**
0801: *
0802: */
0803: public static class ObjectTypeConversion implements TypeConversion {
0804: public Object convertValue(Object value) {
0805: /*
0806: if (value==null) {
0807: return null;
0808: }
0809:
0810: // TODO: Decide if this is important functionality. For now just return the Object that is passed in.
0811: if (value.getClass().isArray()) {
0812: // This is a byte array; we can convert it to an object
0813: if (value.getClass().getComponentType()==Byte.TYPE) {
0814: ByteArrayInputStream bis=
0815: new ByteArrayInputStream((byte[])value);
0816: ApplicationObjectInputStream ois=null;
0817: try {
0818: ois=new ApplicationObjectInputStream(bis);
0819: value=ois.readObject();
0820: } catch (Exception e) {
0821: throw new WrapperRuntimeException(
0822: "Could not deserialize object",e);
0823: } finally {
0824: try {
0825: if (ois!=null) {
0826: ois.close();
0827: }
0828: if (bis!=null) {
0829: bis.close();
0830: }
0831: } catch (IOException e) {
0832: // Ignore
0833: }
0834: }
0835: } else {
0836: // value is OK as is
0837: }
0838: }
0839: */
0840:
0841: return value;
0842: }
0843: }
0844:
0845: ////////////////////////////////////////////////////////////////////////////////
0846: // Test classes
0847: ////////////////////////////////////////////////////////////////////////////////
0848:
0849: private static class TestSuperclass extends Object {
0850: }
0851:
0852: private static class Test extends TestSuperclass {
0853: public static void main(String[] args) {
0854: if (!(TypeConverter.asString(new Integer(12)) instanceof String)) {
0855: throw new Error();
0856: }
0857:
0858: if (!(TypeConverter.asType(Integer.class, "12") instanceof Integer)) {
0859: throw new Error();
0860: }
0861:
0862: if (!(TypeConverter.asType(Long.class, "12") instanceof Long)) {
0863: throw new Error();
0864: }
0865:
0866: if (!(TypeConverter.asType(Float.class, "12.0") instanceof Float)) {
0867: throw new Error();
0868: }
0869:
0870: if (!(TypeConverter.asType(Double.class, "12.0") instanceof Double)) {
0871: throw new Error();
0872: }
0873:
0874: if (!(TypeConverter.asType(Short.class, "12") instanceof Short)) {
0875: throw new Error();
0876: }
0877:
0878: if (!(TypeConverter.asType(BigDecimal.class, "12") instanceof BigDecimal)) {
0879: throw new Error();
0880: }
0881:
0882: if (!(TypeConverter.asType(Boolean.class, "true") instanceof Boolean)) {
0883: throw new Error();
0884: }
0885:
0886: if (!(TypeConverter.asType(Byte.class, "12") instanceof Byte)) {
0887: throw new Error();
0888: }
0889:
0890: if (!(TypeConverter.asType(Character.class, "1") instanceof Character)) {
0891: throw new Error();
0892: }
0893:
0894: System.out.println("Test passed.");
0895: }
0896: }
0897:
0898: ////////////////////////////////////////////////////////////////////////////////
0899: // Class variables
0900: ////////////////////////////////////////////////////////////////////////////////
0901:
0902: private static final Map typeConversions = new HashMap();
0903:
0904: /** Logical type name "null" */
0905: public static final String TYPE_UNKNOWN = "null";
0906:
0907: /** Logical type name "object" */
0908: public static final String TYPE_OBJECT = "object";
0909:
0910: /** Logical type name "string" */
0911: public static final String TYPE_STRING = "string";
0912:
0913: /** Logical type name "int" */
0914: public static final String TYPE_INT = "int";
0915:
0916: /** Logical type name "integer" */
0917: public static final String TYPE_INTEGER = "integer";
0918:
0919: /** Logical type name "long" */
0920: public static final String TYPE_LONG = "long";
0921:
0922: /** Logical type name "float" */
0923: public static final String TYPE_FLOAT = "float";
0924:
0925: /** Logical type name "double" */
0926: public static final String TYPE_DOUBLE = "double";
0927:
0928: /** Logical type name "short" */
0929: public static final String TYPE_SHORT = "short";
0930:
0931: /** Logical type name "boolean" */
0932: public static final String TYPE_BOOLEAN = "boolean";
0933:
0934: /** Logical type name "byte" */
0935: public static final String TYPE_BYTE = "byte";
0936:
0937: /** Logical type name "char" */
0938: public static final String TYPE_CHAR = "char";
0939:
0940: /** Logical type name "character" */
0941: public static final String TYPE_CHARACTER = "character";
0942:
0943: /** Logical type name "bigdecimal" */
0944: public static final String TYPE_BIG_DECIMAL = "bigdecimal";
0945:
0946: /** Logical type name "sqldate" */
0947: public static final String TYPE_SQL_DATE = "sqldate";
0948:
0949: /** Logical type name "sqltime" */
0950: public static final String TYPE_SQL_TIME = "sqltime";
0951:
0952: /** Logical type name "sqltimestamp" */
0953: public static final String TYPE_SQL_TIMESTAMP = "sqltimestamp";
0954:
0955: public static final TypeConversion UNKNOWN_TYPE_CONVERSION = new UnknownTypeConversion();
0956: public static final TypeConversion OBJECT_TYPE_CONVERSION = new ObjectTypeConversion();
0957: public static final TypeConversion STRING_TYPE_CONVERSION = new StringTypeConversion();
0958: public static final TypeConversion INTEGER_TYPE_CONVERSION = new IntegerTypeConversion();
0959: public static final TypeConversion DOUBLE_TYPE_CONVERSION = new DoubleTypeConversion();
0960: public static final TypeConversion BOOLEAN_TYPE_CONVERSION = new BooleanTypeConversion();
0961: public static final TypeConversion LONG_TYPE_CONVERSION = new LongTypeConversion();
0962: public static final TypeConversion FLOAT_TYPE_CONVERSION = new FloatTypeConversion();
0963: public static final TypeConversion SHORT_TYPE_CONVERSION = new ShortTypeConversion();
0964: public static final TypeConversion BIG_DECIMAL_TYPE_CONVERSION = new BigDecimalTypeConversion();
0965: public static final TypeConversion BYTE_TYPE_CONVERSION = new ByteTypeConversion();
0966: public static final TypeConversion CHARACTER_TYPE_CONVERSION = new CharacterTypeConversion();
0967: public static final TypeConversion SQL_DATE_TYPE_CONVERSION = new SqlDateTypeConversion();
0968: public static final TypeConversion SQL_TIME_TYPE_CONVERSION = new SqlTimeTypeConversion();
0969: public static final TypeConversion SQL_TIMESTAMP_TYPE_CONVERSION = new SqlTimestampTypeConversion();
0970:
0971: ////////////////////////////////////////////////////////////////////////////////
0972: // Initializers
0973: ////////////////////////////////////////////////////////////////////////////////
0974:
0975: static {
0976: // Add type conversions by class
0977: registerTypeConversion(Object.class, OBJECT_TYPE_CONVERSION);
0978: registerTypeConversion(String.class, STRING_TYPE_CONVERSION);
0979: registerTypeConversion(Integer.class, INTEGER_TYPE_CONVERSION);
0980: registerTypeConversion(Integer.TYPE, INTEGER_TYPE_CONVERSION);
0981: registerTypeConversion(Double.class, DOUBLE_TYPE_CONVERSION);
0982: registerTypeConversion(Double.TYPE, DOUBLE_TYPE_CONVERSION);
0983: registerTypeConversion(Boolean.class, BOOLEAN_TYPE_CONVERSION);
0984: registerTypeConversion(Boolean.TYPE, BOOLEAN_TYPE_CONVERSION);
0985: registerTypeConversion(Long.class, LONG_TYPE_CONVERSION);
0986: registerTypeConversion(Long.TYPE, LONG_TYPE_CONVERSION);
0987: registerTypeConversion(Float.class, FLOAT_TYPE_CONVERSION);
0988: registerTypeConversion(Float.TYPE, FLOAT_TYPE_CONVERSION);
0989: registerTypeConversion(Short.class, SHORT_TYPE_CONVERSION);
0990: registerTypeConversion(Short.TYPE, SHORT_TYPE_CONVERSION);
0991: registerTypeConversion(BigDecimal.class,
0992: BIG_DECIMAL_TYPE_CONVERSION);
0993: registerTypeConversion(Byte.class, BYTE_TYPE_CONVERSION);
0994: registerTypeConversion(Byte.TYPE, BYTE_TYPE_CONVERSION);
0995: registerTypeConversion(Character.class,
0996: CHARACTER_TYPE_CONVERSION);
0997: registerTypeConversion(Character.TYPE,
0998: CHARACTER_TYPE_CONVERSION);
0999: registerTypeConversion(java.sql.Date.class,
1000: SQL_DATE_TYPE_CONVERSION);
1001: registerTypeConversion(java.sql.Time.class,
1002: SQL_TIME_TYPE_CONVERSION);
1003: registerTypeConversion(java.sql.Timestamp.class,
1004: SQL_TIMESTAMP_TYPE_CONVERSION);
1005:
1006: // Add type conversions by class name
1007: registerTypeConversion(Object.class.getName(),
1008: OBJECT_TYPE_CONVERSION);
1009: registerTypeConversion(String.class.getName(),
1010: STRING_TYPE_CONVERSION);
1011: registerTypeConversion(Integer.class.getName(),
1012: INTEGER_TYPE_CONVERSION);
1013: registerTypeConversion(Double.class.getName(),
1014: DOUBLE_TYPE_CONVERSION);
1015: registerTypeConversion(Boolean.class.getName(),
1016: BOOLEAN_TYPE_CONVERSION);
1017: registerTypeConversion(Long.class.getName(),
1018: LONG_TYPE_CONVERSION);
1019: registerTypeConversion(Float.class.getName(),
1020: FLOAT_TYPE_CONVERSION);
1021: registerTypeConversion(Short.class.getName(),
1022: SHORT_TYPE_CONVERSION);
1023: registerTypeConversion(BigDecimal.class.getName(),
1024: BIG_DECIMAL_TYPE_CONVERSION);
1025: registerTypeConversion(Byte.class.getName(),
1026: BYTE_TYPE_CONVERSION);
1027: registerTypeConversion(Character.class.getName(),
1028: CHARACTER_TYPE_CONVERSION);
1029: registerTypeConversion(java.sql.Date.class.getName(),
1030: SQL_DATE_TYPE_CONVERSION);
1031: registerTypeConversion(java.sql.Time.class.getName(),
1032: SQL_TIME_TYPE_CONVERSION);
1033: registerTypeConversion(java.sql.Timestamp.class.getName(),
1034: SQL_TIMESTAMP_TYPE_CONVERSION);
1035:
1036: // Add type conversions by name
1037: registerTypeConversion(TYPE_UNKNOWN, UNKNOWN_TYPE_CONVERSION);
1038: registerTypeConversion(TYPE_OBJECT, OBJECT_TYPE_CONVERSION);
1039: registerTypeConversion(TYPE_STRING, STRING_TYPE_CONVERSION);
1040: registerTypeConversion(TYPE_INT, INTEGER_TYPE_CONVERSION);
1041: registerTypeConversion(TYPE_INTEGER, INTEGER_TYPE_CONVERSION);
1042: registerTypeConversion(TYPE_DOUBLE, DOUBLE_TYPE_CONVERSION);
1043: registerTypeConversion(TYPE_BOOLEAN, BOOLEAN_TYPE_CONVERSION);
1044: registerTypeConversion(TYPE_LONG, LONG_TYPE_CONVERSION);
1045: registerTypeConversion(TYPE_FLOAT, FLOAT_TYPE_CONVERSION);
1046: registerTypeConversion(TYPE_SHORT, SHORT_TYPE_CONVERSION);
1047: registerTypeConversion(TYPE_BIG_DECIMAL,
1048: BIG_DECIMAL_TYPE_CONVERSION);
1049: registerTypeConversion(TYPE_BYTE, BYTE_TYPE_CONVERSION);
1050: registerTypeConversion(TYPE_CHAR, CHARACTER_TYPE_CONVERSION);
1051: registerTypeConversion(TYPE_CHARACTER,
1052: CHARACTER_TYPE_CONVERSION);
1053: registerTypeConversion(TYPE_SQL_DATE, SQL_DATE_TYPE_CONVERSION);
1054: registerTypeConversion(TYPE_SQL_TIME, SQL_TIME_TYPE_CONVERSION);
1055: registerTypeConversion(TYPE_SQL_TIMESTAMP,
1056: SQL_TIMESTAMP_TYPE_CONVERSION);
1057: }
1058: }
|