Package org.springframework.data.rdf.sparql

Source Code of org.springframework.data.rdf.sparql.SparqlTemplate$genericMapSolutionMapper

/*
* Copyright (c) 2011 by Al Baker, Michael Soren
*
* 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 org.springframework.data.rdf.sparql;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;



/**
* <code>SparqlTemplate</code>
*
* Template design for abstracting the details of working with Jena ARQ's SPARQL
* query API.  Specifically the repetitive Query, QueryFActory, QueryExecution, and QueryExecutionFactory
*
* Inspired by Spring's jdbcTemplate
*
* Implements the template design pattern for the main Jena methods (e.g. execSelect)
*
* Relies upon the SolutionMapper<T> interface for returning the mapped result
*
* @author Al Baker
* @author Michael Soren
*
*/
public class SparqlTemplate {

 
  /**
   * Constructor - Jena Model
   * @param model
   */
  SparqlTemplate(Model model) {
    this.model = model;
  }
 
  SparqlTemplate() { }

  private Model model;

  /**
   * <code>setModel</code>
   *
   * Setter to set the model that will be queried
   *
   * @param model Jena Model Interface
   */
  public void setModel(Model model) {
    this.model = model;
  }

  /**
   * <code>getModel</code>
   *
   * getter method to return the current Jena model being queried. 
   *
   * @return Model Jena Model interface
   */
  public Model getModel() {
    return model;
  }

  /**
   * <code>execSelectList</code>
   *
   * Template design pattern for simplifying SPARQL queries with ARQ
   * Inspired by Spring's jdbcTemplate
   * Differs the mapping algorithm to the SolutionMapper<T> interface
   *
   * Additional comments:
   *   - This implementation generates the list at this point, a more advanced design
   *     would be to return an iterator and not iterate through the results until the client
   *     of this code was invoked, i.e. lazy-loading the results until they were absolutely needed
   *    
   *   - The sparql query string is just a string, presumably with the right parameters already populated.
   *     To avoid SPARQL-Injection, we should consider some automatic way of cleansing this string similar
   *     to the JDBC PreparedStatement object
   *
   * @param <T> Template for the List of objects to be returned
   * @param sparql the String representing the SPARQL query
   * @param mapper the Implementation of SolutionMapper<T>
   * @return List<T> which is mapped to the results of the query
   */
  public <T> List<T> execSelectList(String sparql, SolutionMapper<T> mapper) {
    if (sparql == null || sparql.equals(""))
      return null;
    QueryExecution qe = QueryExecutionFactory.create(QueryFactory.create(sparql, Syntax.syntaxARQ), model);
    ArrayList<T> list = new ArrayList<T>();
    try {
      for (ResultSet rs = qe.execSelect(); rs.hasNext() ; ) {
        list.add(mapper.mapSelect(rs, rs.getRowNumber()));
      }
    } finally {
      qe.close();
    }
    return list;
  }

  public <T> T execSelectOne(String sparql, SolutionMapper<T> mapper) {
    if (sparql == null || sparql.equals("")) {
      return null;
    }

    QueryExecution qe = QueryExecutionFactory.create(QueryFactory.create(sparql, Syntax.syntaxARQ), model);
    try {
      ResultSet rs = qe.execSelect();
      if (rs.hasNext()) {
        return mapper.mapSelect(rs, rs.getRowNumber());
      } else {
        return null;
      }
    } finally {
      qe.close();
    }

  }

  /**
   * <code>execSelectMap</code>
   * @param <T> Key
   * @param <V> Value
   * @param sparql Sparql query to be executed
   * @param mapper SolutionDimensionalMapper
   * @return combined map of all the results (HashMap)
   */
  public <T, V> Map<T, V> execSelectMap(String sparql, SolutionDimensionalMapper<T, V> mapper) {
    Query query = QueryFactory.create(sparql, Syntax.syntaxARQ);
    QueryExecution qe = QueryExecutionFactory.create(query, model);
    Map<T, V> list = new HashMap<T, V>();
    try {
      for (ResultSet rs = qe.execSelect(); rs.hasNext() ; ) {
        list.putAll(mapper.mapSelect(rs, rs.getRowNumber()));
      }
    } finally {
      qe.close();
    }
    return list;
  }

