/* * Hibernate, Relational Persistence for Idiomatic Java * * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * 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 distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.hibernate.dialect.function; import java.util.List; import org.hibernate.QueryException; import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** * Support for slightly more general templating than {@link StandardSQLFunction}, with an unlimited number of arguments. * * @author Gavin King */ public class VarArgsSQLFunction implements SQLFunction { private final String begin; private final String sep; private final String end; private final Type registeredType; /** * Constructs a VarArgsSQLFunction instance with a 'static' return type. An example of a 'static' * return type would be something like an <tt>UPPER</tt> function which is always returning * a SQL VARCHAR and thus a string type. * * @param registeredType The return type. * @param begin The beginning of the function templating. * @param sep The separator for each individual function argument. * @param end The end of the function templating. */ public VarArgsSQLFunction(Type registeredType, String begin, String sep, String end) { this.registeredType = registeredType; this.begin = begin; this.sep = sep; this.end = end; } /** * Constructs a VarArgsSQLFunction instance with a 'dynamic' return type. For a dynamic return type, * the type of the arguments are used to resolve the type. An example of a function with a * 'dynamic' return would be <tt>MAX</tt> or <tt>MIN</tt> which return a double or an integer etc * based on the types of the arguments. * * @param begin The beginning of the function templating. * @param sep The separator for each individual function argument. * @param end The end of the function templating. * * @see #getReturnType Specifically, the 'firstArgumentType' argument is the 'dynamic' type. */ public VarArgsSQLFunction(String begin, String sep, String end) { this( null, begin, sep, end ); } /** * {@inheritDoc} * <p/> * Always returns true here. */ public boolean hasArguments() { return true; } /** * {@inheritDoc} * <p/> * Always returns true here. */ public boolean hasParenthesesIfNoArguments() { return true; } /** * {@inheritDoc} */ public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException { return registeredType == null ? firstArgumentType : registeredType; } public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) { StringBuffer buf = new StringBuffer().append( begin ); for ( int i = 0; i < arguments.size(); i++ ) { buf.append( transformArgument( ( String ) arguments.get( i ) ) ); if ( i < arguments.size() - 1 ) { buf.append( sep ); } } return buf.append( end ).toString(); } /** * Called from {@link #render} to allow applying a change or transformation * to each individual argument. * * @param argument The argument being processed. * @return The transformed argument; may be the same, though should never be null. */ protected String transformArgument(String argument) { return argument; } }