blob: d3ec82d0ee6f952fbbaeb079d98e18fac827c0f7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.jena.sparql.core;
import java.util.* ;
import java.util.function.BiConsumer ;
import java.util.function.Consumer ;
import org.apache.jena.graph.Node ;
import org.apache.jena.sparql.ARQInternalErrorException ;
import org.apache.jena.sparql.engine.binding.Binding ;
import org.apache.jena.sparql.expr.Expr ;
import org.apache.jena.sparql.expr.ExprEvalException ;
import org.apache.jena.sparql.expr.NodeValue ;
import org.apache.jena.sparql.function.FunctionEnv ;
public class VarExprList
{
private List<Var> vars ;
private LinkedHashMap<Var, Expr> exprs ; // Preserve order.
public VarExprList(List<Var> vars)
{
this.vars = new ArrayList<>(vars) ;
this.exprs = new LinkedHashMap<>() ;
}
public VarExprList(VarExprList other)
{
this.vars = new ArrayList<>(other.vars) ;
this.exprs = new LinkedHashMap<>(other.exprs) ;
}
public VarExprList()
{
this.vars = new ArrayList<>() ;
this.exprs = new LinkedHashMap<>() ;
}
public VarExprList(Var var, Expr expr)
{
this() ;
add(var, expr) ;
}
public List<Var> getVars() { return vars ; }
public Map<Var, Expr> getExprs() { return exprs ; }
/** Call the action for each (variable, expression) defined.
* Not called when there is no expression, just a variable.
* Not order preserving.
*/
public void forEachExpr(BiConsumer<Var, Expr> action) {
exprs.forEach(action);
}
/** Call the action for each variable, in order.
* The expression may be null.
* Not called when there is no expression, just a variable.
*/
public void forEachVarExpr(BiConsumer<Var, Expr> action) {
//* See {@link #forEach}
getVars().forEach((v) -> {
// Maybe null.
Expr e = exprs.get(v) ;
action.accept(v, e);
}) ;
}
/** Call the action for each variable, in order. */
public void forEachVar(Consumer<Var> action) {
getVars().forEach((v) -> {
action.accept(v);
}) ;
}
public boolean contains(Var var) { return vars.contains(var) ; }
public boolean hasExpr(Var var) { return exprs.containsKey(var) ; }
public Expr getExpr(Var var) { return exprs.get(var) ; }
// Or Binding.get(var, NamedExprList)
public Node get(Var var, Binding binding, FunctionEnv funcEnv)
{
Expr expr = exprs.get(var) ;
if ( expr == null )
return binding.get(var) ;
try {
NodeValue nv = expr.eval(binding, funcEnv) ;
if ( nv == null )
return null ;
return nv.asNode() ;
} catch (ExprEvalException ex)
//{ Log.warn(this, "Eval failure "+expr+": "+ex.getMessage()) ; }
{ }
return null ;
}
public void add(Var var)
{
// Checking here controls whether duplicate variables are allowed.
// Duplicates with expressions are not allowed (add(Var, Expr))
// See ARQ.allowDuplicateSelectColumns
// Every should work either way round if this is enabled.
// Checking is done in Query for adding result vars, and group vars.
// if ( vars.contains(var) )
vars.add(var) ;
}
public void add(Var var, Expr expr)
{
if ( expr == null )
{
add(var) ;
return ;
}
if ( var == null )
throw new ARQInternalErrorException("Attempt to add a named expression with a null variable") ;
if ( exprs.containsKey(var) )
throw new ARQInternalErrorException("Attempt to assign an expression again") ;
add(var) ;
exprs.put(var, expr) ;
}
public void addAll(VarExprList other)
{
for ( Var v : other.vars )
{
Expr e = other.getExpr( v );
add( v, e );
}
}
public void remove(Var var) {
vars.remove(var) ;
exprs.remove(var) ;
}
public void clear() {
vars.clear();
exprs.clear();
}
public int size() { return vars.size() ; }
public boolean isEmpty() { return vars.isEmpty() ; }
@Override
public int hashCode()
{
int x = vars.hashCode() ^ exprs.hashCode() ;
return x ;
}
@Override
public boolean equals(Object other)
{
if ( this == other) return true ;
if ( ! ( other instanceof VarExprList ) )
return false ;
VarExprList x = (VarExprList)other ;
return Objects.equals(vars, x.vars) && Objects.equals(exprs, x.exprs) ;
}
@Override
public String toString()
{
return vars.toString() + " // "+exprs.toString();
}
}