Package com.baasbox.service.scripting.js

Source Code of com.baasbox.service.scripting.js.NashornMapper

/*
* Copyright (c) 2014.
*
* BaasBox - info@baasbox.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.baasbox.service.scripting.js;

import com.baasbox.dao.exception.ScriptException;
import com.baasbox.service.scripting.base.ScriptEvalException;
import com.baasbox.service.scripting.base.ScriptResult;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.*;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.api.scripting.ScriptUtils;
import jdk.nashorn.internal.runtime.Undefined;
import play.Logger;
import scala.util.parsing.combinator.testing.Str;

import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
* This implements mappings of data to/from javascript
* Created by Andrea Tortorella on 30/06/14.
*/
final class NashornMapper {
    private final static String JSON_PARSE = "asJson";

    private final static String EVENT_NAME="name";
    private final static String EVENT_DATA="data";

    private ScriptObjectMirror mirror;

    NashornMapper(){
    }

    void setMirror(ScriptObjectMirror mirror) {
        this.mirror = mirror;
    }


    Object convertEvent(String event, Object eventData) throws ScriptEvalException{
        // todo add support for all dataTypes
        String eventJson;
        if (eventData == null) {

            eventJson = simpleEvent(event);

        } else if (eventData instanceof String) {

            eventJson = stringEvent(event,(String)eventData);

        } else if (eventData instanceof Integer ||
                   eventData instanceof Long ||
                   eventData instanceof Double ||
                   eventData instanceof Float){

            eventJson = primitiveEvent(event,(Number)eventData);

        } else if (eventData instanceof Boolean) {

            eventJson = primitiveEvent(event,(Boolean)eventData);

        } else if (eventData instanceof JsonNode) {
            eventJson = objectEvent(event, (JsonNode) eventData);
        } else {
            throw new ScriptEvalException("Unsupported event data "+eventData.getClass());
        }

        return convertToJSJson(eventJson);
    }

    private static String stringEvent(String event,String data){
        ObjectNode node = Json.mapper().createObjectNode();
        node.put(EVENT_NAME,event);
        node.put(EVENT_DATA,data);
        return node.toString();
    }

    private static String simpleEvent(String event){
        ObjectNode node = Json.mapper().createObjectNode();
        node.put(EVENT_NAME,event);
        return node.toString();
    }

    private static String primitiveEvent(String event,Number data){
        ObjectNode node = Json.mapper().createObjectNode();
        node.put(EVENT_NAME,event);
        node.put(EVENT_DATA,data.doubleValue());
        return node.toString();
    }

    private static String primitiveEvent(String event,Boolean data) {
        ObjectNode node = Json.mapper().createObjectNode();
        node.put(EVENT_NAME,event);
        node.put(EVENT_DATA,data);
        return node.toString();
    }

    private static String objectEvent(String event,JsonNode data) {
        ObjectNode node = Json.mapper().createObjectNode();
        node.put(EVENT_NAME,event);
        node.put(EVENT_DATA,data);
        return node.toString();
    }

    private Object convertToJSJson(String data) {
        return mirror.callMember(JSON_PARSE,data);
    }


    public ScriptResult convertResult(Object result) throws ScriptEvalException {
        if (result == null){
            return ScriptResult.NULL;
        } else if (result instanceof Boolean){
            return (Boolean) result ?ScriptResult.TRUE:ScriptResult.FALSE;
        } else if (result instanceof String){
            return new ScriptResult((String)result);
        } else if (result instanceof ScriptObjectMirror){
            JsonNode node = convertDeepJson(result);
            if (node != null){
                return new ScriptResult(node);
            } else {
                return ScriptResult.NULL;
            }
        } else if (result instanceof Number){
            return  new ScriptResult((Number)result);
        } else if (result instanceof Undefined){
            return ScriptResult.NULL;
        } else {

            Logger.warn("Mirror: %s, of type: %s",result,result.getClass());
            return ScriptResult.NULL;
        }

    }


    private JsonNode convertNumber(Number number){
        if (number instanceof Long||number instanceof Integer){
            return LongNode.valueOf(number.longValue());
        } else if (number instanceof Double||number instanceof Float){
            return DoubleNode.valueOf(number.doubleValue());
        } else {
            return LongNode.valueOf(number.longValue());
        }
    }

    private JsonNode convertDeepJson(Object obj) throws ScriptEvalException{
        if (obj == null){
            return NullNode.getInstance();
        } else if (obj instanceof Boolean){
            return BooleanNode.valueOf((Boolean) obj);
        } else if (obj instanceof Undefined){
            return MissingNode.getInstance();
        } else if (obj instanceof Number){
            return convertNumber((Number)obj);
        } else if (obj instanceof String){
            return TextNode.valueOf((String)obj);
        } else if (obj instanceof ScriptObjectMirror){
            return convertMirror((ScriptObjectMirror)obj);
        } else {
            return MissingNode.getInstance();
        }
    }

    private JsonNode convertMirror(ScriptObjectMirror mirror) throws ScriptEvalException{
        if (mirror == null){

            return NullNode.getInstance();
        } else if (ScriptObjectMirror.isUndefined(mirror)){
            return MissingNode.getInstance();
        } else if (mirror.isFunction()){
            return MissingNode.getInstance();
        } else if (mirror.isArray()){
            Collection<Object> values = mirror.values();
            ArrayNode node = Json.mapper().createArrayNode();
            for (Object o: values){
                JsonNode e = convertDeepJson(o);
                if (e.isMissingNode()){
                    continue;
                }
                node.add(e);
            }
            return node;
        }else if(mirror.hasMember("toJSON")){
            Object toJSON = mirror.callMember("toJSON");
            return convertDeepJson(toJSON);
        }
        else {
            ObjectNode obj = Json.mapper().createObjectNode();
            Set<Map.Entry<String, Object>> entries = mirror.entrySet();
            for (Map.Entry<String,Object> e:entries){
                Object obv = e.getValue();
                JsonNode jsonNode = convertDeepJson(obv);
                if (jsonNode.isMissingNode()){
                    continue;
                }
                obj.put(e.getKey(),jsonNode);
            }
            return obj;
        }
    }

}
TOP

Related Classes of com.baasbox.service.scripting.js.NashornMapper

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.