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 */ 017package org.apache.juneau.internal; 018 019import static org.apache.juneau.common.utils.ThrowableUtils.*; 020 021import java.lang.reflect.*; 022 023import org.apache.juneau.*; 024import org.apache.juneau.common.utils.*; 025import org.apache.juneau.parser.*; 026import org.apache.juneau.swap.*; 027 028/** 029 * Utility class for efficiently converting objects between types. 030 * 031 * <p> 032 * If the value isn't an instance of the specified type, then converts the value if possible. 033 * 034 * <p> 035 * The following conversions are valid: 036 * <table class='styled'> 037 * <tr><th>Convert to type</th><th>Valid input value types</th><th>Notes</th></tr> 038 * <tr> 039 * <td> 040 * A class that is the normal type of a registered {@link ObjectSwap}. 041 * </td> 042 * <td> 043 * A value whose class matches the transformed type of that registered {@link ObjectSwap}. 044 * </td> 045 * <td> </td> 046 * </tr> 047 * <tr> 048 * <td> 049 * A class that is the transformed type of a registered {@link ObjectSwap}. 050 * </td> 051 * <td> 052 * A value whose class matches the normal type of that registered {@link ObjectSwap}. 053 * </td> 054 * <td> </td> 055 * </tr> 056 * <tr> 057 * <td> 058 * {@code Number} (e.g. {@code Integer}, {@code Short}, {@code Float},...) 059 * <br><code>Number.<jsf>TYPE</jsf></code> (e.g. <code>Integer.<jsf>TYPE</jsf></code>, 060 * <code>Short.<jsf>TYPE</jsf></code>, <code>Float.<jsf>TYPE</jsf></code>,...) 061 * </td> 062 * <td> 063 * {@code Number}, {@code String}, <jk>null</jk> 064 * </td> 065 * <td> 066 * For primitive {@code TYPES}, <jk>null</jk> returns the JVM default value for that type. 067 * </td> 068 * </tr> 069 * <tr> 070 * <td> 071 * {@code Map} (e.g. {@code Map}, {@code HashMap}, {@code TreeMap}, {@code JsonMap}) 072 * </td> 073 * <td> 074 * {@code Map} 075 * </td> 076 * <td> 077 * If {@code Map} is not constructible, an {@code JsonMap} is created. 078 * </td> 079 * </tr> 080 * <tr> 081 * <td> 082 * <c>Collection</c> (e.g. <c>List</c>, <c>LinkedList</c>, <c>HashSet</c>, <c>JsonList</c>) 083 * </td> 084 * <td> 085 * <c>Collection<Object></c> 086 * <br><c>Object[]</c> 087 * </td> 088 * <td> 089 * If <c>Collection</c> is not constructible, a <c>JsonList</c> is created. 090 * </td> 091 * </tr> 092 * <tr> 093 * <td> 094 * <c>X[]</c> (array of any type X) 095 * </td> 096 * <td> 097 * <c>List<X></c> 098 * </td> 099 * <td> </td> 100 * </tr> 101 * <tr> 102 * <td> 103 * <c>X[][]</c> (multi-dimensional arrays) 104 * </td> 105 * <td> 106 * <c>List<List<X>></c> 107 * <br><c>List<X[]></c> 108 * <br><c> List[]<X></c> 109 * </td> 110 * <td> </td> 111 * </tr> 112 * <tr> 113 * <td> 114 * <c>Enum</c> 115 * </td> 116 * <td> 117 * <c>String</c> 118 * </td> 119 * <td> </td> 120 * </tr> 121 * <tr> 122 * <td> 123 * Bean 124 * </td> 125 * <td> 126 * <c>Map</c> 127 * </td> 128 * <td> </td> 129 * </tr> 130 * <tr> 131 * <td> 132 * <c>String</c> 133 * </td> 134 * <td> 135 * Anything 136 * </td> 137 * <td> 138 * Arrays are converted to JSON arrays 139 * </td> 140 * </tr> 141 * <tr> 142 * <td> 143 * Anything with one of the following methods: 144 * <br><code><jk>public static</jk> T fromString(String)</code> 145 * <br><code><jk>public static</jk> T valueOf(String)</code> 146 * <br><code><jk>public</jk> T(String)</code> 147 * </td> 148 * <td> 149 * <c>String</c> 150 * </td> 151 * <td> 152 * <br> 153 * </td> 154 * </tr> 155 * </table> 156 * 157 * <h5 class='section'>See Also:</h5><ul> 158 * </ul> 159 */ 160public class ConverterUtils { 161 162 // Session objects are usually not thread safe, but we're not using any feature 163 // of bean sessions that would cause thread safety issues. 164 private static final BeanSession session = BeanContext.DEFAULT_SESSION; 165 166 /** 167 * Converts the specified object to the specified type. 168 * 169 * @param <T> The class type to convert the value to. 170 * @param value The value to convert. 171 * @param type The class type to convert the value to. 172 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type. 173 * @return The converted value. 174 */ 175 public static <T> T toType(Object value, Class<T> type) { 176 return session.convertToType(value, type); 177 } 178 179 180 /** 181 * Converts the specified object to the specified type. 182 * 183 * @param <T> The class type to convert the value to. 184 * @param value The value to convert. 185 * @param type The class type to convert the value to. 186 * @param args The type arguments. 187 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type. 188 * @return The converted value. 189 */ 190 public static <T> T toType(Object value, Class<T> type, Type...args) { 191 return session.convertToType(value, type, args); 192 } 193 194 /** 195 * Converts an object to a Boolean. 196 * 197 * @param o The object to convert. 198 * @return The converted object. 199 */ 200 public static Boolean toBoolean(Object o) { 201 return toType(o, Boolean.class); 202 } 203 204 /** 205 * Converts an object to an Integer. 206 * 207 * @param o The object to convert. 208 * @return The converted object. 209 */ 210 public static Integer toInteger(Object o) { 211 return toType(o, Integer.class); 212 } 213 214 /** 215 * Converts an object to a Number. 216 * 217 * @param o The object to convert. 218 * @return The converted object. 219 */ 220 public static Number toNumber(Object o) { 221 if (o == null) 222 return null; 223 if (o instanceof Number) 224 return (Number)o; 225 try { 226 return StringUtils.parseNumber(o.toString(), null); 227 } catch (ParseException e) { 228 throw asRuntimeException(e); 229 } 230 } 231}