Googler

两情相悦,又岂在朝朝暮暮。

基于V8的JsonMapper

<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_win32_x86_64</artifactId>
<version>4.6.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_linux_x86_64</artifactId>
<version>4.6.0</version>
<scope>compile</scope>
</dependency>

package org.rx.util;

import com.alibaba.fastjson.JSONObject;
import com.eclipsesource.v8.V8;
import com.eclipsesource.v8.V8Object;
import com.google.common.annotations.Beta;
import com.google.common.base.Strings;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.rx.annotation.ErrorCode;
import org.rx.common.*;

import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static org.rx.common.Contract.*;

@Beta
@Slf4j
public final class JsonMapper extends Disposable {
    private static class V8Console {
        public void log(String message) {
            log.info("[V8] {}", message);
        }

        public void error(String message) {
            log.error("[V8] {}", message);
        }
    }

    public static final JsonMapper Default = new JsonMapper("jScript/");
    private static final String scriptFunc = "(function(){var $={},$val=JSON.parse(_x); %s; return JSON.stringify($);})()";

    private Map<String, Object> settings;
    private Lazy<V8> runtime;

    public JsonMapper(String configPath) {
        settings = refreshSettings(configPath);
        runtime = new Lazy<>(() -> {
            V8 v8 = V8.createV8Runtime();
            V8Object v8Console = new V8Object(v8);
            v8.add("console", v8Console);
            V8Console console = new V8Console();
            Class[] argTypes = new Class[]{String.class};
            v8Console.registerJavaMethod(console, "log", "log", argTypes);
            v8Console.registerJavaMethod(console, "error", "error", argTypes);
            v8.executeScript("console.log('V8 start..');");
            return v8;
        });
    }

    @Override
    protected void freeObjects() {
        if (runtime.isValueCreated()) {
            runtime.getValue().release();
            runtime = null;
        }
    }

    public <F, T> T convertTo(Class<T> toType, F from) {
        require(toType, from);

        return convertTo(toType, from.getClass().getName(), from);
    }

    public <T> T convertTo(Class<T> toType, String configKey, Object sourceValue) {
        require(toType, configKey);

        String script = getScript(toType, configKey);
        V8 v8 = runtime.getValue();
        v8.add("_x", toJsonString(sourceValue));
        String jResult = v8.executeStringScript(String.format(scriptFunc, script));
        return JSONObject.parseObject(jResult, toType);
    }

    @ErrorCode(value = "keyError", messageKeys = {"$key"})
    private String getScript(Class tType, String key) {
        String tKey = tType.getName();
        Map<String, Object> v = as(settings.get(tKey), Map.class);
        if (v == null) {
            throw new SystemException(values(tKey), "keyError");
        }
        String script = (String) v.get(key);
        if (Strings.isNullOrEmpty(script)) {
            throw new SystemException(values(tKey + "." + key), "keyError");
        }
        return script;
    }

    @SneakyThrows
    private Map<String, Object> refreshSettings(String configPath) {
        URL path = App.getClassLoader().getResource(configPath);
        if (path == null) {
            return Collections.emptyMap();
        }

        Map<String, Object> map = new HashMap<>();
        for (Path p : App.fileStream(Paths.get(path.toURI()))) {
            try {
                map.putAll(App.loadYaml(p.toString()));
            } catch (Exception e) {
                log.error("refreshSettings", e);
            }
        }
        return map;
    }
}

 

org.rx.util.DemoBean:
  demoKey: >
  $.id=$val.id;

 

posted on 2019-07-12 17:05  RockyLOMO  阅读(337)  评论(0编辑  收藏  举报

导航

Apple/苹果笔记本 Mac Air MC968CH/A 行货在保 I5 11寸 超级本