# HG changeset patch
# User Augusto Mauch <augusto.mauch@openbravo.com>
# Date 1365422496 -7200
# Node ID bcd71aa006588aeaeec0e09f43b804a957941335
# Parent  5502b4a6d191347f12b1296bba1fd403701761b3
Fixes issue 23011: Enables using simple functions in HQL order by clause

Now it is possible to use one argument functions (i.e. abs(), max(), min(), etc) as part of the HQL order by clauses. A regular expression is used to check if the orderByParam matches the pattern functionName + '(' + property + ')' + 'desc' (optional). If so, it retrieves the function name and the property name, and resolves the property name. After doing it, it wrappes the resolved property name in its function and adds ' desc' if the function was meant to be sorted in descending order.

diff --git a/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java b/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
@@ -28,6 +28,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.commons.lang.StringUtils;
 import org.codehaus.jettison.json.JSONArray;
@@ -1127,7 +1129,26 @@
   }
 
   protected String getOrderByClausePart(String orderByParam) {
-    String localOrderBy = orderByParam;
+	// Support for one argument functions
+	String functionPattern = "(.*)\\((.*)\\) (desc|DESC)+";
+	Pattern p = Pattern.compile(functionPattern);
+	Matcher m = p.matcher(orderByParam);
+
+	String localOrderBy = null;
+	String functionName = null;
+	boolean descOrderedFunction = false;
+	if (m.find()) {
+		// If it is a function, retrieve the function name and the localOrderBy
+		functionName = m.group(1);
+		localOrderBy = m.group(2);
+		if (m.groupCount() == 3) {
+			// Check if the property is to be ordered in descending order
+			descOrderedFunction = true;
+		}
+	} else {
+		localOrderBy = orderByParam;
+	}
+
     final boolean asc = !localOrderBy.startsWith("-");
     String direction = "";
     if (!asc) {
@@ -1196,7 +1217,15 @@
       sb.append(resolvedPath);
       sb.append(direction);
     }
-    return sb.toString();
+
+    String orderByClausePart = sb.toString();
+    if (functionName != null) {
+    	orderByClausePart = functionName + "(" + orderByClausePart + ")";
+    	if (descOrderedFunction) {
+    		orderByClausePart = orderByClausePart + " desc";
+    	}
+    }
+    return orderByClausePart;
   }
 
   // Creates a Hibernate concatenation if there are multiple identifierproperties
