@Override
 protected NodeValue exec(Node[] nodes, FunctionEnv env) {
   Node startNode = nodes[0];
   Node predicate = nodes[1];
   Node function = nodes[2];
   Model model = ModelFactory.createModelForGraph(env.getActiveGraph());
   QuerySolutionMap initialBinding = new QuerySolutionMap();
   StringBuffer expression = new StringBuffer("<" + function + ">(?arg1");
   for (int i = 3; i < nodes.length; i++) {
     expression.append(", ");
     expression.append("?");
     String varName = "arg" + (i - 1);
     expression.append(varName);
     if (nodes[i] != null) {
       initialBinding.add(varName, model.asRDFNode(nodes[i]));
     }
   }
   expression.append(")");
   Query query = ARQFactory.get().createExpressionQuery(expression.toString());
   Node result =
       walkTree(
           model,
           DatasetImpl.wrap(env.getDataset()),
           startNode,
           predicate,
           query,
           initialBinding,
           new HashSet<Node>());
   if (result != null) {
     return NodeValue.makeNode(result);
   } else {
     throw new ExprEvalException("No result");
   }
 }
  @Override
  public List<Literal> getDataPropertyValuesForIndividualByProperty(
      String subjectUri, String propertyUri) {
    log.debug("Data property value query string:\n" + DATA_PROPERTY_VALUE_QUERY_STRING);
    log.debug("Data property value:\n" + dataPropertyValueQuery);

    QuerySolutionMap initialBindings = new QuerySolutionMap();
    initialBindings.add("subject", ResourceFactory.createResource(subjectUri));
    initialBindings.add("property", ResourceFactory.createResource(propertyUri));

    // Run the SPARQL query to get the properties
    List<Literal> values = new ArrayList<Literal>();
    DatasetWrapper w = dwf.getDatasetWrapper();
    Dataset dataset = w.getDataset();
    dataset.getLock().enterCriticalSection(Lock.READ);
    try {
      QueryExecution qexec =
          QueryExecutionFactory.create(dataPropertyValueQuery, dataset, initialBindings);
      ResultSet results = qexec.execSelect();

      while (results.hasNext()) {
        QuerySolution soln = results.next();
        RDFNode node = soln.get("value");
        if (!node.isLiteral()) {
          continue;
        }
        Literal value = soln.getLiteral("value");
        values.add(value);
      }
    } finally {
      dataset.getLock().leaveCriticalSection();
      w.close();
    }
    return values;
  }
  public static String execSparQLQuery(String query) {
    System.out.println("execSPINQuery");
    Model model = getUqModel();

    // Register system functions (such as sp:gt (>))
    SPINModuleRegistry.get().init();

    Query arqQuery = ARQFactory.get().createQuery(model, query);
    ARQ2SPIN arq2SPIN = new ARQ2SPIN(model);
    Select spinQuery = (Select) arq2SPIN.createQuery(arqQuery, null);

    System.out.println("SPIN query in Turtle:");
    model.write(System.out, FileUtils.langTurtle);

    System.out.println("-----");
    String str = spinQuery.toString();
    System.out.println("SPIN query:\n" + str);

    // Now turn it back into a Jena Query
    Query parsedBack = ARQFactory.get().createQuery(spinQuery);
    System.out.println("Jena query:\n" + parsedBack);

    com.hp.hpl.jena.query.Query arq = ARQFactory.get().createQuery(spinQuery);
    QueryExecution qexec = ARQFactory.get().createQueryExecution(arq, model);
    QuerySolutionMap arqBindings = new QuerySolutionMap();
    arqBindings.add("predicate", RDFS.label);
    qexec.setInitialBinding(arqBindings); // Pre-assign the arguments
    ResultSet rs = qexec.execSelect();

    //		System.out.println("#####################################################################");
    //
    //		if (rs.hasNext()) {
    //			QuerySolution row = rs.next();
    //			System.out.println("Row: " +row.toString());
    //			RDFNode user = row.get("User");
    //			Literal label = row.getLiteral("label");
    //			System.out.println(user.toString());
    //		}
    //		RDFNode object = rs.next().get("object");
    //		System.out.println("Label is " + object);

    Collection<User> users = Sparql.exec(getUqModel(), User.class, query);

    String usersString = "";
    for (User user : users) {
      System.out.println("User: "******"<br/>";
    }

    System.out.println("execSPINQuery() done.");
    return usersString;
  }
  private Node walkTree(
      Model model,
      Dataset oldDataset,
      Node node,
      Node predicate,
      Query query,
      QuerySolution initialBinding,
      Set<Node> reached) {
    QuerySolutionMap localBinding = new QuerySolutionMap();
    localBinding.addAll(initialBinding);
    localBinding.add("arg1", model.asRDFNode(node));
    Dataset dataset = new DatasetWithDifferentDefaultModel(model, oldDataset);
    QueryExecution qexec = ARQFactory.get().createQueryExecution(query, dataset, localBinding);
    ResultSet rs = qexec.execSelect();
    try {
      if (rs.hasNext()) {
        List<String> resultVars = rs.getResultVars();
        String varName = resultVars.get(0);
        RDFNode resultNode = rs.next().get(varName);
        if (resultNode != null) {
          return resultNode.asNode();
        }
      }
    } finally {
      qexec.close();
    }

    // Recurse into parents
    ExtendedIterator<Triple> it = createIterator(model.getGraph(), node, predicate);
    try {
      while (it.hasNext()) {
        Node next = getNext(it.next());
        if ((next.isBlank() || next.isURI()) && !reached.contains(next)) {
          reached.add(next);
          Node nextResult =
              walkTree(model, oldDataset, next, predicate, query, initialBinding, reached);
          if (nextResult != null) {
            return nextResult;
          }
        }
      }
    } finally {
      it.close();
    }

    return null;
  }
  protected List<String> allIndividualsRelatedByObjectPropertyStmts(String uri) {
    List<String> additionalUris = new ArrayList<String>();

    QuerySolutionMap initialBinding = new QuerySolutionMap();
    Resource uriResource = ResourceFactory.createResource(uri);
    initialBinding.add("uri", uriResource);

    Query sparqlQuery = QueryFactory.create(QUERY_FOR_RELATED);
    model.getLock().enterCriticalSection(Lock.READ);
    try {
      QueryExecution qExec = QueryExecutionFactory.create(sparqlQuery, model, initialBinding);
      try {
        ResultSet results = qExec.execSelect();
        while (results.hasNext()) {
          QuerySolution soln = results.nextSolution();
          Iterator<String> iter = soln.varNames();
          while (iter.hasNext()) {
            String name = iter.next();
            RDFNode node = soln.get(name);
            if (node != null) {
              if (node.isURIResource()) {
                additionalUris.add(node.as(Resource.class).getURI());
              } else {
                log.warn(
                    "value from query for var " + name + "  was not a URIResource, it was " + node);
              }
            } else {
              log.warn("value for query for var " + name + " was null");
            }
          }
        }
      } catch (Throwable t) {
        log.error(t, t);
      } finally {
        qExec.close();
      }
    } finally {
      model.getLock().leaveCriticalSection();
    }
    return additionalUris;
  }