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.marshall.internal; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020import static org.apache.juneau.commons.utils.StringUtils.*; 021import static org.apache.juneau.commons.utils.ThrowableUtils.*; 022 023import java.util.*; 024 025import org.apache.juneau.commons.collections.*; 026import org.apache.juneau.commons.conversion.*; 027import org.apache.juneau.marshall.parser.*; 028import org.apache.juneau.marshall.utils.*; 029 030/** 031 * Utility class for common type conversions and building typed collections and maps. 032 */ 033public class ConverterUtils { 034 035 /** 036 * Prevents instantiation. 037 */ 038 private ConverterUtils() {} 039 040 /** 041 * Converts an object to a Boolean. 042 * 043 * @param o The object to convert. 044 * @return The converted object. 045 */ 046 public static Boolean toBoolean(Object o) { 047 return BasicConverter.INSTANCE.to(o, Boolean.class); 048 } 049 050 /** 051 * Converts an object to an Integer. 052 * 053 * @param o The object to convert. 054 * @return The converted object. 055 */ 056 public static Integer toInteger(Object o) { 057 return BasicConverter.INSTANCE.to(o, Integer.class); 058 } 059 060 /** 061 * Converts an object to a Number. 062 * 063 * @param o The object to convert. 064 * @return The converted object. 065 */ 066 public static Number toNumber(Object o) { 067 if (o == null) 068 return null; 069 if (o instanceof Number o2) 070 return o2; 071 try { 072 return parseNumber(o.toString(), null); 073 } catch (ParseException e) { 074 throw toRex(e); 075 } 076 } 077 078 /** 079 * Converts the specified object to the specified type. 080 * 081 * <p> 082 * Uses the full {@link MarshallingContextConverter} to support bean-aware conversions such as 083 * {@link Map} to bean, bean to bean, and {@link org.apache.juneau.marshall.swap.spi.ObjectSwap} transforms. 084 * 085 * @param <T> The class type to convert the value to. 086 * @param value The value to convert. 087 * @param type The class type to convert the value to. 088 * @return The converted value. 089 */ 090 public static <T> T toType(Object value, Class<T> type) { 091 return MarshallingContextConverter.INSTANCE.to(value, type); 092 } 093 094 /** 095 * Converts the specified object to a {@link Lists} with elements of the specified type. 096 * 097 * <p> 098 * The input value can be any of the following: 099 * <ul> 100 * <li>An array of objects convertible to the element type 101 * <li>A {@link Collection} of objects convertible to the element type 102 * <li>A single object convertible to the element type (creates a list with one element) 103 * <li>A JSON array string that can be parsed into objects of the element type 104 * </ul> 105 * 106 * @param <T> The element type. 107 * @param value The value to convert. Can be <jk>null</jk> (no elements are added; an empty builder is returned). 108 * @param type The element type class. 109 * @return A new {@link Lists} containing the converted elements. 110 */ 111 public static <T> Lists<T> toListBuilder(Object value, Class<T> type) { 112 return lb(type).elementFunction(o -> MarshallingContextConverter.INSTANCE.to(o, type)).addAny(value); 113 } 114 115 /** 116 * Converts the specified object to a {@link Maps} with keys and values of the specified types. 117 * 118 * <p> 119 * The input value can be any of the following: 120 * <ul> 121 * <li>A {@link Map Map} with entries convertible to the key/value types 122 * <li>A JSON object string that can be parsed into a map with the specified key/value types 123 * <li>An object with bean properties that can be converted to map entries 124 * </ul> 125 * 126 * @param <K> The key type. 127 * @param <V> The value type. 128 * @param value The value to convert. Can be <jk>null</jk> (no entries are added; an empty builder is returned). 129 * @param keyType The key type class. 130 * @param valueType The value type class. 131 * @return A new {@link Maps} containing the converted entries. 132 */ 133 public static <K,V> Maps<K,V> toMapBuilder(Object value, Class<K> keyType, Class<V> valueType) { 134 return mb(keyType, valueType) 135 .keyFunction(o -> MarshallingContextConverter.INSTANCE.to(o, keyType)) 136 .valueFunction(o -> MarshallingContextConverter.INSTANCE.to(o, valueType)) 137 .addAny(value); 138 } 139 140 /** 141 * Converts the specified object to a {@link Sets} with elements of the specified type. 142 * 143 * <p> 144 * The input value can be any of the following: 145 * <ul> 146 * <li>An array of objects convertible to the element type 147 * <li>A {@link Collection} of objects convertible to the element type 148 * <li>A single object convertible to the element type (creates a set with one element) 149 * <li>A JSON array string that can be parsed into objects of the element type 150 * </ul> 151 * 152 * <p> 153 * Duplicate elements (after conversion) will be automatically removed as per {@link Set Set} semantics. 154 * 155 * @param <T> The element type. 156 * @param value The value to convert. Can be <jk>null</jk> (no elements are added; an empty builder is returned). 157 * @param type The element type class. 158 * @return A new {@link Sets} containing the converted elements. 159 */ 160 public static <T> Sets<T> toSetBuilder(Object value, Class<T> type) { 161 return stb(type).elementFunction(o -> MarshallingContextConverter.INSTANCE.to(o, type)).addAny(value); 162 } 163}