org.bimserver.shared.json.JsonConverter.java Source code

Java tutorial

Introduction

Here is the source code for org.bimserver.shared.json.JsonConverter.java

Source

package org.bimserver.shared.json;

/******************************************************************************
 * Copyright (C) 2009-2016  BIMserver.org
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see {@literal<http://www.gnu.org/licenses/>}.
 *****************************************************************************/

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.activation.DataHandler;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.bimserver.plugins.serializers.CacheStoringEmfSerializerDataSource;
import org.bimserver.plugins.serializers.SerializerException;
import org.bimserver.shared.meta.SBase;
import org.bimserver.shared.meta.SClass;
import org.bimserver.shared.meta.SField;
import org.bimserver.shared.meta.SServicesMap;
import org.bimserver.utils.ByteArrayDataSource;

import com.google.common.base.Charsets;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonWriter;

public class JsonConverter {

    private final SServicesMap servicesMap;

    public JsonConverter(SServicesMap servicesMap) {
        this.servicesMap = servicesMap;
    }

    public void toJson(Object object, JsonWriter out) throws IOException, SerializerException {
        if (object instanceof SBase) {
            SBase base = (SBase) object;
            out.beginObject();
            out.name("__type");
            out.value(base.getSClass().getSimpleName());
            for (SField field : base.getSClass().getAllFields()) {
                out.name(field.getName());
                toJson(base.sGet(field), out);
            }
            out.endObject();
        } else if (object instanceof Collection) {
            Collection<?> collection = (Collection<?>) object;
            out.beginArray();
            for (Object value : collection) {
                toJson(value, out);
            }
            out.endArray();
        } else if (object instanceof Date) {
            out.value(((Date) object).getTime());
        } else if (object instanceof DataHandler) {
            DataHandler dataHandler = (DataHandler) object;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            if (dataHandler.getDataSource() instanceof CacheStoringEmfSerializerDataSource) {
                CacheStoringEmfSerializerDataSource cacheStoringEmfSerializerDataSource = (CacheStoringEmfSerializerDataSource) dataHandler
                        .getDataSource();
                cacheStoringEmfSerializerDataSource.writeToOutputStream(baos, null);
                out.value(new String(Base64.encodeBase64(baos.toByteArray()), Charsets.UTF_8));
            } else {
                InputStream inputStream = dataHandler.getInputStream();
                IOUtils.copy(inputStream, baos);
                out.value(new String(Base64.encodeBase64(baos.toByteArray()), Charsets.UTF_8));
            }
        } else if (object instanceof byte[]) {
            byte[] data = (byte[]) object;
            out.value(new String(Base64.encodeBase64(data), Charsets.UTF_8));
        } else if (object instanceof String) {
            out.value((String) object);
        } else if (object instanceof Number) {
            out.value((Number) object);
        } else if (object instanceof Enum) {
            out.value(object.toString());
        } else if (object instanceof Boolean) {
            out.value((Boolean) object);
        } else if (object == null) {
            out.nullValue();
        } else {
            throw new UnsupportedOperationException(object.toString());
        }
    }

