/* * eXist Open Source Native XML Database * Copyright (C) 2001-09 Wolfgang M. Meier * wolfgang@exist-db.org * http://exist.sourceforge.net * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ package org.exist.xquery; import org.exist.dom.QName; import org.exist.xquery.value.FunctionParameterSequenceType; import org.exist.xquery.value.SequenceType; import org.exist.xquery.value.Type; /** * Describes the signature of a built-in or user-defined function, i.e. * its name, the type and cardinality of its arguments and its return type. * * @author wolf * @author lcahlander * @version 1.3 */ public class FunctionSignature { /** * Default sequence type for function parameters. */ public final static SequenceType DEFAULT_TYPE = new SequenceType(Type.ITEM, Cardinality.ZERO_OR_MORE); /** * Empty array to specify if a function doesn't take any arguments. */ public final static SequenceType[] NO_ARGS = new SequenceType[0]; private static final String DEPRECATION_REMOVAL_MESSAGE = "\nThis function could be removed at anytime during the 1.5 development and will be removed in the 1.6 release."; public final static SequenceType[] singleArgument(SequenceType arg) { return new SequenceType[] { arg }; } private final QName name; private SequenceType[] arguments; private SequenceType returnType; private boolean isOverloaded = false; private String description = null; private String deprecated = null; public FunctionSignature(QName name) { this(name, null, DEFAULT_TYPE, false); } public FunctionSignature(QName name, SequenceType[] arguments, SequenceType returnType) { this(name, null, arguments, returnType); } public FunctionSignature(QName name, SequenceType[] arguments, SequenceType returnType, boolean overloaded) { this(name, null, arguments, returnType, overloaded); } public FunctionSignature(QName name, String description, SequenceType[] arguments, SequenceType returnType) { this(name, description, arguments, returnType, false); } public FunctionSignature(QName name, String description, SequenceType[] arguments, SequenceType returnType, String deprecated) { this(name, description, arguments, returnType, false); setDeprecated(deprecated); } public FunctionSignature(QName name, String description, SequenceType[] arguments, SequenceType returnType, boolean overloaded, String deprecated) { this(name, description, arguments, returnType, overloaded); setDeprecated(deprecated); } /** * Create a new function signature. * * @param name the QName of the function. * @param arguments the sequence types of all expected arguments * @param returnType the sequence type returned by the function * @param overloaded set to true if the function may expect additional parameters */ public FunctionSignature(QName name, String description, SequenceType[] arguments, SequenceType returnType, boolean overloaded) { this.name = name; this.arguments = arguments; this.returnType = returnType; this.isOverloaded = overloaded; this.description = description; } public QName getName() { return name; } public int getArgumentCount() { if(isOverloaded) return -1; return arguments != null ? arguments.length : 0; } public FunctionId getFunctionId() { return new FunctionId(name, getArgumentCount()); } public SequenceType getReturnType() { return returnType; } public void setReturnType(SequenceType type) { returnType = type; } public SequenceType[] getArgumentTypes() { return arguments; } public void setArgumentTypes(SequenceType[] types) { this.arguments = types; } public String getDescription() { return description; } public boolean isOverloaded() { return isOverloaded; } public boolean isDeprecated() { return deprecated != null; } public String getDeprecated() { if (deprecated != null && deprecated.length() > 0) return deprecated + DEPRECATION_REMOVAL_MESSAGE; else return null; } public void setDeprecated(String message) { deprecated = message; } public String toString() { StringBuilder buf = new StringBuilder(); buf.append(name.getStringValue()); buf.append('('); if(arguments != null) { char var = 'a'; for(int i = 0; i < arguments.length; i++) { if(i > 0) buf.append(", "); buf.append('$'); if (arguments[i] instanceof FunctionParameterSequenceType) { buf.append(((FunctionParameterSequenceType)arguments[i]).getAttributeName()); } else { buf.append((char)(var + i)); } buf.append(" as "); buf.append(arguments[i].toString()); } if(isOverloaded) buf.append(", ..."); } buf.append(") "); buf.append(returnType.toString()); return buf.toString(); } public boolean equals(Object obj) { FunctionSignature other = (FunctionSignature) obj; if (name.equalsSimple(other.name)) return getArgumentCount() == other.getArgumentCount(); return false; } }