/* * 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.expr; import java.util.ArrayList ; import java.util.List ; import org.apache.jena.sparql.serializer.SerializationContext ; /** A function in the expression hierarchy. * Everything that is evaluable (i.e. not NodeValue, NodeVar) is a function). * It is useful to distinguish between values, vars and functions. * The exists operations (which take a op, not arguments) are functions of zero arguments. */ public abstract class ExprFunction extends ExprNode { protected FunctionLabel funcSymbol ; protected String opSign ; protected ExprFunction(String fName) { funcSymbol = new FunctionLabel(fName) ; opSign = null ; } protected ExprFunction(String fName, String opSign) { this(fName) ; this.opSign = opSign ; } public abstract Expr getArg(int i) ; public abstract int numArgs() ; // ExprFunctionN overrides this. public List<Expr> getArgs() { List<Expr> argList = new ArrayList<>(numArgs()) ; for ( int i = 1 ; i <= numArgs() ; i++ ) argList.add(this.getArg(i)) ; return argList ; } @Override public boolean isFunction() { return true ; } @Override public ExprFunction getFunction() { return this ; } @Override public int hashCode() { return funcSymbol.hashCode() ^ numArgs() ; } // A function is equal if: // + The name is the same // + The arguments are the same (including arity). @Override public boolean equals(Expr other, boolean bySyntax) { if ( other == null ) return false ; if ( this == other ) return true ; if ( ! other.getClass().equals(this.getClass()) ) return false ; ExprFunction ex = (ExprFunction)other ; if ( ! funcSymbol.equals(ex.funcSymbol) ) return false ; if ( numArgs() != ex.numArgs() ) return false ; // Arguments are 1, 2, 3, ... for ( int i = 1 ; i <= numArgs() ; i++ ) { Expr a1 = this.getArg(i) ; Expr a2 = ex.getArg(i) ; if ( ! a1.equals(a2, bySyntax) ) return false ; } return true ; } /** Name used for output in SPARQL format needing functional form (no specific keyword). * e.g. regexp(), custom functions, ... */ public String getFunctionPrintName(SerializationContext cxt) { return funcSymbol.getSymbol() ; } /** Name used in a functional form (i.e. SPARQL algebra). * getOpName() is used in preference as a short, symbol name. */ public String getFunctionName(SerializationContext cxt) { return funcSymbol.getSymbol() ; } /** Used to get a unique name for the function, which is intern'ed. Used in hashCode() */ public FunctionLabel getFunctionSymbol() { return funcSymbol ; } /** URI for this function, whether custom or specification defined URI (these are keywords in the language) */ public String getFunctionIRI() { return null ; } /** Get the symbol name (+, ! etc) for this function -- maybe null for none */ public String getOpName() { return opSign ; } }