Package net.fortytwo.ripple.query

Source Code of net.fortytwo.ripple.query.QueryPipe

package net.fortytwo.ripple.query;

import net.fortytwo.flow.Buffer;
import net.fortytwo.flow.Collector;
import net.fortytwo.flow.HistorySink;
import net.fortytwo.flow.Sink;
import net.fortytwo.flow.Source;
import net.fortytwo.flow.Tee;
import net.fortytwo.ripple.RippleException;
import net.fortytwo.ripple.cli.Interpreter;
import net.fortytwo.ripple.cli.ParserExceptionSink;
import net.fortytwo.ripple.cli.RecognizerAdapter;
import net.fortytwo.ripple.cli.RecognizerEvent;
import net.fortytwo.ripple.cli.ast.KeywordAST;
import net.fortytwo.ripple.cli.ast.ListAST;
import net.fortytwo.ripple.model.ListGenerator;
import net.fortytwo.ripple.model.ModelConnection;
import net.fortytwo.ripple.model.RippleList;
import net.fortytwo.ripple.query.commands.DefineKeywordCmd;
import net.fortytwo.ripple.query.commands.RippleQueryCmd;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* A pipeline for evaluating expressions in Ripple's text-based syntax.
* Each submitted String must be a complete, valid expression consisting of a sequence of programs and/or commands.
* Expressions are pushed into the QueryPipe using the put method,
* and the results flow from the other end of the pipe into the specified sink.
* Results arrive at any time and in any order, depending on the intermediate components of the pipe.
*
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class QueryPipe implements Sink<String> {
    private final RecognizerAdapter recognizerAdapter;
    private final Sink<Exception> parserExceptionSink;
    private final Buffer<RippleList> resultBuffer;
    private final HistorySink<RippleList> queryResultHistory
            = new HistorySink<RippleList>(1);
    private final ModelConnection connection;

    public QueryPipe(final QueryEngine queryEngine,
                     final Sink<RippleList> resultSink) throws RippleException {
        connection = queryEngine.getConnection();

        resultBuffer = new Buffer<RippleList>(resultSink);
        final Object mutex = "";

        final Sink<RippleList> resultTee = new Tee<RippleList>
                (resultBuffer, queryResultHistory);

        recognizerAdapter = new RecognizerAdapter(queryEngine.getErrorPrintStream()) {
            protected void handleQuery(ListAST ast) throws RippleException {
                synchronized (mutex) {
                    queryResultHistory.advance();

                    new RippleQueryCmd(ast, resultTee).execute(queryEngine, connection);
                    connection.commit();
                }
            }

            protected void handleCommand(Command command) throws RippleException {
                command.execute(queryEngine, connection);
                connection.commit();
            }

            protected void handleEvent(RecognizerEvent event) throws RippleException {
                // TODO
            }

            protected void handleAssignment(KeywordAST name) throws RippleException {
                Source<RippleList> source = queryResultHistory.get(0);
                if (null == source) {
                    source = new Collector<RippleList>();
                }

                new DefineKeywordCmd(name, new ListGenerator(source)).execute(queryEngine, connection);
                connection.commit();
            }
        };

        parserExceptionSink = new ParserExceptionSink(
                queryEngine.getErrorPrintStream());
    }

    public ModelConnection getConnection() {
        return connection;
    }

    public void close() throws RippleException {
        //connection.close();
    }

    public void put(final InputStream input) throws RippleException {
        // TODO: creating a new Interpreter for each unit of input is not very efficient
        Interpreter interpreter = new Interpreter(recognizerAdapter, input, parserExceptionSink);
        interpreter.parse();

        try {
            input.close();
        } catch (IOException e) {
            throw new RippleException(e);
        }

        connection.finish();
        resultBuffer.flush();
    }

    public void put(final String expr) throws RippleException {
//        System.out.println("interpreting query: " + expr);
//System.exit(1);
        InputStream input = new ByteArrayInputStream((expr + "\n").getBytes());

        try {
            try {
                put(input);
            } finally {
                input.close();
            }
        } catch (IOException e) {
            throw new RippleException(e);
        }
    }
}
TOP

Related Classes of net.fortytwo.ripple.query.QueryPipe

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.