Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have written a Java JSON stringifier with the Nashorn API. Since this code is slow, I wanted to ask if I can improve it. My target is the highest possible performance to make it an alternative to other JSON libraries.

JSON.java

package com.example.json;

import java.util.Map;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.example.json.util.TextFile;

public class JSON {

    private static final Invocable inv = create();

    private static final Invocable create() {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        try {
            engine.eval(TextFile.readFromResource("/js/json-stringify.js"));
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        return (Invocable) engine;
    }

    public static final String stringify(Map<String, Object> json) {
        try {
            return (String) inv.invokeFunction("stringifyJSON", json);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

}

JSONObject.java

package com.example.json.stringify;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class JSONObject {

    private Map<String, Object> map = new HashMap<String, Object>();

    public void appendChild(String key, Object object) {
        map.put(key, object);
    }

    public static final Map<String, Object> convertToJavaScript(JSONObject obj) {
        return obj.map;
    }

}

JSONArray.java

package com.example.json.stringify;

public class JSONArray {

    private Object[] array;

    public JSONArray(int length) {
        array = new Object[length];
    }

    public void set(int index, Object object) {
        if (index >= 0 && index <= array.length - 1) array[index] = object;
    }

    public static final Object[] convertToJavaScript(JSONArray arr) {
        return arr.array;
    }

}

/js/json-stringify.js

function stringifyJSON(json) {

    var JSONObject = Java.type("com.example.json.stringify.JSONObject");
    var JSONArray = Java.type("com.example.json.stringify.JSONArray");

    return JSON.stringify(convertJSONObject(json));

    function convert(json) {
        if (isJSONObject(json)) return convertJSONObject(JSONObject.convertToJavaScript(json));
        if (isJSONArray(json)) return convertJSONArray(JSONArray.convertToJavaScript(json));
        return json;
    }

    function convertJSONObject(object) {
        var jsobject = {};
        for (key in object) {
            jsobject[key] = convert(object.get(key));
        }
        return jsobject;
    }

    function convertJSONArray(array) {
        var jsarray = [];
        for (var index = 0, len = array.length; index < len; index++) {
            jsarray.push(convert(array[index]));
        }
        return jsarray;
    }

    function isJSONObject(json) Object.prototype.toString.call(json) === "[object com.example.json.stringify.JSONObject]";
    function isJSONArray(json) Object.prototype.toString.call(json) === "[object com.example.json.stringify.JSONArray]";

}

TextFile.java (from this post)

Example

I used the same example JSON from my JSON parser.

Map<String, Object> json = new HashMap<String, Object>();
JSONArray employees = new JSONArray(3);

JSONObject employee1 = new JSONObject();
employee1.appendChild("firstName", "John");
employee1.appendChild("lastName", "Doe");
employees.set(0, employee1);

JSONObject employee2 = new JSONObject();
employee2.appendChild("firstName", "Anna");
employee2.appendChild("lastName", "Smith");
employees.set(1, employee2);

JSONObject employee3 = new JSONObject();
employee3.appendChild("firstName", "Peter");
employee3.appendChild("lastName", "Jones");
employees.set(2, employee3);

json.put("employees", employees);

System.out.println(JSON.stringify(json));

Result

{"employees":[{"firstName":"John","lastName":"Doe"},{"firstName":"Anna","lastName":"Smith"},{"firstName":"Peter","lastName":"Jones"}]}

share|improve this question

1 Answer 1

you can get JSON from engine by

ScriptObjectMirror json = (ScriptObjectMirror) engine.eval("JSON");

and call it's parse or stringify method via:

json.callMember("stringify", object);
json.callMember("parse", str)
share|improve this answer
    
I'm sorry, but ScriptObjectMirror isn't an option for me, because this API is part of the Java EE and I use Java SE. –  Datagrammar Aug 2 at 20:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.