Fixed issue 32610: Standard datasources do not accept _where parameter
authorNaroa Iriarte <naroa.iriarte@openbravo.com>
Wed, 13 Apr 2016 12:37:44 +0200
changeset 29023 4bc26a30e296
parent 28882 6ce3115fb452 (current diff)
parent 29022 2872178cbaa9 (diff)
child 29024 7241af045c9e
Fixed issue 32610: Standard datasources do not accept _where parameter
src-db/database/sourcedata/AD_MESSAGE.xml
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/ADAlertDatasourceService.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/ADAlertDatasourceService.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2015 Openbravo SLU
+ * All portions are Copyright (C) 2015-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -71,10 +71,8 @@
       alertStatus = parameters.get(ALERT_STATUS);
       alertStatus = StringUtils.isEmpty(alertStatus) ? "" : alertStatus.toUpperCase();
 
-      List<String> alertList = getAlertIds();
-
-      String whereClause = buildWhereClause(alertStatus, alertList);
-      parameters.put(JsonConstants.WHERE_PARAMETER, whereClause);
+      String whereClause = getWhereAndFilterClause(parameters);
+      parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, whereClause);
 
       if (parameters.get(JsonConstants.DISTINCT_PARAMETER) == null) {
         // Also return the tab id of the alert rule, just when loading the grid from the server.
@@ -159,7 +157,13 @@
     return alertIds;
   }
 
