Package com.alibaba.dubbo.common.json

Source Code of com.alibaba.dubbo.common.json.GenericJSONConverter$Encoder

/*
* Copyright 1999-2011 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.dubbo.common.json;

import java.io.IOException;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import com.alibaba.dubbo.common.bytecode.Wrapper;
import com.alibaba.dubbo.common.io.Bytes;

public class GenericJSONConverter implements JSONConverter
{
  private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
 
  protected interface Encoder{ void encode(Object obj, JSONWriter jb) throws IOException; }

  protected interface Decoder{ Object decode(Object jv) throws IOException; }

  private static final Map<Class<?>, Encoder> GlobalEncoderMap = new HashMap<Class<?>, Encoder>();

  private static final Map<Class<?>, Decoder> GlobalDecoderMap = new HashMap<Class<?>, Decoder>();

  @SuppressWarnings("unchecked")
  public void writeValue(Object obj, JSONWriter jb, boolean writeClass) throws IOException
  {
    if (obj == null) {
      jb.valueNull();
      return;
    }
    Class<?> c = obj.getClass();
    Encoder encoder = GlobalEncoderMap.get(c);

    if( encoder != null )
    {
      encoder.encode(obj, jb);
    }
    else if( obj instanceof JSONNode )
    {
      ((JSONNode)obj).writeJSON(this, jb, writeClass);
    }
    else if( c.isEnum() )
    {
      jb.valueString(((Enum<?>)obj).name());
    }
    else if( c.isArray() )
    {
      int len = Array.getLength(obj);
      jb.arrayBegin();
      for(int i=0;i<len;i++)
        writeValue(Array.get(obj, i), jb, writeClass);
      jb.arrayEnd();
    }
    else if( Map.class.isAssignableFrom(c) )
    {
      Object key, value;
      jb.objectBegin();
      for( Map.Entry<Object, Object> entry : ((Map<Object, Object>)obj).entrySet() )
      {
        key = entry.getKey();
        if( key == null )
          continue;
        jb.objectItem(key.toString());

        value = entry.getValue();
        if( value == null )
          jb.valueNull();
        else
          writeValue(value, jb, writeClass);
      }
      jb.objectEnd();
    }
    else if( Collection.class.isAssignableFrom(c) )
    {
      jb.arrayBegin();
      for( Object item : (Collection<Object>)obj )
      {
        if( item == null )
          jb.valueNull();
        else
          writeValue(item, jb, writeClass);
      }
      jb.arrayEnd();
    }
    else
    {
      jb.objectBegin();
     
      Wrapper w = Wrapper.getWrapper(c);
      String pns[] = w.getPropertyNames();

      for( String pn : pns )
      {
        if ((obj instanceof Throwable) && (
            "localizedMessage".equals(pn)
            || "cause".equals(pn)
            || "stackTrace".equals(pn))) {
          continue;
        }
       
        jb.objectItem(pn);

        Object value = w.getPropertyValue(obj,pn);
        if( value == null || value == obj)
          jb.valueNull();
        else
          writeValue(value, jb, writeClass);
      }
      if (writeClass) {
          jb.objectItem(JSONVisitor.CLASS_PROPERTY);
          writeValue(obj.getClass().getName(), jb, writeClass);
      }
      jb.objectEnd();
    }
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  public Object readValue(Class<?> c, Object jv) throws IOException
  {
    if (jv == null) {
      return null;
    }
    Decoder decoder = GlobalDecoderMap.get(c);
    if( decoder != null ) {
      return decoder.decode(jv);
    }
    if (c.isEnum()) {
      return Enum.valueOf((Class<Enum>)c, String.valueOf(jv));
    }
    return jv;
  }

  static
  {
    // init encoder map.
    Encoder e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueBoolean((Boolean)obj);
      }
    };
    GlobalEncoderMap.put(boolean.class, e);
    GlobalEncoderMap.put(Boolean.class, e);

    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueInt(((Number)obj).intValue());
      }
    };
    GlobalEncoderMap.put(int.class, e);
    GlobalEncoderMap.put(Integer.class, e);
    GlobalEncoderMap.put(short.class, e);
    GlobalEncoderMap.put(Short.class, e);
    GlobalEncoderMap.put(byte.class, e);
    GlobalEncoderMap.put(Byte.class, e);
    GlobalEncoderMap.put(AtomicInteger.class, e);
   
    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueString(Character.toString((Character)obj));
      }
    };
    GlobalEncoderMap.put(char.class, e);
    GlobalEncoderMap.put(Character.class, e);
   
    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueLong(((Number)obj).longValue());
      }
    };
    GlobalEncoderMap.put(long.class, e);
    GlobalEncoderMap.put(Long.class, e);
    GlobalEncoderMap.put(AtomicLong.class, e);
    GlobalEncoderMap.put(BigInteger.class, e);

    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueFloat(((Number)obj).floatValue());
      }
    };
    GlobalEncoderMap.put(float.class, e);
    GlobalEncoderMap.put(Float.class, e);

    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueDouble(((Number)obj).doubleValue());
      }
    };
    GlobalEncoderMap.put(double.class, e);
    GlobalEncoderMap.put(Double.class, e);
    GlobalEncoderMap.put(BigDecimal.class, e);

    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueString(obj.toString());
      }
    };
    GlobalEncoderMap.put(String.class, e);
    GlobalEncoderMap.put(StringBuilder.class, e);
    GlobalEncoderMap.put(StringBuffer.class, e);

    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueString(Bytes.bytes2base64((byte[])obj));
      }
    };
    GlobalEncoderMap.put(byte[].class, e);
   
    e = new Encoder(){
      public void encode(Object obj, JSONWriter jb) throws IOException
      {
        jb.valueString(new SimpleDateFormat(DATE_FORMAT).format((Date)obj));
      }
    };
    GlobalEncoderMap.put(Date.class, e);

    // init decoder map.
    Decoder d = new Decoder(){
      public Object decode(Object jv){
        return jv.toString();
      }
    };
    GlobalDecoderMap.put(String.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Boolean ) return ((Boolean)jv).booleanValue();
        return false;
      }
    };
    GlobalDecoderMap.put(boolean.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Boolean ) return (Boolean)jv;
        return (Boolean)null;
      }
    };
    GlobalDecoderMap.put(Boolean.class, d);
   
    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof String && ((String)jv).length() > 0) return ((String)jv).charAt(0);
        return (char)0;
      }
    };
    GlobalDecoderMap.put(char.class, d);
   
    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof String && ((String)jv).length() > 0) return ((String)jv).charAt(0);
        return (Character)null;
      }
    };
    GlobalDecoderMap.put(Character.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return ((Number)jv).intValue();
        return 0;
      }
    };
    GlobalDecoderMap.put(int.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return Integer.valueOf(((Number)jv).intValue());
        return (Integer)null;
      }
    };
    GlobalDecoderMap.put(Integer.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return ((Number)jv).shortValue();
        return (short)0;
      }
    };
    GlobalDecoderMap.put(short.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return Short.valueOf(((Number)jv).shortValue());
        return (Short)null;
      }
    };
    GlobalDecoderMap.put(Short.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return ((Number)jv).longValue();
        return (long)0;
      }
    };
    GlobalDecoderMap.put(long.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return Long.valueOf(((Number)jv).longValue());
        return (Long)null;
      }
    };
    GlobalDecoderMap.put(Long.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return ((Number)jv).floatValue();
        return (float)0;
      }
    };
    GlobalDecoderMap.put(float.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return new Float(((Number)jv).floatValue());
        return (Float)null;
      }
    };
    GlobalDecoderMap.put(Float.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return ((Number)jv).doubleValue();
        return (double)0;
      }
    };
    GlobalDecoderMap.put(double.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return new Double(((Number)jv).doubleValue());
        return (Double)null;
      }
    };
    GlobalDecoderMap.put(Double.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return ((Number)jv).byteValue();
        return (byte)0;
      }
    };
    GlobalDecoderMap.put(byte.class, d);

    d = new Decoder(){
      public Object decode(Object jv)
      {
        if( jv instanceof Number ) return Byte.valueOf(((Number)jv).byteValue());
        return (Byte)null;
      }
    };
    GlobalDecoderMap.put(Byte.class, d);

    d = new Decoder(){
      public Object decode(Object jv) throws IOException
      {
        if( jv instanceof String ) return Bytes.base642bytes((String)jv);
        return (byte[])null;
      }
    };
    GlobalDecoderMap.put(byte[].class, d);

    d = new Decoder(){
      public Object decode(Object jv) throws IOException{ return new StringBuilder(jv.toString()); }
    };
    GlobalDecoderMap.put(StringBuilder.class, d);

    d = new Decoder(){
      public Object decode(Object jv) throws IOException{ return new StringBuffer(jv.toString()); }
    };
    GlobalDecoderMap.put(StringBuffer.class, d);

    d = new Decoder(){
      public Object decode(Object jv) throws IOException
      {
        if( jv instanceof Number ) return BigInteger.valueOf(((Number)jv).longValue());
        return (BigInteger)null;
      }
    };
    GlobalDecoderMap.put(BigInteger.class, d);

    d = new Decoder(){
      public Object decode(Object jv) throws IOException
      {
        if( jv instanceof Number ) return BigDecimal.valueOf(((Number)jv).doubleValue());
        return (BigDecimal)null;
      }
    };
    GlobalDecoderMap.put(BigDecimal.class, d);

    d = new Decoder(){
      public Object decode(Object jv) throws IOException
      {
        if( jv instanceof Number ) return new AtomicInteger(((Number)jv).intValue());
        return (AtomicInteger)null;
      }
    };
    GlobalDecoderMap.put(AtomicInteger.class, d);

    d = new Decoder(){
      public Object decode(Object jv) throws IOException
      {
        if( jv instanceof Number ) return new AtomicLong(((Number)jv).longValue());
        return (AtomicLong)null;
      }
    };
    GlobalDecoderMap.put(AtomicLong.class, d);
   
    d = new Decoder(){
      public Object decode(Object jv) throws IOException
      {
        if( jv instanceof String ) {
          try {
            return new SimpleDateFormat(DATE_FORMAT).parse((String) jv);
          } catch (ParseException e) {
            throw new IllegalArgumentException(e.getMessage(), e);
          }
        }
        if( jv instanceof Number )
          return new Date(((Number)jv).longValue());
        return (Date)null;
      }
    };
    GlobalDecoderMap.put(Date.class, d);
  }
}
TOP

Related Classes of com.alibaba.dubbo.common.json.GenericJSONConverter$Encoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.