Package lupos.endpoint.caching

Source Code of lupos.endpoint.caching.DeltaEndpoint$SPARQLExecutionDeltaImplementation

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.endpoint.caching;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import lupos.datastructures.bindings.Bindings;
import lupos.datastructures.bindings.BindingsArrayReadTriples;
import lupos.datastructures.items.Triple;
import lupos.datastructures.queryresult.QueryResult;
import lupos.endpoint.server.Endpoint;
import lupos.endpoint.server.Endpoint.OutputStreamLogger;
import lupos.endpoint.server.Endpoint.SPARQLExecution;
import lupos.endpoint.server.Endpoint.SPARQLHandler;
import lupos.endpoint.server.format.Formatter;
import lupos.engine.evaluators.BasicIndexQueryEvaluator;
import lupos.engine.evaluators.CommonCoreQueryEvaluator;
import lupos.engine.evaluators.RDF3XQueryEvaluator;

import com.sun.net.httpserver.HttpExchange;

/**
* This class is the server-side-implementation of the delta approach:
* The delta approach uses a cache of triples at the client and the server always sends
* missing triples to the client for a new query.
* For this purpose, the server holds a set of triples already sent to the client,
* retrieves the query triples for a new query and sends all those triples to the client,
* which the client did not receive before.
* The clients just adds the triples, which it receives from the server, and
* evaluates the query on it.
*/
public class DeltaEndpoint {

  public static void main(final String[] args) throws Exception {
    // init according to command line arguments
    final int port = Endpoint.init(args);
    // register the sparqldelta context
    Endpoint.registerHandler("/sparqldelta", new SPARQLHandler(new SPARQLExecutionDeltaImplementation(Endpoint.createQueryEvaluator(args[0]), args[0])));
    Endpoint.registerStandardFormatter();
    // run the endpoint!
    Endpoint.initAndStartServer(port);
  }

  public static class SPARQLExecutionDeltaImplementation implements SPARQLExecution {

    /** The already sent triples to the different clients.
     *  A client is identified by its InetSocketAddress.
     */
    protected HashMap<InetSocketAddress, HashSet<Triple>> deltaIndices = new HashMap<InetSocketAddress, HashSet<Triple>>();

    protected final BasicIndexQueryEvaluator evaluator;
    protected final String dir;

    public SPARQLExecutionDeltaImplementation(final BasicIndexQueryEvaluator evaluator, final String dir){
      this.evaluator = evaluator;
      this.dir = dir;
    }

    @Override
    public void execute(final String queryParameter, final Formatter formatter, final HttpExchange t) throws IOException {
      try {
        synchronized(this.evaluator){ // avoid any inference of several queries in parallel!
          System.out.println("Evaluating query using the delta approach:\n"+queryParameter);
          // log query-triples by using BindingsArrayReadTriples as class for storing the query solutions!
          Bindings.instanceClass = BindingsArrayReadTriples.class;
          final QueryResult queryResult = (this.evaluator instanceof CommonCoreQueryEvaluator)?((CommonCoreQueryEvaluator)this.evaluator).getResult(queryParameter, true):this.evaluator.getResult(queryParameter);
          final String mimeType = "text/n3";
          System.out.println("Done, sending response using MIME type "+mimeType);
          t.getResponseHeaders().add("Content-type", mimeType);
          t.getResponseHeaders().add("Transfer-encoding", "chunked");
          t.sendResponseHeaders(200, 0);
          OutputStream os = t.getResponseBody();
          if(Endpoint.log){
            os = new OutputStreamLogger(os);
          }

          // get the client's address
          final InetSocketAddress clientAddress = t.getRemoteAddress();
          // get the delta index for this client
          HashSet<Triple> deltaIndex = this.deltaIndices.get(clientAddress);
          if(deltaIndex==null){
            // initialize the delta index if it is not already there
            deltaIndex = new HashSet<Triple>();
          }
          // iterate through the solution and its query triples
          final Iterator<Bindings> itBindings = queryResult.oneTimeIterator();
          while(itBindings.hasNext()){
            final Bindings bindings = itBindings.next();
            for(final Triple triple: bindings.getTriples()){
              // Add the triple to the delta index and check if it is already in the delta index at the same time!
              // (Previously sent triples are eliminated as well as duplicates within the query triples of the same query result.)
              if(deltaIndex.add(triple)){
                // if the triple is not already in the delta index, then send it to the client!
                os.write(triple.toN3String().getBytes());
              }
            }
          }

          this.deltaIndices.put(clientAddress, deltaIndex);

          os.close();

          if(this.evaluator instanceof RDF3XQueryEvaluator){
            ((RDF3XQueryEvaluator)this.evaluator).writeOutIndexFileAndModifiedPages(this.dir);
          }
        }
        return;
      } catch (final Error e) {
        System.err.println(e);
        e.printStackTrace();
        t.getResponseHeaders().add("Content-type", "text/plain");
        final String answer = "Error:\n"+e.getMessage();
        System.out.println(answer);
        Endpoint.sendString(t, answer);
        return;
      } catch (final Exception e){
        System.err.println(e);
        e.printStackTrace();
        t.getResponseHeaders().add("Content-type", "text/plain");
        final String answer = "Error:\n"+e.getMessage();
        System.out.println(answer);
        Endpoint.sendString(t, answer);
        return;
      }
    }
  }
}
TOP

Related Classes of lupos.endpoint.caching.DeltaEndpoint$SPARQLExecutionDeltaImplementation

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.