-  private String buildWhereClause(String alertStatus, List<String> alertList) {
+  @Override
+  protected String getWhereAndFilterClause(Map<String, String> parameters) {
+    String alertStatus = "";
+    alertStatus = parameters.get(ALERT_STATUS);
+    alertStatus = StringUtils.isEmpty(alertStatus) ? "" : alertStatus.toUpperCase();
+
+    List<String> alertList = getAlertIds();
     int chunkSize = 1000;
     String filterClause;
     String whereClause = "coalesce(to_char(status), 'NEW') = '"
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/CachedPreference.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/CachedPreference.java	Wed Apr 13 12:37:44 2016 +0200
@@ -53,10 +53,11 @@
 @ApplicationScoped
 public class CachedPreference {
   public static final String ALLOW_UNPAGED_DS_MANUAL_REQUEST = "OBJSON_AllowUnpagedDatasourceManualRequest";
+  public static final String ALLOW_WHERE_PARAMETER = "OBSERDS_AllowWhereParameter";
 
   private static final Logger log = LoggerFactory.getLogger(CachedPreference.class);
-  private List<String> propertyList = new ArrayList<String>(
-      Arrays.asList(ALLOW_UNPAGED_DS_MANUAL_REQUEST));
+  private List<String> propertyList = new ArrayList<String>(Arrays.asList(
+      ALLOW_UNPAGED_DS_MANUAL_REQUEST, ALLOW_WHERE_PARAMETER));
   private Map<String, String> cachedPreference = new HashMap<String, String>();
 
   /**
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-pick-and-execute-grid.js.ftl	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-pick-and-execute-grid.js.ftl	Wed Apr 13 12:37:44 2016 +0200
@@ -12,7 +12,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2011-2013 Openbravo SLU
+ * All portions are Copyright (C) 2011-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -21,9 +21,6 @@
 
 {
 <@compress single_line=true>
-  <#if data.whereClause != "">
-  whereClause: '${data.whereClause?js_string}',
-  </#if>
   <#if data.whereClauseSQL != "">
   sqlWhereClause: '${data.whereClauseSQL?js_string}',
   </#if>  
@@ -36,8 +33,10 @@
   <#if data.sortField != "">
   sortField: '${data.sortField?js_string}',
   </#if>
-  <#if data.filterClause != "">
-  filterClause: '${data.filterClause?js_string}',
+  <#if data.hasFilterClause>
+  filterClause: true,
+  <#else>
+  filterClause: false,
   </#if>
   <#if data.filterClauseSQL != "">
   sqlFilterClause: '${data.filterClauseSQL?js_string}',
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-view-grid.js.ftl	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/templates/ob-view-grid.js.ftl	Wed Apr 13 12:37:44 2016 +0200
@@ -12,7 +12,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2010-2013 Openbravo SLU
+ * All portions are Copyright (C) 2010-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -23,17 +23,16 @@
     view: this,
     uiPattern: '${data.uiPattern}', 
      
-    <#if data.whereClause != "">
-        whereClause: '${data.whereClause?js_string}',
-    </#if>
     <#if data.orderByClause != "">
         orderByClause: '${data.orderByClause?js_string}',
     </#if>
     <#if data.sortField != "">
         sortField: '${data.sortField?js_string}',
     </#if>
-    <#if data.filterClause != "">
-        filterClause: '${data.filterClause?js_string}',
+    <#if data.hasFilterClause>
+        filterClause: true,
+    <#else>
+        filterClause: false,
     </#if>
     <#if data.filterName != "">
         filterName: '${data.filterName?js_string}',
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/OBViewGridComponent.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/window/OBViewGridComponent.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2010-2014 Openbravo SLU
+ * All portions are Copyright (C) 2010-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -23,6 +23,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang.StringUtils;
 import org.hibernate.criterion.Restrictions;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
@@ -45,11 +46,9 @@
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.ad.ui.AuxiliaryInput;
 import org.openbravo.model.ad.ui.Tab;
-import org.openbravo.model.common.order.Order;
 import org.openbravo.model.common.order.OrderLine;
 import org.openbravo.service.datasource.DataSource;
 import org.openbravo.service.db.DalConnectionProvider;
-import org.openbravo.service.json.JsonConstants;
 
 /**
  * The backing bean for generating the OBViewGrid client-side representation.
@@ -91,13 +90,6 @@
     entity = ModelProvider.getInstance().getEntityByTableId((String) DalUtil.getId(tab.getTable()));
   }
 
-  public String getWhereClause() {
-    if (tab.getHqlwhereclause() != null) {
-      return tab.getHqlwhereclause();
-    }
-    return "";
-  }
-
   public String getWhereClauseSQL() {
     if (tab.getSQLWhereClause() != null) {
       return tab.getSQLWhereClause();
@@ -161,11 +153,8 @@
     return "";
   }
 
-  public String getFilterClause() {
-    if (tab.getHqlfilterclause() != null) {
-      return addTransactionalFilter(tab.getHqlfilterclause());
-    }
-    return addTransactionalFilter("");
+  public boolean isHasFilterClause() {
+    return (this.isApplyTransactionalFilter() || StringUtils.isNotBlank(tab.getHqlfilterclause()));
   }
 
   public String getFilterClauseSQL() {
@@ -209,23 +198,6 @@
     return filterName;
   }
 
-  private String addTransactionalFilter(String filterClause) {
-    if (!this.isApplyTransactionalFilter()) {
-      return filterClause;
-    }
-    String transactionalFilter = " e.updated > " + JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE
-        + " ";
-    if (entity.hasProperty(Order.PROPERTY_PROCESSED)) {
-      transactionalFilter += " or e.processed = 'N' ";
-    }
-    transactionalFilter = " (" + transactionalFilter + ") ";
-
-    if (filterClause.length() > 0) {
-      return " (" + transactionalFilter + " and (" + filterClause + ")) ";
-    }
-    return transactionalFilter;
-  }
-
   public String getUiPattern() {
     return tab.getUIPattern();
   }
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-grid.js	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-grid.js	Wed Apr 13 12:37:44 2016 +0200
@@ -90,6 +90,10 @@
     return this.fetchingData;
   },
 
+  isFilterClauseApplied: function () {
+    return true === this.filterClause;
+  },
+
   cellHoverHTML: function (record, rowNum, colNum) {
 
     var ret, field = this.getField(colNum),
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js	Wed Apr 13 12:37:44 2016 +0200
@@ -26,6 +26,8 @@
   ARROW_UP_KEY_NAME: 'Arrow_Up',
   ARROW_DOWN_KEY_NAME: 'Arrow_Down',
   ERROR_MESSAGE_PROP: '_hasErrors',
+  EXISTS_FILTER_CLAUSE: 'hasFilterClause',
+  IS_FILTER_CLAUSE_APPLIED: 'isImplicitFilterApplied',
   ICONS: {
     PROGRESS: 0,
     OPEN_IN_FORM: 1,
@@ -56,7 +58,6 @@
   // handles this form
   // and the grid and other related components.
   view: null,
-
   // ** {{{ editGrid }}} **
   // Controls if an edit link column is created in the grid, set to false to
   // prevent this.
@@ -2295,17 +2296,7 @@
     // add all the new session properties context info to the requestProperties
     isc.addProperties(params, this.view.getContextInfo(true, false));
 
-    if (this.filterClause) {
-      if (this.whereClause) {
-        params[OB.Constants.WHERE_PARAMETER] = ' ((' + this.whereClause + ') and (' + this.filterClause + ')) ';
-      } else {
-        params[OB.Constants.WHERE_PARAMETER] = this.filterClause;
-      }
-    } else if (this.whereClause) {
-      params[OB.Constants.WHERE_PARAMETER] = this.whereClause;
-    } else {
-      params[OB.Constants.WHERE_PARAMETER] = null;
-    }
+    params[isc.OBViewGrid.IS_FILTER_CLAUSE_APPLIED] = this.isFilterClauseApplied();
 
     if (this.isSorting) {
       params.isSorting = true;
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-pick-and-execute-grid.js	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-pick-and-execute-grid.js	Wed Apr 13 12:37:44 2016 +0200
@@ -776,17 +776,7 @@
     // prevent the count operation
     params[isc.OBViewGrid.NO_COUNT_PARAMETER] = 'true';
 
-    if (this.filterClause) {
-      if (props.whereClause) {
-        params[OB.Constants.WHERE_PARAMETER] = ' ((' + props.whereClause + ') and (' + this.filterClause + ")) ";
-      } else {
-        params[OB.Constants.WHERE_PARAMETER] = this.filterClause;
-      }
-    } else if (props.whereClause) {
-      params[OB.Constants.WHERE_PARAMETER] = props.whereClause;
-    } else {
-      params[OB.Constants.WHERE_PARAMETER] = null;
-    }
+    params[isc.OBViewGrid.IS_FILTER_CLAUSE_APPLIED] = this.isFilterClauseApplied();
 
     if (this.sqlFilterClause) {
       if (props.sqlWhereClause) {
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/KernelUtils.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/KernelUtils.java	Wed Apr 13 12:37:44 2016 +0200
@@ -138,7 +138,6 @@
   }
 
   public JSONObject createErrorJSON(Exception e) {
-    log.error(e.getMessage(), e);
     JSONObject error = new JSONObject();
     try {
       error.put("message", e.getMessage());
--- a/modules/org.openbravo.service.datasource/src-db/database/sourcedata/AD_REF_LIST.xml	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src-db/database/sourcedata/AD_REF_LIST.xml	Wed Apr 13 12:37:44 2016 +0200
@@ -1,5 +1,17 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <data>
+<!--23658853CF2D417B8FB94FE849DB3337--><AD_REF_LIST>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <AD_REF_LIST_ID><![CDATA[23658853CF2D417B8FB94FE849DB3337]]></AD_REF_LIST_ID>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <VALUE><![CDATA[OBSERDS_AllowWhereParameter]]></VALUE>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <NAME><![CDATA[Allow Where Parameter]]></NAME>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <DESCRIPTION><![CDATA[This preference allows to include the '_where' parameter in the datasource requests. If this preference is set to true the datasource will take into account the '_where' request parameter, if not it will be ignored.]]></DESCRIPTION>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--23658853CF2D417B8FB94FE849DB3337-->  <AD_MODULE_ID><![CDATA[A44B9BA75C354D8FB2E3F7D6EB6BFDC4]]></AD_MODULE_ID>
+<!--23658853CF2D417B8FB94FE849DB3337--></AD_REF_LIST>
+
 <!--62980B3E5545466D91CA8B2AC352AF72--><AD_REF_LIST>
 <!--62980B3E5545466D91CA8B2AC352AF72-->  <AD_REF_LIST_ID><![CDATA[62980B3E5545466D91CA8B2AC352AF72]]></AD_REF_LIST_ID>
 <!--62980B3E5545466D91CA8B2AC352AF72-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/BaseDataSourceService.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/BaseDataSourceService.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2010-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2010-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -22,11 +22,20 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.inject.Inject;
+
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
+import org.openbravo.client.application.window.ApplicationDictionaryCachedStructures;
 import org.openbravo.client.kernel.Template;
+import org.openbravo.dal.core.DalUtil;
+import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.ad.ui.Tab;
+import org.openbravo.model.common.order.Order;
+import org.openbravo.service.json.JsonConstants;
 
 /**
  * A base data source service which can be extended. It combines the common parts for data sources
@@ -48,6 +57,9 @@
   private DataSource dataSource;
   private List<DataSourceProperty> dataSourceProperties = new ArrayList<DataSourceProperty>();
 
+  @Inject
+  private ApplicationDictionaryCachedStructures cachedStructures;
+
   /*
    * (non-Javadoc)
    * 
@@ -126,4 +138,75 @@
   public void setName(String name) {
     this.name = name;
   }
+
+  /**
+   * This method returns a String with the where and filter clauses that will be applied.
+   *
+   * @return A String with the value of the where and filter clause. It can be null when there is no
+   *         filter clause nor where clause.
+   */
+  protected String getWhereAndFilterClause(Map<String, String> parameters) {
+    if (!parameters.containsKey(JsonConstants.TAB_PARAMETER)) {
+      return "";
+    } else {
+      String whereAndFilterClause = null;
+      String tabId = parameters.get(JsonConstants.TAB_PARAMETER);
+      try {
+        OBContext.setAdminMode(true);
+        Tab tab = cachedStructures.getTab(tabId);
+        String where = tab.getHqlwhereclause();
+        if (isFilterApplied(parameters)) {
+          String filterClause = getFilterClause(tab);
+          if (StringUtils.isNotBlank(where)) {
+            whereAndFilterClause = " ((" + where + ") and (" + filterClause + "))";
+          } else {
+            whereAndFilterClause = filterClause;
+          }
+        } else if (StringUtils.isNotBlank(where)) {
+          whereAndFilterClause = where;
+        }
+      } finally {
+        OBContext.restorePreviousMode();
+      }
+      return whereAndFilterClause;
+    }
+  }
+
+  private boolean isRootTab(Tab tab) {
+    return tab.getTabLevel() == 0;
+  }
+
+  private String getFilterClause(Tab tab) {
+    String tableId = (String) DalUtil.getId(tab.getTable());
+    Entity ent = ModelProvider.getInstance().getEntityByTableId(tableId);
+    boolean isTransactionalWindow = tab.getWindow().getWindowType().equals("T");
+    String filterClause = null;
+    if (tab.getHqlfilterclause() == null) {
+      filterClause = "";
+    } else {
+      filterClause = tab.getHqlfilterclause();
+    }
+    if (!isTransactionalFilterApplied(isTransactionalWindow, tab)) {
+      return filterClause;
+    }
+    String transactionalFilter = " e.updated > " + JsonConstants.QUERY_PARAM_TRANSACTIONAL_RANGE
+        + " ";
+    if (ent.hasProperty(Order.PROPERTY_PROCESSED)) {
+      transactionalFilter += " or e.processed = 'N' ";
+    }
+    transactionalFilter = " (" + transactionalFilter + ") ";
+
+    if (filterClause.length() > 0) {
+      return " (" + transactionalFilter + " and (" + filterClause + ")) ";
+    }
+    return transactionalFilter;
+  }
+
+  private boolean isTransactionalFilterApplied(boolean isTransactionalWindow, Tab tab) {
+    return isTransactionalWindow && isRootTab(tab);
+  }
+
+  private boolean isFilterApplied(Map<String, String> parameters) {
+    return "true".equals(parameters.get(JsonConstants.FILTER_APPLIED_PARAMETER));
+  }
 }
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Wed Apr 13 12:37:44 2016 +0200
@@ -57,6 +57,7 @@
 import org.openbravo.base.model.domaintype.EnumerateDomainType;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.base.session.OBPropertiesProvider;
+import org.openbravo.base.weld.WeldUtils;
 import org.openbravo.client.application.Parameter;
 import org.openbravo.client.application.Process;
 import org.openbravo.client.application.RefWindow;
@@ -198,6 +199,11 @@
       return;
     }
 
+    // The WHERE_AND_FILTER_CLAUSE parameter is initialized, it will be set after.
+    parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, "");
+
+    parameters.put(JsonConstants.WHERE_CLAUSE_HAS_BEEN_CHECKED, "false");
+
     if (log.isDebugEnabled()) {
       getRequestContent(request);
     }
