IDEMPIERE-663 Zk: Remove the need of re-query for table editor after user have create a new record.

This commit is contained in:
Heng Sin Low 2013-02-25 19:57:24 +08:00
parent 4216a8caed
commit 486201c8b1
7 changed files with 197 additions and 4 deletions

View File

@ -2255,6 +2255,9 @@ public abstract class PO
m_createNew = false;
if (!newRecord)
CacheMgt.get().reset(p_info.getTableName());
else if (get_ID() > 0)
CacheMgt.get().newRecord(p_info.getTableName(), get_ID());
return success;
} // saveFinish

View File

@ -394,5 +394,8 @@ public class CCache<K,V> implements CacheInterface, Map<K, V>, Serializable
V removed = cache.remove(recordId);
return removed != null ? 1 : 0;
}
@Override
public void newRecord(int record_ID) {
}
} // CCache

View File

@ -41,6 +41,12 @@ public interface CacheInterface
* @return number of items
*/
public int size();
/**
* New record created notification
* @param record_ID
*/
public void newRecord(int record_ID);
} // CacheInterface

View File

@ -159,6 +159,24 @@ public class CacheMgt
}
}
/**
* do a cluster wide cache reset for tableName with recordId key
* @param tableName
* @param recordId record id for the cache entries to delete. pass -1 if you don't want to delete
* cache entries by record id
* @return number of deleted cache entries
*/
private void clusterNewRecord(String tableName, int recordId) {
IServiceHolder<IClusterService> holder = Service.locator().locate(IClusterService.class);
IClusterService service = holder.getService();
if (service != null) {
CacheNewRecordCallable callable = new CacheNewRecordCallable(tableName, recordId);
service.execute(callable, service.getMembers());
} else {
localNewRecord(tableName, recordId);
}
}
/**
* do a cluster wide cache reset
* @return number of deleted cache entries
@ -248,6 +266,36 @@ public class CacheMgt
return total;
}
/**
* Reset local Cache
* @param tableName table name
* @param Record_ID record if applicable or 0 for all
* @return number of deleted cache entries
*/
protected void localNewRecord (String tableName, int Record_ID)
{
if (tableName == null)
return;
if (!m_tableNames.contains(tableName))
return;
//
for (int i = 0; i < m_instances.size(); i++)
{
CacheInterface stored = (CacheInterface)m_instances.get(i);
if (stored != null && stored instanceof CCache)
{
CCache<?, ?> cc = (CCache<?, ?>)stored;
if (cc.getTableName() != null && cc.getTableName().startsWith(tableName)) // reset lines/dependent too
{
{
stored.newRecord(Record_ID);
}
}
}
}
}
/**
* Total Cached Elements
* @return count
@ -298,4 +346,8 @@ public class CacheMgt
.append("]");
return sb.toString ();
} // toString
public void newRecord(String tableName, int recordId) {
clusterNewRecord(tableName, recordId);
}
} // CCache

View File

@ -0,0 +1,47 @@
/******************************************************************************
* Copyright (C) 2013 Heng Sin Low *
* Copyright (C) 2013 Trek Global *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.compiere.util;
import java.io.Serializable;
import java.util.concurrent.Callable;
/**
*
* @author hengsin
*
*/
public class CacheNewRecordCallable implements Callable<Integer>, Serializable
{
/**
* generated serial id
*/
private static final long serialVersionUID = 6669645804211785491L;
private String tableName;
private int Record_ID;
protected CacheNewRecordCallable(String tableName, int Record_ID)
{
this.tableName = tableName;
this.Record_ID = Record_ID;
}
@Override
public Integer call() throws Exception {
CacheMgt.get().localNewRecord(tableName, Record_ID);
return 1;
}
}

View File

@ -118,6 +118,7 @@ public abstract class WEditor implements EventListener<Event>, PropertyChangeLis
this.gridField = gridField;
if (gridField.getGridTab() != null) {
comp.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, gridField.getGridTab().getTableName()+"0"+gridField.getColumnName());
this.gridTab = gridField.getGridTab();
} else {
comp.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, gridField.getColumnName());
}

