Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I convert a Rhino-produced JSON datastructure (NativeObject) to Java datastructure?

Tags:

java

json

rhino

I am trying to generate a data structure inside JavaScript code, and process the results from Java (Rhino in Java 6 or 7).

I succeeded in invoking the JS function from Java using:

Object result = invocableEngine.invokeFunction(functionName, parameters);

Now, on JS side, that result is a JSON data structure as follows:

{ 
  "key1" : { "key1_1" : "value1_1", "key1_2" : 11 },

  "key2" : [ {  "key2_1": "foo2"
              , "key2_1" : "bar2" },

             {  "key2_1": "foo2"
              , "key2_1" : "bar2"
              , "key2_3" : [1,2,3] } ]
}

On the Java side, however, "result" is an object of type sun.org.mozilla.javascript.internal.NativeObject

Is there a way for me to convert it to a reasonable Java datastructure, without having the overhead of serializing that JSON to a string and then using Gson to parse it?

Assume for the moment that the data structure is reasonably well defined, e.g. I know that the object is a hash with keys "key1" and "key2", the first maps to a hash with keys "key1_1" and "key1_2"; the second maps to an array of hashes, each of which has keys "key2_1" and "key2_2" that are scalar and "key2_3" which is an array.

My 2 priorities are, in that order:

  1. Performance (which is one reason why I'm wary of serialize + Gson-parse)
  2. Portability between Java 6, 7 and 8 (however, I'd prefer a materially faster non-portable solution).
like image 706
DVK Avatar asked Mar 19 '15 02:03

DVK


1 Answers

This is the code from NativeObject to JSONObject. I think from NativeObject to Map is similar.

    public static JSONObject toJsonObject(NativeObject nativeObject)
    {
        JSONObject object = new JSONObject();
        Set<Entry<Object, Object>> entrySet = nativeObject.entrySet();
        for (Entry<Object, Object> entry : entrySet)
        {
            try
            {
                if (entry.getValue() instanceof String)
                {
                    object.put(entry.getKey().toString(), new JSONObject(entry.getValue().toString()));
                }
                else if (entry.getValue() instanceof NativeArray)
                {
                    object.put(entry.getKey().toString(), toJsonArray((NativeArray) entry.getValue()));
                }
                else if (entry.getValue() instanceof NativeObject)
                {
                    object.put(entry.getKey().toString(), toJsonObject((NativeObject) entry.getValue()));
                }
            }
            catch (JSONException e)
            {
                try
                {
                    object.put(entry.getKey().toString(), entry.getValue().toString());
                }
                catch (JSONException ignored)
                {
                }
            }
        }


        return object;
    }

    public static JSONArray toJsonArray(NativeArray nativeArray)
    {
        JSONArray array = new JSONArray();

        for (Object o : nativeArray)
        {
            if (o instanceof NativeObject)
            {
                array.put(toJsonObject((NativeObject) o));
            }
            else if (o instanceof NativeArray)
            {
                array.put(toJsonArray((NativeArray) o));
            }
            else
            {
                try
                {
                    array.put(new JSONObject(o.toString()));
                }
                catch (JSONException e)
                {
                    array.put(o.toString());
                }
            }
        }

        return array;
    }
like image 126
Norman Wang Avatar answered Oct 29 '22 12:10

Norman Wang