@@ -207,10 +213,14 @@
       }
 
       String filterClass = parameters.get(DataSourceConstants.DS_FILTERCLASS_PARAM);
+
       if (filterClass != null) {
         try {
-          DataSourceFilter filter = (DataSourceFilter) Class.forName(filterClass).newInstance();
+          DataSourceFilter filter = (DataSourceFilter) WeldUtils
+              .getInstanceFromStaticBeanManager(Class.forName(filterClass));
           filter.doFilter(parameters, request);
+        } catch (OBSecurityException e) {
+          throw e;
         } catch (Exception e) {
           log.error("Error trying to apply datasource filter with class: " + filterClass, e);
         }
@@ -721,7 +731,9 @@
   }
 
   private void handleException(Exception e, HttpServletResponse response) throws IOException {
-    log4j.error(e.getMessage(), e);
+    if (!(e instanceof OBException && ((OBException) e).isLogExceptionNeeded())) {
+      log4j.error(e.getMessage(), e);
+    }
     if (e instanceof SQLGrammarException) {
       log.error(((SQLGrammarException) e).getSQL());
     }
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DefaultDataSourceService.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DefaultDataSourceService.java	Wed Apr 13 12:37:44 2016 +0200
@@ -24,9 +24,13 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.inject.Inject;
+
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.Property;
 import org.openbravo.base.model.domaintype.DateDomainType;
@@ -34,11 +38,13 @@
 import org.openbravo.base.model.domaintype.EnumerateDomainType;
 import org.openbravo.base.provider.OBProvider;
 import org.openbravo.base.structure.BaseOBObject;
+import org.openbravo.client.application.CachedPreference;
 import org.openbravo.client.kernel.KernelUtils;
 import org.openbravo.dal.core.DalUtil;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.dal.service.OBQuery;
+import org.openbravo.erpCommon.utility.OBMessageUtils;
 import org.openbravo.model.ad.ui.Field;
 import org.openbravo.model.ad.ui.Tab;
 import org.openbravo.service.json.DataResolvingMode;
@@ -59,6 +65,9 @@
 public class DefaultDataSourceService extends BaseDataSourceService {
   private static final Logger log4j = Logger.getLogger(DefaultDataSourceService.class);
 
+  @Inject
+  private CachedPreference cachedPreference;
+
   /*
    * (non-Javadoc)
    * 
@@ -89,19 +98,42 @@
     }
   }
 
-  private void addFetchParameters(Map<String, String> parameters) {
-
+  /**
+   * Adds some extra parameters that will be used to fetch data.
+   */
+  protected void addFetchParameters(Map<String, String> parameters) {
     if (getEntity() != null) {
       parameters.put(JsonConstants.ENTITYNAME, getEntity().getName());
     }
 
-    if (getWhereClause() != null) {
-      if (parameters.get(JsonConstants.WHERE_PARAMETER) != null) {
-        final String currentWhere = parameters.get(JsonConstants.WHERE_PARAMETER);
-        parameters.put(JsonConstants.WHERE_PARAMETER, "(" + currentWhere + ") and ("
-            + getWhereClause() + ")");
+    if (!"true".equals(parameters.get(JsonConstants.WHERE_CLAUSE_HAS_BEEN_CHECKED))) {
+      if (whereParameterIsNotBlank(parameters)) {
+        if (manualWhereClausePreferenceIsEnabled()) {
+          parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE,
+              parameters.get(JsonConstants.WHERE_PARAMETER));
+          String warnMsg = OBMessageUtils.getI18NMessage("WhereParameterAppliedWarning", null);
+          log4j.warn(warnMsg + "Parameters: "
+              + DefaultJsonDataService.convertParameterToString(parameters));
+        } else {
+          String errorMsg = OBMessageUtils.getI18NMessage("WhereParameterException", null);
+          log4j.error(errorMsg + " Parameters: "
+              + DefaultJsonDataService.convertParameterToString(parameters));
+          throw new OBSecurityException(errorMsg, false);
+        }
       } else {
-        parameters.put(JsonConstants.WHERE_PARAMETER, getWhereClause());
+        String whereAndFilterClause = getWhereAndFilterClause(parameters);
+        if (StringUtils.isNotBlank(whereAndFilterClause)) {
+          if (getWhereClause() != null) {
+            parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, "(" + whereAndFilterClause
+                + ") and (" + getWhereClause() + ")");
+          } else {
+            parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, whereAndFilterClause);
+          }
+        } else {
+          if (getWhereClause() != null) {
+            parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, getWhereClause());
+          }
+        }
       }
     }
 
@@ -123,17 +155,26 @@
       }
 
       final String whereClause;
