Package org.geoscript.js

Source Code of org.geoscript.js.GeoObject

package org.geoscript.js;

import java.math.BigDecimal;
import java.net.URI;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.geoscript.js.feature.FeatureCollection;
import org.geoscript.js.feature.Feature;
import org.geoscript.js.feature.Schema;
import org.geoscript.js.geom.Bounds;
import org.geoscript.js.geom.GeometryWrapper;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.NativeJSON;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Wrapper;
import org.mozilla.javascript.annotations.JSFunction;
import org.mozilla.javascript.annotations.JSGetter;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

public class GeoObject extends ScriptableObject implements Wrapper {

    /** serialVersionUID */
    private static final long serialVersionUID = 5069578216502688712L;
   
    protected enum Type {

        String(String.class),
        Integer(Integer.class),
        Short(Short.class),
        Float(Float.class),
        Long(Long.class),
        Number(Double.class),
        Double(Double.class),
        Boolean(Boolean.class),
        Geometry(com.vividsolutions.jts.geom.Geometry.class),
        Point(com.vividsolutions.jts.geom.Point.class),
        LineString(com.vividsolutions.jts.geom.LineString.class),
        Polygon(com.vividsolutions.jts.geom.Polygon.class),
        GeometryCollection(com.vividsolutions.jts.geom.GeometryCollection.class),
        MultiPoint(com.vividsolutions.jts.geom.MultiPoint.class),
        MultiLineString(com.vividsolutions.jts.geom.MultiLineString.class),
        MultiPolygon(com.vividsolutions.jts.geom.MultiPolygon.class),
        Bounds(ReferencedEnvelope.class),
        FeatureCollection(org.geotools.feature.FeatureCollection.class),
        Filter(org.opengis.filter.Filter.class),
        Projection(CoordinateReferenceSystem.class),
        Date(Date.class),
        Time(Time.class),
        Datetime(java.util.Date.class),
        Timestamp(Timestamp.class),
        BigDecimal(BigDecimal.class),
        URI(URI.class);
   
        private Class<?> binding;
       
        Type(Class<?> binding) {
            this.binding = binding;
        }
       
        public static String getName(Class<?> binding) {
            String name = null;
            for (Type type : Type.values()) {
                if (!binding.isPrimitive()) {
                    if (!binding.isInterface()) {
                        if (type.getBinding().equals(binding)) {
                            name = type.name();
                            break;
                        }
                    } else if (type.getBinding().isAssignableFrom(binding)) {
                        name = type.name();
                        break;
                    }
                } else {
                    try {
                        Class<?> cls = (Class<?>) type.getBinding().getField("TYPE").get(null);
                        if (cls.equals(binding)) {
                            name = type.name();
                            break;
                        }
                    } catch (Exception e) {
                        // no type field on binding, keep looking
                    }
                }
            }
            return name;
        }

        /**
         * @return the binding
         */
        public Class<?> getBinding() {
            return binding;
        }
       
    }

   
    @JSGetter
    public Scriptable getConfig() {
        Scriptable scope = getParentScope();
        Context cx = getCurrentContext();
        Scriptable obj = cx.newObject(scope);
        obj.put("type", obj, getClass().getSimpleName());
        return obj;
    }
   
    @JSGetter
    public Object getJson() {
        Scriptable config = getConfig();
        Scriptable scope = getParentScope();
        Context cx = getCurrentContext();
        Object json = NativeJSON.stringify(cx, scope, config, null, null);
        return json;
    }

    public Object unwrap() {
        return null;
    }

    @Override
    public String getClassName() {
        return getClass().getName();
    }

    /**
     * String representation of an array.
     * @param array
     * @return
     */
    protected String arrayRepr(NativeArray array) {
        String repr = "[";
        int length = array.size();
        for (int i=0; i<length; ++i) {
            Object item = array.get(i);
            if (item instanceof NativeArray) {
                repr += arrayRepr((NativeArray) item);
            } else if (item instanceof String) {
                repr += '"' + (String) item + '"';
            } else {
                repr += Context.toString(item);
            }
            if (i < length -1) {
                repr += ", ";
            }
        }
        return repr + "]";
    }

   
    @JSFunction
    public String toString() {
        String full = toFullString();
        if (full.length() > 0) {
            full = " " + full;
        }
        if (full.length() > 60) {
            full = full.substring(0, 61) + "...";
        }
        return "<" + getClass().getSimpleName() + full + ">";
    }
   
    /**
     * Descriptive string representation of this object.
     * @return
     */
    public String toFullString() {
        return "";
    }
   
    /**
     * Get the context associated with the current thread.
     * @return The current context.
     */
    protected static Context getCurrentContext() {
        Context cx = Context.getCurrentContext();
        if (cx == null) {
            throw new RuntimeException("No context associated with current thread.");
        }
        return cx;
    }
   
    /**
     * Get an optional member.  If the member is present and the value is not
     * null, the value must be an instance of the provided class.
     *
     * @param obj
     * @param name
     * @param cls If provided, the member value must be an instance of this
     * class.
     * @return
     */
    protected static Object getOptionalMember(Scriptable obj, String name, Class<?> cls) {
        return getOptionalMember(obj, name, cls, cls.getSimpleName());
    }

