Package cc.plural.jsonij.marshal

Source Code of cc.plural.jsonij.marshal.JSONDocumentMarshaler

/*
* Copyright 2011 jmarsden.
*
* 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 cc.plural.jsonij.marshal;

import cc.plural.jsonij.JSON;
import cc.plural.jsonij.Value;
import cc.plural.jsonij.marshal.codec.JSONValueCodecStore.JSONValueCodecHelper;
import cc.plural.jsonij.parser.ParserException;
import cc.plural.jsonij.reflect.ClassProperty;
import cc.plural.jsonij.reflect.Inspection;
import cc.plural.jsonij.reflect.ReflectType;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author jmarsden
*/
public class JSONDocumentMarshaler {

    public Object marshalJSONDocument(JSON json, Class<?> objectClass) throws JSONMarshalerException {
        Object resultObject = null;
        Value jsonRoot = json.getRoot();
        if (jsonRoot.type() == Value.TYPE.OBJECT) {
            JSON.Object<CharSequence, Value> jsonObjectRoot = (JSON.Object<CharSequence, Value>) jsonRoot;
            resultObject = marshalJSONDocumentObject(jsonObjectRoot, objectClass);
        } else if (jsonRoot.type() == Value.TYPE.ARRAY) {
            JSON.Array<Value> jsonArrayRoot = (JSON.Array<Value>) jsonRoot;
            resultObject = marshalJSONDocumentArray(jsonArrayRoot, objectClass);
        } else {
            throw new RuntimeException("Not an Object or Array Type.");
        }
        return resultObject;
    }

    public Object marshalJSONDocument(Value value, Class<?> objectClass) throws JSONMarshalerException {
        Object resultObject = null;

        ReflectType type = ReflectType.inspectObjectType(objectClass);
        switch (type) {
            case OBJECT:
                if (value.type() == Value.TYPE.OBJECT) {
                    JSON.Object<CharSequence, Value> jsonObjectRoot = (JSON.Object<CharSequence, Value>) value;
                    resultObject = marshalJSONDocumentObject(jsonObjectRoot, objectClass);
                } else {
                    // TODO
                }
                break;
            case ARRAY:
            case ARRAY_BOOLEAN:
            case ARRAY_BYTE:
            case ARRAY_SHORT:
            case ARRAY_INTEGER:
            case ARRAY_FLOAT:
            case ARRAY_DOUBLE:
            case ARRAY_LONG:
            case ARRAY_STRING:
            case ARRAY_ENUM:
                if (value.type() == Value.TYPE.ARRAY) {
                    JSON.Array<Value> jsonArrayRoot = (JSON.Array<Value>) value;
                    resultObject = marshalJSONDocumentArray(jsonArrayRoot, objectClass);
                } else {
                    // TODO: Strict
                }
                break;

            case STRING:
                if (value.type() == Value.TYPE.STRING) {
                    return value.toString();
                }
                break;
            case BOOLEAN:
                if (value.type() == Value.TYPE.TRUE) {
                    return true;
                } else if (value.type() == Value.TYPE.FALSE) {
                    return false;
                } else {
                }
                break;
            case BYTE:
                if (value.type() == Value.TYPE.NUMERIC) {
                    return value.getNumber().byteValue();
                } else {
                    // TODO: Strict
                }
                break;
            case SHORT:
                if (value.type() == Value.TYPE.NUMERIC) {
                    return value.getNumber().shortValue();
                } else {
                    // TODO: Strict
                }
                break;
            case INTEGER:
                if (objectClass == BigInteger.class) {
                    return new BigInteger(value.getString());
                } else if (value.type() == Value.TYPE.NUMERIC) {
                    return value.getNumber().intValue();
                } else {
                    // TODO: Strict
                }
                break;
            case DOUBLE:
                if (objectClass == BigDecimal.class) {
                    return new BigDecimal(value.getString());
                } else if (value.type() == Value.TYPE.NUMERIC) {
                    return value.getNumber().doubleValue();
                } else {
                    // TODO: Strict
                }
                break;
            case FLOAT:
                if (value.type() == Value.TYPE.NUMERIC) {
                    return value.getNumber().floatValue();
                } else {
                    // TODO: Strict
                }
                break;
            case LONG:
                if (value.type() == Value.TYPE.NUMERIC) {
                    return value.getNumber().longValue();
                } else {
                    // TODO: Strict
                }
                break;
            case CLASS:
                if (value.type() == Value.TYPE.STRING) {
                    try {
                        return Class.forName(value.toString());
                    } catch (ClassNotFoundException ex) { }
                }
            case UNKOWN:
            default:
                System.out.println("Unknown Type:" + type + " " + value);
                throw new RuntimeException("Unhandled Type " + type + " " + value);
        }

        return resultObject;
    }

