* Separate the new callout extension interface from the classic callout interface. this is to avoid confusion since the methodName argument is not used here and implementation is expected to implement the start method.

* Change the getCallout method to findCallout and return a list of registered callout for a column. Callout is not a singleton service and developer can register multiple callout per column
* Make consistent with current semantic where callout is not invoke if record is processed and not always updateable.
* Make consistent with current semantic where only non empty string return from the callout instance is return to the caller as an error message string.
This commit is contained in:
Heng Sin Low 2010-03-09 00:27:33 +00:00
parent f73caa3e98
commit 052a829023
5 changed files with 177 additions and 100 deletions

View File

@ -58,7 +58,7 @@ Instead, you specify Table and Column in the extension declaration.
</documentation> </documentation>
<appinfo> <appinfo>
<meta.attribute kind="java" basedOn=":org.compiere.model.Callout"/> <meta.attribute kind="java" basedOn=":org.adempiere.base.IColumnCallout"/>
</appinfo> </appinfo>
</annotation> </annotation>
</attribute> </attribute>

View File

@ -9,14 +9,14 @@ import org.compiere.model.Callout;
/** /**
* This is a facade class for the Service Locator. * This is a facade class for the Service Locator.
* It provides simple access to all core services. * It provides simple access to all core services.
* *
* @author viola * @author viola
*/ */
public class Core { public class Core {
public static IResourceFinder getResourceFinder() { public static IResourceFinder getResourceFinder() {
return new IResourceFinder() { return new IResourceFinder() {
public URL getResource(String name) { public URL getResource(String name) {
List<IResourceFinder> f = Service.list(IResourceFinder.class); List<IResourceFinder> f = Service.list(IResourceFinder.class);
for (IResourceFinder finder : f) { for (IResourceFinder finder : f) {
@ -29,13 +29,13 @@ public class Core {
}; };
} }
public static Callout getCallout(String tableName, String columnName) { public static List<IColumnCallout> findCallout(String tableName, String columnName) {
ServiceQuery query = new ServiceQuery(); ServiceQuery query = new ServiceQuery();
query.put("tableName", tableName); query.put("tableName", tableName);
query.put("columnName", columnName); query.put("columnName", columnName);
return Service.locate(Callout.class, query); return Service.list(IColumnCallout.class, query);
} }
} }

View File

@ -0,0 +1,48 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
* 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. *
* For the text or an alternative of this public license, you may reach us *
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
* or via info@compiere.org or http://www.compiere.org/license.html *
*****************************************************************************/
package org.adempiere.base;
import java.util.Properties;
import org.compiere.model.GridField;
import org.compiere.model.GridTab;
/**
* Column Callout Interface
*/
public interface IColumnCallout extends IService
{
/**
* Start Callout.
* <p>
* Callout's are used for cross field validation and setting values in other fields
* when returning a non empty (error message) string, an exception is raised
* <p>
* When invoked, the Tab model has the new value!
*
* @param ctx Context
* @param WindowNo current Window No
* @param mTab Model Tab
* @param mField Model Field
* @param value The new value
* @param oldValue The old value
* @return Error message or ""
*/
public String start (Properties ctx, int WindowNo,
GridTab mTab, GridField mField, Object value, Object oldValue);
}

View File

@ -27,7 +27,7 @@ import org.adempiere.base.IService;
* @author Jorg Janke * @author Jorg Janke
* @version $Id: Callout.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $ * @version $Id: Callout.java,v 1.2 2006/07/30 00:51:05 jjanke Exp $
*/ */
public interface Callout extends IService public interface Callout
{ {
/** /**
* Start Callout. * Start Callout.

View File

@ -38,6 +38,7 @@ import javax.script.ScriptEngine;
import javax.swing.event.EventListenerList; import javax.swing.event.EventListenerList;
import org.adempiere.base.Core; import org.adempiere.base.Core;
import org.adempiere.base.IColumnCallout;
import org.adempiere.base.Service; import org.adempiere.base.Service;
import org.compiere.util.CLogMgt; import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
@ -72,7 +73,7 @@ import org.compiere.util.ValueNamePair;
* </pre> * </pre>
* @author Jorg Janke * @author Jorg Janke
* @version $Id: GridTab.java,v 1.10 2006/10/02 05:18:39 jjanke Exp $ * @version $Id: GridTab.java,v 1.10 2006/10/02 05:18:39 jjanke Exp $
* *
* @author Teo Sarca, SC ARHIPAC SERVICE SRL * @author Teo Sarca, SC ARHIPAC SERVICE SRL
* <li>BF [ 1742159 ] Editable number field for inactive record * <li>BF [ 1742159 ] Editable number field for inactive record
* <li>BF [ 1968598 ] Callout is not called if tab is processed * <li>BF [ 1968598 ] Callout is not called if tab is processed
@ -86,7 +87,7 @@ import org.compiere.util.ValueNamePair;
* https://sourceforge.net/tracker/?func=detail&aid=2874109&group_id=176962&atid=879332 * https://sourceforge.net/tracker/?func=detail&aid=2874109&group_id=176962&atid=879332
* <li>BF [ 2905287 ] GridTab query is not build correctly * <li>BF [ 2905287 ] GridTab query is not build correctly
* https://sourceforge.net/tracker/?func=detail&aid=2905287&group_id=176962&atid=879332 * https://sourceforge.net/tracker/?func=detail&aid=2905287&group_id=176962&atid=879332
* @author Victor Perez , e-Evolution.SC * @author Victor Perez , e-Evolution.SC
* <li>FR [1877902] Implement JSR 223 Scripting APIs to Callout * <li>FR [1877902] Implement JSR 223 Scripting APIs to Callout
* <li>BF [ 2910358 ] Error in context when a field is found in different tabs. * <li>BF [ 2910358 ] Error in context when a field is found in different tabs.
* https://sourceforge.net/tracker/?func=detail&aid=2910358&group_id=176962&atid=879332 * https://sourceforge.net/tracker/?func=detail&aid=2910358&group_id=176962&atid=879332
@ -102,12 +103,12 @@ import org.compiere.util.ValueNamePair;
public class GridTab implements DataStatusListener, Evaluatee, Serializable public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
/** /**
* *
*/ */
private static final long serialVersionUID = -8762357519103152929L; private static final long serialVersionUID = -8762357519103152929L;
public static final String DEFAULT_STATUS_MESSAGE = "NavigateOrUpdate"; public static final String DEFAULT_STATUS_MESSAGE = "NavigateOrUpdate";
/** /**
* Create Tab (Model) from Value Object. * Create Tab (Model) from Value Object.
* <p> * <p>
@ -120,7 +121,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
this(vo, w, false); this(vo, w, false);
} }
/** /**
* Create Tab (Model) from Value Object. * Create Tab (Model) from Value Object.
* <p> * <p>
@ -196,13 +197,13 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
/** Logger */ /** Logger */
protected CLogger log = CLogger.getCLogger(getClass()); protected CLogger log = CLogger.getCLogger(getClass());
private boolean m_parentNeedSave = false; private boolean m_parentNeedSave = false;
private long m_lastDataStatusEventTime; private long m_lastDataStatusEventTime;
private DataStatusEvent m_lastDataStatusEvent; private DataStatusEvent m_lastDataStatusEvent;
// Context property names: // Context property names:
public static final String CTX_KeyColumnName = "_TabInfo_KeyColumnName"; public static final String CTX_KeyColumnName = "_TabInfo_KeyColumnName";
public static final String CTX_LinkColumnName = "_TabInfo_LinkColumnName"; public static final String CTX_LinkColumnName = "_TabInfo_LinkColumnName";
@ -213,7 +214,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
public static final String CTX_AD_Table_ID = "_TabInfo_AD_Table_ID"; public static final String CTX_AD_Table_ID = "_TabInfo_AD_Table_ID";
public static final String CTX_FindSQL = "_TabInfo_FindSQL"; public static final String CTX_FindSQL = "_TabInfo_FindSQL";
public static final String CTX_SQL = "_TabInfo_SQL"; public static final String CTX_SQL = "_TabInfo_SQL";
/************************************************************************** /**************************************************************************
@ -258,7 +259,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
return m_loadComplete; return m_loadComplete;
} }
/** /**
* Initialize Tab with record from AD_Tab_v * Initialize Tab with record from AD_Tab_v
* @param async async * @param async async
@ -268,7 +269,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
log.fine("#" + m_vo.TabNo + " - Async=" + async + " - Where=" + m_vo.WhereClause); log.fine("#" + m_vo.TabNo + " - Async=" + async + " - Where=" + m_vo.WhereClause);
if (isLoadComplete()) return true; if (isLoadComplete()) return true;
if (m_loader != null && m_loader.isAlive()) if (m_loader != null && m_loader.isAlive())
{ {
waitLoadCompete(); waitLoadCompete();
@ -289,9 +290,9 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
} // initTab } // initTab
protected boolean loadTab() protected boolean loadTab()
{ {
m_extendedWhere = m_vo.WhereClause; m_extendedWhere = m_vo.WhereClause;
// Get Field Data // Get Field Data
if (!loadFields()) if (!loadFields())
{ {
@ -305,7 +306,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
m_loadComplete = true; m_loadComplete = true;
return true; return true;
} }
/** /**
* Dispose - clean up resources * Dispose - clean up resources
*/ */
@ -412,7 +413,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
} }
} // for all fields } // for all fields
if (! m_mTable.getTableName().equals(X_AD_PInstance_Log.Table_Name)) { // globalqss, bug 1662433 if (! m_mTable.getTableName().equals(X_AD_PInstance_Log.Table_Name)) { // globalqss, bug 1662433
// Add Standard Fields // Add Standard Fields
if (m_mTable.getField("Created") == null) if (m_mTable.getField("Created") == null)
{ {
@ -609,7 +610,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows) public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows)
{ {
if (!m_loadComplete) initTab(false); if (!m_loadComplete) initTab(false);
log.fine("#" + m_vo.TabNo log.fine("#" + m_vo.TabNo
+ " - Only Current Rows=" + onlyCurrentRows + " - Only Current Rows=" + onlyCurrentRows
+ ", Days=" + onlyCurrentDays + ", Detail=" + isDetail()); + ", Days=" + onlyCurrentDays + ", Detail=" + isDetail());
@ -645,7 +646,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
String value = null; String value = null;
if ( m_parentColumnName.length() > 0 ) if ( m_parentColumnName.length() > 0 )
{ {
// explicit parent link defined // explicit parent link defined
value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getParentTabNo(), m_parentColumnName, true); value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getParentTabNo(), m_parentColumnName, true);
if (value == null || value.length() == 0) if (value == null || value.length() == 0)
@ -654,8 +655,8 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getParentTabNo(), lc, true); value = Env.getContext(m_vo.ctx, m_vo.WindowNo, getParentTabNo(), lc, true);
if (value == null || value.length() == 0) if (value == null || value.length() == 0)
value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc, true); // back compatibility value = Env.getContext(m_vo.ctx, m_vo.WindowNo, lc, true); // back compatibility
} }
// Same link value? // Same link value?
if (refresh) if (refresh)
refresh = m_linkValue.equals(value); refresh = m_linkValue.equals(value);
@ -933,25 +934,25 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
if (hasChangedCurrentTabAndParents()) if (hasChangedCurrentTabAndParents())
return false; return false;
boolean retValue = (m_mTable.dataSave(manualCmd) == GridTable.SAVE_OK); boolean retValue = (m_mTable.dataSave(manualCmd) == GridTable.SAVE_OK);
if (manualCmd) if (manualCmd)
{ {
setCurrentRow(m_currentRow, false); setCurrentRow(m_currentRow, false);
if (m_lastDataStatusEvent != null && m_lastDataStatusEvent.getCurrentRow() == m_currentRow if (m_lastDataStatusEvent != null && m_lastDataStatusEvent.getCurrentRow() == m_currentRow
&& ((m_lastDataStatusEvent.Record_ID != null && m_lastDataStatusEvent.Record_ID instanceof Integer && ((m_lastDataStatusEvent.Record_ID != null && m_lastDataStatusEvent.Record_ID instanceof Integer
&& (Integer) m_lastDataStatusEvent.Record_ID == 0) || m_lastDataStatusEvent.Record_ID == null)) && (Integer) m_lastDataStatusEvent.Record_ID == 0) || m_lastDataStatusEvent.Record_ID == null))
{ {
updateDataStatusEventProperties(m_lastDataStatusEvent); updateDataStatusEventProperties(m_lastDataStatusEvent);
} }
} }
fireStateChangeEvent(new StateChangeEvent(this, StateChangeEvent.DATA_SAVE)); fireStateChangeEvent(new StateChangeEvent(this, StateChangeEvent.DATA_SAVE));
if (retValue) { if (retValue) {
// refresh parent tabs // refresh parent tabs
refreshParents(); refreshParents();
} }
return retValue; return retValue;
} }
catch (Exception e) catch (Exception e)
@ -1052,7 +1053,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
log.fine("#" + m_vo.TabNo); log.fine("#" + m_vo.TabNo);
m_mTable.dataIgnore(); m_mTable.dataIgnore();
setCurrentRow(m_currentRow, false); // re-load data setCurrentRow(m_currentRow, false); // re-load data
fireStateChangeEvent(new StateChangeEvent(this, StateChangeEvent.DATA_IGNORE)); fireStateChangeEvent(new StateChangeEvent(this, StateChangeEvent.DATA_IGNORE));
log.fine("#" + m_vo.TabNo + "- fini"); log.fine("#" + m_vo.TabNo + "- fini");
} // dataIgnore } // dataIgnore
@ -1085,11 +1086,11 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
} }
log.finest("Processed=" + processed); log.finest("Processed=" + processed);
} }
//hengsin, dont create new when parent is empty //hengsin, dont create new when parent is empty
if (isDetail() && m_parentNeedSave) if (isDetail() && m_parentNeedSave)
return false; return false;
/** /**
* temporary set currentrow to point to the new row to ensure even cause by m_mTable.dataNew * temporary set currentrow to point to the new row to ensure even cause by m_mTable.dataNew
* is handle properly. * is handle properly.
@ -1101,7 +1102,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
if (!retValue) if (!retValue)
return retValue; return retValue;
setCurrentRow(m_currentRow + 1, true); setCurrentRow(m_currentRow + 1, true);
// process all Callouts (no dependency check - assumed that settings are valid) // process all Callouts (no dependency check - assumed that settings are valid)
for (int i = 0; i < getFieldCount(); i++) for (int i = 0; i < getFieldCount(); i++)
processCallout(getField(i)); processCallout(getField(i));
@ -1112,7 +1113,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
getField(i).validateValue(); getField(i).validateValue();
} }
m_mTable.setChanged(false); m_mTable.setChanged(false);
fireStateChangeEvent(new StateChangeEvent(this, StateChangeEvent.DATA_NEW)); fireStateChangeEvent(new StateChangeEvent(this, StateChangeEvent.DATA_NEW));
return retValue; return retValue;
} // dataNew } // dataNew
@ -1193,7 +1194,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
return m_keyColumnName; return m_keyColumnName;
} // getKeyColumnName } // getKeyColumnName
/** /**
* Set Name of the Key Column * Set Name of the Key Column
* @param keyColumnName * @param keyColumnName
@ -1226,9 +1227,9 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
m_parentColumnName = DB.getSQLValueString(null, sql, m_vo.Parent_Column_ID ); m_parentColumnName = DB.getSQLValueString(null, sql, m_vo.Parent_Column_ID );
if ( m_parentColumnName == null ) if ( m_parentColumnName == null )
m_parentColumnName = ""; m_parentColumnName = "";
if (linkColumnName != null) if (linkColumnName != null)
m_linkColumnName = linkColumnName; m_linkColumnName = linkColumnName;
else else
@ -1344,7 +1345,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
*/ */
public boolean isDetail() public boolean isDetail()
{ {
// First Tab Level is not a detail // First Tab Level is not a detail
if (m_vo.TabLevel == 0) if (m_vo.TabLevel == 0)
return false; return false;
// We have IsParent columns and/or a link column // We have IsParent columns and/or a link column
@ -1406,7 +1407,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
if (m_vo.IsReadOnly) if (m_vo.IsReadOnly)
return true; return true;
//hengsin, make detail readonly when parent is empty //hengsin, make detail readonly when parent is empty
if (m_parentNeedSave) return true; if (m_parentNeedSave) return true;
@ -1790,7 +1791,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
DB.close(rs, pstmt); DB.close(rs, pstmt);
rs = null; pstmt = null; rs = null; pstmt = null;
} }
if (filled) if (filled)
return mf.format (arguments); return mf.format (arguments);
return " "; return " ";
@ -1857,7 +1858,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
DB.close(rs, pstmt); DB.close(rs, pstmt);
rs = null; pstmt = null; rs = null; pstmt = null;
} }
if (filled) if (filled)
return mf.format (arguments); return mf.format (arguments);
return " "; return " ";
@ -1935,7 +1936,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
if (colFax != null && (colFax.getVFormat() == null || colFax.getVFormat().length() == 0)) if (colFax != null && (colFax.getVFormat() == null || colFax.getVFormat().length() == 0))
fFax.setVFormat(phone_frm); fFax.setVFormat(phone_frm);
} }
} // loadDependentInfo } // loadDependentInfo
@ -2202,11 +2203,11 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
} }
else // Redistribute Info with current row info else // Redistribute Info with current row info
fireDataStatusChanged(m_DataStatusEvent); fireDataStatusChanged(m_DataStatusEvent);
//reset //reset
m_lastDataStatusEventTime = System.currentTimeMillis(); m_lastDataStatusEventTime = System.currentTimeMillis();
m_lastDataStatusEvent = m_DataStatusEvent; m_lastDataStatusEvent = m_DataStatusEvent;
m_DataStatusEvent = null; m_DataStatusEvent = null;
// log.fine("dataStatusChanged #" + m_vo.TabNo + "- fini", e.toString()); // log.fine("dataStatusChanged #" + m_vo.TabNo + "- fini", e.toString());
} // dataStatusChanged } // dataStatusChanged
@ -2325,9 +2326,9 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
// Row range check // Row range check
int newRow = verifyRow(targetRow); int newRow = verifyRow(targetRow);
// Check, if we have old uncommitted data // Check, if we have old uncommitted data
if (m_mTable.dataSave(newRow, false) == false) if (m_mTable.dataSave(newRow, false) == false)
return m_currentRow; return m_currentRow;
//remove/ignore new and unchange row //remove/ignore new and unchange row
@ -2337,7 +2338,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
newRow--; newRow--;
dataIgnore(); dataIgnore();
} }
// new position // new position
return setCurrentRow(newRow, true); return setCurrentRow(newRow, true);
} // navigate } // navigate
@ -2427,7 +2428,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
// Object value = null; // Object value = null;
// if (mField.isKey() || mField.isParent() || mField.getColumnName().equals(m_linkColumnName)) // if (mField.isKey() || mField.isParent() || mField.getColumnName().equals(m_linkColumnName))
// value = mField.getDefault(); // value = mField.getDefault();
// CarlosRuiz - globalqss [ 1881480 ] Navigation problem between tabs // CarlosRuiz - globalqss [ 1881480 ] Navigation problem between tabs
// the implementation of linking with window context variables is very weak // the implementation of linking with window context variables is very weak
// you must be careful when defining a column in a detail tab with a field // you must be careful when defining a column in a detail tab with a field
@ -2453,7 +2454,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
m_DataStatusEvent = m_lastDataStatusEvent; m_DataStatusEvent = m_lastDataStatusEvent;
} }
// inform APanel/.. -> dataStatus with row updated // inform APanel/.. -> dataStatus with row updated
if (m_DataStatusEvent == null) if (m_DataStatusEvent == null)
m_DataStatusEvent = new DataStatusEvent(this, getRowCount(), m_DataStatusEvent = new DataStatusEvent(this, getRowCount(),
@ -2465,10 +2466,10 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
if (status == null || status.length() == 0) if (status == null || status.length() == 0)
m_DataStatusEvent.setInfo(DEFAULT_STATUS_MESSAGE, null, false,false); m_DataStatusEvent.setInfo(DEFAULT_STATUS_MESSAGE, null, false,false);
fireDataStatusChanged(m_DataStatusEvent); fireDataStatusChanged(m_DataStatusEvent);
//reset //reset
m_DataStatusEvent = null; m_DataStatusEvent = null;
return m_currentRow; return m_currentRow;
} // setCurrentRow } // setCurrentRow
@ -2565,10 +2566,10 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
return "NoField"; return "NoField";
log.fine(field.getColumnName() + "=" + value + " - Row=" + m_currentRow); log.fine(field.getColumnName() + "=" + value + " - Row=" + m_currentRow);
if (DisplayType.isID(field.getDisplayType()) && value instanceof Integer && ((Integer)value).intValue() < 0) if (DisplayType.isID(field.getDisplayType()) && value instanceof Integer && ((Integer)value).intValue() < 0)
value = null; value = null;
int col = m_mTable.findColumn(field.getColumnName()); int col = m_mTable.findColumn(field.getColumnName());
m_mTable.setValueAt(value, m_currentRow, col, false); m_mTable.setValueAt(value, m_currentRow, col, false);
// //
@ -2643,12 +2644,12 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
} // for all dependent fields } // for all dependent fields
} // processDependencies } // processDependencies
private List<String> activeCallouts = new ArrayList<String>(); private List<String> activeCallouts = new ArrayList<String>();
private List<Callout> activeCalloutInstance = new ArrayList<Callout>(); private List<Callout> activeCalloutInstance = new ArrayList<Callout>();
/** /**
* *
* @return list of active call out for this tab * @return list of active call out for this tab
*/ */
public String[] getActiveCallouts() public String[] getActiveCallouts()
@ -2656,9 +2657,9 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
String[] list = new String[activeCallouts.size()]; String[] list = new String[activeCallouts.size()];
return activeCallouts.toArray(list); return activeCallouts.toArray(list);
} }
/** /**
* *
* @return list of active call out instance for this tab * @return list of active call out instance for this tab
*/ */
public Callout[] getActiveCalloutInstance() public Callout[] getActiveCalloutInstance()
@ -2684,20 +2685,48 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
*/ */
public String processCallout (GridField field) public String processCallout (GridField field)
{ {
Object value = field.getValue();
Object oldValue = field.getOldValue();
Callout co = Core.getCallout(getTableName(), field.getColumnName());
if (co!=null) {
return co.start(m_vo.ctx, "", m_vo.WindowNo, this, field, value, oldValue);
}
String callout = field.getCallout();
if (callout.length() == 0)
return "";
// //
if (isProcessed() && !field.isAlwaysUpdateable()) // only active records if (isProcessed() && !field.isAlwaysUpdateable()) // only active records
return ""; // "DocProcessed"; return ""; // "DocProcessed";
Object value = field.getValue();
Object oldValue = field.getOldValue();
List<IColumnCallout> callouts = Core.findCallout(getTableName(), field.getColumnName());
if (callouts != null && !callouts.isEmpty()) {
for(IColumnCallout co : callouts)
{
String retValue = "";
String cmd = co.getClass().getName();
//detect infinite loop
if (activeCallouts.contains(cmd)) continue;
try
{
activeCallouts.add(cmd);
retValue = co.start(m_vo.ctx, m_vo.WindowNo, this, field, value, oldValue);
}
catch (Exception e)
{
log.log(Level.SEVERE, "start", e);
retValue = "Callout Invalid: " + e.toString();
return retValue;
}
finally
{
activeCallouts.remove(cmd);
}
if (!Util.isEmpty(retValue)) // interrupt on first error
{
log.severe (retValue);
return retValue;
}
}
}
String callout = field.getCallout();
if (callout.length() == 0)
return "";
log.fine(field.getColumnName() + "=" + value log.fine(field.getColumnName() + "=" + value
+ " (" + callout + ") - old=" + oldValue); + " (" + callout + ") - old=" + oldValue);
@ -2705,26 +2734,26 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
while (st.hasMoreTokens()) // for each callout while (st.hasMoreTokens()) // for each callout
{ {
String cmd = st.nextToken().trim(); String cmd = st.nextToken().trim();
//detect infinite loop //detect infinite loop
if (activeCallouts.contains(cmd)) continue; if (activeCallouts.contains(cmd)) continue;
String retValue = ""; String retValue = "";
// FR [1877902] // FR [1877902]
// CarlosRuiz - globalqss - implement beanshell callout // CarlosRuiz - globalqss - implement beanshell callout
// Victor Perez - vpj-cd implement JSR 223 Scripting // Victor Perez - vpj-cd implement JSR 223 Scripting
if (cmd.toLowerCase().startsWith(MRule.SCRIPT_PREFIX)) { if (cmd.toLowerCase().startsWith(MRule.SCRIPT_PREFIX)) {
MRule rule = MRule.get(m_vo.ctx, cmd.substring(MRule.SCRIPT_PREFIX.length())); MRule rule = MRule.get(m_vo.ctx, cmd.substring(MRule.SCRIPT_PREFIX.length()));
if (rule == null) { if (rule == null) {
retValue = "Callout " + cmd + " not found"; retValue = "Callout " + cmd + " not found";
log.log(Level.SEVERE, retValue); log.log(Level.SEVERE, retValue);
return retValue; return retValue;
} }
if ( ! (rule.getEventType().equals(MRule.EVENTTYPE_Callout) if ( ! (rule.getEventType().equals(MRule.EVENTTYPE_Callout)
&& rule.getRuleType().equals(MRule.RULETYPE_JSR223ScriptingAPIs))) { && rule.getRuleType().equals(MRule.RULETYPE_JSR223ScriptingAPIs))) {
retValue = "Callout " + cmd retValue = "Callout " + cmd
+ " must be of type JSR 223 and event Callout"; + " must be of type JSR 223 and event Callout";
log.log(Level.SEVERE, retValue); log.log(Level.SEVERE, retValue);
return retValue; return retValue;
} }
@ -2734,7 +2763,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
// Window context are W_ // Window context are W_
// Login context are G_ // Login context are G_
MRule.setContext(engine, m_vo.ctx, m_vo.WindowNo); MRule.setContext(engine, m_vo.ctx, m_vo.WindowNo);
// now add the callout parameters windowNo, tab, field, value, oldValue to the engine // now add the callout parameters windowNo, tab, field, value, oldValue to the engine
// Method arguments context are A_ // Method arguments context are A_
engine.put(MRule.ARGUMENTS_PREFIX + "WindowNo", m_vo.WindowNo); engine.put(MRule.ARGUMENTS_PREFIX + "WindowNo", m_vo.WindowNo);
engine.put(MRule.ARGUMENTS_PREFIX + "Tab", this); engine.put(MRule.ARGUMENTS_PREFIX + "Tab", this);
@ -2743,7 +2772,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
engine.put(MRule.ARGUMENTS_PREFIX + "OldValue", oldValue); engine.put(MRule.ARGUMENTS_PREFIX + "OldValue", oldValue);
engine.put(MRule.ARGUMENTS_PREFIX + "Ctx", m_vo.ctx); engine.put(MRule.ARGUMENTS_PREFIX + "Ctx", m_vo.ctx);
try try
{ {
activeCallouts.add(cmd); activeCallouts.add(cmd);
retValue = engine.eval(rule.getScript()).toString(); retValue = engine.eval(rule.getScript()).toString();
@ -2758,7 +2787,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
activeCallouts.remove(cmd); activeCallouts.remove(cmd);
} }
} else { } else {
Callout call = null; Callout call = null;
@ -2799,9 +2828,9 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
activeCallouts.remove(cmd); activeCallouts.remove(cmd);
activeCalloutInstance.remove(call); activeCalloutInstance.remove(call);
} }
} }
if (!Util.isEmpty(retValue)) // interrupt on first error if (!Util.isEmpty(retValue)) // interrupt on first error
{ {
log.severe (retValue); log.severe (retValue);
@ -2870,7 +2899,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
return null; return null;
return m_mTable.getValueAt(row, col); return m_mTable.getValueAt(row, col);
} // getValue } // getValue
/* /*
public boolean isNeedToSaveParent() public boolean isNeedToSaveParent()
{ {
@ -2924,11 +2953,11 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
{ {
m_listenerList.add(DataStatusListener.class, l); m_listenerList.add(DataStatusListener.class, l);
} }
/** /**
* @param l * @param l
*/ */
public synchronized void addStateChangeListener(StateChangeListener l) public synchronized void addStateChangeListener(StateChangeListener l)
{ {
m_listenerList.add(StateChangeListener.class, l); m_listenerList.add(StateChangeListener.class, l);
} }
@ -2936,11 +2965,11 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
/** /**
* @param l * @param l
*/ */
public synchronized void removeStateChangeListener(StateChangeListener l) public synchronized void removeStateChangeListener(StateChangeListener l)
{ {
m_listenerList.remove(StateChangeListener.class, l); m_listenerList.remove(StateChangeListener.class, l);
} }
/** /**
* Feature Request [1707462] * Feature Request [1707462]
* Enable runtime change of VFormat * Enable runtime change of VFormat
@ -2951,7 +2980,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
public void setFieldVFormat (String identifier, String strNewFormat) public void setFieldVFormat (String identifier, String strNewFormat)
{ {
m_mTable.setFieldVFormat(identifier, strNewFormat); m_mTable.setFieldVFormat(identifier, strNewFormat);
} // setFieldVFormat } // setFieldVFormat
/** /**
* Switches the line/seqNo of the two rows * Switches the line/seqNo of the two rows
@ -3010,10 +3039,10 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
if (lineNoCurrentRow >= 9900 if (lineNoCurrentRow >= 9900
|| lineNoNextRow >= 9900) { || lineNoNextRow >= 9900) {
log.fine("don't sort - might be special lines"); log.fine("don't sort - might be special lines");
return; return;
} }
// switch the line numbers and save new values // switch the line numbers and save new values
m_mTable.setValueAt(lineNoCurrentRow, to, lineCol); m_mTable.setValueAt(lineNoCurrentRow, to, lineCol);
setCurrentRow(to, false); setCurrentRow(to, false);
m_mTable.dataSave(true); m_mTable.dataSave(true);
@ -3028,7 +3057,7 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
} }
navigate(to); navigate(to);
} }
private void fireStateChangeEvent(StateChangeEvent e) private void fireStateChangeEvent(StateChangeEvent e)
{ {
StateChangeListener[] listeners = m_listenerList.getListeners(StateChangeListener.class); StateChangeListener[] listeners = m_listenerList.getListeners(StateChangeListener.class);
@ -3037,11 +3066,11 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
for(int i = 0; i < listeners.length; i++) { for(int i = 0; i < listeners.length; i++) {
listeners[i].stateChange(e); listeners[i].stateChange(e);
} }
} }
/** /**
* *
* @return list of all tabs included in this tab * @return list of all tabs included in this tab
*/ */
public List<GridTab> getIncludedTabs() public List<GridTab> getIncludedTabs()
@ -3064,8 +3093,8 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
} }
return list; return list;
} }
//BF [ 2910358 ] //BF [ 2910358 ]
/** /**
* get Parent Tab No * get Parent Tab No
* @return Tab No * @return Tab No
@ -3079,9 +3108,9 @@ public class GridTab implements DataStatusListener, Evaluatee, Serializable
return tabNo; return tabNo;
while (parentLevel != currentLevel) while (parentLevel != currentLevel)
{ {
tabNo--; tabNo--;
currentLevel = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, tabNo, GridTab.CTX_TabLevel); currentLevel = Env.getContextAsInt(m_vo.ctx, m_vo.WindowNo, tabNo, GridTab.CTX_TabLevel);
} }
return tabNo; return tabNo;
} }
} // GridTab } // GridTab