    public JsonElement toJson(Object object) throws IOException {
        if (object instanceof SBase) {
            SBase base = (SBase) object;
            JsonObject jsonObject = new JsonObject();
            jsonObject.add("__type", new JsonPrimitive(base.getSClass().getSimpleName()));
            for (SField field : base.getSClass().getOwnFields()) {
                jsonObject.add(field.getName(), toJson(base.sGet(field)));
            }
            return jsonObject;
        } else if (object instanceof Collection) {
            Collection<?> collection = (Collection<?>) object;
            JsonArray jsonArray = new JsonArray();
            for (Object value : collection) {
                jsonArray.add(toJson(value));
            }
            return jsonArray;
        } else if (object instanceof Date) {
            return new JsonPrimitive(((Date) object).getTime());
        } else if (object instanceof DataHandler) {
            DataHandler dataHandler = (DataHandler) object;
            InputStream inputStream = dataHandler.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, out);
            return new JsonPrimitive(new String(Base64.encodeBase64(out.toByteArray()), Charsets.UTF_8));
        } else if (object instanceof Boolean) {
            return new JsonPrimitive((Boolean) object);
        } else if (object instanceof String) {
            return new JsonPrimitive((String) object);
        } else if (object instanceof Long) {
            return new JsonPrimitive((Long) object);
        } else if (object instanceof Integer) {
            return new JsonPrimitive((Integer) object);
        } else if (object instanceof Double) {
            return new JsonPrimitive((Double) object);
        } else if (object instanceof Enum) {
            return new JsonPrimitive(object.toString());
        } else if (object == null) {
            return JsonNull.INSTANCE;
        } else if (object instanceof byte[]) {
            byte[] data = (byte[]) object;
            return new JsonPrimitive(new String(Base64.encodeBase64(data), Charsets.UTF_8));
        }
        throw new UnsupportedOperationException(object.getClass().getName());
    }

    public Object fromJson(SClass definedType, SClass genericType, Object object)
            throws ConvertException, IOException {
        try {
            if (object instanceof JsonObject) {
                JsonObject jsonObject = (JsonObject) object;
                if (jsonObject.has("__type")) {
                    String type = jsonObject.get("__type").getAsString();
                    SClass sClass = servicesMap.getType(type);
                    SBase newObject = sClass.newInstance();
                    for (SField field : newObject.getSClass().getAllFields()) {
                        if (jsonObject.has(field.getName())) {
                            newObject.sSet(field, fromJson(field.getType(), field.getGenericType(),
                                    jsonObject.get(field.getName())));
                        }
                    }
                    return newObject;
                } else {
                    if (jsonObject.entrySet().size() != 0) {
                        throw new ConvertException("Missing __type field in " + jsonObject.toString());
                    } else {
                        return null;
                    }
                }
            } else if (object instanceof JsonArray) {
                JsonArray array = (JsonArray) object;
                if (definedType.isList()) {
                    List<Object> list = new ArrayList<Object>();
                    for (int i = 0; i < array.size(); i++) {
                        list.add(fromJson(definedType, genericType, array.get(i)));
                    }
                    return list;
                } else if (definedType.isSet()) {
                    Set<Object> set = new HashSet<Object>();
                    for (int i = 0; i < array.size(); i++) {
                        set.add(fromJson(definedType, genericType, array.get(i)));
                    }
                    return set;
                }
            } else if (object instanceof JsonNull) {
                return null;
            } else if (definedType.isByteArray()) {
                if (object instanceof JsonPrimitive) {
                    JsonPrimitive jsonPrimitive = (JsonPrimitive) object;
                    return Base64.decodeBase64(jsonPrimitive.getAsString().getBytes(Charsets.UTF_8));
                }
            } else if (definedType.isDataHandler()) {
                if (object instanceof JsonPrimitive) {
                    JsonPrimitive jsonPrimitive = (JsonPrimitive) object;
                    byte[] data = Base64.decodeBase64(jsonPrimitive.getAsString().getBytes(Charsets.UTF_8));
                    return new DataHandler(new ByteArrayDataSource(null, data));
                }
            } else if (definedType.isInteger()) {
                if (object instanceof JsonPrimitive) {
                    return ((JsonPrimitive) object).getAsInt();
                }
            } else if (definedType.isLong()) {
                if (object instanceof JsonPrimitive) {
                    return ((JsonPrimitive) object).getAsLong();
                }
            } else if (definedType.isEnum()) {
                JsonPrimitive primitive = (JsonPrimitive) object;
                for (Object enumConstantObject : definedType.getInstanceClass().getEnumConstants()) {
                    Enum<?> enumConstant = (Enum<?>) enumConstantObject;
                    if (enumConstant.name().equals(primitive.getAsString())) {
                        return enumConstant;
                    }
                }
            } else if (definedType.isDate()) {
                if (object instanceof JsonPrimitive) {
                    return new Date(((JsonPrimitive) object).getAsLong());
                }
            } else if (definedType.isString()) {
                if (object instanceof JsonPrimitive) {
                    return ((JsonPrimitive) object).getAsString();
                } else if (object instanceof JsonNull) {
                    return null;
                }
            } else if (definedType.isBoolean()) {
                if (object instanceof JsonPrimitive) {
                    return ((JsonPrimitive) object).getAsBoolean();
                }
            } else if (definedType.isList()) {
                if (genericType.isLong()) {
                    if (object instanceof JsonPrimitive) {
                        return ((JsonPrimitive) object).getAsLong();
                    }
                } else if (genericType.isInteger()) {
                    if (object instanceof JsonPrimitive) {
                        return ((JsonPrimitive) object).getAsInt();
                    }
                } else if (genericType.isString()) {
                    if (object instanceof JsonPrimitive) {
                        return ((JsonPrimitive) object).getAsString();
                    }
                } else if (genericType.isDouble()) {
                    if (object instanceof JsonPrimitive) {
                        return ((JsonPrimitive) object).getAsDouble();
                    }
                }
            } else if (definedType.isSet()) {
                if (genericType.isLong()) {
                    if (object instanceof JsonPrimitive) {
                        return ((JsonPrimitive) object).getAsLong();
                    }
                } else if (genericType.isInteger()) {
                    if (object instanceof JsonPrimitive) {
                        return ((JsonPrimitive) object).getAsInt();
                    }
                } else if (genericType.isString()) {
                    if (object instanceof JsonPrimitive) {
                        return ((JsonPrimitive) object).getAsString();
                    }
                }
            } else if (definedType.isDouble()) {
                if (object instanceof JsonPrimitive) {
                    return ((JsonPrimitive) object).getAsDouble();
                }
            } else if (definedType.isFloat()) {
                if (object instanceof JsonPrimitive) {
                    return ((JsonPrimitive) object).getAsFloat();
                }
            } else if (definedType.isVoid()) {
                return null;
            }
        } catch (NumberFormatException e) {
            throw new ConvertException(e);
        }
        throw new UnsupportedOperationException(object.toString());
    }
}