-      if (parameters.get(JsonConstants.WHERE_PARAMETER) != null
-          && !parameters.get(JsonConstants.WHERE_PARAMETER).equals("null")) {
-        whereClause = parameters.get(JsonConstants.WHERE_PARAMETER) + " and (";
+      if (parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE) != null
+          && !parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE).equals("null")) {
+        whereClause = parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE) + " and (";
       } else {
         whereClause = " (";
       }
-      parameters.put(JsonConstants.WHERE_PARAMETER, whereClause + JsonConstants.MAIN_ALIAS + "."
-          + parentProperty + ".id='" + parentId + "')");
+      parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, whereClause + JsonConstants.MAIN_ALIAS
+          + "." + parentProperty + ".id='" + parentId + "')");
     }
+    parameters.put(JsonConstants.USE_ALIAS, "true");
+  }
 
-    parameters.put(JsonConstants.USE_ALIAS, "true");
+  private boolean manualWhereClausePreferenceIsEnabled() {
+    return "Y".equals(cachedPreference.getPreferenceValue(CachedPreference.ALLOW_WHERE_PARAMETER));
+  }
+
+  private boolean whereParameterIsNotBlank(Map<String, String> parameters) {
+    return parameters.containsKey(JsonConstants.WHERE_PARAMETER)
+        && StringUtils.isNotBlank(parameters.get(JsonConstants.WHERE_PARAMETER))
+        && !"null".equals(parameters.get(JsonConstants.WHERE_PARAMETER));
   }
 
   /*
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/HQLDataSourceService.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/HQLDataSourceService.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2014-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -580,7 +580,7 @@
     addFilterWhereClause(additionalFilter, filterWhereClause);
 
     // the _where parameter contains the filter clause and the where clause defined at tab level
-    String whereClauseParameter = parameters.get(JsonConstants.WHERE_PARAMETER);
+    String whereClauseParameter = parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE);
     if (whereClauseParameter != null && !whereClauseParameter.trim().isEmpty()
         && !"null".equals(whereClauseParameter)) {
       additionalFilter.append(AND + whereClauseParameter);
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/ReadOnlyDataSourceService.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/ReadOnlyDataSourceService.java	Wed Apr 13 12:37:44 2016 +0200
@@ -58,6 +58,7 @@
    */
   public String fetch(Map<String, String> parameters) {
 
+    addFetchParameters(parameters);
     final String startRowStr = parameters.get(JsonConstants.STARTROW_PARAMETER);
     final String endRowStr = parameters.get(JsonConstants.ENDROW_PARAMETER);
     int startRow = 0;
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java	Wed Apr 13 12:37:44 2016 +0200
@@ -355,7 +355,7 @@
       }
     }
     // add the special whereParameter