View File

@ -43,13 +43,17 @@ import org.compiere.model.MBPartnerLocation;
import org.compiere.model.MLocation;
import org.compiere.model.MQuery;
import org.compiere.model.MTable;
import org.compiere.util.CCache;
import org.compiere.util.CLogger;
import org.compiere.util.CacheMgt;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.NamePair;
import org.compiere.util.ValueNamePair;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
@ -81,9 +85,12 @@ ContextMenuListener, IZoomableEditor
public static final String SHORT_LIST_EVENT = "SHORT_LIST"; // IDEMPIERE 90
protected boolean onlyShortListItems; // IDEMPIERE 90
private CCacheListener tableCacheListener;
public WTableDirEditor(GridField gridField)
{
super(new Combobox(), gridField);
super(new EditorCombobox(), gridField);
((EditorCombobox)getComponent()).editor = this;
lookup = gridField.getLookup();
init();
}
@ -100,7 +107,8 @@ ContextMenuListener, IZoomableEditor
*/
public WTableDirEditor(Lookup lookup, String label, String description, boolean mandatory, boolean readonly, boolean updateable)
{
super(new Combobox(), label, description, mandatory, readonly, updateable);
super(new EditorCombobox(), label, description, mandatory, readonly, updateable);
((EditorCombobox)getComponent()).editor = this;
if (lookup == null)
{
@ -123,7 +131,8 @@ ContextMenuListener, IZoomableEditor
public WTableDirEditor(String columnName, boolean mandatory, boolean isReadOnly, boolean isUpdateable,
Lookup lookup)
{
super(new Combobox(), columnName, null, null, mandatory, isReadOnly, isUpdateable);
super(new EditorCombobox(), columnName, null, null, mandatory, isReadOnly, isUpdateable);
((EditorCombobox)getComponent()).editor = this;
if (lookup == null)
{
throw new IllegalArgumentException("Lookup cannot be null");
@ -201,6 +210,12 @@ ContextMenuListener, IZoomableEditor
}
}
private void createCacheListener() {
String columnName = lookup.getColumnName();
String tableName = columnName.substring(0, columnName.indexOf("."));
tableCacheListener = new CCacheListener(tableName, this);
}
@Override
public String getDisplay()
{
@ -600,4 +615,70 @@ ContextMenuListener, IZoomableEditor
|| (isReadWrite() && lookup.getSize() != getComponent().getItemCount())))
this.actionRefresh();
}
private static class EditorCombobox extends Combobox {
/**
* generated serial id
*/
private static final long serialVersionUID = 4540856986889452983L;
protected WTableDirEditor editor;
@Override
public void onPageAttached(Page newpage, Page oldpage) {
super.onPageAttached(newpage, oldpage);
if (editor.tableCacheListener == null) {
editor.createCacheListener();
}
}
@Override
public void onPageDetached(Page page) {
super.onPageDetached(page);
if (editor.tableCacheListener != null) {
CacheMgt.get().unregister(editor.tableCacheListener);
editor.tableCacheListener = null;
}
}
}
private static class CCacheListener extends CCache<String, Object> {
/**
* generated serial
*/
private static final long serialVersionUID = 3543247404379028327L;
private WTableDirEditor editor;
protected CCacheListener(String tableName, WTableDirEditor editor) {
super(tableName, tableName, 0, true);
this.editor = editor;
}
@Override
public int reset() {
if (editor.getComponent().getDesktop() != null && editor.isReadWrite()) {
refreshLookupList();
}
return 0;
}
private void refreshLookupList() {
Executions.schedule(editor.getComponent().getDesktop(), new EventListener<Event>() {
@Override
public void onEvent(Event event) {
try {
if (editor.isReadWrite())
editor.actionRefresh();
} catch (Exception e) {}
}
}, new Event("onResetLookupList"));
}
@Override
public void newRecord(int record_ID) {
if (editor.getComponent().getDesktop() != null && editor.isReadWrite()) {
refreshLookupList();
}
}
}
}