    /**
     * Get an optional member.  If the member is present and the value is not
     * null, the value must be an instance of the provided class.
     *
     * @param obj
     * @param name
     * @param cls If provided, the member value must be an instance of this
     * class.
     * @param clsName The constructor name displayed to the user in the case
     * of an error.
     * @return
     */
    protected static Object getOptionalMember(Scriptable obj, String name,
            Class<?> cls, String clsName) {
        Object result = getMember(obj, name);
        if (result != null && !cls.isInstance(result)) {
            throw ScriptRuntime.constructError("Error",
                    "The optional " + name + " member must be a " + clsName);
        }
        return result;
    }

   
    /**
     * Get a required member.  If the member is present and the value is not
     * null, the value must be an instance of the provided class.
     *
     * @param obj
     * @param name
     * @param cls The member value must be an instance of this class.
     * @return
     */
    protected static Object getRequiredMember(Scriptable obj, String name, Class<?> cls) {
        return getRequiredMember(obj, name, cls, cls.getSimpleName());
    }

    /**
     * Get a required member.  If the member is present and the value is not
     * null, the value must be an instance of the provided class.
     *
     * @param obj
     * @param name
     * @param cls The member value must be an instance of this class.
     * @param clsName The constructor name displayed to the user in the case
     * of an error.
     * @return
     */
    protected static Object getRequiredMember(Scriptable obj, String name,
            Class<?> cls, String clsName) {
        Object result = getMember(obj, name);
        if (result == null) {
            throw ScriptRuntime.constructError("Error",
                    "The required " + name + " member must be non-null");
        }
        if (!cls.isInstance(result)) {
            throw ScriptRuntime.constructError("Error",
                    "Expected the '" + name + "' member to be a " +
                    cls.getSimpleName() + ". Got: " + Context.toString(result));
        }
        return result;
    }

    /**
     * Get an object member.  Returns null if the member is not present or if
     * the value is null.
     * @param obj
     * @return
     */
    private static Object getMember(Scriptable obj, String name) {
        Object result = null;
        if (obj.has(name, obj)) {
            result = obj.get(name, obj);
        }
        return result;
    }

    /**
     * Convert a JavaScript object into the appropriate Java type.
     * @param value
     * @return
     */
    public static Object jsToJava(Object value) {
        if (value instanceof Wrapper) {
            value = ((Wrapper) value).unwrap();
        } else if (value instanceof Scriptable) {
            if (value instanceof NativeObject) {
                value = jsObjectToMap((Scriptable) value);
            } else if (((Scriptable) value).getClassName().equals("Date")) {
                value = Context.jsToJava(value, java.util.Date.class);
            }
        } else if (value instanceof org.mozilla.javascript.ConsString) {
            value = value.toString();
        }
        return value;
    }
   
    /**
     * Convert a JavaScript object into a Java map.
     * @param obj
     * @return
     */
    public static Map<String, Object> jsObjectToMap(Scriptable obj) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        Object[] ids = obj.getIds();
        for (Object id : ids) {
            String name = (String) id;
            map.put(name, jsToJava(obj.get(name, obj)));
        }
        return map;
    }

    /**
     * Convert a Java object into the appropriate JavaScript type.
     * @param value
     * @param scope
     * @return
     */
    public static Object javaToJS(Object value, Scriptable scope) {
        if (value instanceof Map) {
            value = mapToJSObject((Map<?, ?>) value, scope);
        } else if (value instanceof List) {
            value = listToJSArray((List<?>) value, scope);
        } else if (value instanceof java.util.Date) {
            java.util.Date date = (java.util.Date) value;
            Object[] args = { new Long(date.getTime()) };
            Context cx = getCurrentContext();
            value = cx.newObject(scope, "Date", args);
        } else if (value instanceof com.vividsolutions.jts.geom.Geometry) {
            value = GeometryWrapper.wrap(scope, (com.vividsolutions.jts.geom.Geometry) value);
        } else if (value instanceof ReferencedEnvelope) {
            value = new Bounds(scope, (ReferencedEnvelope) value);
        } else if (value instanceof SimpleFeature) {
            value = new Feature(scope, (SimpleFeature) value);
        } else if (value instanceof SimpleFeatureType) {
            value = new Schema(scope, (SimpleFeatureType) value);
        } else if (value instanceof SimpleFeatureCollection) {
            value = new FeatureCollection(scope, (SimpleFeatureCollection) value);
        }
        return Context.javaToJS(value, scope);
    }
   
    /**
     * Convert a Java list to a JavaScript array.
     * @param value
     * @param scope
     * @return
     */
    private static NativeArray listToJSArray(List<?> list, Scriptable scope) {
        int length = list.size();
        Context cx = getCurrentContext();
        NativeArray array = (NativeArray) cx.newArray(scope, length);
        for (int i=0; i<length; ++i) {
            array.put(i, array, javaToJS(list.get(i), scope));
        }
        return array;
    }

    /**
     * Convert a Java map into a JavaScript object.
     * @param map
     * @param scope
     * @return
     */
    public static NativeObject mapToJSObject(Map<?, ?> map, Scriptable scope) {
        Context context = getCurrentContext();
        NativeObject obj = (NativeObject) context.newObject(scope);
        for (Object id  : map.keySet()) {
            obj.put(id.toString(), obj, javaToJS(map.get(id), scope));
        }
        return obj;
    }

}
TOP

Related Classes of org.geoscript.js.GeoObject

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.