Package org.geoscript.js.io

Source Code of org.geoscript.js.io.JSON

package org.geoscript.js.io;

import java.lang.reflect.Constructor;

import org.geoscript.js.GeoObject;
import org.geoscript.js.geom.Point;
import org.geoscript.js.geom.LineString;
import org.geoscript.js.geom.Polygon;
import org.geoscript.js.geom.GeometryCollection;
import org.geoscript.js.geom.MultiPoint;
import org.geoscript.js.geom.MultiLineString;
import org.geoscript.js.geom.MultiPolygon;
import org.geoscript.js.feature.Feature;
import org.geoscript.js.feature.FeatureCollection;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.json.JsonParser;
import org.mozilla.javascript.json.JsonParser.ParseException;

public class JSON {

    private enum Type {
        Point(Point.class),
        LineString(LineString.class),
        Polygon(Polygon.class),
        GeometryCollection(GeometryCollection.class),
        MultiPoint(MultiPoint.class),
        MultiLineString(MultiLineString.class),
        MultiPolygon(MultiPolygon.class),
        Feature(Feature.class),
        FeatureCollection(FeatureCollection.class);
       
        private Class<?> cls;

        Type(Class<?> cls) {
            this.cls = cls;
        }
       
        public Object create(Scriptable scope, NativeObject object) {
            Constructor<?> ctor;
            try {
                ctor = cls.getDeclaredConstructor(Scriptable.class, NativeObject.class);
            } catch (Exception e) {
                String msg = "Trouble parsing " + name() +
                        ". Failed to get constructor for object: " +
                        Context.toString(object);
                throw ScriptRuntime.constructError("Error", msg);
            }
            Object result;
            try {
                result = ctor.newInstance(scope, object);
            } catch (Exception e) {
                String msg = "Trouble parsing " + name() +
                        ". Failed to parse object: " +
                        Context.toString(object);
                throw ScriptRuntime.constructError("Error", msg);
            }
            return result;
        }
       
    }

    /**
     * Parse the JSON representation for some GeoScript object.
     * @param cx
     * @param thisObj
     * @param args
     * @param funObj
     * @return A geometry object
     */
    public static Object read(Context cx, Scriptable thisObj,
                               Object[] args, Function funObj) {
        String json = null;
        if (args.length == 1) {
            Object jsonObj = args[0];
            if (jsonObj instanceof String) {
                json = (String) jsonObj;
            }
        }
        if (json == null) {
            throw ScriptRuntime.constructError("Error",
                    "The read function expects a single string argument");
        }
        Scriptable scope = funObj.getParentScope();
        JsonParser parser = new JsonParser(cx, scope);
        Object parsed;
        try {
            parsed = parser.parseValue(json);
        } catch (ParseException e) {
            throw ScriptRuntime.constructError("Error", e.getMessage());
        }
        Object result;
        if (parsed instanceof NativeObject) {
            NativeObject obj = (NativeObject) parsed;
            result = readObj(obj);
        } else {
            throw ScriptRuntime.constructError("Error", "Expected a string representing a JSON object, got " + Context.toString(parsed));
        }
        return result;
    }

    /**
     * Given an object parsed from a GeoJSON string, create a GeoScript object.
     * @param obj
     * @return
     */
    public static Object readObj(NativeObject obj) {
        Scriptable scope = obj.getParentScope();
        Object typeObj = obj.get("type", obj);
        String typeName;
        if (typeObj instanceof String) {
            typeName = (String) typeObj;
        } else {
            throw ScriptRuntime.constructError("Error", "The GeoJSON type member must be a string");
        }
        Type type = Type.valueOf(typeName);
        return type.create(scope, obj);
    }

    /**
     * Serialize a GeoScript object as a JSON string.
     * @param cx
     * @param thisObj
     * @param args
     * @param funObj
     * @return
     */
    public static Object write(Context cx, Scriptable thisObj,
            Object[] args, Function funObj) {
        GeoObject geo = null;
        if (args.length == 1) {
            Object geoObj = args[0];
            if (geoObj instanceof GeoObject) {
                geo = (GeoObject) geoObj;
            }
        }
        if (geo == null) {
            throw ScriptRuntime.constructError("Error",
                    "The write function expects a single object argument");
        }
        return geo.getJson();
    }

    /**
     * Create object with read/write methods.
     * @param scope
     * @return
     */
    public static NativeObject init(ScriptableObject scope) {
       
        Context context = Context.getCurrentContext();
        if (context == null) {
            throw ScriptRuntime.constructError("Error",
                    "No context associated with current thread");
        }
        NativeObject json = (NativeObject) context.newObject(scope);
        json.defineFunctionProperties(new String[] { "read", "write" },
                JSON.class, ScriptableObject.PERMANENT);
        return json;
    }

}
TOP

Related Classes of org.geoscript.js.io.JSON

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.