/* * Copyright 1999-2101 Alibaba Group. * * Licensed 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 com.alibaba.fastjson; import static com.alibaba.fastjson.util.TypeUtils.castToBigDecimal; import static com.alibaba.fastjson.util.TypeUtils.castToBigInteger; import static com.alibaba.fastjson.util.TypeUtils.castToBoolean; import static com.alibaba.fastjson.util.TypeUtils.castToByte; import static com.alibaba.fastjson.util.TypeUtils.castToBytes; import static com.alibaba.fastjson.util.TypeUtils.castToDate; import static com.alibaba.fastjson.util.TypeUtils.castToDouble; import static com.alibaba.fastjson.util.TypeUtils.castToFloat; import static com.alibaba.fastjson.util.TypeUtils.castToInt; import static com.alibaba.fastjson.util.TypeUtils.castToLong; import static com.alibaba.fastjson.util.TypeUtils.castToShort; import static com.alibaba.fastjson.util.TypeUtils.castToSqlDate; import static com.alibaba.fastjson.util.TypeUtils.castToTimestamp; import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.AntiCollisionHashMap; import com.alibaba.fastjson.util.TypeUtils; /** * @author wenshao<szujobs@hotmail.com> */ public class JSONObject extends JSON implements Map<String, Object>, JSONAware, Cloneable, Serializable, InvocationHandler { private static final long serialVersionUID = 1L; private static final int DEFAULT_INITIAL_CAPACITY = 16; private final Map<String, Object> map; public JSONObject() { this(DEFAULT_INITIAL_CAPACITY, false); } public JSONObject(Map<String, Object> map) { this.map = map; } public JSONObject(boolean ordered) { this(DEFAULT_INITIAL_CAPACITY, ordered); } public JSONObject(int initialCapacity) { this(initialCapacity, false); } public JSONObject(int initialCapacity, boolean ordered) { if (ordered) { map = new LinkedHashMap<String, Object>(initialCapacity); } else { map = new AntiCollisionHashMap<String, Object>(initialCapacity); } } public int size() { return map.size(); } public boolean isEmpty() { return map.isEmpty(); } public boolean containsKey(Object key) { return map.containsKey(key); } public boolean containsValue(Object value) { return map.containsValue(value); } public Object get(Object key) { return map.get(key); } public JSONObject getJSONObject(String key) { Object value = map.get(key); if (value instanceof JSONObject) { return (JSONObject) value; } return (JSONObject) toJSON(value); } public JSONArray getJSONArray(String key) { Object value = map.get(key); if (value instanceof JSONArray) { return (JSONArray) value; } return (JSONArray) toJSON(value); } public <T> T getObject(String key, Class<T> clazz) { Object obj = map.get(key); return TypeUtils.castToJavaBean(obj, clazz); } public Boolean getBoolean(String key) { Object value = get(key); if (value == null) { return null; } return castToBoolean(value); } public byte[] getBytes(String key) { Object value = get(key); if (value == null) { return null; } return castToBytes(value); } public boolean getBooleanValue(String key) { Object value = get(key); if (value == null) { return false; } return castToBoolean(value).booleanValue(); } public Byte getByte(String key) { Object value = get(key); return castToByte(value); } public byte getByteValue(String key) { Object value = get(key); if (value == null) { return 0; } return castToByte(value).byteValue(); } public Short getShort(String key) { Object value = get(key); return castToShort(value); } public short getShortValue(String key) { Object value = get(key); if (value == null) { return 0; } return castToShort(value).shortValue(); } public Integer getInteger(String key) { Object value = get(key); return castToInt(value); } public int getIntValue(String key) { Object value = get(key); if (value == null) { return 0; } return castToInt(value).intValue(); } public Long getLong(String key) { Object value = get(key); return castToLong(value); } public long getLongValue(String key) { Object value = get(key); if (value == null) { return 0L; } return castToLong(value).longValue(); } public Float getFloat(String key) { Object value = get(key); return castToFloat(value); } public float getFloatValue(String key) { Object value = get(key); if (value == null) { return 0F; } return castToFloat(value).floatValue(); } public Double getDouble(String key) { Object value = get(key); return castToDouble(value); } public double getDoubleValue(String key) { Object value = get(key); if (value == null) { return 0D; } return castToDouble(value); } public BigDecimal getBigDecimal(String key) { Object value = get(key); return castToBigDecimal(value); } public BigInteger getBigInteger(String key) { Object value = get(key); return castToBigInteger(value); } public String getString(String key) { Object value = get(key); if (value == null) { return null; } return value.toString(); } public Date getDate(String key) { Object value = get(key); return castToDate(value); } public java.sql.Date getSqlDate(String key) { Object value = get(key); return castToSqlDate(value); } public java.sql.Timestamp getTimestamp(String key) { Object value = get(key); return castToTimestamp(value); } public Object put(String key, Object value) { return map.put(key, value); } public void putAll(Map<? extends String, ? extends Object> m) { map.putAll(m); } public void clear() { map.clear(); } public Object remove(Object key) { return map.remove(key); } public Set<String> keySet() { return map.keySet(); } public Collection<Object> values() { return map.values(); } public Set<Map.Entry<String, Object>> entrySet() { return map.entrySet(); } @Override public Object clone() { return new JSONObject(new HashMap<String, Object>(map)); } public boolean equals(Object obj) { return this.map.equals(obj); } public int hashCode() { return this.map.hashCode(); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Class<?>[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length == 1) { Class<?> returnType = method.getReturnType(); if (returnType != void.class) { throw new JSONException("illegal setter"); } String name = null; JSONField annotation = method.getAnnotation(JSONField.class); if (annotation != null) { if (annotation.name().length() != 0) { name = annotation.name(); } } if (name == null) { name = method.getName(); if (!name.startsWith("set")) { throw new JSONException("illegal setter"); } name = name.substring(3); if (name.length() == 0) { throw new JSONException("illegal setter"); } name = Character.toLowerCase(name.charAt(0)) + name.substring(1); } map.put(name, args[0]); return null; } if (parameterTypes.length == 0) { Class<?> returnType = method.getReturnType(); if (returnType == void.class) { throw new JSONException("illegal getter"); } String name = null; JSONField annotation = method.getAnnotation(JSONField.class); if (annotation != null) { if (annotation.name().length() != 0) { name = annotation.name(); } } if (name == null) { name = method.getName(); if (name.startsWith("get")) { name = name.substring(3); if (name.length() == 0) { throw new JSONException("illegal getter"); } name = Character.toLowerCase(name.charAt(0)) + name.substring(1); } else if (name.startsWith("is")) { name = name.substring(2); if (name.length() == 0) { throw new JSONException("illegal getter"); } name = Character.toLowerCase(name.charAt(0)) + name.substring(1); } else { throw new JSONException("illegal getter"); } } Object value = map.get(name); return TypeUtils.cast(value, method.getGenericReturnType(), ParserConfig.getGlobalInstance()); } throw new UnsupportedOperationException(method.toGenericString()); } }