-    final String whereParameter = filterParameters.get(JsonConstants.WHERE_PARAMETER);
+    final String whereParameter = filterParameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE);
     if (whereParameter != null && !whereParameter.equals("null") && whereParameter.length() > 0) {
       if (localWhereClause.length() > 0) {
         localWhereClause = " (" + localWhereClause + ") and (" + whereParameter + ") ";
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java	Wed Apr 13 12:37:44 2016 +0200
@@ -496,12 +496,14 @@
     if (!directNavigation) {
       // set the where/org filter parameters and the @ parameters
       for (String key : parameters.keySet()) {
-        if (key.equals(JsonConstants.WHERE_PARAMETER)
-            || key.equals(JsonConstants.IDENTIFIER)
+        if (key.equals(JsonConstants.IDENTIFIER)
+            || key.equals(JsonConstants.WHERE_PARAMETER)
+            || key.equals(JsonConstants.WHERE_AND_FILTER_CLAUSE)
             || key.equals(JsonConstants.ORG_PARAMETER)
             || key.equals(JsonConstants.TARGETRECORDID_PARAMETER)
             || (key.startsWith(DataEntityQueryService.PARAM_DELIMITER) && key
-                .endsWith(DataEntityQueryService.PARAM_DELIMITER))) {
+                .endsWith(DataEntityQueryService.PARAM_DELIMITER))
+            || (key.equals(SelectorConstants.DS_REQUEST_SELECTOR_ID_PARAMETER))) {
           queryService.addFilterParameter(key, parameters.get(key));
         }
 
@@ -586,13 +588,13 @@
   }
 
   private void removeWhereParameter(Map<String, String> parameters) {
-    if (parameters.containsKey(JsonConstants.WHERE_PARAMETER)) {
-      parameters.remove(JsonConstants.WHERE_PARAMETER);
+    if (parameters.containsKey(JsonConstants.WHERE_AND_FILTER_CLAUSE)) {
+      parameters.remove(JsonConstants.WHERE_AND_FILTER_CLAUSE);
     }
   }
 
   // Given a map of parameters, returns a string with the pairs key:value
-  private String convertParameterToString(Map<String, String> parameters) {
+  public static String convertParameterToString(Map<String, String> parameters) {
     String paramMsg = "";
     for (String paramKey : parameters.keySet()) {
       paramMsg += paramKey + ":" + parameters.get(paramKey) + "\n";
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonConstants.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonConstants.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -54,6 +54,7 @@
 
   public static final String FILTERBYPARENTPROPERTY_PARAMETER = "_filterByParentProperty";
   public static final String WHERE_PARAMETER = "_where";
+  public static final String FILTER_APPLIED_PARAMETER = "isImplicitFilterApplied";
   public static final String SELECTEDPROPERTIES_PARAMETER = "_selectedProperties";
   public static final String DISTINCT_PARAMETER = "_distinct";
   public static final String SHOW_FK_DROPDOWN_UNFILTERED_PARAMETER = "_showFkDropdownUnfiltered";
@@ -122,5 +123,9 @@
   public static final String QUERY_PARAM_TRANSACTIONAL_RANGE = "@transactionalRange@";
 
   public static final String IS_WS_CALL = "_isWsCall";
-
+  public static final String WHERE_AND_FILTER_CLAUSE = "whereAndFilterClause";
+  public static final String TABLE_ID = "tableId";
+  public static final String WHERE_CLAUSE_HAS_BEEN_CHECKED = "whereClauseHasBeenChecked";
+  public static final String WINDOW_ID = "windowId";
+  public static final String DATASOURCE_NAME = "dataSourceName";
 }
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorComponent.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorComponent.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2009-2015 Openbravo SLU
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -376,10 +376,6 @@
     return Boolean.FALSE.toString();
   }
 
-  public String getWhereClause() {
-    return getSafeValue(getSelector().getHQLWhereClause());
-  }
-
   public String getTitle() {
     final String userLanguageId = OBContext.getOBContext().getLanguage().getId();
     String description = null;
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorDataSourceFilter.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorDataSourceFilter.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2010-2014 Openbravo SLU
+ * All portions are Copyright (C) 2010-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -26,15 +26,18 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.inject.Inject;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.codehaus.jettison.json.JSONObject;
 import org.hibernate.criterion.Restrictions;
+import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.model.Property;
+import org.openbravo.client.application.CachedPreference;
 import org.openbravo.client.application.Parameter;
 import org.openbravo.client.application.ParameterUtils;
 import org.openbravo.client.kernel.reference.StringUIDefinition;
@@ -44,8 +47,10 @@
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
+import org.openbravo.erpCommon.utility.OBMessageUtils;
 import org.openbravo.model.ad.domain.Validation;
 import org.openbravo.service.datasource.DataSourceFilter;
+import org.openbravo.service.json.DefaultJsonDataService;
 import org.openbravo.service.json.JsonConstants;
 import org.openbravo.service.json.JsonUtils;
 import org.openbravo.service.json.QueryBuilder.TextMatching;
@@ -63,6 +68,9 @@
   private DateFormat systemDateFormat = null;
   private TextMatching textMatching = TextMatching.exact;
 
+  @Inject
+  private CachedPreference cachedPreference;
+
   public SelectorDataSourceFilter() {
   }
 
@@ -114,28 +122,52 @@
         }
       }
 
-      if (!StringUtils.isEmpty(filterHQL)) {
-        log.debug("Adding to where clause (based on filter expression): " + filterHQL);
-
-        String currentWhere = parameters.get(JsonConstants.WHERE_PARAMETER);
-
-        if (currentWhere == null || currentWhere.equals("null") || currentWhere.equals("")) {
-          parameters.put(JsonConstants.WHERE_PARAMETER, filterHQL);
+      if (whereParameterIsNotBlank(parameters)) {
+        if (manualWhereClausePreferenceIsEnabled()) {
+          parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE,
+              parameters.get(JsonConstants.WHERE_PARAMETER));
+          String warnMsg = OBMessageUtils.getI18NMessage("WhereParameterAppliedWarning", null);
+          log.warn(warnMsg + " Parameters: "
+              + DefaultJsonDataService.convertParameterToString(parameters));
         } else {
-          parameters.put(JsonConstants.WHERE_PARAMETER, currentWhere + " and " + filterHQL);
+          String errorMsg = OBMessageUtils.getI18NMessage("WhereParameterException", null);
+          log.error(errorMsg + " Parameters: "
+              + DefaultJsonDataService.convertParameterToString(parameters));
+          throw new OBSecurityException(errorMsg, false);
+        }
+      } else {
+        String currentWhere = "";
+        if (!StringUtils.isEmpty(filterHQL)) {
+          log.debug("Adding to where clause (based on filter expression): " + filterHQL);
+          currentWhere = sel.getHQLWhereClause();
+          if (StringUtils.isBlank(currentWhere)) {
+            parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, filterHQL);
+          } else {
+            parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, currentWhere + " and "
+                + filterHQL);
+          }
+        } else {
+          currentWhere = sel.getHQLWhereClause();
+          if (StringUtils.isNotBlank(currentWhere)) {
+            parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, currentWhere);
+          }
         }
       }
 
+      parameters.put(JsonConstants.WHERE_CLAUSE_HAS_BEEN_CHECKED, "true");
+
       // Applying default expression for selector fields when is not a selector window request
       if (!"Window".equals(requestType)) {
         OBCriteria<SelectorField> sfc = OBDal.getInstance().createCriteria(SelectorField.class);
         sfc.add(Restrictions.isNotNull(SelectorField.PROPERTY_DEFAULTEXPRESSION));
         sfc.add(Restrictions.eq(SelectorField.PROPERTY_OBUISELSELECTOR, sel));
 
-        applyDefaultExpressions(sel, parameters, sfc, request);
+        applyDefaultExpressions(sel, parameters, sfc, request, filterHQL);
         verifyPropertyTypes(sel, parameters);
       }
 
+    } catch (OBSecurityException e) {
+      throw e;
     } catch (Exception e) {
       log.error("Error executing filter: " + e.getMessage(), e);
     } finally {
@@ -276,8 +308,9 @@
    * Evaluates the default expressions and modifies the parameters map for data filtering
    */
   private void applyDefaultExpressions(Selector sel, Map<String, String> parameters,
-      OBCriteria<SelectorField> sfc, HttpServletRequest request) {
+      OBCriteria<SelectorField> sfc, HttpServletRequest request, String hqlFilterClause) {
 
+    String currentWhere = "";
     if (sfc.count() == 0) {
       return;
     }
@@ -385,12 +418,38 @@
 
     log.debug("Adding to where clause (based on fields default expression): " + sb.toString());
 
-    String currentWhere = parameters.get(JsonConstants.WHERE_PARAMETER);
-
-    if (currentWhere == null || currentWhere.equals("null") || currentWhere.equals("")) {
-      parameters.put(JsonConstants.WHERE_PARAMETER, sb.toString());
+    if (whereParameterIsNotBlank(parameters)) {
+      if (manualWhereClausePreferenceIsEnabled()) {
+        parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE,
+            parameters.get(JsonConstants.WHERE_PARAMETER));
+      } else {
+        String errorMsg = OBMessageUtils.getI18NMessage("WhereParameterException", null);
+        log.error(errorMsg + " Parameters: "
+            + DefaultJsonDataService.convertParameterToString(parameters));
+        throw new OBSecurityException(errorMsg);
+      }
     } else {
-      parameters.put(JsonConstants.WHERE_PARAMETER, currentWhere + " and " + sb.toString());
+      if (StringUtils.isNotBlank(hqlFilterClause)) {
+        currentWhere = parameters.get(JsonConstants.WHERE_AND_FILTER_CLAUSE);
+      } else {
+        currentWhere = sel.getHQLWhereClause();
+      }
+      if (currentWhere == null || currentWhere.equals("null") || currentWhere.equals("")) {
+        parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE, sb.toString());
+      } else {
+        parameters.put(JsonConstants.WHERE_AND_FILTER_CLAUSE,
+            currentWhere + " and " + sb.toString());
+      }
     }
   }
+
+  private boolean manualWhereClausePreferenceIsEnabled() {
+    return "Y".equals(cachedPreference.getPreferenceValue(CachedPreference.ALLOW_WHERE_PARAMETER));
+  }
+
+  private boolean whereParameterIsNotBlank(Map<String, String> parameters) {
+    return parameters.containsKey(JsonConstants.WHERE_PARAMETER)
+        && StringUtils.isNotBlank(parameters.get(JsonConstants.WHERE_PARAMETER))
+        && !"null".equals(parameters.get(JsonConstants.WHERE_PARAMETER));
+  }
 }
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/templates/selector-as-link.ftl	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/templates/selector-as-link.ftl	Wed Apr 13 12:37:44 2016 +0200
@@ -55,9 +55,6 @@
         this.dataSource = ${data.dataSourceJavascript};
         this.Super('init', arguments);
     },
