All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sherpa.client.SHPSolutions Maven / Gradle / Ivy

Go to download

Defines a SPARQL client API implementation using the SHERPA fast protocol for client-server communication. Requires a SHERPA-enabled server.

There is a newer version: 0.1.7
Show newest version
/*
 * Copyright 2011 Revelytix, Inc.
 * 
 * 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 sherpa.client;

/**
 * Represents a Solutions implementation.
 */
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import sherpa.protocol.BNode;
import sherpa.protocol.IRI;
import sherpa.protocol.PlainLiteral;
import sherpa.protocol.TypedLiteral;
import spark.api.Solutions;
import spark.api.rdf.RDFNode;
import spark.spi.Conversions;
import spark.spi.StreamingSolutions;
import spark.spi.rdf.BlankNodeImpl;
import spark.spi.rdf.NamedNodeImpl;
import spark.spi.rdf.PlainLiteralImpl;
import spark.spi.rdf.TypedLiteralImpl;

public class SHPSolutions extends StreamingSolutions implements Solutions {

  private final QueryExecution query;
  
  /**
   * Construct an SHPSolutions where 
   * @param command
   * @param query
   */
  public SHPSolutions(SHPCommand command, QueryExecution query) {
    super(command, query.getVars());
    if (vars == null) throw new IllegalStateException("SHPSolutions constructed with un-initialized QueryExecution");
    this.query = query;    
  }

  @Override
  protected Map fetchNext() {
    List rowData = null;
    if (query.incrementCursor()) rowData = query.getRow();
    if (rowData != null) {
      if (rowData.size() != vars.size()) throw new IllegalStateException("Mis-matched variable and data list");
      Map result = new HashMap();
      for (int i = 0; i < vars.size(); i++) {
        result.put(vars.get(i), toNode(rowData.get(i)));
      }
      return result;
    }
    return null;
  }

  /** Convert a protocol data object to an RDFNode. */
  private static RDFNode toNode(Object value) {
    if (value == null) {
      return null;
    } else if (value instanceof RDFNode) {
      return (RDFNode) value;
    } else if (value instanceof IRI) {
      return new NamedNodeImpl(URI.create(((IRI)value).iri.toString()));
    } else if (value instanceof PlainLiteral) {
      PlainLiteral pl = (PlainLiteral)value;
      String lang = pl.language != null ? pl.language.toString() : null;
      return new PlainLiteralImpl(pl.lexical.toString(), lang);
    } else if (value instanceof TypedLiteral) {
      TypedLiteral tl = (TypedLiteral)value;
      return new TypedLiteralImpl(tl.lexical.toString(), URI.create(tl.datatype.toString()));
    } else if (value instanceof BNode) {
      return new BlankNodeImpl(((BNode)value).label.toString());
    } else {
      // Sherpa passes strings as something other than java.lang.String, so convert.
      if (value instanceof CharSequence) {
        value = value.toString();
      }
      // What's left is a primitive Java type, convert it to an XSD-typed literal.
      // Falls back to xsd:anySimpleType for unrecognized classes
      return Conversions.toLiteral(value);
    }
  }
  
  @Override
  public boolean isLast() {
    return this.query.isLast();
  }

  @Override
  public void close() throws IOException {
    super.close();
    this.query.close();
  }

}