  /**
   * <code>execConstruct</code>
   *
   * Template method for executing a CONSTRUCT statement
   * No mapper is used as the mapping is performed in the SPARQL
   *
   * @param sparql
   * @return new Model
   */
  public Model execConstruct(String sparql) {
    Query query = QueryFactory.create(sparql);
    QueryExecution qe = QueryExecutionFactory.create(query, model);
    Model m = qe.execConstruct();
    qe.close();
    return m;
  }


  /**
   * <code>mapSolutionMapper creates a map for the next solution</code>
   * whose keys are variable names and values are the String values for those variables
   * @return Map<String, String> of variable names and values for the solution
   */
  class mapSolutionMapper implements SolutionMapper<Map<String, String>> {
    public Map<String, String> mapSelect(ResultSet rs, int number) {
      QuerySolution sol = rs.nextSolution();
      Map<String, String> row = new HashMap<String, String>();
      for (Iterator<String> varNames = sol.varNames(); varNames.hasNext(); ) {
        String varName = varNames.next();
        row.put(varName, sol.get(varName).toString());
      }
      return row;
    }
  }

  /**
   * <code>mapSolutionMapper creates a map for the next solution</code>
   * whose keys are variable names and values are the (possibly typed) values for those variables
   * @return Map<String, Object> of variable names and values for the solution
   */
  class genericMapSolutionMapper implements SolutionMapper<Map<String, Object>> {
    public Map<String, Object> mapSelect(ResultSet rs, int number) {
      QuerySolution sol = rs.nextSolution();
      Map<String, Object> row = new HashMap<String, Object>();
      for (Iterator<String> varNames = sol.varNames(); varNames.hasNext(); ) {
        String varName = varNames.next();
        RDFNode varNode = sol.get(varName);
        row.put(varName, (varNode.isLiteral() ? varNode.asLiteral().getValue() : varNode.toString()));
      }
      return row;
    }
  }
 
  /**
   * <code>execSelect(String query)</code>
   * @param sparql - SELECT based SPARQL to execute
   * @return map of parameters in the result set
   */
  public List<Map<String, Object>> execSelectGenericMap(String sparql) {
    return execSelectList(sparql, new genericMapSolutionMapper());
  }
 
  public Map<String, Object> execSelectSingleGenericMap(String sparql) {
    return execSelectOne(sparql, new genericMapSolutionMapper());
  }


  /**
   * <code>execSelectOne</code>
   * @param model - model to be queried
   * @param sparql - SELECT based sparql query
   * @return single map of property to value
   */
  public Map<String, String> execSelectStringMap(String sparql) {
    if (sparql == null || sparql.equals(""))
      return null;
    Map<String, String> result = new HashMap<String, String>();
    QueryExecution qe = QueryExecutionFactory.create(QueryFactory.create(sparql), model);
    try {
      ResultSet rs = qe.execSelect();
      while (rs.hasNext()) {
        QuerySolution sol = rs.nextSolution();
        for (Iterator<String> varNames = sol.varNames(); varNames.hasNext(); ) {
          String varName = varNames.next();
          result.put(varName, sol.get(varName).toString());
        }
      }
    } finally {
      qe.close();
    }
    return result;
  }

  /**
   * <code>execSelectSingleString</code>
   * @param sparql - SELECT based sparql query
   * @return single string of the sparql query result
   */
  public String execSelectString(String sparql) {
    if (sparql == null || sparql.equals(""))
      return null;
    String result = null;
    QueryExecution qe = QueryExecutionFactory.create(QueryFactory.create(sparql, Syntax.syntaxARQ), model);
    try {
      ResultSet rs = qe.execSelect();
      while (rs.hasNext()) {
        QuerySolution sol = rs.nextSolution();
        for (Iterator<String> varNames = sol.varNames(); varNames.hasNext(); ) {
          String varName = varNames.next();
          result = sol.get(varName).toString();
        }
      }
    } finally {
      qe.close();
    }
    return result;
  }


  /**
   * <code>debug</code>
   * Prints entire model attached to this sparqltemplate with
   * ResultSetFormatter to System.out
   */
  public void debug() {
    String sparql = "SELECT ?x ?y ?z WHERE { ?x ?y ?z} ";

    Query query = QueryFactory.create(sparql);
    QueryExecution qe = QueryExecutionFactory.create(query, model);

    try {
      ResultSet rs = qe.execSelect();
      ResultSetFormatter.out(System.out, rs);
    } finally {
      qe.close();
    }

  }

}
TOP

Related Classes of org.springframework.data.rdf.sparql.SparqlTemplate$genericMapSolutionMapper

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.