| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.dubbo.rpc.protocol.rest.util; |
| |
| import org.apache.dubbo.common.utils.Assert; |
| import org.apache.dubbo.common.utils.StringUtils; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| |
| public class NumberUtils { |
| |
| public static <T> T parseNumber(String text, Class<T> targetClass) { |
| Assert.notNull(text, "Text must not be null"); |
| Assert.notNull(targetClass, "Target class must not be null"); |
| String trimmed = trimAllWhitespace(text); |
| |
| if (Byte.class == targetClass || byte.class == targetClass) { |
| return (T) (isHexNumber(trimmed) ? Byte.decode(trimmed) : Byte.valueOf(trimmed)); |
| } else if (Short.class == targetClass || short.class == targetClass) { |
| return (T) (isHexNumber(trimmed) ? Short.decode(trimmed) : Short.valueOf(trimmed)); |
| } else if (Integer.class == targetClass || int.class == targetClass) { |
| return (T) (isHexNumber(trimmed) ? Integer.decode(trimmed) : Integer.valueOf(trimmed)); |
| } else if (Long.class == targetClass || long.class == targetClass) { |
| return (T) (isHexNumber(trimmed) ? Long.decode(trimmed) : Long.valueOf(trimmed)); |
| } else if (BigInteger.class == targetClass) { |
| return (T) (isHexNumber(trimmed) ? decodeBigInteger(trimmed) : new BigInteger(trimmed)); |
| } else if (Float.class == targetClass || float.class == targetClass) { |
| return (T) Float.valueOf(trimmed); |
| } else if (Double.class == targetClass || double.class == targetClass) { |
| return (T) Double.valueOf(trimmed); |
| } else if (BigDecimal.class == targetClass || Number.class == targetClass) { |
| return (T) new BigDecimal(trimmed); |
| } else { |
| throw new IllegalArgumentException( |
| "Cannot convert String [" + text + "] to target class [" + targetClass.getName() + "]"); |
| } |
| } |
| |
| private static boolean isHexNumber(String value) { |
| int index = (value.startsWith("-") ? 1 : 0); |
| return (value.startsWith("0x", index) || value.startsWith("0X", index) || value.startsWith("#", index)); |
| } |
| |
| private static BigInteger decodeBigInteger(String value) { |
| int radix = 10; |
| int index = 0; |
| boolean negative = false; |
| |
| // Handle minus sign, if present. |
| if (value.startsWith("-")) { |
| negative = true; |
| index++; |
| } |
| |
| // Handle radix specifier, if present. |
| if (value.startsWith("0x", index) || value.startsWith("0X", index)) { |
| index += 2; |
| radix = 16; |
| } else if (value.startsWith("#", index)) { |
| index++; |
| radix = 16; |
| } else if (value.startsWith("0", index) && value.length() > 1 + index) { |
| index++; |
| radix = 8; |
| } |
| |
| BigInteger result = new BigInteger(value.substring(index), radix); |
| return (negative ? result.negate() : result); |
| } |
| |
| public static String trimAllWhitespace(String str) { |
| if (StringUtils.isEmpty(str)) { |
| return str; |
| } |
| |
| int len = str.length(); |
| StringBuilder sb = new StringBuilder(str.length()); |
| for (int i = 0; i < len; i++) { |
| char c = str.charAt(i); |
| if (!Character.isWhitespace(c)) { |
| sb.append(c); |
| } |
| } |
| return sb.toString(); |
| } |
| |
| public static Object numberToBytes(Number number) { |
| |
| if (number instanceof Byte) { |
| // Use default encoding. |
| return Byte.toString(number.byteValue()).getBytes(); |
| } else if (number instanceof Double) { |
| return Double.toString(number.doubleValue()).getBytes(); |
| } else if (number instanceof Float) { |
| return Float.toString(number.floatValue()).getBytes(); |
| } else if (number instanceof Integer) { |
| return Float.toString(number.intValue()).getBytes(); |
| } else if (number instanceof Long) { |
| return Long.toString(number.longValue()).getBytes(); |
| } else if (number instanceof Short) { |
| return Short.toString(number.shortValue()).getBytes(); |
| } else if (number instanceof BigDecimal) { |
| return BigDecimal.class.cast(number).toString().getBytes(); |
| } |
| |
| return number; |
| } |
| } |