IDEMPIERE-3627 Field and Process Parameter: @SQL support for Readonly logic

This commit is contained in:
Heng Sin Low 2018-01-22 22:36:33 +08:00
parent 9ce5c347cb
commit 0821aadd8c
1 changed files with 66 additions and 15 deletions

View File

@ -30,7 +30,9 @@ import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.logging.Level; import java.util.logging.Level;
@ -353,7 +355,7 @@ public class GridField
{ {
boolean retValue = false; boolean retValue = false;
if (m_vo.MandatoryLogic != null && m_vo.MandatoryLogic.startsWith("@SQL=")) { if (m_vo.MandatoryLogic != null && m_vo.MandatoryLogic.startsWith("@SQL=")) {
retValue = mandatorySqlStatement(); retValue = parseSQLLogic(m_vo.MandatoryLogic);
} else{ } else{
retValue= Evaluator.evaluateLogic(this, m_vo.MandatoryLogic); retValue= Evaluator.evaluateLogic(this, m_vo.MandatoryLogic);
@ -385,21 +387,46 @@ public class GridField
return isDisplayed (checkContext); return isDisplayed (checkContext);
} // isMandatory } // isMandatory
private boolean mandatorySqlStatement() { private boolean parseSQLLogic(String sqlLogic) {
String sql = m_vo.MandatoryLogic.substring(5); // w/o tag String sql = sqlLogic.substring(5); // remove @SQL=
sql = Env.parseContext(m_vo.ctx, m_vo.WindowNo, sql, false, false); // replace boolean reverse = false;
if (sql.startsWith("!")) {
reverse = true;
sql = sql.substring(1); //remove !
}
sql = Env.parseContext(m_vo.ctx, m_vo.WindowNo, m_vo.TabNo, sql, false, false); // replace
// variables // variables
if (sql.equals("")) { if (sql.equals("")) {
log.log(Level.WARNING,"(" + m_vo.ColumnName + ") - Mandatory SQL variable parse failed: " + m_vo.MandatoryLogic); log.log(Level.WARNING,"(" + m_vo.ColumnName + ") - SQL variable parse failed: " + sqlLogic);
} else { } else {
SQLLogicResult cache = sqlLogicCache.get(sql);
if (cache != null) {
long since = System.currentTimeMillis() - cache.timestamp;
if (since <= 500) {
cache.timestamp = System.currentTimeMillis();
if (cache.value)
return reverse ? false : true;
else
return reverse ? true : false;
}
}
PreparedStatement stmt = null; PreparedStatement stmt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
stmt = DB.prepareStatement(sql, null); stmt = DB.prepareStatement(sql, null);
rs = stmt.executeQuery(); rs = stmt.executeQuery();
if (rs.next()) boolean hasNext = rs.next();
return true; if (cache == null) {
cache = new SQLLogicResult();
sqlLogicCache.put(sql, cache);
}
cache.value = hasNext;
cache.timestamp = System.currentTimeMillis();
if (hasNext)
return reverse ? false : true;
else
return reverse ? true : false;
} catch (SQLException e) { } catch (SQLException e) {
log.log(Level.WARNING, "(" + m_vo.ColumnName + ") " + sql, e); log.log(Level.WARNING, "(" + m_vo.ColumnName + ") " + sql, e);
} finally { } finally {
@ -419,10 +446,19 @@ public class GridField
public boolean isEditablePara(boolean checkContext) { public boolean isEditablePara(boolean checkContext) {
if (checkContext && m_vo.ReadOnlyLogic.length() > 0) if (checkContext && m_vo.ReadOnlyLogic.length() > 0)
{ {
boolean retValue = !Evaluator.evaluateLogic(this, m_vo.ReadOnlyLogic); if (m_vo.ReadOnlyLogic.startsWith("@SQL="))
if (log.isLoggable(Level.FINEST)) log.finest(m_vo.ColumnName + " R/O(" + m_vo.ReadOnlyLogic + ") => R/W-" + retValue); {
if (!retValue) boolean retValue = !parseSQLLogic(m_vo.ReadOnlyLogic);
return false; if (!retValue)
return false;
}
else
{
boolean retValue = !Evaluator.evaluateLogic(this, m_vo.ReadOnlyLogic);
if (log.isLoggable(Level.FINEST)) log.finest(m_vo.ColumnName + " R/O(" + m_vo.ReadOnlyLogic + ") => R/W-" + retValue);
if (!retValue)
return false;
}
} }
// ultimately visibility decides // ultimately visibility decides
@ -522,10 +558,19 @@ public class GridField
// Do we have a readonly rule // Do we have a readonly rule
if (checkContext && m_vo.ReadOnlyLogic.length() > 0) if (checkContext && m_vo.ReadOnlyLogic.length() > 0)
{ {
boolean retValue = !Evaluator.evaluateLogic(this, m_vo.ReadOnlyLogic); if (m_vo.ReadOnlyLogic.startsWith("@SQL="))
if (log.isLoggable(Level.FINEST)) log.finest(m_vo.ColumnName + " R/O(" + m_vo.ReadOnlyLogic + ") => R/W-" + retValue); {
if (!retValue) boolean retValue = !parseSQLLogic(m_vo.ReadOnlyLogic);
return false; if (!retValue)
return false;
}
else
{
boolean retValue = !Evaluator.evaluateLogic(this, m_vo.ReadOnlyLogic);
if (log.isLoggable(Level.FINEST)) log.finest(m_vo.ColumnName + " R/O(" + m_vo.ReadOnlyLogic + ") => R/W-" + retValue);
if (!retValue)
return false;
}
} }
//BF [ 2910368 ] //BF [ 2910368 ]
@ -2516,4 +2561,10 @@ public class GridField
return m_lookupEditorSettingValue; return m_lookupEditorSettingValue;
} }
private final Map<String, SQLLogicResult> sqlLogicCache = new HashMap<>();
private class SQLLogicResult {
long timestamp;
boolean value;
}
} // GridField } // GridField