/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed 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 (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.core.utils.querybuilder;

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

/**
 * The HibernateCondition class extends the generic Condition class. A condition 
 * is defined by a property to be compared against a value. Comparision is done
 * by using a specific operator. The HibernateCondition adds two more properties,
 * namely the Entity and the Parameter property. The property to be compared
 * against the value has to be prefixed with the entity it refers to. Furthermore,
 * hibernate queries allow to specify parameters as values that will be replaced
 * at query execution time, much like prepared statements. The two additional
 * properties allow to specify these values.
 * 
 * @author nico.mack@tudor.lu
 */

public class HibernateCondition extends Condition
{
	private static final long serialVersionUID = 1L;

	private String	m_Entity;
	private String	m_Parameter;

//***************************************************************************
//* Class Constants                                                         *
//***************************************************************************
	
	private static final String c_DefaultEntity = "o";
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructors                                       						*
//***************************************************************************
//---------------------------------------------------------------------------

public HibernateCondition (String p_Property, Operator p_Operator, Object p_Value)
	{
	super (p_Property,p_Operator,p_Value);
	
	m_Entity    = c_DefaultEntity;
	m_Parameter = null;
	}

//---------------------------------------------------------------------------

public HibernateCondition (String p_Property, Operator p_Operator, String p_Parameter, Object p_Value)
	{
	super (p_Property,p_Operator,p_Value);
	
	m_Entity 	= c_DefaultEntity;
	m_Parameter = p_Parameter;
	}

//---------------------------------------------------------------------------

public HibernateCondition (String p_Entity, String p_Property, Operator p_Operator, String p_Parameter, Object p_Value)
	{
	super (p_Property,p_Operator,p_Value);
	
	m_Entity 	= p_Entity;
	m_Parameter = p_Parameter;
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives                                       						*
//***************************************************************************
//---------------------------------------------------------------------------
/**
 * Wraps the specified string in quotes so that it can be used in a hibernate
 * query.
 * @param p_Unquoted specifies the string to be quoted.
 * @return the properly quoted string.
 */
//---------------------------------------------------------------------------

public String quoteString (String p_Unquoted)
	{
	StringBuffer l_Quoted;
	
	l_Quoted = new StringBuffer ();
	l_Quoted.append("'").append(p_Unquoted).append("'");
	
	return l_Quoted.toString();
	}

//---------------------------------------------------------------------------

public String addWildcards (String p_Exact)
	{
	StringBuffer l_Quoted;
	
	l_Quoted = new StringBuffer ();
	l_Quoted.append("%").append(p_Exact).append("%");
	
	return l_Quoted.toString();
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body		                                                        *
//***************************************************************************
//---------------------------------------------------------------------------

public void setEntity (String p_Entity)
	{
	m_Entity = p_Entity;
	}

//---------------------------------------------------------------------------

public String getEntity ()
	{
	return m_Entity;
	}

//---------------------------------------------------------------------------

public void setParameter (String p_Parameter)
	{
	m_Parameter = p_Parameter;
	}

//---------------------------------------------------------------------------

public String getParameter ()
	{
	return m_Parameter;
	}

//---------------------------------------------------------------------------
/**
 * The specifiesParameter allows to tell whether or not a HibernateCondition
 * specifies a parameter or not.
 * @return <code>true</code> if parameter property is set, <code>false</code>
 * otherwise
 */
//---------------------------------------------------------------------------

public boolean specifiesParameter ()
	{
	return ((m_Parameter != null) && (m_Parameter.length() > 0));
	}

//---------------------------------------------------------------------------
/**
 * Renders the hibernate specific representation of this condition
 * @return Hibernate specific representation of this condition
 */
//---------------------------------------------------------------------------

public String toString ()
	{
	StringBuffer	l_Entity;
	StringBuffer	l_Argument;
	StringBuffer	l_Condition;
	
	l_Condition = new StringBuffer ();
	l_Entity 	= new StringBuffer ();
	l_Argument  = new StringBuffer ();
	
	// Assemble Entity and Property first. Assuming Entity is 'o' and
	// property is 'id' resulting Entity ought to be 'o.id'
	
	if (m_Entity == null) m_Entity = c_DefaultEntity; 
	l_Entity.append(m_Entity).append('.').append(this.getProperty());

	// Next we're going to take care of the argument. In case this condition
	// specifies a parameter, argument is going to be the name of this parameter
	// prefixed with a double colon. If no parameter has been specified, then
	// a value has to be specified. Depending on the type of value, we have to
	// do a couple of things. If its a String object, we have to properly quote the
	// value. In case its another TreeNode, then we have to let it render itself.
	
	if (this.specifiesParameter()) l_Argument.append(':').append(m_Parameter);
	else if (this.getValue() != null)  
		{
		if ((this.getValue() instanceof String) && (!this.getValue().equals (Condition.c_Null)))
			{
			l_Argument.append(this.quoteString((String)this.getValue()));
			
//			if (this.getOperator().getOperator() == Operator.c_Like) 
//				 l_Argument.append(this.quoteString(this.addWildcards((String)this.getValue())));
//			else l_Argument.append(this.quoteString((String)this.getValue()));
			}
		else if (this.getValue() instanceof TreeNode)
			 l_Argument.append(this.getValue().toString());
		else l_Argument.append(this.getValue());
		}
	
	// Last but not least, we have to check whether condition ought to be case
	// sensitive or not. If condition has to be case insensitive, then we have to wrap
	// entity and argument with call to hibernate upper() method.

	if (this.getCaseSensitive())
		 l_Condition.append (l_Entity);
	else l_Condition.append ("upper(").append(l_Entity).append(")");
		
	l_Condition.append (this.getOperator());

	if (this.getCaseSensitive())
		 l_Condition.append (l_Argument);
	else l_Condition.append ("upper(").append(l_Argument).append(")");
	
	return l_Condition.toString();
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* End Of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

}

