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