package org.jblooming.oql;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.hql.ParameterTranslations;
import org.hibernate.hql.QueryTranslator;
import org.hibernate.hql.ast.ASTQueryTranslatorFactory;
import org.hibernate.type.LiteralType;
import org.hibernate.type.Type;
import org.jblooming.persistence.exceptions.PersistenceException;
import org.jblooming.persistence.hibernate.PersistenceContext;
import org.jblooming.utilities.*;
import org.jblooming.waf.settings.ApplicationState;
import org.jblooming.waf.constants.Fields;
import org.jblooming.agenda.CompanyCalendar;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Matcher;
public class QueryHelper {
public static final String TYPE_CHAR = "C";
public static final String TYPE_CLOB = "CLOB";
public static final String TYPE_DATE = "D";
public static final String TYPE_INT = "N";
/**
* @deprecated use TYPE_INT
*/
public static final String TYPE_NUM = "N";
public static final String TYPE_DOUBLE = "DBL";
public static final String TYPE_FLOAT = "FLT";
public static final String TYPE_LONG = "LOG";
public static final String TYPE_logicAND = " and ";
public static final String TYPE_logicOR = " or ";
public static final String QBE_CONVERT_TO_UPPER = "QBE_CONVERT_TO_UPPER";
// set the default behaviour for uppercase
public boolean convertToUpper = Fields.TRUE.equals(ApplicationState.getApplicationSetting(QBE_CONVERT_TO_UPPER));
//"transient" value in single method call: is not empty when calling say addQBEClause, in parsing QBE condition invalid use is found
private String improperUseOfQBEErrorCode = null;
private boolean invalidQBE = false;
public boolean isValidQBE() {
return !invalidQBE;
}
public enum DefaultMatch {
EQUALS, STARTS_WITH, CONTAINS
}
public static Set<String> qbeOperatorsChars = CollectionUtilities.toSet("=", "!", "\"", "<", ">", "(", ")", "[", "]", "*", "#", "+", "//", ":");
public DefaultMatch defaultMatch = DefaultMatch.CONTAINS;
private String hql = "";
private Map args = new HashTable();
public QueryHelper(String hql) {
this.hql = hql;
}
public class QueryHelperElement {
public QueryHelperElement(String property, String alias, String type) {
this.property = property;
this.alias = alias;
this.type = type;
}
public String property;
public String alias;
public String type;
}
public QueryHelperElement getOrElement(String property, String alias, String type) {
return new QueryHelperElement(property, alias, type);
}
public OqlQuery toHql() throws PersistenceException {
return toHql(hql);
}
public OqlQuery toHql(PersistenceContext pc) throws PersistenceException {
return toHql(hql, pc);
}
public OqlQuery toHql(String query) throws PersistenceException {
return toHql(query, getArgs());
}
public OqlQuery toHql(String queryString, Map args) throws PersistenceException {
OqlQuery oql = new OqlQuery(queryString);
return toHqlArgued(args, oql);
}
public OqlQuery toHql(String queryString, PersistenceContext pc) throws PersistenceException {
OqlQuery oql = new OqlQuery(queryString, pc);
return toHqlArgued(getArgs(), oql);
}
private OqlQuery toHqlArgued(Map args, OqlQuery oql) throws PersistenceException {
if (args != null && args.size() > 0) {
for (Iterator iterator = args.keySet().iterator(); iterator.hasNext();) {
String paramName = (String) iterator.next();
Object value = args.get(paramName);
if (value instanceof Collection)
try {
oql.getQuery().setParameterList(paramName, (Collection) value);
} catch (HibernateException e) {
throw new PersistenceException(e);
}
else
oql.setParameter(paramName, value);
}
}
return oql;
}
public String getHqlString() {
return hql;
}
/**
* Only in very rare cases it should be used. If your name doesn't start with R||P avoid to use it.
*
* @param hql
*/
public void setHqlString(String hql) {
this.hql = hql;
}
public void wrapHql(String pre,String post){
this.hql= JSP.w(pre)+" "+this.hql+" "+JSP.w(post);
}
public void addOQLClause(String condition) {
addOQLClause(condition, null, null);
}
public void addOQLInClause(String property, String namedParameter, List arg) {
addOQLClause(property + " in (:" + namedParameter + ")", namedParameter, arg);
}
/**
* @param condition condition of the sort: t.name=:paramName
* @param paramName this must be stated explicitly as the params are to be held in a separate map
* @param arg the filter e.g. "a*"
*/
public void addOQLClause(String condition, String paramName, Object arg) {
if (paramName != null && arg != null)
addParameter(paramName, arg);
privateAddQueryClause(condition);
}
/**
* @param condition condition of the sort: t.name=:paramName
* @param paramName this must be stated explicitly as the params are to be held in a separate map
* @param arg the filter e.g. "a*"
*/
public StringBuffer getOQLClause(String condition, String paramName, Object arg) {
StringBuffer ret = new StringBuffer();
if (paramName != null && arg != null)
addParameter(paramName, arg);
ret.append(condition);
return ret;
}
/**
* @param property of the object on which to filter by QBE e.g. "description"
* @param namedParameter this must be stated explicitly as the params are to be held in a separate map
* @param qbeString the filter e.g. "a*"
* @param type is TYPE_CHAR or TYPE_DATE of the property in which we are searching
*/
public void addQBEORClause(String property, String namedParameter, String qbeString, String type) {
addQBEORClause(property, namedParameter, qbeString, type);
}
public void addQBEClause(String property, String namedParameter, String qbeString, String type) {
privateAddQueryClause(getQbeClause(property, namedParameter, qbeString, type).toString());
}
public void addQBEORClauses(String filter, QueryHelperElement... clauses) {
String query = "(";
boolean isFirst = true;
for (QueryHelperElement qhe : clauses) {
query += (!isFirst ? " or " : "") + getQbeClause(qhe.property, qhe.alias, filter, qhe.type).toString();
isFirst = false;
}
query += " )";
addQueryClause(query);
}
public void addParameter(String key, Object value) {
if (!getArgs().containsKey(key))
getArgs().put(key, value);
//else
//throw new PersistenceException("Oql query: parameter " + key +" set twice");
}
public void setParameter(String key, Object value) {
getArgs().put(key, value);
}
public StringBuffer getQbeClause(String property, String alias, String testo, String type) {
StringBuffer ret = new StringBuffer();
testo = testo.trim().replaceAll("\\*", "%");
if (convertToUpper && TYPE_CHAR.equals(type)) {
testo = testo.toUpperCase();
property = "upper(" + property + ")";
}
testo = testo.replaceAll(" ", " ");
testo = testo.replaceAll(" \\+ ", "&");
testo = testo.replaceAll("\\+ ", "&");
testo = testo.replaceAll(" \\+", "&");
testo = testo.replaceAll(" and ", "+");
testo = testo.replaceAll(" AND ", "+");
/*testo = testo.replaceAll(" & ", "+");
testo = testo.replaceAll("& ", "+");
testo = testo.replaceAll(" &", "+");
testo = testo.replaceAll("&", "+"); */
testo = testo.replaceAll(" + ", "+");
testo = testo.replaceAll(" or ", "|");
testo = testo.replaceAll(" OR ", "|");
testo = testo.replaceAll(" , ", "|");
testo = testo.replaceAll(", ", "|");
testo = testo.replaceAll(" ,", "|");
testo = testo.replaceAll(",", "|");
testo = testo.replaceAll(";", "|");
//testo = testo.replaceAll(" | ", "|");
//testo = testo.replaceAll(" ", "+");
String valore = testo.substring(1);// Mid(testo, 3) ;
String left = testo.substring(0, 1); // Left(testo, 2)
if (testo.length() >= 1) {
valore = testo.substring(1);// Mid(testo, 3) ;
left = testo.substring(0, 1); // Left(testo, 2)
}
/*
testo = parseString(testo);
if (left.equals("#"))
testo = "% " + valore + " %|% " + valore + "|" + valore + " %|=" + valore;
*/
// to search the string # must be
if (left.equals("#"))
testo = "%" + valore + "%|%" + valore + "|" + valore + "%|=" + valore;
else
testo = parseString(testo);
ret.append(controlString(new String[]{",", "|"}, testo.replaceAll("\\+", ","), property, alias, type));
return ret;
}
private String controlString(String[] op_cond, String testo, String campo, String aliasIn, String tipo) {
improperUseOfQBEErrorCode = null;
String testof = testo;
String testoFinale = "";// testo;
String testolav = "";
String testoins;
String condnext = "";
String condnext2 = "";
String testodas = "";
int pos1 = -1;
int pos2 = -1;
int pos = -1;
int i = 0;
int testcount = testof.length();
if (op_cond.length > 0) {
//while (!testof.trim().equals("")) {
while (testcount > 0) {
i++;
//for ( i = 0; i < testcount; i++) {
pos1 = testof.indexOf(op_cond[0]);
pos2 = testof.indexOf(op_cond[1]);
testoins = "";
if (((pos1) >= 0) || (pos2 >= 0)) {
if (((pos1 >= 0 && pos2 >= 0) && (pos1 < pos2)) || ((pos2 < 0) && (pos1 >= 0))) {
pos = pos1;
//condnext = op_cond[0];
condnext = TYPE_logicAND;
} else if (((pos1 >= 0 && pos2 >= 0) && (pos2 < pos1)) || ((pos1 < 0) && (pos2 >= 0))) {
pos = pos2;
//condnext = op_cond[1];
condnext = TYPE_logicOR;
}
if (pos >= 0)
testoins = testof.substring(0, pos);
testof = testof.trim().substring(pos + 1);
if (testolav.equals("")) {
if (testoins != null && !testoins.equals("")) {
//testolav = testoins;
testodas = QBEPartExtractor(campo, aliasIn + i, testoins, tipo).toString();
if (!testodas.equals("")) {
if (!testolav.equals(""))
testolav = condnext2 + " ( " + testodas + " ) ";
else
testolav = " ( " + testodas + " ) ";
}
}
} else {
if (!testodas.equals("")) {
if (!testoins.equals(""))
testodas = QBEPartExtractor(campo, aliasIn + i, testoins, tipo).toString();
// testolav += condnext2 + testoins;
if (!testodas.equals(""))
testolav += condnext2 + " ( " + testodas + " ) ";
}
}
condnext2 = condnext;
pos1 = -1;
pos2 = -1;
pos = -1;
testcount = testof.length();
} else {
if (!testof.equals("")) {
//testolav += condnext2 + testof;
// testolav += condnext2 + " (" + QBEPartExtractor(campo, aliasIn + i, testof, tipo).toString() + " ) ";
testodas = QBEPartExtractor(campo, aliasIn + i, testof, tipo).toString();
if (!testodas.equals("")) {
if (testolav.equals(""))
testolav = " (" + testodas + " ) ";
else
testolav += condnext2 + " (" + testodas + " ) ";
}
}
break;
}
}
}
if (!testolav.equals(""))
testoFinale = testolav;
else {
testodas = QBEPartExtractor(campo, aliasIn, testoFinale, tipo).toString();
if (!testodas.equals("")) {
testoFinale = "(" + testodas + ")";
} else {
testoFinale = "";
}
}
return testoFinale;
}
private String parseString(String testof) {
int testcount = testof.length();
String testofinale = "";
String value;
while (testcount > 0) {
int pos3 = testof.indexOf("\"");
if (pos3 >= 0) {
testofinale += testof.substring(0, pos3).replaceAll(" ", "|");
value = testof.substring(pos3 + 1);
pos3 = value.indexOf("\"");
if (pos3 >= 0) {
testofinale += "=" + value.substring(0, pos3);
testof = value.substring(pos3 + 1);
} else {
testofinale += value;
testof = "";
}
} else {
//testofinale = testof.replaceAll(" ", "|");
testofinale += testof.replaceAll(" ", "|");
testof = "";
}
testcount = testof.length();
}
return testofinale;
}
private StringBuffer QBEPartExtractor(String field, String alias, String text, String type) {
String value;
String left = "";
StringBuffer finalstring = new StringBuffer();
value = text;
type = type.toUpperCase();
boolean invalidValue = false;
Date dateValue = null;
Date dateValue2 = null;
Date valore1 = null;
Date valore2 = null;
Number valoreInt = 0;
Number valoreInt2 = 0;
boolean thereisTime = false;
// hack to convert LM to from:to
if (type.equals(TYPE_DATE)) {
text = DateUtilities.qbeIntervalFromString(text);
}
// operatori di 2 carattere
if (text.length() >= 2) {
value = text.substring(2);// Mid(testo, 3) ;
left = text.substring(0, 2); // Left(testo, 2)
}
// "()"
if ((left.equals("[]") || left.equals("()"))) {
if (type.equals(TYPE_CHAR)) {
finalstring.append(field).append(" is null or ").append(field).append("=:").append(alias).append("isempty");
addParameter(alias + "isempty", "");
} else {
finalstring.append(field).append("=").append("null");
}
// "//"
} else if (left.equals("//")) {
if (type.equals(TYPE_CHAR)) {
finalstring.append(field).append("=:").append(alias).append("isempty");
addParameter(alias + "isempty", "");
} else {
finalstring.append("(").append(field).append(" =").append("null)");
}
// "<>", "!="
} else if (left.equals("<>") || left.equals("!=")) {
if (type.equals(TYPE_CHAR)) {
finalstring.append(field).append("!=:").append(alias);
addParameter(alias, value);
} else if (type.equals(TYPE_DATE)) {
finalstring.append(" not(").append(QBEPartExtractor(field, alias, value, type).toString()).append(")");
} else if (type.equals(TYPE_CLOB)) {
setImproperUseOfQBEErrorCode("Cannot use " + left + " on text/blob fields");
} else {
try {
valoreInt = getNumberValue(text, valoreInt, type);
} catch (ParseException e) {
invalidValue = true;
}
if (!invalidValue) {
finalstring.append(field).append("!=:").append(alias);
addParameter(alias, valoreInt);
}
}
// ">=" ,"<="
} else if (left.equals(">=") || left.equals("<=")) {
if (type.equals(TYPE_CHAR)) {
finalstring.append(field).append(left).append(":").append(alias);
addParameter(alias, value);
} else if (type.equals(TYPE_CLOB)) {
setImproperUseOfQBEErrorCode("Cannot use " + left + " on text/blob fields");
} else if (type.equals(TYPE_DATE)) {
value = value.replaceAll("-", "/");
CompanyCalendar c = new CompanyCalendar();
try {
c.setTime(DateUtilities.dateFromString(value));
dateValue = c.getTime();
c.setAndGetTimeToDayStart();
valore1 = c.getTime();
} catch (ParseException e) {
invalidValue = true;
}
if (left.equals("<=")) {
if (!invalidValue) {
if (valore1.compareTo(dateValue) == 0) { // da vedere il caso con ora in format
c.setAndGetTimeToDayEnd();
valore1 = c.getTime();
} else {
valore1 = dateValue;
}
}
} else if (left.equals(">=")) {
if (!invalidValue) {
if (valore1.compareTo(dateValue) == 0) { // da vedere il caso con ora in format
c.setAndGetTimeToDayStart();
valore1 = c.getTime();
} else {
valore1 = dateValue;
}
}
}
if (!invalidValue) {
finalstring.append(field).append(left).append(":").append(alias);
addParameter(alias, valore1);
}
} else {
try {
valoreInt = getNumberValue(value, valoreInt, type);
} catch (ParseException e) {
invalidValue = true;
}
if (!invalidValue) {
finalstring.append(field).append(left).append(":").append(alias);
addParameter(alias, valoreInt);
}
}
// one char operators
} else {
if (text.length() >= 1) {
value = (text).substring(1);// Mid(testo, 3) ;
left = (text).substring(0, 1); // Left(testo, 2)
}
// "!"
if (left.equals("!"))
// finalstring.append(" not(").append(QBEPartExtractor(field, alias, value, type, customDateFormat).toString()).append(") or " + field + " is null "); // robik 21/12/2009 this invalidate // !() searches
finalstring.append(" not(").append(QBEPartExtractor(field, alias, value, type).toString()).append(")");
// ">", "<", "="
else if (left.equals("<") || left.equals(">") || left.equals("=")) {
if (type.equals(TYPE_CHAR)) {
finalstring.append(field).append(left).append(":").append(alias);
addParameter(alias, value);
} else if (type.equals(TYPE_CLOB)) {
if (left.equals("=")) {
finalstring.append(field).append(" like ").append(":").append(alias);
addParameter(alias, value);
} else
setImproperUseOfQBEErrorCode("Cannot use " + left + " on text/blob fields");
} else if (type.equals(TYPE_DATE)) {
//value = value.replaceAll("-", "/"); removed by bicch on 24/04/2009 as invalidate >-3w expressions
CompanyCalendar c = new CompanyCalendar();
try {
c.setTime(DateUtilities.dateFromString(value));
dateValue = c.getTime();
c.setAndGetTimeToDayStart();
valore1 = c.getTime();
} catch (ParseException e) {
invalidValue = true;
}
if (left.equals("<")) {
if (!invalidValue) {
if (valore1.compareTo(dateValue) == 0 && !thereisTime) { // da vedere il caso con ora in format
c.setAndGetTimeToDayStart();
valore1 = c.getTime();
} else {
valore1 = dateValue;
}
}
} else if (left.equals(">")) {
if (!invalidValue) {
if (valore1.compareTo(dateValue) == 0 && !thereisTime) { // da vedere il caso con ora in format
c.setAndGetTimeToDayEnd();
valore1 = c.getTime();
} else {
valore1 = dateValue;
}
}
} else if (left.equals("=")) {
if (!invalidValue) {
if (valore1.compareTo(dateValue) == 0 && !thereisTime) { // da vedere il caso con ora in format
c.setAndGetTimeToDayStart();
valore1 = c.getTime();
c.setAndGetTimeToDayEnd();
valore2 = c.getTime();
} else {
valore1 = dateValue;
valore2 = dateValue;
}
}
}
if (!invalidValue) {
if (left.equals("=")) {
finalstring.append(field).append(">=:").append(alias).append("A");
finalstring.append(" and ").append(field).append("<=:").append(alias).append("B");
addParameter(alias + "A", valore1);
addParameter(alias + "B", valore2);
} else {
finalstring.append(field).append(left).append(":").append(alias);
addParameter(alias, valore1);
}
}
} else {
try {
valoreInt = getNumberValue(value, valoreInt, type);
} catch (ParseException e) {
invalidValue = true;
}
if (!invalidValue) {
finalstring.append(field).append(left).append(":").append(alias);
addParameter(alias, valoreInt);
}
}
// "$"
} else if (left.equals("$")) {
if (type.equals(TYPE_CHAR) || type.equals(TYPE_CLOB)) {
finalstring.append(field).append(" like :").append(alias);
if (text.indexOf("%") >= 0)
addParameter(alias, value);
else
addParameter(alias, value + "%");
} else
setImproperUseOfQBEErrorCode("Cannot use " + left + " on this field");
//no initial operator
} else {
int pos = text.indexOf(":");
if (pos > 0) {
if (type.equals(TYPE_CHAR)) {
finalstring.append(field).append(" between :").append(alias).append("A and :").append(alias).append("B");
addParameter(alias + "A", text.substring(0, pos));
addParameter(alias + "B", text.substring(pos + 1) + "zzzz");
} else if (type.equals(TYPE_CLOB)) {
setImproperUseOfQBEErrorCode("Cannot use " + left + " on text/blob fields");
} else if (type.equals(TYPE_DATE)) {
String valore1Str = text.substring(0, pos);
String valore2Str = text.substring(pos + 1);
CompanyCalendar c1 = new CompanyCalendar();
CompanyCalendar c2 = new CompanyCalendar();
try {
c1.setTime(DateUtilities.dateFromString(valore1Str));
dateValue = c1.getTime();
c1.setAndGetTimeToDayStart();
valore1 = c1.getTime();
c2.setTime(DateUtilities.dateFromString(valore2Str));
dateValue2 = c2.getTime();
c2.setAndGetTimeToDayStart();
valore2 = c2.getTime();
} catch (ParseException e) {
invalidValue = true;
}
if (!invalidValue) {
if (valore1.compareTo(dateValue) == 0 && !thereisTime) { // da vedere il caso con ora in format
c1.setAndGetTimeToDayStart();
valore1 = c1.getTime();
} else {
valore1 = dateValue;
}
if (valore2.compareTo(dateValue2) == 0 && !thereisTime) { // da vedere il caso con ora in format
c2.setAndGetTimeToDayEnd();
valore2 = c2.getTime();
} else {
valore2 = dateValue2;
}
finalstring.append(field).append(" between :").append(alias).append("A and :").append(alias).append("B");
addParameter(alias + "A", valore1);
addParameter(alias + "B", valore2);
}
} else {
try {
valoreInt = getNumberValue(text.substring(0, pos), valoreInt, type);
valoreInt2 = getNumberValue(text.substring(pos + 1), valoreInt2, type);
} catch (ParseException e) {
invalidValue = true;
}
if (!invalidValue) {
finalstring.append(field).append(" between :").append(alias).append("A and :").append(alias).append("B");
addParameter(alias + "A", valoreInt);
addParameter(alias + "B", valoreInt2);
}
}
//fallout case
} else {
if (type.equals(TYPE_CHAR) || type.equals(TYPE_CLOB)) {
finalstring.append(field).append(" like :").append(alias);
if (text.indexOf("%") >= 0)
addParameter(alias, text);
else {
if (DefaultMatch.CONTAINS.equals(defaultMatch))
addParameter(alias, "%" + text + "%");
else if (DefaultMatch.STARTS_WITH.equals(defaultMatch))
addParameter(alias, text + "%");
else if (DefaultMatch.EQUALS.equals(defaultMatch))
addParameter(alias, text);
}
} else if (type.equals(TYPE_DATE)) {
CompanyCalendar c = new CompanyCalendar();
try {
c.setTime(DateUtilities.dateFromString(text));
dateValue = c.getTime();
c.setAndGetTimeToDayStart();
valore1 = c.getTime();
} catch (ParseException e) {
invalidValue = true;
}
if (!invalidValue) {
if (valore1.compareTo(dateValue) == 0 && !thereisTime) { // da vedere il caso con ora in format
c.setAndGetTimeToDayStart();
valore1 = c.getTime();
c.setAndGetTimeToDayEnd();
valore2 = c.getTime();
} else {
valore1 = dateValue;
valore2 = dateValue;
}
}
if (!invalidValue) {
finalstring.append(field).append(">=:").append(alias).append("A");
finalstring.append(" and ").append(field).append("<=:").append(alias).append("B");
addParameter(alias + "A", valore1);
addParameter(alias + "B", valore2);
}
} else {
try {
valoreInt = getNumberValue(text, valoreInt, type);
} catch (ParseException e) {
invalidValue = true;
}
if (!invalidValue) {
finalstring.append(field).append("=:").append(alias);
addParameter(alias, valoreInt);
}
}
}
}
}
return finalstring;
}
private Number getNumberValue(String testo, Number valoreInt, String type) throws ParseException {
if (TYPE_INT.equals(type) || TYPE_INT.equals(type))
valoreInt = NumberFormat.getInstance().parse(testo).intValue();
else if (TYPE_DOUBLE.equals(type))
valoreInt = NumberFormat.getInstance().parse(testo).doubleValue();
else if (TYPE_FLOAT.equals(type))
valoreInt = NumberFormat.getInstance().parse(testo).floatValue();
else if (TYPE_LONG.equals(type))
valoreInt = NumberFormat.getInstance().parse(testo).longValue();
return valoreInt;
}
private QueryHelper privateAddQueryClause(String condition) {
return privateAddQueryClause(condition, "");
}
private QueryHelper privateAddQueryClause(String condition, String logic) {
String sqlstr;
String orderBySql = "";
String groupBySql = "";
String whereSql = "";
if (logic.trim().equals(""))
logic = TYPE_logicAND;
int posOrderBy, posQroupBy, posWhere;
String orderBy = " order by ";
String groupBy = " group by ";
String where = " where ";
StringBuffer sqlQuery = new StringBuffer();
sqlstr = hql.toLowerCase();
if (!condition.trim().equals("")) {
//check whether sqlstr has already "ORDER BY"
posOrderBy = sqlstr.indexOf(orderBy);
if (posOrderBy > 0) {
orderBySql = hql.substring(posOrderBy);
sqlstr = sqlstr.substring(0, posOrderBy);
hql = hql.substring(0, posOrderBy);
}
//check whether sqlstr has already "GROUP BY"
posQroupBy = sqlstr.indexOf(groupBy);
if (posQroupBy > 0) {
groupBySql = hql.substring(posQroupBy);
hql = hql.substring(0, posQroupBy);
sqlstr = sqlstr.substring(0, posQroupBy);
}
//check whether sqlstr has already "WHERE"
posWhere = sqlstr.indexOf(where);
if (posWhere > 0) {
whereSql = hql.substring(posWhere) + logic;
hql = hql.substring(0, posWhere);
sqlstr = sqlstr.substring(0, posWhere);
} else {
whereSql = where.toLowerCase();
}
sqlQuery.append(hql);
sqlQuery.append(whereSql);
sqlQuery.append(" (").append(condition).append(") ");
sqlQuery.append(groupBySql);
sqlQuery.append(orderBySql);
} else {
sqlQuery.append(hql);
}
hql = sqlQuery.toString();
//return sqlQuery;
return this;
}
public void addQueryClause(String condition) {
privateAddQueryClause(condition);
}
public void addOrQueryClause(String condition) {
privateAddQueryClause(condition, TYPE_logicOR);
}
public void addToHqlString(String additionalHql) {
hql = hql + additionalHql;
}
public void addJoinAlias(String joinAlias) {
if (!joinAlias.startsWith(" "))
joinAlias = " " + joinAlias;
if (!joinAlias.endsWith(" "))
joinAlias = joinAlias + " ";
if (joinAlias.toLowerCase().indexOf("join") == -1)
joinAlias = " join " + joinAlias;
int afterFromIndex = hql.indexOf("from") + 4;
String afterFrom = hql.substring(afterFromIndex);
int spacesAfterFrom = StringUtilities.countConsecutiveOccurrences(" ", afterFrom);
int afterClassIndex = hql.indexOf(" ", afterFromIndex + spacesAfterFrom);
String afterClass = hql.substring(afterClassIndex);
int spacesAfterClass = StringUtilities.countConsecutiveOccurrences(" ", afterClass);
//is there "as" ?
if (hql.substring(afterClassIndex + spacesAfterClass).trim().startsWith("as ")) {
int spacesAfterAs = StringUtilities.countConsecutiveOccurrences(" ", hql.substring(afterClassIndex + spacesAfterClass + 2));
//int afterClassAndAfterAs = hql.indexOf(" ",afterClassIndex+spacesAfterClass+2);
afterClassIndex = afterClassIndex + 2 + spacesAfterAs;
}
int afterMainAlias = hql.indexOf(" ", afterClassIndex + spacesAfterClass);
if (afterMainAlias == -1)
afterMainAlias = hql.length();
//int mainAlias = upToFrom.trim().indexOf(" ");
hql = hql.substring(0, afterMainAlias) + joinAlias + hql.substring(afterMainAlias);
}
public Map getArgs() {
return args;
}
public String getSQLString(PersistenceContext pc) {
return this.getSQLString(pc, false);
}
public String getSQLString(PersistenceContext pc, boolean formatted) {
String sql = "";
try {
if(null == pc)
pc = PersistenceContext.getDefaultPersistenceContext();
SessionFactoryImplementor session = (SessionFactoryImplementor)pc.persistenceConfiguration.getSessionFactory();
QueryTranslator translator = new ASTQueryTranslatorFactory().createQueryTranslator("",this.getHqlString(),this.getArgs(),session);
translator.compile(this.getArgs(), true);
sql = translator.getSQLString();
// parameters
if(!this.getArgs().isEmpty()) {
TreeMap<Integer, String> tokenMap = new TreeMap<Integer, String>();
ParameterTranslations parameterTranslations = translator.getParameterTranslations();
Dialect dialect = session.getDialect();
for (Iterator iter = parameterTranslations.getNamedParameterNames().iterator(); iter.hasNext();) {
String paramName = (String) iter.next();
Object paramValue = this.getArgs().get(paramName);
Type type = parameterTranslations.getNamedParameterExpectedType(paramName);
String paramValueString;
if(ReflectionUtilities.extendsOrImplements(type.getClass(), LiteralType.class)) {
paramValueString = ((LiteralType)type).objectToSQLString(paramValue, dialect);
} else {
paramValueString = null != paramValue ? paramValue.toString() : "null";
}
int[] locations = parameterTranslations.getNamedParameterSqlLocations(paramName);
for(int position : locations)
tokenMap.put(position, paramValueString);
}
for(String value : tokenMap.values()) {
sql = sql.replaceFirst("=\\? ", Matcher.quoteReplacement("=" + value + " "));
}
}
//if(formatted)
//sql = new org.hibernate.pretty.Formatter(sql).format(); //no more formatter in hib 3.6.3
} catch(Throwable e) {
sql = "Conversion error in creating the SQL query";
}
return sql;
}
public String doDebug(PersistenceContext pc) {
StringBuffer str = new StringBuffer();
// output the hql
str.append("/*---------- hql ---------- */\n");
str.append(getHqlString());
str.append("\n\n");
// get parameter values
str.append("/*---------- parameters ---------- */\n");
str.append(args.toString());
str.append("\n\n");
// output the sql
str.append("/*---------- sql ---------- */\n");
str.append(this.getSQLString(pc, true));
str.append("\n\n");
return str.toString();
}
public String doDebug() {
return this.doDebug(null);
}
public void setDistinct() {
String query = getHqlString();
String distinct = "distinct";
if (query.toLowerCase().indexOf(distinct) == -1) {
int start = (query.startsWith("select") ? 6 : 0);
query = "select distinct" + query.substring(start);
}
hql = query;
}
public static boolean containsQBEChars(String filter) {
boolean containsQBEChars = false;
for (int i = 0; i < filter.length(); i++) {
String s = filter.substring(i, i + 1);
if (qbeOperatorsChars.contains(s)) {
containsQBEChars = true;
break;
}
}
return containsQBEChars;
}
public String getImproperUseOfQBEErrorCode() {
return improperUseOfQBEErrorCode;
}
private void setImproperUseOfQBEErrorCode(String improperUseOfQBEErrorCode) {
this.improperUseOfQBEErrorCode = improperUseOfQBEErrorCode;
if (JSP.ex(improperUseOfQBEErrorCode))
invalidQBE = true;
}
}