package adql.query.operand.function; /* * This file is part of ADQLLibrary. * * ADQLLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ADQLLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with ADQLLibrary. If not, see <http://www.gnu.org/licenses/>. * * Copyright 2012-2015 - UDS/Centre de DonnĂ©es astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ import adql.db.FunctionDef; import adql.query.ADQLList; import adql.query.ADQLObject; import adql.query.ClauseADQL; import adql.query.TextPosition; import adql.query.operand.ADQLOperand; import adql.translator.ADQLTranslator; import adql.translator.TranslationException; /** * It represents any function which is not managed by ADQL. * * @author Grégory Mantelet (CDS;ARI) * @version 1.4 (06/2015) */ public final class DefaultUDF extends UserDefinedFunction { /** Define/Describe this user defined function. * This object gives the return type and the number and type of all parameters. */ protected FunctionDef definition = null; /** Its parsed parameters. */ protected final ADQLList<ADQLOperand> parameters; /** Parsed name of this UDF. */ protected final String functionName; /** * Creates a user function. * @param params Parameters of the function. */ public DefaultUDF(final String name, final ADQLOperand[] params) throws NullPointerException{ functionName = name; parameters = new ClauseADQL<ADQLOperand>(); if (params != null){ for(ADQLOperand p : params) parameters.add(p); } } /** * Builds a UserFunction by copying the given one. * * @param toCopy The UserFunction to copy. * @throws Exception If there is an error during the copy. */ @SuppressWarnings("unchecked") public DefaultUDF(final DefaultUDF toCopy) throws Exception{ functionName = toCopy.functionName; parameters = (ADQLList<ADQLOperand>)(toCopy.parameters.getCopy()); setPosition((toCopy.getPosition() == null) ? null : new TextPosition(toCopy.getPosition()));; } /** * Get the signature/definition/description of this user defined function. * The returned object provides information on the return type and the number and type of parameters. * * @return Definition of this function. (MAY be NULL) */ public final FunctionDef getDefinition(){ return definition; } /** * <p>Let set the signature/definition/description of this user defined function.</p> * * <p><i><b>IMPORTANT:</b> * No particular checks are done here except on the function name which MUST * be the same (case insensitive) as the name of the given definition. * Advanced checks must have been done before calling this setter. * </i></p> * * @param def The definition applying to this parsed UDF, or NULL if none has been found. * * @throws IllegalArgumentException If the name in the given definition does not match the name of this parsed function. * * @since 1.3 */ public final void setDefinition(final FunctionDef def) throws IllegalArgumentException{ if (def != null && (def.name == null || !functionName.equalsIgnoreCase(def.name))) throw new IllegalArgumentException("The parsed function name (" + functionName + ") does not match to the name of the given UDF definition (" + def.name + ")."); this.definition = def; } @Override public final boolean isNumeric(){ return (definition == null || definition.isNumeric()); } @Override public final boolean isString(){ return (definition == null || definition.isString()); } @Override public final boolean isGeometry(){ return (definition == null || definition.isGeometry()); } @Override public ADQLObject getCopy() throws Exception{ DefaultUDF copy = new DefaultUDF(this); copy.setDefinition(definition); return copy; } @Override public final String getName(){ return functionName; } @Override public final ADQLOperand[] getParameters(){ ADQLOperand[] params = new ADQLOperand[parameters.size()]; int i = 0; for(ADQLOperand op : parameters) params[i++] = op; return params; } @Override public final int getNbParameters(){ return parameters.size(); } @Override public final ADQLOperand getParameter(int index) throws ArrayIndexOutOfBoundsException{ return parameters.get(index); } /** * Function to override if you want to check the parameters of this user defined function. * * @see adql.query.operand.function.ADQLFunction#setParameter(int, adql.query.operand.ADQLOperand) */ @Override public ADQLOperand setParameter(int index, ADQLOperand replacer) throws ArrayIndexOutOfBoundsException, NullPointerException, Exception{ ADQLOperand oldParam = parameters.set(index, replacer); setPosition(null); return oldParam; } @Override public String translate(final ADQLTranslator caller) throws TranslationException{ StringBuffer sql = new StringBuffer(functionName); sql.append('('); for(int i = 0; i < parameters.size(); i++){ if (i > 0) sql.append(',').append(' '); sql.append(caller.translate(parameters.get(i))); } sql.append(')'); return sql.toString(); } }