    public Object marshalJSONDocument(InputStream stream, Class<?> objectClass) throws JSONMarshalerException {
        JSON json;
        try {
            json = JSON.parse(stream);
        } catch (ParserException ex) {
            throw new JSONMarshalerException("", ex);
        } catch (IOException ex) {
            throw new JSONMarshalerException("", ex);
        }
        return marshalJSONDocument(json, objectClass);
    }

    public Object marshalJSONDocument(String jsonString, Class<?> objectClass) throws JSONMarshalerException {
        JSON json;
        try {
            json = JSON.parse(jsonString);
        } catch (ParserException ex) {
            throw new JSONMarshalerException("", ex);
        } catch (IOException ex) {
            throw new JSONMarshalerException("", ex);
        }
        return marshalJSONDocument(json, objectClass);
    }

    public Object marshalJSONDocumentObject(JSON.Object<CharSequence, Value> jsonObject, Class<?> objectClass) throws JSONMarshalerException {
        Object object = null;

        if (JSONMarshaler.hasCodec(objectClass)) {
            JSONValueCodecHelper codecHelper = JSONMarshaler.getCodecHelper(objectClass);
            try {
                object = codecHelper.decode(jsonObject, objectClass);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {

            try {
                object = objectClass.newInstance();
            } catch (InstantiationException ex) {
                Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                throw new JSONMarshalerException("newInstance");
            } catch (IllegalAccessException ex) {
                Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                throw new JSONMarshalerException("illegalAccess");
            }

            ReflectType type = ReflectType.inspectObjectType(objectClass);
            Inspection inspection = ReflectType.getInspection(objectClass);

            boolean hasCollector = inspection.hasCollectors();
            Map<CharSequence, Value> collector = null;
            Map<CharSequence, Value> innerObjectCollector = null;
            List<Value> innerArrayCollector = null;

            if (hasCollector) {
                collector = new HashMap<CharSequence, Value>();
            }
            if (inspection.hasInnerMap()) {
                innerObjectCollector = new HashMap<CharSequence, Value>();
            }
            if (inspection.hasInnerList()) {
                innerArrayCollector = new ArrayList<Value>();
            }

            for (Entry<CharSequence, Value> documentPropertyEntry : jsonObject.entrySet()) {
                CharSequence key = documentPropertyEntry.getKey();
                if (inspection.hasProperty(key.toString())) {
                    ClassProperty inspectorProperty = inspection.getProperty(key.toString());
                    Value documentValue = documentPropertyEntry.getValue();
                    try {
                        marshalJSONValue(documentValue, object, inspectorProperty);
                    } catch (IllegalAccessException ex) {
                        Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IllegalArgumentException ex) {
                        Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (InvocationTargetException ex) {
                        Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } else {
                    if (hasCollector) {
                        collector.put(key, documentPropertyEntry.getValue());
                    }
                    if (inspection.hasInnerMap()) {
                        innerObjectCollector.put(key, documentPropertyEntry.getValue());
                    }
                    if (inspection.hasInnerList()) {
                        innerArrayCollector.add(documentPropertyEntry.getValue());
                    }
                }
            }

            if (hasCollector) {
                for (ClassProperty collectorProperty : inspection.getCollectors()) {
                    try {
                        collectorProperty.getMutator().fire(object, collector);
                    } catch (IllegalAccessException ex) {
                        Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IllegalArgumentException ex) {
                        Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (InvocationTargetException ex) {
                        Logger.getLogger(JSONDocumentMarshaler.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            if (inspection.hasInnerMap()) {
            }
            if (inspection.hasInnerList()) {
            }
        }
        return object;
    }

    public Object marshalJSONDocumentArray(JSON.Array<Value> jsonArray, Class<?> objectClass) throws JSONMarshalerException {
        int size = jsonArray.size();
        ReflectType type = ReflectType.inspectObjectType(objectClass);
        if (type == ReflectType.OBJECT) {
            return marshalJSONDocumentList(jsonArray, objectClass);
        } else {
            Class<?> componentClass = objectClass.getComponentType();
            ReflectType componentType = ReflectType.inspectObjectType(componentClass);
            Object array = Array.newInstance(componentClass, size);
            for (int i = 0; i < size; i++) {
                Value value = jsonArray.get(i);
                if (value.getValueType() == Value.TYPE.OBJECT) {
                    Array.set(array, i, marshalJSONDocumentObject((JSON.Object<CharSequence, Value>) value, componentClass));
                } else if (value.getValueType() == Value.TYPE.ARRAY) {
                    Array.set(array, i, marshalJSONDocumentArray((JSON.Array<Value>) value, componentClass));
                } else if (componentType == ReflectType.INTEGER) {
                    Array.set(array, i, jsonArray.get(i).getNumber().intValue());
                } else if (componentType == ReflectType.FLOAT) {
                    Array.set(array, i, jsonArray.get(i).getNumber().floatValue());
                } else if (componentType == ReflectType.DOUBLE) {
                    Array.set(array, i, jsonArray.get(i).getNumber().doubleValue());
                } else if (componentType == ReflectType.BYTE) {
                    Array.set(array, i, jsonArray.get(i).getNumber().byteValue());
                } else if (componentType == ReflectType.BOOLEAN) {
                    Array.set(array, i, jsonArray.get(i).getBoolean());
                } else if (componentType == ReflectType.STRING) {
                    Array.set(array, i, jsonArray.get(i).getString());
                } else {
                }
            }
            return array;
        }
    }

    public List<?> marshalJSONDocumentList(JSON.Array<Value> jsonArray, Class<?> objectClass) throws JSONMarshalerException {
        return null;
    }

    public Map<?, ?> marshalJSONDocumentMap(JSON.Object<CharSequence, Value> jsonMap, Type type) throws JSONMarshalerException {

        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;

            Type[] parameterTypeArray = parameterizedType.getActualTypeArguments();
            if (parameterTypeArray != null && parameterTypeArray.length == 2) {
                Class<?> keyClass = null;
                if (parameterTypeArray[0] instanceof Class) {
                    keyClass = (Class<?>) parameterTypeArray[0];
                }
                Class<?> valueClass = null;
                if (parameterTypeArray[1] instanceof Class) {
                    valueClass = (Class<?>) parameterTypeArray[1];
                } else if (parameterTypeArray[1] instanceof ParameterizedType) {
                    ParameterizedType valueType = (ParameterizedType) parameterTypeArray[1];
                    valueClass = (Class<?>) valueType.getRawType();
                }

//                if(keyClass == null || valueClass == null) {
//                    return null;
//                }
//               
                Map<CharSequence, Object> returnMap = new HashMap();

                Iterator<CharSequence> keySetIterator = jsonMap.keySet().iterator();
                while (keySetIterator.hasNext()) {

                    CharSequence keyValue = keySetIterator.next();
                    Value value = jsonMap.get(keyValue);

                    Object o = marshalJSONDocument(value, valueClass);
                    returnMap.put(keyValue, o);
                }

                return returnMap;

            } else {
                throw new RuntimeException("Beef this up");
            }
        }

        System.out.println(jsonMap);

        Iterator<CharSequence> keySet = jsonMap.keySet().iterator();
        while (keySet.hasNext()) {
            CharSequence key = keySet.next();
            Value v = jsonMap.get(key);


        }


        return null;
    }

    private void marshalJSONValue(Value value, Object object, ClassProperty inspectorProperty) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, JSONMarshalerException {
        ClassProperty.ClassPropertyMutator mutator = inspectorProperty.getMutator();
        ReflectType type = ReflectType.inspectObjectType(mutator.getType());
        switch (type) {
            case BOOLEAN:
                mutator.fire(object, value.getBoolean());
                return;
            case BYTE:
                mutator.fire(object, value.getNumber().byteValue());
                return;
            case SHORT:
                mutator.fire(object, value.getNumber().shortValue());
                return;
            case INTEGER:
                mutator.fire(object, value.getNumber().intValue());
                return;
            case FLOAT:
                mutator.fire(object, value.getNumber().floatValue());
                return;
            case LONG:
                mutator.fire(object, value.getNumber().longValue());
                return;
            case STRING:
                mutator.fire(object, value.getString());
                return;
            case ARRAY:
            case ARRAY_BOOLEAN:
            case ARRAY_BYTE:
            case ARRAY_SHORT:
            case ARRAY_INTEGER:
            case ARRAY_FLOAT:
            case ARRAY_DOUBLE:
            case ARRAY_LONG:
            case ARRAY_STRING:
            case ARRAY_ENUM:
                mutator.fire(object, marshalJSONDocumentArray((JSON.Array<Value>) value, mutator.getType()));
                return;
            case OBJECT:
                Object propertyObject = marshalJSONDocument(value, mutator.getType());
                mutator.fire(object, propertyObject);
                return;
            case MAP:
                Map<?, ?> propertyMap = marshalJSONDocumentMap((JSON.Object<CharSequence, Value>) value, mutator.getGenericType());
                mutator.fire(object, propertyMap);
                return;
            case UNKOWN:
                Object propertyUnknown = marshalJSONDocument(value, mutator.getType());
                mutator.fire(object, propertyUnknown);
            default:
                System.out.println("Unknown Type:" + type + " " + value);
                throw new RuntimeException("Unhandled Type " + type + " " + value);

        }

    }
}
TOP

Related Classes of cc.plural.jsonij.marshal.JSONDocumentMarshaler

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.