/** * */ package org.adempiere.util; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.Vector; import org.compiere.model.GridField; import org.compiere.model.GridTab; import org.compiere.model.GridTable; import org.compiere.util.Env; import org.compiere.util.Evaluatee; import org.compiere.util.KeyNamePair; import org.compiere.util.ValueNamePair; /** * Context (Properties) wrapper to be able to evaluate grid row context * @author Teo Sarca, teo.sarca@gmail.com */ public class GridRowCtx extends Properties implements Evaluatee { /** * generated serial id */ private static final long serialVersionUID = 8163657930039348267L; private final Properties ctx; private final GridTab gridTab; private final int windowNo; private final int row; /** * @param ctx * @param tab */ public GridRowCtx(Properties ctx, GridTab tab) { this(ctx, tab, -1); } /** * @param ctx * @param tab * @param row */ public GridRowCtx(Properties ctx, GridTab tab, int row) { super(); this.ctx = ctx; this.gridTab = tab; this.windowNo = tab.getWindowNo(); this.row = row; } /** * Get column name from context property * @param key context property * @return column name */ private String getColumnName(Object key) { if (! (key instanceof String) ) return null; String windowStr = windowNo+"|"; String keyStr = (String)key; if (!keyStr.startsWith(windowStr)) { return null; } String columnName = keyStr.substring(windowStr.length()).trim(); //strip tab no too if (columnName.indexOf("|") > 0) { columnName = columnName.substring(columnName.indexOf("|")+1); } return columnName; } @Override public synchronized Object get(Object key) { String columnName = getColumnName(key); if (columnName == null) { return ctx.get(key); } GridTable gridTable = gridTab.getTableModel(); int col = gridTable.findColumn(columnName); if (col == -1) { return ctx.get(key); } Object value = gridTable.getValueAt(getRow(), col); if (value == null) { value = ""; } else if (value instanceof KeyNamePair) { value = ((KeyNamePair)value).getKey(); } else if (value instanceof ValueNamePair) { value = ((ValueNamePair)value).getID(); } else if (value instanceof Boolean) { value = ((Boolean)value).booleanValue() ? "Y" : "N"; } return value.toString(); } /** * @return current row */ private int getRow() { return row >= 0 ? row : gridTab.getCurrentRow(); } @Override public synchronized void clear() { ctx.clear(); } @Override public synchronized Object clone() { final GridRowCtx grc; grc = new GridRowCtx((Properties)this.ctx.clone(), this.gridTab, this.row); return grc; } @Override public synchronized boolean contains(Object value) { return this.containsValue(value); } @Override public synchronized boolean containsKey(Object key) { GridTable gridTable = gridTab.getTableModel(); String columnName = getColumnName(key); if (columnName != null && gridTable.findColumn(columnName) != -1) return true; return ctx.containsKey(key); } @Override public boolean containsValue(Object value) { if (value != null) { GridField[] fields = gridTab.getFields(); for(GridField field : fields) { Object fieldValue = gridTab.getValue(getRow(), field.getColumnName()); if (fieldValue != null && fieldValue.equals(value)) { return true; } } } return ctx.containsValue(value); } @Override public synchronized Enumeration elements() { Vector list = new Vector<>(ctx.values()); GridField[] fields = gridTab.getFields(); for(GridField field : fields) { Object fieldValue = gridTab.getValue(getRow(), field.getColumnName()); if (fieldValue != null) { list.add(fieldValue); } } return list.elements(); } @Override public Set> entrySet() { Set> set = new HashSet<>(ctx.entrySet()); GridField[] fields = gridTab.getFields(); Map fieldMap = new LinkedHashMap<>(); for(GridField field : fields) { Object fieldValue = gridTab.getValue(getRow(), field.getColumnName()); fieldMap.put(field.getColumnName(), fieldValue); } set.addAll(fieldMap.entrySet()); return set; } @Override public synchronized boolean isEmpty() { return false; } @Override public synchronized Enumeration keys() { Vector list = new Vector(ctx.keySet()); GridField[] fields = gridTab.getFields(); for(GridField field : fields) { list.add(field.getColumnName()); } return list.elements(); } @Override public Set keySet() { Set set = new HashSet<>(ctx.keySet()); GridField[] fields = gridTab.getFields(); for(GridField field : fields) { set.add(field.getColumnName()); } return set; } @Override public synchronized Object put(Object key, Object value) { return ctx.put(key, value); } @Override public synchronized void putAll(Map t) { for (Map.Entry e : t.entrySet()) put(e.getKey(), e.getValue()); } @Override public synchronized Object remove(Object key) { return ctx.remove(key); } @Override public synchronized int size() { return ctx.size() + gridTab.getFieldCount(); } @Override public synchronized String toString() { StringBuilder builder = new StringBuilder(ctx.toString()); if (builder.length() > 0) { builder.deleteCharAt(builder.length()-1); if (builder.length() > 1) { builder.append(", "); } } else { builder.append("{"); } GridField[] fields = gridTab.getFields(); for(int i = 0; i < fields.length; i++) { builder.append(fields[i].getColumnName()).append("="); Object value = gridTab.getValue(getRow(), fields[i].getColumnName()); builder.append(value==null ? "" : value.toString()); if (i == fields.length-1) { builder.append("}"); } else { builder.append(", "); } } return builder.toString(); } @Override public Collection values() { return ctx.values(); } @Override public String getProperty(String key) { // I need to override this method, because Properties.getProperty method is calling super.get() instead of get() Object oval = get(key); return oval == null ? null : oval.toString(); } @Override public String get_ValueAsString(String variableName) { return Env.getContext (this, windowNo, variableName, true); } }