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