diff --git a/base/src/org/compiere/model/GridTab.java b/base/src/org/compiere/model/GridTab.java
index a7492a863e..998db567ba 100644
--- a/base/src/org/compiere/model/GridTab.java
+++ b/base/src/org/compiere/model/GridTab.java
@@ -99,10 +99,11 @@ import org.compiere.util.ValueNamePair;
*/
public class GridTab implements DataStatusListener, Evaluatee, Serializable
{
+
/**
*
*/
- private static final long serialVersionUID = -5882167959482156252L;
+ private static final long serialVersionUID = 7198494041906579986L;
public static final String DEFAULT_STATUS_MESSAGE = "NavigateOrUpdate";
@@ -112,13 +113,28 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
* MTab provides a property listener for changed rows and a
* DataStatusListener for communicating changes of the underlying data
* @param vo Value Object
+ * @param w
*/
public GridTab(GridTabVO vo, GridWindow w)
+ {
+ this(vo, w, false);
+ }
+
+ /**
+ * Create Tab (Model) from Value Object.
+ *
+ * MTab provides a property listener for changed rows and a
+ * DataStatusListener for communicating changes of the underlying data
+ * @param vo Value Object
+ * @param w
+ * @param virtual
+ */
+ public GridTab(GridTabVO vo, GridWindow w, boolean virtual)
{
m_window = w;
m_vo = vo;
// Create MTable
- m_mTable = new GridTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true);
+ m_mTable = new GridTable (m_vo.ctx, m_vo.AD_Table_ID, m_vo.TableName, m_vo.WindowNo, m_vo.TabNo, true, virtual);
m_mTable.setReadOnly(m_vo.IsReadOnly || m_vo.IsView);
m_mTable.setDeleteable(m_vo.IsDeleteable);
// Load Tab
@@ -637,7 +653,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getParentTabNo(), lc, true);
if (value == null || value.length() == 0)
value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc, true); // back compatibility
- }
+ }
// Same link value?
if (refresh)
@@ -3055,11 +3071,11 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
int parentLevel = currentLevel-1;
if (parentLevel < 0)
return tabNo;
- while (parentLevel != currentLevel)
- {
- tabNo--;
- currentLevel = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, tabNo, GridTab.CTX_TabLevel);
- }
+ while (parentLevel != currentLevel)
+ {
+ tabNo--;
+ currentLevel = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, tabNo, GridTab.CTX_TabLevel);
+ }
return tabNo;
}
} // GridTab
diff --git a/base/src/org/compiere/model/GridTable.java b/base/src/org/compiere/model/GridTable.java
index a49ff799a9..85f2e5f6a0 100644
--- a/base/src/org/compiere/model/GridTable.java
+++ b/base/src/org/compiere/model/GridTable.java
@@ -30,6 +30,9 @@ import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
@@ -85,7 +88,7 @@ public class GridTable extends AbstractTableModel
/**
*
*/
- private static final long serialVersionUID = 4273775926021737068L;
+ private static final long serialVersionUID = 6148998589248950598L;
/**
* JDBC Based Buffered Table
@@ -99,6 +102,23 @@ public class GridTable extends AbstractTableModel
*/
public GridTable(Properties ctx, int AD_Table_ID, String TableName, int WindowNo, int TabNo,
boolean withAccessControl)
+ {
+ this(ctx, AD_Table_ID, TableName, WindowNo, TabNo, withAccessControl, false);
+ }
+
+ /**
+ * JDBC Based Buffered Table
+ *
+ * @param ctx Properties
+ * @param AD_Table_ID table id
+ * @param TableName table name
+ * @param WindowNo window no
+ * @param TabNo tab no
+ * @param withAccessControl if true adds AD_Client/Org restrictuins
+ * @param virtual use virtual table mode if table is mark as high volume
+ */
+ public GridTable(Properties ctx, int AD_Table_ID, String TableName, int WindowNo, int TabNo,
+ boolean withAccessControl, boolean virtual)
{
super();
log.info(TableName);
@@ -108,6 +128,7 @@ public class GridTable extends AbstractTableModel
m_WindowNo = WindowNo;
m_TabNo = TabNo;
m_withAccessControl = withAccessControl;
+ m_virtual = virtual && MTable.get(ctx, AD_Table_ID).isHighVolume();
} // MTable
private static CLogger log = CLogger.getCLogger(GridTable.class.getName());
@@ -120,6 +141,11 @@ public class GridTable extends AbstractTableModel
private boolean m_withAccessControl;
private boolean m_readOnly = true;
private boolean m_deleteable = true;
+ //virtual table state variables
+ private boolean m_virtual;
+ private int m_cacheStart;
+ private int m_cacheEnd;
+ public static final String CTX_KeyColumnName = "KeyColumnName";
//
/** Rowcount */
@@ -296,7 +322,7 @@ public class GridTable extends AbstractTableModel
select.append(" FROM ").append(m_tableName);
m_SQL_Select = select.toString();
m_SQL_Count = "SELECT COUNT(*) FROM " + m_tableName;
- //BF [ 2910358 ]
+ //BF [ 2910358 ]
//Restore the Original Value for Key Column Name based in Tab Context Value
int parentTabNo = getParentTabNo();
String parentKey = Env.getContext(m_ctx, m_WindowNo, parentTabNo, GridTab.CTX_KeyColumnName, true);
@@ -304,8 +330,8 @@ public class GridTable extends AbstractTableModel
String currKey = Env.getContext(m_ctx, m_WindowNo, parentKey);
if (valueKey != null && valueKey.length() > 0 && parentKey != null && parentKey.length() > 0 && ! currKey.equals(valueKey))
{
- Env.setContext(m_ctx, m_WindowNo, parentKey, valueKey);
- }
+ Env.setContext(m_ctx, m_WindowNo, parentKey, valueKey);
+ }
StringBuffer where = new StringBuffer("");
// WHERE
@@ -356,7 +382,9 @@ public class GridTable extends AbstractTableModel
// ORDER BY
if (!m_orderClause.equals(""))
+ {
m_SQL += " ORDER BY " + m_orderClause;
+ }
//
log.fine(m_SQL_Count);
Env.setContext(m_ctx, m_WindowNo, m_TabNo, GridTab.CTX_SQL, m_SQL);
@@ -538,6 +566,11 @@ public class GridTable extends AbstractTableModel
return true;
}
+ if (m_virtual)
+ {
+ verifyVirtual();
+ }
+
// create m_SQL and m_countSQL
createSelectSql();
if (m_SQL == null || m_SQL.equals(""))
@@ -549,10 +582,19 @@ public class GridTable extends AbstractTableModel
// Start Loading
m_loader = new Loader();
m_rowCount = m_loader.open(maxRows);
- m_buffer = new ArrayList