src/java.management.rest/share/classes/com/oracle/jmx/remote/rest/mapper/JSONMappingFactory.java
branchjmx-rest-api
changeset 55985 0c5a02edfdef
child 55994 9721e36abeb0
equal deleted inserted replaced
55984:a43ae4e5fa0a 55985:0c5a02edfdef
       
     1 /*
       
     2  * To change this license header, choose License Headers in Project Properties.
       
     3  * To change this template file, choose Tools | Templates
       
     4  * and open the template in the editor.
       
     5  */
       
     6 package com.oracle.jmx.remote.rest.mapper;
       
     7 
       
     8 import javax.management.MalformedObjectNameException;
       
     9 import javax.management.ObjectName;
       
    10 import javax.management.openmbean.*;
       
    11 import com.oracle.jmx.remote.rest.json.JSONArray;
       
    12 import com.oracle.jmx.remote.rest.json.JSONElement;
       
    13 import com.oracle.jmx.remote.rest.json.JSONObject;
       
    14 import com.oracle.jmx.remote.rest.json.JSONPrimitive;
       
    15 import java.lang.reflect.Array;
       
    16 import java.math.BigDecimal;
       
    17 import java.math.BigInteger;
       
    18 import java.text.DateFormat;
       
    19 import java.text.ParseException;
       
    20 import java.text.SimpleDateFormat;
       
    21 import java.util.Date;
       
    22 import java.util.HashMap;
       
    23 import java.util.Map;
       
    24 
       
    25 /**
       
    26  * @author harsha
       
    27  */
       
    28 public final class JSONMappingFactory {
       
    29 
       
    30     public static final JSONMappingFactory INSTANCE;
       
    31     private static final Map<Class<?>, JSONMapper> typeMapper;
       
    32     private static final Map<String, Class<?>> primitiveMap = new HashMap<>();
       
    33 
       
    34     static {
       
    35         // Make order of Initialization explicit
       
    36         typeMapper = new HashMap<>();
       
    37 
       
    38         primitiveMap.put("boolean", Boolean.TYPE);
       
    39         primitiveMap.put("int", Integer.TYPE);
       
    40         primitiveMap.put("long", Long.TYPE);
       
    41         primitiveMap.put("double", Double.TYPE);
       
    42         primitiveMap.put("float", Float.TYPE);
       
    43         primitiveMap.put("bool", Boolean.TYPE);
       
    44         primitiveMap.put("char", Character.TYPE);
       
    45         primitiveMap.put("byte", Byte.TYPE);
       
    46         primitiveMap.put("void", Void.TYPE);
       
    47         primitiveMap.put("short", Short.TYPE);
       
    48 
       
    49         INSTANCE = new JSONMappingFactory();
       
    50     }
       
    51 
       
    52     private JSONMappingFactory() {
       
    53 
       
    54         typeMapper.put(void.class, null);
       
    55         typeMapper.put(Void.class, null);
       
    56 
       
    57         typeMapper.put(boolean.class, new BooleanMapper());
       
    58         typeMapper.put(Boolean.class, new BooleanMapper());
       
    59 
       
    60         typeMapper.put(byte.class, new ByteMapper());
       
    61         typeMapper.put(Byte.class, new ByteMapper());
       
    62 
       
    63         typeMapper.put(short.class, new ShortMapper());
       
    64         typeMapper.put(Short.class, new ShortMapper());
       
    65 
       
    66         typeMapper.put(int.class, new IntegerMapper());
       
    67         typeMapper.put(Integer.class, new IntegerMapper());
       
    68 
       
    69         typeMapper.put(long.class, new LongMapper());
       
    70         typeMapper.put(Long.class, new LongMapper());
       
    71 
       
    72         typeMapper.put(float.class, new FloatMapper());
       
    73         typeMapper.put(Float.class, new FloatMapper());
       
    74 
       
    75         typeMapper.put(double.class, new DoubleMapper());
       
    76         typeMapper.put(Double.class, new DoubleMapper());
       
    77 
       
    78         typeMapper.put(char.class, new CharacterMapper());
       
    79         typeMapper.put(Character.class, new CharacterMapper());
       
    80 
       
    81         typeMapper.put(String.class, new StringMapper());
       
    82         typeMapper.put(BigInteger.class, new BigIntegerMapper());
       
    83         typeMapper.put(BigDecimal.class, new BigDecimalMapper());
       
    84         typeMapper.put(ObjectName.class, new ObjectNameMapper());
       
    85         typeMapper.put(Date.class, new DateMapper());
       
    86     }
       
    87 
       
    88     private Class<?> getArrayComponent(Class<?> cls) {
       
    89         if (cls == null) {
       
    90             return cls;
       
    91         }
       
    92         Class<?> compType = cls;
       
    93         // TODO: Add check for max array dimention of 15
       
    94         while (compType.isArray()) {
       
    95             compType = compType.getComponentType();
       
    96         }
       
    97         return compType;
       
    98     }
       
    99 
       
   100     private Object getArrayElement(Object arrayObj) {
       
   101         if (arrayObj != null && arrayObj.getClass().isArray()) {
       
   102             while (arrayObj.getClass().isArray()) {
       
   103                 Class<?> componentType = arrayObj.getClass().getComponentType();
       
   104                 if (Array.getLength(arrayObj) > 0) {
       
   105                     Object component = null;
       
   106                     for (int i = 0; i < Array.getLength(arrayObj); i++) {
       
   107                         component = Array.get(arrayObj, i);
       
   108                         if (component != null) {
       
   109                             break;
       
   110                         }
       
   111                     }
       
   112                     if (component == null) {
       
   113                         return null;
       
   114                     }
       
   115                     if (componentType.isPrimitive()) {
       
   116                         componentType = component.getClass();
       
   117                     }
       
   118                     arrayObj = componentType.cast(component);
       
   119                 } else {
       
   120                     return null;
       
   121                 }
       
   122             }
       
   123         }
       
   124         return arrayObj;
       
   125     }
       
   126 
       
   127     // TODO: This should be access controlled. Define new permissions
       
   128     public void addMapping(Class<?> cls, JSONMapper mapper) {
       
   129         Class<?> input = cls;
       
   130         if (cls.isArray()) {
       
   131             input = getArrayComponent(cls);
       
   132         }
       
   133         if (!typeMapper.containsKey(input)) {
       
   134             typeMapper.put(input, mapper);
       
   135         }
       
   136     }
       
   137 
       
   138     public JSONMapper getTypeMapper(Object object) {
       
   139         Object obj = object;
       
   140         Class<?> cls = object.getClass();
       
   141         if (cls.isArray()) {
       
   142             Object arrayElement = getArrayElement(obj);
       
   143             if (arrayElement instanceof CompositeDataSupport) {
       
   144                 CompositeDataSupport cds = (CompositeDataSupport) arrayElement;
       
   145                 return new OpenArrayTypeMapper(cls, cds.getCompositeType());
       
   146             } else if (arrayElement instanceof TabularDataSupport) {
       
   147                 TabularDataSupport tds = (TabularDataSupport) arrayElement;
       
   148                 return new OpenArrayTypeMapper(cls, tds.getTabularType());
       
   149             }
       
   150         }
       
   151 
       
   152         if (object instanceof CompositeDataSupport) {
       
   153             CompositeDataSupport cds = (CompositeDataSupport) object;
       
   154             return getTypeMapper(cds.getCompositeType());
       
   155         } else if (object instanceof TabularDataSupport) {
       
   156             TabularDataSupport cds = (TabularDataSupport) object;
       
   157             return getTypeMapper(cds.getTabularType());
       
   158         } else {
       
   159             return getTypeMapper(cls);
       
   160         }
       
   161     }
       
   162 
       
   163     /*
       
   164     Using class object is better than class name as class objects for same class
       
   165     name differ for each classloader
       
   166      */
       
   167     public JSONMapper getTypeMapper(Class<?> type) {
       
   168         if (type.isArray()) {
       
   169             Class<?> compType = getArrayComponent(type);
       
   170             if (typeMapper.get(compType) != null) {
       
   171                 return new GenericArrayMapper(type);
       
   172             } else {
       
   173                 return null;
       
   174             }
       
   175         }
       
   176         return typeMapper.get(type);
       
   177     }
       
   178 
       
   179     public JSONMapper getTypeMapper(OpenType<?> type) {
       
   180         if (type instanceof CompositeType) {
       
   181             return new OpenCompositeTypeMapper((CompositeType) type);
       
   182         } else if (type instanceof SimpleType) {
       
   183             try {
       
   184                 return getTypeMapper(Class.forName(((SimpleType) type).getClassName()));
       
   185             } catch (ClassNotFoundException ex) { // This should not happen as SimpleTypes are always loaded
       
   186                 throw new RuntimeException(ex);
       
   187             }
       
   188         } else if (type instanceof ArrayType) {
       
   189             try {
       
   190                 ArrayType<?> at = (ArrayType) type;
       
   191                 Class<?> arrayClass = Class.forName(type.getClassName());
       
   192                 return new OpenArrayTypeMapper(arrayClass, at.getElementOpenType());
       
   193             } catch (ClassNotFoundException ex) { // This should not happen as SimpleTypes are always loaded
       
   194                 throw new RuntimeException(ex);
       
   195             }
       
   196         } else if (type instanceof TabularType) {
       
   197             // TODO
       
   198         }
       
   199         return null; //keep compiler happy
       
   200     }
       
   201 
       
   202     public boolean isTypeMapped(String type) throws ClassNotFoundException {
       
   203         if (primitiveMap.get(type) != null) {
       
   204             return true;
       
   205         }
       
   206         Class<?> inputCls = Class.forName(type);
       
   207         inputCls = getArrayComponent(inputCls);
       
   208         if (inputCls.equals(CompositeData.class) || inputCls.equals(TabularData.class)
       
   209                 || inputCls.equals(CompositeDataSupport.class) || inputCls.equals(TabularDataSupport.class)) {
       
   210             return true;
       
   211         }
       
   212         return JSONMappingFactory.INSTANCE.getTypeMapper(inputCls) != null;
       
   213     }
       
   214 
       
   215     private static class OpenArrayTypeMapper extends GenericArrayMapper {
       
   216 
       
   217         public OpenArrayTypeMapper(Class<?> type, OpenType<?> elementOpenType) {
       
   218             super(type);
       
   219             mapper = JSONMappingFactory.INSTANCE.getTypeMapper(elementOpenType);
       
   220         }
       
   221     }
       
   222 
       
   223     private static class GenericArrayMapper implements JSONMapper {
       
   224 
       
   225         private final Class<?> type;
       
   226         protected JSONMapper mapper;
       
   227 
       
   228         GenericArrayMapper(Class<?> type) {
       
   229             this.type = type;
       
   230             mapper = JSONMappingFactory.INSTANCE.getTypeMapper(JSONMappingFactory.INSTANCE.getArrayComponent(type));
       
   231         }
       
   232 
       
   233         private Object handleArrayType(Class<?> classType, JSONElement jsonValue) throws JSONDataException {
       
   234             if (!(jsonValue instanceof JSONArray)) {
       
   235                 throw new JSONDataException("Invald JSON data format");
       
   236             }
       
   237             JSONArray jarr = (JSONArray) jsonValue;
       
   238             Class<?> compType = classType.getComponentType();
       
   239             Object resultArray = Array.newInstance(compType, jarr.size());
       
   240 
       
   241             for (int i = 0; i < jarr.size(); i++) {
       
   242                 if (compType != null && compType.isArray()) {
       
   243                     Array.set(resultArray, i, handleArrayType(compType, jarr.get(i)));
       
   244                 } else {
       
   245                     Array.set(resultArray, i, mapper.toJavaObject(jarr.get(i)));
       
   246                 }
       
   247             }
       
   248             return resultArray;
       
   249         }
       
   250 
       
   251         @Override
       
   252         public Object toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   253             return handleArrayType(type, jsonValue);
       
   254         }
       
   255 
       
   256         @Override
       
   257         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   258             if (data == null) {
       
   259                 return new JSONPrimitive();
       
   260             }
       
   261             if (!data.getClass().equals(type)) {
       
   262                 throw new JSONMappingException("Illegal type : " + data.getClass());
       
   263             }
       
   264             return getJasonValue(data);
       
   265         }
       
   266 
       
   267         private JSONElement getJasonValue(Object data) throws JSONMappingException {
       
   268             if (data == null) {
       
   269                 return new JSONPrimitive();
       
   270             }
       
   271             if (!data.getClass().isArray()) {
       
   272                 return mapper.toJsonValue(data);
       
   273             } else {
       
   274                 JSONArray jArray = new JSONArray();
       
   275                 for (int i = 0; i < Array.getLength(data); i++) {
       
   276                     jArray.add(getJasonValue(Array.get(data, i)));
       
   277                 }
       
   278                 return jArray;
       
   279             }
       
   280         }
       
   281     }
       
   282 
       
   283     private static class OpenCompositeTypeMapper implements JSONMapper {
       
   284 
       
   285         private final CompositeType type;
       
   286 
       
   287         OpenCompositeTypeMapper(CompositeType type) {
       
   288             this.type = type;
       
   289         }
       
   290 
       
   291         @Override
       
   292         public CompositeDataSupport toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   293             if (!(jsonValue instanceof JSONObject)) {
       
   294                 throw new JSONDataException("JSON String not an object");
       
   295             }
       
   296 
       
   297             JSONObject jObject = (JSONObject) jsonValue;
       
   298             Map<String, Object> compositeDataMap = new HashMap<>();
       
   299             for (String itemName : type.keySet()) {
       
   300                 OpenType<?> oType = type.getType(itemName);
       
   301                 JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(oType);
       
   302                 compositeDataMap.put(itemName, typeMapper.toJavaObject(jObject.get(itemName)));
       
   303             }
       
   304             try {
       
   305                 return new CompositeDataSupport(type, compositeDataMap);
       
   306             } catch (OpenDataException ex) {
       
   307                 throw new JSONDataException("Could not create CompositeData", ex);
       
   308             }
       
   309         }
       
   310 
       
   311         @Override
       
   312         public JSONElement toJsonValue(Object d) throws JSONMappingException {
       
   313             CompositeDataSupport data = (CompositeDataSupport) d;
       
   314             if (data == null) {
       
   315                 return new JSONPrimitive();
       
   316             }
       
   317             JSONObject jObject = new JSONObject();
       
   318             for (String itemName : type.keySet()) {
       
   319                 OpenType<?> oType = type.getType(itemName);
       
   320                 JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(oType);
       
   321                 if (typeMapper != null) {
       
   322                     jObject.put(itemName, typeMapper.toJsonValue(data.get(itemName)));
       
   323                 } else {
       
   324                     System.out.println("Unable to find mapper for : " + oType);
       
   325                 }
       
   326             }
       
   327             return jObject;
       
   328         }
       
   329     }
       
   330 
       
   331     private static class OpenTabularTypeMapper implements JSONMapper {
       
   332 
       
   333         private final TabularType type;
       
   334 
       
   335         public OpenTabularTypeMapper(TabularType type) {
       
   336             this.type = type;
       
   337         }
       
   338 
       
   339         /*
       
   340         Tabular data in JSON can be represented in below format
       
   341         [
       
   342             {
       
   343                 "key" : [<list of elements>],
       
   344                 "value": { <CompositeData> }
       
   345             },
       
   346             {
       
   347                 "key" : [<list of elements>],
       
   348                 "value": { <CompositeData> }
       
   349             }
       
   350         ]
       
   351          */
       
   352         @Override
       
   353         public TabularDataSupport toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   354 //            if(jsonValue instanceof JSONArray) {
       
   355 //                JSONArray jarr = (JSONArray) jsonValue;
       
   356 //                for(JSONValue jval : jarr) {
       
   357 //                    if(jval instanceof JSONObject) {
       
   358 //                        JSONObject jObject = (JSONObject) jval;
       
   359 //                        JSONValue jval1 = jObject.get("key");
       
   360 //                        Object[] key;
       
   361 //                        if(jval1 != null && jval1 instanceof JSONArray) {
       
   362 //                            JSONArray jarr1 = (JSONArray) jval1;
       
   363 //                            key = new Object[jarr1.size()];
       
   364 //                            int i=0;
       
   365 //                            for(JSONValue jval2: jarr1){
       
   366 //                                key[i++] = ((JSONPrimitive)jval2).getValue();
       
   367 //                            }
       
   368 //                        }
       
   369 //                        JSONValue jval2 = jObject.get("value");
       
   370 //                        
       
   371 //                        if(jval2 instanceof JSONObject) {
       
   372 //                            JSONObject jObj1 = (JSONObject) jval2;
       
   373 //                            JSONMapper typeMapper = JSONMappingFactory.INSTANCE.getTypeMapper(type.getRowType());
       
   374 //                            Object valueObj = typeMapper.toJavaObject(jObj1);
       
   375 //                        }
       
   376 //                    }
       
   377 //                }
       
   378 //            }
       
   379             throw new UnsupportedOperationException();
       
   380         }
       
   381 
       
   382         @Override
       
   383         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   384             throw new UnsupportedOperationException();
       
   385         }
       
   386     }
       
   387 
       
   388     private static class VoidMapper implements JSONMapper {
       
   389 
       
   390         @Override
       
   391         public Void toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   392             return null;
       
   393         }
       
   394 
       
   395         @Override
       
   396         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   397             return new JSONPrimitive();
       
   398         }
       
   399     }
       
   400 
       
   401     private static class BooleanMapper implements JSONMapper {
       
   402 
       
   403         @Override
       
   404         public Boolean toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   405             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Boolean) {
       
   406                 return (Boolean) ((JSONPrimitive) jsonValue).getValue();
       
   407             } else {
       
   408                 throw new JSONDataException("Invalid type convertion - cannot convert "
       
   409                         + ((JSONPrimitive) jsonValue).getValue() + "(" + ((JSONPrimitive) jsonValue).getValue().getClass() + ")" + " to boolean");
       
   410             }
       
   411         }
       
   412 
       
   413         @Override
       
   414         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   415             return new JSONPrimitive((Boolean) data);
       
   416         }
       
   417     }
       
   418 
       
   419     private static class ByteMapper implements JSONMapper {
       
   420 
       
   421         @Override
       
   422         public Byte toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   423             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
       
   424                 return ((Long) ((JSONPrimitive) jsonValue).getValue()).byteValue();
       
   425             } else {
       
   426                 throw new JSONDataException("Invalid type convertion - cannot convert "
       
   427                         + (((JSONPrimitive) jsonValue).getValue().getClass()) + " to byte");
       
   428             }
       
   429         }
       
   430 
       
   431         @Override
       
   432         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   433             return new JSONPrimitive((Byte) data);
       
   434         }
       
   435     }
       
   436 
       
   437     private static class ShortMapper implements JSONMapper {
       
   438 
       
   439         @Override
       
   440         public Short toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   441             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
       
   442                 return ((Long) ((JSONPrimitive) jsonValue).getValue()).shortValue();
       
   443             } else {
       
   444                 throw new JSONDataException("Invalid JSON");
       
   445             }
       
   446         }
       
   447 
       
   448         @Override
       
   449         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   450             return new JSONPrimitive((Short) data);
       
   451         }
       
   452     }
       
   453 
       
   454     private static class IntegerMapper implements JSONMapper {
       
   455 
       
   456         @Override
       
   457         public Integer toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   458             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
       
   459                 return ((Long) ((JSONPrimitive) jsonValue).getValue()).intValue();
       
   460             } else {
       
   461                 throw new JSONDataException("Invalid JSON");
       
   462             }
       
   463         }
       
   464 
       
   465         @Override
       
   466         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   467             return new JSONPrimitive((Integer) data);
       
   468         }
       
   469     }
       
   470 
       
   471     private static class LongMapper implements JSONMapper {
       
   472 
       
   473         @Override
       
   474         public Long toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   475             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
       
   476                 return (Long) ((JSONPrimitive) jsonValue).getValue();
       
   477             } else {
       
   478                 throw new JSONDataException("Invalid JSON");
       
   479             }
       
   480         }
       
   481 
       
   482         @Override
       
   483         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   484             return new JSONPrimitive((Long) data);
       
   485         }
       
   486     }
       
   487 
       
   488     private static class FloatMapper implements JSONMapper {
       
   489 
       
   490         @Override
       
   491         public Float toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   492             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Double) {
       
   493                 return ((Double) ((JSONPrimitive) jsonValue).getValue()).floatValue();
       
   494             } else {
       
   495                 throw new JSONDataException("Invalid JSON");
       
   496             }
       
   497         }
       
   498 
       
   499         @Override
       
   500         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   501             return new JSONPrimitive((Float) data);
       
   502         }
       
   503     }
       
   504 
       
   505     private static class DoubleMapper implements JSONMapper {
       
   506 
       
   507         @Override
       
   508         public Double toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   509             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
       
   510                 return (Double) ((JSONPrimitive) jsonValue).getValue();
       
   511             } else {
       
   512                 throw new JSONDataException("Invalid JSON");
       
   513             }
       
   514         }
       
   515 
       
   516         @Override
       
   517         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   518             return new JSONPrimitive((Double) data);
       
   519         }
       
   520     }
       
   521 
       
   522     private static class CharacterMapper implements JSONMapper {
       
   523 
       
   524         @Override
       
   525         public Character toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   526             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
       
   527                 String data = ((String) ((JSONPrimitive) jsonValue).getValue());
       
   528                 if (data.length() < 1) {
       
   529                     throw new JSONDataException("Invalid char");
       
   530                 }
       
   531                 return data.charAt(0);
       
   532             } else {
       
   533                 throw new JSONDataException("Invalid JSON");
       
   534             }
       
   535         }
       
   536 
       
   537         @Override
       
   538         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   539             return new JSONPrimitive((Character) data);
       
   540         }
       
   541     }
       
   542 
       
   543     private static class StringMapper implements JSONMapper {
       
   544 
       
   545         @Override
       
   546         public String toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   547             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
       
   548                 return (String) ((JSONPrimitive) jsonValue).getValue();
       
   549             } else {
       
   550                 throw new JSONDataException("Invalid JSON");
       
   551             }
       
   552         }
       
   553 
       
   554         @Override
       
   555         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   556             return new JSONPrimitive((String) data);
       
   557         }
       
   558     }
       
   559 
       
   560     private static class BigDecimalMapper implements JSONMapper {
       
   561 
       
   562         @Override
       
   563         public BigDecimal toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   564             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Double) {
       
   565                 return BigDecimal.valueOf((Double) ((JSONPrimitive) jsonValue).getValue());
       
   566             } else {
       
   567                 throw new JSONDataException("Invalid JSON");
       
   568             }
       
   569         }
       
   570 
       
   571         @Override
       
   572         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   573             return new JSONPrimitive(((BigDecimal) data).doubleValue());
       
   574         }
       
   575     }
       
   576 
       
   577     private static class BigIntegerMapper implements JSONMapper {
       
   578 
       
   579         @Override
       
   580         public BigInteger toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   581             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof Long) {
       
   582                 return BigInteger.valueOf((Long) ((JSONPrimitive) jsonValue).getValue());
       
   583             } else {
       
   584                 throw new JSONDataException("Invalid JSON");
       
   585             }
       
   586         }
       
   587 
       
   588         @Override
       
   589         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   590             return new JSONPrimitive(((BigInteger) data).longValue());
       
   591         }
       
   592     }
       
   593 
       
   594     private static class ObjectNameMapper implements JSONMapper {
       
   595 
       
   596         @Override
       
   597         public ObjectName toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   598             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
       
   599                 try {
       
   600                     return new ObjectName((String) ((JSONPrimitive) jsonValue).getValue());
       
   601                 } catch (MalformedObjectNameException ex) {
       
   602                     throw new JSONDataException("Invalid Objectname");
       
   603                 }
       
   604             } else {
       
   605                 throw new JSONDataException("Invalid JSON");
       
   606             }
       
   607         }
       
   608 
       
   609         @Override
       
   610         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   611             return new JSONPrimitive(data.toString());
       
   612         }
       
   613     }
       
   614 
       
   615     private static class DateMapper implements JSONMapper {
       
   616 
       
   617         private final DateFormat df = new SimpleDateFormat("YYYY-MM-DD");
       
   618 
       
   619         @Override
       
   620         public Date toJavaObject(JSONElement jsonValue) throws JSONDataException {
       
   621             if (jsonValue instanceof JSONPrimitive && ((JSONPrimitive) jsonValue).getValue() instanceof String) {
       
   622                 String data = ((String) ((JSONPrimitive) jsonValue).getValue());
       
   623                 try {
       
   624                     return df.parse(data);
       
   625                 } catch (ParseException ex) {
       
   626                     throw new JSONDataException("Invalid Data " + data);
       
   627                 }
       
   628             } else {
       
   629                 throw new JSONDataException("Invalid JSON");
       
   630             }
       
   631         }
       
   632 
       
   633         @Override
       
   634         public JSONElement toJsonValue(Object data) throws JSONMappingException {
       
   635             return new JSONPrimitive(df.format((Date) data));
       
   636         }
       
   637     }
       
   638 }