-    <#if data.whereClause != "">
-        whereClause : '${data.whereClause?js_string}'
-    </#if>
 <#else>
 /* jslint */
 sc_${data.columnName} = isc.OBSelectorLinkWidget.create({
@@ -95,9 +92,6 @@
     },
     extraSearchFields: [${data.extraSearchFields}],
     dataSource: ${data.dataSourceJavascript},
-    <#if data.whereClause != "">
-        whereClause : '${data.whereClause?js_string}',
-    </#if>
     callOut: ${data.callOut},
     title : '${data.title}'
 });
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/templates/selector.ftl	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/templates/selector.ftl	Wed Apr 13 12:37:44 2016 +0200
@@ -12,7 +12,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2009-2014 Openbravo SLU
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -70,9 +70,6 @@
         this.optionDataSource = ${data.dataSourceJavascript};
         this.Super('init', arguments);
     },
-    <#if data.whereClause != "">
-        whereClause: '${data.whereClause?js_string}',
-    </#if>
     <#if data.outHiddenInputPrefix != "">
         outHiddenInputPrefix: '${data.outHiddenInputPrefix}'
     </#if>
@@ -125,9 +122,6 @@
     },
     extraSearchFields: [${data.extraSearchFields}],
     dataSource: ${data.dataSourceJavascript},
-    <#if data.whereClause != "">
-        whereClause: '${data.whereClause?js_string}',
-    </#if>
     callOut: ${data.callOut},
     title : '${data.title}',
     comboReload: ${data.comboReload}
--- a/modules/org.openbravo.userinterface.selector/web/org.openbravo.userinterface.selector/js/ob-selector-item.js	Wed Apr 13 10:50:18 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/web/org.openbravo.userinterface.selector/js/ob-selector-item.js	Wed Apr 13 12:37:44 2016 +0200
@@ -1174,9 +1174,6 @@
       params.filterClass = 'org.openbravo.userinterface.selector.SelectorDataSourceFilter';
     }
 
-    // the additional where clause
-    params[OB.Constants.WHERE_PARAMETER] = selector.whereClause;
-
     // and sort according to the display field
     // initially
     params[OB.Constants.SORTBY_PARAMETER] = selector.displayField;
--- a/src-db/database/sourcedata/AD_MESSAGE.xml	Wed Apr 13 10:50:18 2016 +0200
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml	Wed Apr 13 12:37:44 2016 +0200
@@ -17555,6 +17555,18 @@
 <!--244CD1EF25C346B68813FAAB7C4712E2-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--244CD1EF25C346B68813FAAB7C4712E2--></AD_MESSAGE>
 
+<!--2467CC97B04343E694062E46EB8935FF--><AD_MESSAGE>
+<!--2467CC97B04343E694062E46EB8935FF-->  <AD_MESSAGE_ID><![CDATA[2467CC97B04343E694062E46EB8935FF]]></AD_MESSAGE_ID>
+<!--2467CC97B04343E694062E46EB8935FF-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--2467CC97B04343E694062E46EB8935FF-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--2467CC97B04343E694062E46EB8935FF-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--2467CC97B04343E694062E46EB8935FF-->  <VALUE><![CDATA[WhereParameterException]]></VALUE>
+<!--2467CC97B04343E694062E46EB8935FF-->  <MSGTEXT><![CDATA[The '_where' parameter has been included in the request. This value will not be taken into account. To be able to use this value, set the OBSERDS_AllowWhereParameter preference to true.]]></MSGTEXT>
+<!--2467CC97B04343E694062E46EB8935FF-->  <MSGTYPE><![CDATA[E]]></MSGTYPE>
+<!--2467CC97B04343E694062E46EB8935FF-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--2467CC97B04343E694062E46EB8935FF-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--2467CC97B04343E694062E46EB8935FF--></AD_MESSAGE>
+
 <!--24B4AED8FE3542C2933B4EA37DF641C5--><AD_MESSAGE>
 <!--24B4AED8FE3542C2933B4EA37DF641C5-->  <AD_MESSAGE_ID><![CDATA[24B4AED8FE3542C2933B4EA37DF641C5]]></AD_MESSAGE_ID>
 <!--24B4AED8FE3542C2933B4EA37DF641C5-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -22419,6 +22431,18 @@
 <!--8CDB54F9158D413D831AC5E9D65FCCF4-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--8CDB54F9158D413D831AC5E9D65FCCF4--></AD_MESSAGE>
 
+<!--8D24790CD4224733A47B5B6BFABC002E--><AD_MESSAGE>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <AD_MESSAGE_ID><![CDATA[8D24790CD4224733A47B5B6BFABC002E]]></AD_MESSAGE_ID>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <VALUE><![CDATA[WhereParameterAppliedWarning]]></VALUE>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <MSGTEXT><![CDATA[The '_where' parameter has been included in the request. The provided value will be used by the datasource because the OBSERDS_AllowWhereParameter preference is set to true.]]></MSGTEXT>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <MSGTYPE><![CDATA[W]]></MSGTYPE>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--8D24790CD4224733A47B5B6BFABC002E-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--8D24790CD4224733A47B5B6BFABC002E--></AD_MESSAGE>
+
 <!--8D490FAC95814DD2BC9C061E9FAC4568--><AD_MESSAGE>
 <!--8D490FAC95814DD2BC9C061E9FAC4568-->  <AD_MESSAGE_ID><![CDATA[8D490FAC95814DD2BC9C061E9FAC4568]]></AD_MESSAGE_ID>
 <!--8D490FAC95814DD2BC9C061E9FAC4568-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-test/src/org/openbravo/test/AllWebserviceTests.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/src-test/src/org/openbravo/test/AllWebserviceTests.java	Wed Apr 13 12:37:44 2016 +0200
@@ -21,6 +21,7 @@
 
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
+import org.openbravo.test.datasource.DataSourceWhereParameter;
 import org.openbravo.test.datasource.ExtendedNavigationModelTest;
 import org.openbravo.test.datasource.FICTest;
 import org.openbravo.test.datasource.FKDropDownDatasource;
@@ -48,7 +49,8 @@
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
 
