Java tutorial
/* * Copyright (C) 2012-2013 by it's authors. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.github.autermann.matlab.json; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.reflect.Type; import java.util.Map.Entry; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import org.joda.time.DateTime; import org.joda.time.format.ISODateTimeFormat; import com.github.autermann.matlab.value.MatlabArray; import com.github.autermann.matlab.value.MatlabBoolean; import com.github.autermann.matlab.value.MatlabCell; import com.github.autermann.matlab.value.MatlabDateTime; import com.github.autermann.matlab.value.MatlabFile; import com.github.autermann.matlab.value.MatlabMatrix; import com.github.autermann.matlab.value.MatlabScalar; import com.github.autermann.matlab.value.MatlabString; import com.github.autermann.matlab.value.MatlabStruct; import com.github.autermann.matlab.value.MatlabType; import com.github.autermann.matlab.value.MatlabValue; import com.github.autermann.matlab.value.ReturningMatlabValueVisitor; import com.google.common.io.BaseEncoding; import com.google.common.io.ByteStreams; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonNull; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; /** * {@link MatlabValue} serializer. * * @author Richard Jones * */ public class MatlabValueSerializer implements JsonSerializer<MatlabValue>, JsonDeserializer<MatlabValue> { @Override public JsonElement serialize(MatlabValue value, Type type, JsonSerializationContext ctx) { if (value == null) { return new JsonNull(); } JsonObject object = new JsonObject(); object.addProperty(MatlabJSONConstants.TYPE, value.getType().toString()); object.add(MatlabJSONConstants.VALUE, value.accept(new VisitingSerializer(ctx))); return object; } @Override public MatlabValue deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return deserializeValue(json); } /** * Deserializes an {@link MatlabValue} from a {@link JsonElement}. * * @param element the <code>JsonElement</code> containing a * serialized <code>MatlabValue</code> * * @return the deserialized <code>MatlabValue</code> */ public MatlabValue deserializeValue(JsonElement element) { if (!element.isJsonObject()) { throw new JsonParseException("expected JSON object"); } JsonObject json = element.getAsJsonObject(); MatlabType type = getType(json); JsonElement value = json.get(MatlabJSONConstants.VALUE); switch (type) { case ARRAY: return parseMatlabArray(value); case BOOLEAN: return parseMatlabBoolean(value); case CELL: return parseMatlabCell(value); case FILE: return parseMatlabFile(value); case MATRIX: return parseMatlabMatrix(value); case SCALAR: return parseMatlabScalar(value); case STRING: return parseMatlabString(value); case STRUCT: return parseMatlabStruct(value); case DATE_TIME: return parseMatlabDateTime(value); default: throw new JsonParseException("Unknown type: " + type); } } private MatlabType getType(JsonObject json) throws JsonParseException { String type = json.get(MatlabJSONConstants.TYPE).getAsString(); try { return MatlabType.fromString(type); } catch (IllegalArgumentException e) { throw new JsonParseException("Unknown type: " + type); } } private MatlabMatrix parseMatlabMatrix(JsonElement value) { JsonArray array = value.getAsJsonArray(); double[][] values = new double[array.size()][array.get(0).getAsJsonArray().size()]; for (int i = 0; i < array.size(); i++) { JsonArray innerArray = array.get(i).getAsJsonArray(); for (int j = 0; j < innerArray.size(); j++) { values[i][j] = innerArray.get(j).getAsDouble(); } } return new MatlabMatrix(values); } private MatlabArray parseMatlabArray(JsonElement value) { JsonArray array = value.getAsJsonArray(); double[] values = new double[array.size()]; for (int i = 0; i < array.size(); i++) { values[i] = array.get(i).getAsDouble(); } return new MatlabArray(values); } private MatlabStruct parseMatlabStruct(JsonElement value) { MatlabStruct struct = new MatlabStruct(); for (Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) { struct.set(e.getKey(), deserializeValue(e.getValue())); } return struct; } private MatlabCell parseMatlabCell(JsonElement value) { JsonArray array = value.getAsJsonArray(); MatlabValue[] cell = new MatlabValue[array.size()]; for (int i = 0; i < array.size(); i++) { cell[i] = deserializeValue(array.get(i)); } return new MatlabCell(cell); } private MatlabScalar parseMatlabScalar(JsonElement value) { JsonPrimitive p = (JsonPrimitive) value; if (p.isString()) { return new MatlabScalar(Double.valueOf(p.getAsString())); } else { return new MatlabScalar(p.getAsDouble()); } } private MatlabBoolean parseMatlabBoolean(JsonElement value) { return MatlabBoolean.fromBoolean(value.getAsBoolean()); } private MatlabString parseMatlabString(JsonElement value) { return new MatlabString(value.getAsString()); } private MatlabFile parseMatlabFile(JsonElement value) { return new MatlabFile(gunzip(value.getAsString())); } private byte[] gunzip(String value) { GZIPInputStream in = null; try { byte[] gzipped = BaseEncoding.base64().decode(value); in = new GZIPInputStream(new ByteArrayInputStream(gzipped)); return ByteStreams.toByteArray(in); } catch (IOException ex) { throw new RuntimeException(ex); } finally { try { if (in != null) { in.close(); } } catch (IOException ex) { } } } private String gzip(byte[] bytes) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream out = null; try { out = new GZIPOutputStream(baos); out.write(bytes); out.finish(); return BaseEncoding.base64().encode(baos.toByteArray()); } catch (IOException ex) { throw new RuntimeException(ex); } finally { try { if (out != null) { out.close(); } } catch (IOException ex) { } } } private MatlabDateTime parseMatlabDateTime(JsonElement value) { DateTime dt = ISODateTimeFormat.dateTime().parseDateTime(value.getAsString()); return new MatlabDateTime(dt); } private class VisitingSerializer implements ReturningMatlabValueVisitor<JsonElement> { private final JsonSerializationContext ctx; VisitingSerializer(JsonSerializationContext ctx) { this.ctx = ctx; } @Override public JsonElement visit(MatlabArray array) { return ctx.serialize(array.value()); } @Override public JsonElement visit(MatlabBoolean bool) { return ctx.serialize(bool.value()); } @Override public JsonElement visit(MatlabCell cell) { return ctx.serialize(cell.value()); } @Override public JsonElement visit(MatlabMatrix matrix) { return ctx.serialize(matrix.value()); } @Override public JsonElement visit(MatlabScalar scalar) { if (Double.isNaN(scalar.value()) || Double.isInfinite(scalar.value())) { return ctx.serialize(Double.toString(scalar.value())); } else { return ctx.serialize(scalar.value()); } } @Override public JsonElement visit(MatlabString string) { return ctx.serialize(string.value()); } @Override public JsonElement visit(MatlabStruct struct) { JsonObject object = new JsonObject(); for (Entry<MatlabString, MatlabValue> e : struct.value().entrySet()) { object.add(e.getKey().value(), serialize(e.getValue(), MatlabValue.class, ctx)); } return object; } @Override public JsonElement visit(MatlabFile file) { try { return ctx.serialize(gzip(file.getContent())); } catch (IOException ex) { throw new RuntimeException(ex); } } @Override public JsonElement visit(MatlabDateTime time) { return ctx.serialize(ISODateTimeFormat.dateTime().print(time.value())); } } }