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