Package net.fortytwo.ripple.scriptengine

Source Code of net.fortytwo.ripple.scriptengine.RippleScriptEngine

package net.fortytwo.ripple.scriptengine;

import net.fortytwo.flow.Collector;
import net.fortytwo.ripple.RippleException;
import net.fortytwo.ripple.URIMap;
import net.fortytwo.ripple.config.SailConfiguration;
import net.fortytwo.ripple.model.Model;
import net.fortytwo.ripple.model.NumericValue;
import net.fortytwo.ripple.model.RDFValue;
import net.fortytwo.ripple.model.RippleList;
import net.fortytwo.ripple.model.RippleValue;
import net.fortytwo.ripple.model.impl.sesame.SesameModel;
import net.fortytwo.ripple.query.LazyStackEvaluator;
import net.fortytwo.ripple.query.QueryEngine;
import net.fortytwo.ripple.query.QueryPipe;
import net.fortytwo.ripple.query.StackEvaluator;
import org.openrdf.model.BNode;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.XMLSchema;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Reader;
import java.net.URISyntaxException;
import java.util.LinkedList;
import java.util.List;

/**
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class RippleScriptEngine implements ScriptEngine {
    private final ScriptEngineFactory factory;
    private final SailConfiguration sailConfig;
    private final Model model;
    //private final QueryEngine queryEngine;
    private final QueryPipe queryPipe;
    private final Collector<RippleList> results;
    private ScriptContext context;

    public RippleScriptEngine(final ScriptEngineFactory factory) throws RippleException {
        this.factory = factory;

        results = new Collector<>();

        URIMap uriMap = new URIMap();
        sailConfig = new SailConfiguration(uriMap);

        // TODO: shutDown on failure
        model = new SesameModel(sailConfig.getSail());

        StackEvaluator eval = new LazyStackEvaluator();
        QueryEngine queryEngine = new QueryEngine(model, eval, System.out, System.err);

        queryPipe = new QueryPipe(queryEngine, results);
    }

    @Override
    public void finalize() throws Throwable {
        super.finalize();

        shutDown();
    }

    private void shutDown() throws RippleException {
        model.shutDown();
    }

    public Object eval(final String script,
                       final ScriptContext context) throws ScriptException {
        // TODO: use context
        return eval(script);
    }

    public Object eval(final Reader reader,
                       final ScriptContext context) throws ScriptException {
        // TODO: use context
        return eval(reader);
    }

    public Object eval(final String script) throws ScriptException {
        results.clear();

        try {
            queryPipe.put(script);
        } catch (RippleException e) {
            throw new ScriptException(e);
        }

        if (0 == results.size()) {
            return null;
        } else {
            for (Object result : results) {
                RippleList l = (RippleList) result;
                if (!l.isNil()) {
                    return toJavaObject(l.getFirst());
                }
            }

            return null;
        }
    }

    // Note: objects which are not equivalent in Ripple (e.g. a wrapped URI and
    // a wrapped xsd:anyURI-typed literal) may map to equivalent Java objects.
    private Object toJavaObject(final RippleValue v) throws ScriptException {
        if (v instanceof NumericValue) {
            NumericValue n = (NumericValue) v;
            switch (n.getDatatype()) {
                case DECIMAL:
                    return n.decimalValue();
                case DOUBLE:
                    return n.doubleValue();
                case FLOAT:
                    return n.floatValue();
                case INTEGER:
                    return n.intValue();
                case LONG:
                    return n.longValue();
                default:
                    throw new ScriptException("numeric value of unexpected type: " + v);
            }
        } else if (v instanceof RDFValue) {
            return toJavaObject(((RDFValue) v).sesameValue());
        } else if (v instanceof RippleList) {
            RippleList l = (RippleList) v;
            List<Object> javaList = new LinkedList<Object>();
            for (RippleValue v2 : l.toJavaList()) {
                javaList.add(toJavaObject(v2));
            }
            return javaList;
        } else {
            return v.toString();
        }
    }

    private Object toJavaObject(final Value v) throws ScriptException {
        if (v instanceof URI) {
            try {
                return new java.net.URI(v.toString());
            } catch (URISyntaxException e) {
                throw new ScriptException(e);
            }
        } else if (v instanceof Literal) {
            Literal l = (Literal) v;
            URI datatype = l.getDatatype();
            if (null == datatype) {
                return l.getLabel();
            } else if (XMLSchema.STRING.equals(datatype)) {
                return l.getLabel();
            } else if (XMLSchema.INTEGER.equals(datatype)) {
                return l.integerValue();
            } else if (XMLSchema.INT.equals(datatype)) {
                return l.intValue();
            } else if (XMLSchema.ANYURI.equals(datatype)) {
                try {
                    return new java.net.URI(l.getLabel());
                } catch (URISyntaxException e) {
                    throw new ScriptException(e);
                }
            } else if (XMLSchema.SHORT.equals(datatype)) {
                return l.shortValue();
            } else if (XMLSchema.LONG.equals(datatype)) {
                return l.longValue();
            } else if (XMLSchema.FLOAT.equals(datatype)) {
                return l.floatValue();
            } else if (XMLSchema.BYTE.equals(datatype)) {
                return l.byteValue();
            } else if (XMLSchema.DATETIME.equals(datatype)) {
                return l.calendarValue();
            } else if (XMLSchema.DOUBLE.equals(datatype)) {
                return l.doubleValue();
            } else if (XMLSchema.BOOLEAN.equals(datatype)) {
                return l.booleanValue();
            } else if (XMLSchema.DECIMAL.equals(datatype)) {
                return l.decimalValue();
            } else {
                return l.getLabel();
            }
        } else if (v instanceof BNode) {
            return ((BNode) v).getID();
        } else {
            throw new ScriptException("RDF value of unexpected type: " + v);
        }
    }

    public Object eval(final Reader reader) throws ScriptException {
        // TODO: use reader stream (instead of converting to a String)
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                int ch;
                while (-1 != (ch = reader.read())) {
                    bos.write(ch);
                }

                return eval(bos.toString());
            } finally {
                bos.close();
            }
        } catch (IOException e) {
            throw new ScriptException(e);
        }
    }

    public Object eval(final String script,
                       final Bindings n) throws ScriptException {
        // TODO: use bindings
        return eval(script);
    }

    public Object eval(final Reader reader,
                       final Bindings n) throws ScriptException {
        // TODO: use bindings
        return eval(reader);
    }

    public void put(final String key,
                    final Object value) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public Object get(final String key) {
        return null//To change body of implemented methods use File | Settings | File Templates.
    }

    public Bindings getBindings(final int scope) {
        switch (scope) {
            case ScriptContext.ENGINE_SCOPE:
                break;
            case ScriptContext.GLOBAL_SCOPE:
                break;
        }

        // FIXME
        return null//To change body of implemented methods use File | Settings | File Templates.
    }

    public void setBindings(final Bindings bindings,
                            final int scope) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public Bindings createBindings() {
        return null//To change body of implemented methods use File | Settings | File Templates.
    }

    public ScriptContext getContext() {
        return context;
    }

    public void setContext(final ScriptContext context) {
        this.context = context;
    }

    public ScriptEngineFactory getFactory() {
        return factory;
    }
}
TOP

Related Classes of net.fortytwo.ripple.scriptengine.RippleScriptEngine

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.