org.boris.xlloop.http.JSONCodec.java Source code

Java tutorial

Introduction

Here is the source code for org.boris.xlloop.http.JSONCodec.java

Source

/*******************************************************************************
 * This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     Peter Smith
 *******************************************************************************/
package org.boris.xlloop.http;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

import org.boris.xlloop.IFunctionHandler;
import org.boris.xlloop.RequestException;
import org.boris.xlloop.xloper.XLArray;
import org.boris.xlloop.xloper.XLBool;
import org.boris.xlloop.xloper.XLError;
import org.boris.xlloop.xloper.XLInt;
import org.boris.xlloop.xloper.XLMissing;
import org.boris.xlloop.xloper.XLNil;
import org.boris.xlloop.xloper.XLNum;
import org.boris.xlloop.xloper.XLSRef;
import org.boris.xlloop.xloper.XLString;
import org.boris.xlloop.xloper.XLoper;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

public class JSONCodec {
    public static void doRequest(IFunctionHandler handler, Reader input, Writer output)
            throws IOException, JSONException {
        BufferedWriter bw = new BufferedWriter(output);
        try {
            FunctionRequest fr = JSONCodec.decodeRequest(input);
            System.out.println(JSONCodec.encodeRequest(fr).toString(4));
            XLoper res = handler.execute(null, fr.getName(), fr.getArgs());
            System.out.println(JSONCodec.encode(res).toString(4));
            JSONCodec.encodeXLoper(res, bw);
        } catch (RequestException e) {
            e.printStackTrace();
            XLoper res = new XLString(e.getMessage());
            JSONCodec.encodeXLoper(res, bw);
            bw.flush();
        } finally {
            if (bw != null)
                bw.flush();
        }
    }

    public static FunctionRequest decodeRequest(Reader r) throws IOException, JSONException {
        JSONTokener t = new JSONTokener(r);
        JSONObject jo = new JSONObject(t);
        String name = jo.getString("name");
        JSONArray args = jo.getJSONArray("args");
        String sheetName = (String) jo.opt("sheetName");
        JSONObject caller = (JSONObject) jo.opt("caller");
        XLSRef cref = null;
        if (caller != null) {
            cref = (XLSRef) decode(caller);
        }
        XLoper[] xargs = new XLoper[args.length()];
        for (int i = 0; i < xargs.length; i++) {
            xargs[i] = decode(args.getJSONObject(i));
        }

        return new FunctionRequest(name, xargs, cref, sheetName);

    }

    public static XLoper decodeXLoper(Reader r) throws IOException, JSONException {
        JSONTokener t = new JSONTokener(r);
        JSONObject jo = new JSONObject(t);
        return decode(jo);
    }

    public static void encodeRequest(FunctionRequest fr, Writer w) throws IOException, JSONException {
        encodeRequest(fr).write(w);
    }

    public static JSONObject encodeRequest(FunctionRequest fr) throws IOException, JSONException {
        JSONObject o = new JSONObject();
        o.put("request", "XLLoop");
        o.put("version", "0.1.0");
        o.put("name", fr.getName());
        if (fr.getSheetName() != null)
            o.put("sheetName", fr.getSheetName());
        if (fr.getCaller() != null)
            o.put("caller", encode(fr.getCaller()));
        JSONArray a = new JSONArray();
        XLoper[] xargs = fr.getArgs();
        if (xargs != null) {
            for (int i = 0; i < xargs.length; i++) {
                a.put(encode(xargs[i]));
            }
        }
        o.put("args", a);
        return o;
    }

    public static void encodeXLoper(XLoper x, Writer w) throws IOException, JSONException {
        JSONObject o = encode(x);
        o.write(w);
    }

    public static JSONObject encode(XLoper x) throws JSONException {
        JSONObject o = new JSONObject();
        if (x == null) {
            o.put("type", XLoper.xlTypeNil);
            return o;
        }
        o.put("type", x.type);
        switch (x.type) {
        case XLoper.xlTypeBool:
            o.put("bool", ((XLBool) x).bool);
            break;
        case XLoper.xlTypeErr:
            o.put("error", ((XLError) x).err);
            break;
        case XLoper.xlTypeInt:
            o.put("int", ((XLInt) x).w);
            break;
        case XLoper.xlTypeMissing:
            break;
        case XLoper.xlTypeMulti:
            XLArray a = (XLArray) x;
            o.put("rows", a.rows);
            o.put("cols", a.columns);
            JSONArray ja = new JSONArray();
            for (int i = 0; i < a.length; i++) {
                ja.put(encode(a.array[i]));
            }
            o.put("array", ja);
            break;
        case XLoper.xlTypeNil:
            break;
        case XLoper.xlTypeNum:
            o.put("num", ((XLNum) x).num);
            break;
        case XLoper.xlTypeStr:
            o.put("str", ((XLString) x).str);
            break;
        case XLoper.xlTypeSRef:
            o.put("colFirst", ((XLSRef) x).colFirst);
            o.put("colLast", ((XLSRef) x).colLast);
            o.put("rowFirst", ((XLSRef) x).rwFirst);
            o.put("rowLast", ((XLSRef) x).rwLast);
        }
        return o;
    }

    private static XLoper decode(JSONObject jo) throws JSONException {
        switch (jo.getInt("type")) {
        case XLoper.xlTypeBool:
            return jo.getBoolean("bool") ? XLBool.TRUE : XLBool.FALSE;
        case XLoper.xlTypeErr:
            return new XLError(jo.getInt("error"));
        case XLoper.xlTypeInt:
            return new XLInt(jo.getInt("int"));
        case XLoper.xlTypeMissing:
            return XLMissing.MISSING;
        case XLoper.xlTypeMulti:
            int rows = jo.getInt("rows");
            int cols = jo.getInt("cols");
            int len = rows * cols;
            XLoper[] a = new XLoper[len];
            JSONArray ja = jo.getJSONArray("array");
            for (int i = 0; i < len; i++) {
                a[i] = decode(ja.getJSONObject(i));
            }
            return new XLArray(a, rows, cols);
        case XLoper.xlTypeNil:
            return XLNil.NIL;
        case XLoper.xlTypeNum:
            return new XLNum(jo.getDouble("num"));
        case XLoper.xlTypeStr:
            return new XLString(jo.getString("str"));
        case XLoper.xlTypeSRef:
            return new XLSRef(jo.getInt("colFirst"), jo.getInt("colLast"), jo.getInt("rowFirst"),
                    jo.getInt("rowLast"));
        }

        return null;
    }
}