| /* |
| * 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(); |
| } |
| } |