-WSReadTest.class, //
+DataSourceWhereParameter.class, //
+    WSReadTest.class, //
     WSUpdateTest.class, //
     PerformanceTest.class, //
     WSAddRecordWithComputedColumns.class, //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/datasource/DataSourceWhereParameter.java	Wed Apr 13 12:37:44 2016 +0200
@@ -0,0 +1,274 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License. 
+ * The Original Code is Openbravo ERP. 
+ * The Initial Developer of the Original Code is Openbravo SLU 
+ * All portions are Copyright (C) 2015 Openbravo SLU 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.test.datasource;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.openbravo.service.json.JsonConstants;
+
+/**
+ * This test evaluates if some expected values are get when a filter is applied and if some
+ * unexpected values are not get when the filter is applied, but are get when the filter is removed.
+ *
+ * 
+ * @author Naroa Iriarte
+ * 
+ */
+@RunWith(Parameterized.class)
+public class DataSourceWhereParameter extends BaseDataSourceTestDal {
+
+  // Expected
+
+  private static final String USER_EXPECTED_VALUE = "A530AAE22C864702B7E1C22D58E7B17B";
+  private static final String ALERT_EXPECTED_VALUE = "D0CB68A7ADDD462E8B46438E2B9F58F6";
+  private static final String CUSTOM_QUERY_SELECTOR_EXPECTED_VALUE = "C0D9FAD1047343BAA53AF6F60D572DD0";
+  private static final String PRODUCT_SELECTOR_DATASOURCE_EXPECTED_VALUE = "B2D40D8A5D644DD89E329DC29730905541732EFCA6374148BFD8B08C8B12DB73";
+
+  // Unexpected
+
+  private static final String USER_UNEXPECTED_VALUE = "6A3D3D6A808C455EAF1DAB48058FDBF4";
+  private static final String ALERT_UNEXPECTED_VALUE = "D938304218B6405F8B2665D5E77A3EE4";
+  private static final String CUSTOM_QUERY_SELECTOR_UNEXPECTED_VALUE = "369"; // The "<" symbol
+  private static final String PRODUCT_SELECTOR_DATASOURCE_UNEXPECTED_VALUE = "3DBB480253094C99A4408923F69806D7"; // Electricity
+
+  private static final String TABLE_ID = "105";
+  private static final String RECORD_ID = "283";
+  private static final String MANUAL_WHERE = "1=1) or 2=2";
+
+  private DataSource datasource;
+
+  @SuppressWarnings("serial")
+  private enum DataSource {
+    User("ADUser", USER_EXPECTED_VALUE, USER_UNEXPECTED_VALUE, false,
+        new HashMap<String, String>() {
+          {
+            put("isImplicitFilterApplied", "true");
+            put("windowId", "108");
+            put("tabId", "118");
+            put("_noActiveFilter", "true");
+            put("_startRow", "0");
+            put("_endRow", "100");
+          }
+        }, true), //
+    QuickLaunch("99B9CC42FDEA4CA7A4EE35BC49D61E0E", null, null, true,
+        new HashMap<String, String>() {
+          {
+            put("_startRow", "0");
+            put("_endRow", "50");
+          }
+        }), //
+
+    QuickCreate("C17951F970E942FD9F3771B7BE91D049", null, null, true,
+        new HashMap<String, String>() {
+          {
+            put("_startRow", "0");
+            put("_endRow", "50");
+          }
+        }), //
+
+    Alert("DB9F062472294F12A0291A7BD203F922", ALERT_EXPECTED_VALUE, ALERT_UNEXPECTED_VALUE, false,
+        new HashMap<String, String>() {
+          {
+            put("_alertStatus", "New");
+            put("_startRow", "0");
+            put("_endRow", "50");
+          }
+        }), //
+    ActionRegardingSelector("ADList", CUSTOM_QUERY_SELECTOR_EXPECTED_VALUE,
+        CUSTOM_QUERY_SELECTOR_UNEXPECTED_VALUE, false, new HashMap<String, String>() {
+          {
+            put("inpwindowId", "E547CE89D4C04429B6340FFA44E70716");
+            put("fin_paymentmethod_id", "47506D4260BA4996B92768FF609E6665");
+            put("fin_financial_account_id", "C2AA9C0AFB434FD4B827BE58DC52C1E2");
+            put("issotrx", "true");
+            put("_selectorDefinitionId", "41B3A5EA61AB46FBAF4567E3755BA190");
+            put("filterClass", "org.openbravo.userinterface.selector.SelectorDataSourceFilter");
+            put("_selectorFieldId", "52BD390363394BE980D0A55AFC4CDBB9");
+            put("_startRow", "0");
+            put("_endRow", "75");
+
+          }
+        }), //
+
+    ProductSelectorDataSource("ProductByPriceAndWarehouse",
+        PRODUCT_SELECTOR_DATASOURCE_EXPECTED_VALUE, PRODUCT_SELECTOR_DATASOURCE_UNEXPECTED_VALUE,
+        false, new HashMap<String, String>() {
+          {
+            put("_org", "E443A31992CB4635AFCAEABE7183CE85");
+            put("_startRow", "0");
+            put("_endRow", "75");
+          }
+        }), //
+
+    Note("090A37D22E61FE94012E621729090048", null, null, true, new HashMap<String, String>() {
+      {
+        // Note of a record in Windows, Tabs and Fields.
+        String criteria = "{\"fieldName\":\"table\",\"operator\":\"equals\",\"value\":\""
+            + TABLE_ID + "\"}__;__{\"fieldName\":\"record\",\"operator\":\"equals\",\"value\":\""
+            + RECORD_ID + "\"}";
+        String entityName = "OBUIAPP_Note";
+        put("criteria", criteria);
+        put("_entityName", entityName);
+        put("_startRow", "0");
+        put("_endRow", "50");
+      }
+    });
+
+    private String ds;
+    private String expected;
+    private String unexpected;
+    private boolean onlySuccessAssert;
+    private Map<String, String> params;
+    private boolean hasImplicitFilter;
+
+    private DataSource(String ds, String expected, String unexpected, boolean onlySuccessAssert) {
+      this.ds = ds;
+      this.expected = expected;
+      this.unexpected = unexpected;
+      this.onlySuccessAssert = onlySuccessAssert;
+      params = new HashMap<String, String>();
+      params.put("_operationType", "fetch");
+    }
+
+    private DataSource(String ds, String expected, String unexpected, boolean onlySuccessAssert,
+        Map<String, String> extraParams) {
+      this(ds, expected, unexpected, onlySuccessAssert);
+      params.putAll(extraParams);
+    }
+
+    private DataSource(String ds, String expected, String unexpected, boolean onlySuccessAssert,
+        Map<String, String> extraParams, boolean hasImplicitFilter) {
+      this(ds, expected, unexpected, onlySuccessAssert, extraParams);
+      this.hasImplicitFilter = hasImplicitFilter;
+    }
+  }
+
+  public DataSourceWhereParameter(DataSource datasource, String expectedRecords,
+      String notExpectedRecords) {
+    this.datasource = datasource;
+  }
+
+  @Parameters(name = "{0} datasource")
+  public static Collection<Object[]> parameters() {
+    List<Object[]> tests = new ArrayList<Object[]>();
+    for (DataSource t : DataSource.values()) {
+      tests.add(new Object[] { t, t.expected, t.unexpected });
+    }
+
+    return tests;
+  }
+
+  @Test
+  public void datasourceWithNoManualWhereParameter() throws Exception {
+    boolean isRecordPresent;
+    if (!datasource.onlySuccessAssert) {
+      if (datasource.hasImplicitFilter) {
+        datasource.params.put("isImplicitFilterApplied", "true");
+        isRecordPresent = isRecordPresentInTheResponse(datasource.expected);
+        assertThat("Record present.", isRecordPresent, is(true));
+        isRecordPresent = isRecordPresentInTheResponse(datasource.unexpected);
+        assertThat("Record not present.", isRecordPresent, is(false));
+        datasource.params.put("isImplicitFilterApplied", "false");
+        isRecordPresent = isRecordPresentInTheResponse(datasource.expected);
+        assertThat("Record present.", isRecordPresent, is(true));
+        isRecordPresent = isRecordPresentInTheResponse(datasource.unexpected);
+        assertThat("Record present.", isRecordPresent, is(true));
+
+      } else {
+        isRecordPresent = isRecordPresentInTheResponse(datasource.expected);
+        assertThat("Record present.", isRecordPresent, is(true));
+        isRecordPresent = isRecordPresentInTheResponse(datasource.unexpected);
+        assertThat("Record not present", isRecordPresent, is(false));
+      }
+    }
+  }
+
+  @Test
+  public void datasourceWithManualWhereParameter() throws Exception {
+    if (!datasource.onlySuccessAssert && !"DB9F062472294F12A0291A7BD203F922".equals(datasource.ds)) {
+      datasource.params.put("isImplicitFilterApplied", "true");
+      datasource.params.put("_where", MANUAL_WHERE);
+      String datasourceResponseWhereTrue = getDataSourceResponse();
+      JSONObject jsonResponse = new JSONObject(datasourceResponseWhereTrue);
+      assertThat("If a manual _where parameters is added, the request status should be -4.",
+          getStatus(jsonResponse),
+          is(String.valueOf(JsonConstants.RPCREQUEST_STATUS_VALIDATION_ERROR)));
+      datasource.params.remove(JsonConstants.WHERE_PARAMETER);
+    }
+  }
+
+  @Test
+  public void datasourceRequestStatusShouldBeSuccessful() throws Exception {
+    if (datasource.params.containsKey(JsonConstants.WHERE_PARAMETER)) {
+      datasource.params.remove(JsonConstants.WHERE_PARAMETER);
+    }
+    String datasourceResponse = getDataSourceResponse();
+    JSONObject jsonResponse = new JSONObject(datasourceResponse);
+    assertThat("The request status should be successful.", getStatus(jsonResponse),
+        is(String.valueOf(JsonConstants.RPCREQUEST_STATUS_SUCCESS)));
+  }
+
+  private boolean isRecordPresentInTheResponse(String expectedRecord) throws Exception {
+    boolean isExpectedRecordPresent;
+    String datasourceResponse = getDataSourceResponse();
+    isExpectedRecordPresent = isValueInTheResponseData(expectedRecord, datasourceResponse);
+    return isExpectedRecordPresent;
+  }
+
+  private boolean isValueInTheResponseData(String valueId, String dataSourceResponse)
+      throws Exception {
+    JSONObject dataSourceResponseMid = new JSONObject();
+    JSONArray dataSourceData = new JSONArray();
+    boolean existsValue = false;
+    JSONObject jsonResponse = new JSONObject(dataSourceResponse);
+    dataSourceResponseMid = jsonResponse.getJSONObject("response");
+    dataSourceData = dataSourceResponseMid.getJSONArray("data");
+    String dataSourceDataString = dataSourceData.toString();
+    if (dataSourceDataString.contains(valueId)) {
+      existsValue = true;
+    } else {
+      existsValue = false;
+    }
+    return existsValue;
+  }
+
+  private String getDataSourceResponse() throws Exception {
+    String response = doRequest("/org.openbravo.service.datasource/" + datasource.ds,
+        datasource.params, 200, "POST");
+    return response;
+  }
+
+  private String getStatus(JSONObject jsonResponse) throws JSONException {
+    return jsonResponse.getJSONObject("response").get("status").toString();
+  }
+}
--- a/src-test/src/org/openbravo/test/datasource/ProductSelectorDataSourceTest.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/src-test/src/org/openbravo/test/datasource/ProductSelectorDataSourceTest.java	Wed Apr 13 12:37:44 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2014 Openbravo SLU 
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -66,7 +66,14 @@
     Map<String, String> params = new HashMap<String, String>();
     params.put("_selectorDefinitionId", "4C8BC3E8E56441F4B8C98C684A0C9212");
     params.put("filterClass", "org.openbravo.userinterface.selector.SelectorDataSourceFilter");
-    params.put("_where", "e.active='Y'");
+
+    JSONObject criteria = new JSONObject();
+    criteria.put("fieldName", "active");
+    criteria.put("operator", "equals");
+    criteria.put("value", "true");
+    criteria.put("_constructor", "AdvancedCriteria");
+    params.put("criteria", criteria.toString());
+
     params.put("_sortBy", "_identifier");
     params.put("_requestType", "Window");
     params.put("_distinct", "storageBin$warehouse");
@@ -77,12 +84,11 @@
     params.put("_textMatchStyle", "substring");
 
     if (addFilter) {
-      JSONObject criteria = new JSONObject();
-      criteria.put("fieldName", "storageBin$warehouse$_identifier");
-      criteria.put("operator", "iContains");
-      criteria.put("value", "US");
-
-      params.put("criteria", criteria.toString());
+      JSONObject filterCriteria = new JSONObject();
+      filterCriteria.put("fieldName", "storageBin$warehouse$_identifier");
+      filterCriteria.put("operator", "iContains");
+      filterCriteria.put("value", "US");
+      params.put("criteria", filterCriteria.toString());
     }
 
     String response = doRequest("/org.openbravo.service.datasource/ProductStockView", params, 200,
@@ -92,5 +98,4 @@
     assertTrue("Response should have data", resp.has("data"));
     return resp;
   }
-
 }
--- a/src/org/openbravo/base/exception/OBSecurityException.java	Wed Apr 13 10:50:18 2016 +0200
+++ b/src/org/openbravo/base/exception/OBSecurityException.java	Wed Apr 13 12:37:44 2016 +0200
@@ -44,4 +44,9 @@
   public OBSecurityException(Throwable cause) {
     super(cause);
   }
+
+  public OBSecurityException(String message, boolean logException) {
+    super(message, logException);
+  }
+
 }