[Webfunds-commits] java/webfunds/client AccountBrowserImpl.java ReceiptBrowser.java ReceiptTableModel.java

Ian Grigg iang@cypherpunks.ai
Sat, 17 Mar 2001 18:05:13 -0400 (AST)


iang        01/03/17 18:05:13

  Modified:    webfunds/client AccountBrowserImpl.java ReceiptBrowser.java
                        ReceiptTableModel.java
  Log:
  Fixed History Browser to use contracts so that the amount can be displayed
  as a unit of account, not as unit of contract.  Also uses the Transaction
  internally, now stored.  Should really rewrite as Plugin (I tried and failed!).

Revision  Changes    Path
1.84      +17 -4     java/webfunds/client/AccountBrowserImpl.java

Index: AccountBrowserImpl.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/AccountBrowserImpl.java,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -r1.83 -r1.84
--- AccountBrowserImpl.java	2001/02/27 01:28:19	1.83
+++ AccountBrowserImpl.java	2001/03/17 22:05:12	1.84
@@ -1,5 +1,5 @@
 /*
- * $Id: AccountBrowserImpl.java,v 1.83 2001/02/27 01:28:19 iang Exp $
+ * $Id: AccountBrowserImpl.java,v 1.84 2001/03/17 22:05:12 iang Exp $
  *
  * Copyright (c) Systemics Inc 1999 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -922,19 +922,32 @@
             if (obj instanceof WalletInterface)
             {
               WalletInterface wi = (WalletInterface)obj;
-              rb.init(wi);
+              rb.init(wi, cs);
             }
             else if (obj instanceof AccountInfo)
             {
               AccountInfo account = (AccountInfo)obj;
-              rb.init(account);
+              rb.init(account, cs);
             }
             else if (obj instanceof Contract || obj instanceof ItemId)
             {
               DefaultMutableTreeNode parent;
               parent = (DefaultMutableTreeNode)node.getParent();
               AccountInfo acct = (AccountInfo)(parent).getUserObject();
-              rb.init(acct, getItemId(obj));
+              /*
+               * XXX: work out what the contract is, pass that.
+               * need to change all of ReceiptBrowser into Plugin
+               * to do this properly.
+               */
+              Contract con;
+              if (obj instanceof ItemId)
+                  con = cs.getContract((ItemId)obj);
+              else
+                  con = (Contract)obj;
+              if (con == null)
+                  rb.init(acct, (ItemId)obj);
+              else
+                  rb.init(acct, con);
             }
           }
         };



1.19      +63 -86    java/webfunds/client/ReceiptBrowser.java

Index: ReceiptBrowser.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/ReceiptBrowser.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- ReceiptBrowser.java	2001/03/07 00:10:14	1.18
+++ ReceiptBrowser.java	2001/03/17 22:05:13	1.19
@@ -1,5 +1,5 @@
 /*
- * $Id: ReceiptBrowser.java,v 1.18 2001/03/07 00:10:14 gelderen Exp $
+ * $Id: ReceiptBrowser.java,v 1.19 2001/03/17 22:05:13 iang Exp $
  *
  * Copyright (c) Systemics Ltd 1995-1999 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -13,12 +13,13 @@
 import java.awt.event.*;
 
 import webfunds.sox.ItemId;
-//import webfunds.ricardian.Contract;
+import webfunds.ricardian.Contract;
+import webfunds.client.contracts.ChangeContractStore;
 
 /**
- *  Display list of Receipts and Pendings.
- *  Looks like this needs to be a plugin, in order to
- *  correctly convert the contract numbers to account numbers...
+ *  Display list of WebFunds Transactions.
+ *  XXX: Looks like this needs to be a plugin, for the moment is hacked
+ *  to pass the contracts specially.
  */
 public class ReceiptBrowser
     extends JFrame
@@ -36,7 +37,8 @@
 
     WalletInterface   wi;
     AccountInfo       info;
-    ItemId            contract;
+    ItemId            itemId;
+    Contract          contract;
 
     public ReceiptBrowser()
     {
@@ -80,34 +82,56 @@
         this.setSize(400,300);
     }
 
-    public void init(AccountInfo account)
+    public void init(AccountInfo account, ChangeContractStore cs)
     {
         mode = ACCOUNTMODE;
         info = account;
+        wi = info.getWalletInterface();
         this.setTitle("History for " + account);
-        tablemodel = new ReceiptTableModel(account);
+        tablemodel = new ReceiptTableModel(account, cs);
         table.setModel(tablemodel);
+        itemId = null;
         contract = null;
         initActions();
         this.show();
     }
 
-    public void init(WalletInterface wallet)
+    /**
+     *  Unused.
+     */
+    public void init(WalletInterface wallet, ChangeContractStore cs)
     {
         mode = WALLETMODE;
         wi = wallet;
         this.setTitle("History for wallet " + wallet.getShortName());
-        tablemodel = new ReceiptTableModel(wallet);
+        tablemodel = new ReceiptTableModel(wallet, cs);
         table.setModel(tablemodel);
+        itemId = null;
         contract = null;
         initActions();
         this.show();
     }
     
-    public void init(AccountInfo account, ItemId contract)
+    public void init(AccountInfo account, ItemId itemId)
     {
         mode = CONTRACTMODE;
         info = account;
+        wi = info.getWalletInterface();
+        this.itemId = itemId;
+        this.contract = null;
+        this.setTitle("History for contract " + itemId + " in " + account);
+        tablemodel = new ReceiptTableModel(account, itemId);
+        table.setModel(tablemodel);
+        initActions();
+        this.show();
+    }
+
+    public void init(AccountInfo account, Contract contract)
+    {
+        mode = CONTRACTMODE;
+        info = account;
+        wi = info.getWalletInterface();
+        this.itemId = null;
         this.contract = contract;
         this.setTitle("History for contract " + contract + " in " + account);
         tablemodel = new ReceiptTableModel(account, contract);
@@ -189,47 +213,26 @@
     
     private void tryForCancel(Vector victor, int row)
     {
-        int col = tablemodel.findColumn("Status");
-        String status = (String)tablemodel.getValueAt(row, col);
-
-        if (!status.startsWith("PENDING"))
-            return ;
-
-        int type = tablemodel.findColumn("Type");
-
-        if (!tablemodel.getValueAt(row, type).equals("Payment"))
-            return ;
-
-        int src = tablemodel.findColumn("Source");
-        int tid = tablemodel.findColumn("TransactionID");
-        //int con = tablemodel.findColumn("Contract");
-        ItemId item = contract;
-        if (item == null)
-        {
-            int con = tablemodel.findColumn("Contract");
-            item = (ItemId)tablemodel.getValueAt(row, con);
-        }
+        Transaction t = tablemodel.getTransaction(row);
+        if (!t.isAnyPending())
+            return;
+        if (!t.isPayment())
+            return;
 
-        AccountInfo account = (AccountInfo)tablemodel.getValueAt(row, src);
-        String transid = (String)tablemodel.getValueAt(row, tid);
-        Transaction t;
-        t = new Transaction(Transaction.TYPE_PAYMENT, transid, item, account,
-                                                 null, 0, null, null);
-
 	victor.addElement(t);
         return ;
     }
-    
+
     private void cancelAllPendings()
     {
         int len = tablemodel.getRowCount();
         Vector victor = new Vector();
 
-        //
-        //  Have to scan all the rows, and collect out the info
-        //  from the rows before cancelling, as a cancel will
-        //  cause the rows to shuffle.
-        //
+        /*
+         *  Have to scan all the rows, and collect out the info
+         *  from the rows before cancelling, as a cancel will
+         *  cause the rows to shuffle.
+         */
         for (int row = 0; row < len; row++)
         {
             tryForCancel(victor, row);
@@ -242,8 +245,6 @@
 	Transaction trans[] = new Transaction[victor.size()];
 	victor.copyInto((Object[])trans);
 
-        AccountInfo account = trans[0].getSource();
-        WalletInterface wi = account.getWalletInterface(); // all accounts same
 	wi.cancel(trans);
 
         refresh();
@@ -254,52 +255,23 @@
         int row;
         Vector victor = new Vector();
 
-        //
-        //  Have to identify the rows, and collect out the info
-        //  from the rows before cancelling, as a cancell will
-        //  cause the rows to shuffle, but not the select!
-        //
-        AccountInfo account = null;
+        /*
+         *  Have to identify the rows, and collect out the info
+         *  from the rows before cancelling, as a cancell will
+         *  cause the rows to shuffle, but not the select!
+         */
         for (int i = 0; i < rows.length;i++)
         {
-            row = rows[i];
-            int col = tablemodel.findColumn("Status");
-            String status = (String)tablemodel.getValueAt(row, col);
-
-            if (!status.startsWith("PENDING"))
-                continue ;
-
-            int type = tablemodel.findColumn("Type");
-
-            if (!tablemodel.getValueAt(row, type).equals("Payment"))
-                continue ;
-
-            int src = tablemodel.findColumn("Source");
-            int tid = tablemodel.findColumn("TransactionID");
-
-            ItemId item = contract;
-            if (item == null)
-            {
-                int con = tablemodel.findColumn("Contract");
-                item = (ItemId)tablemodel.getValueAt(row, con);
-            }
-
-            account = (AccountInfo)tablemodel.getValueAt(row, src);
-            String transid = (String)tablemodel.getValueAt(row, tid);
-            Transaction t;
-            t = new Transaction(Transaction.TYPE_PAYMENT, transid, item,
-                                account, null, 0, null, null);
+            tryForCancel(victor, rows[i]);
+        }
 
-	    victor.addElement(t);
-            //wi.cancel(t);
-	}
+        int siz = victor.size();
+	if (siz == 0)     // nothing happened, no transactions found.
+	    return ;
 
-	Transaction trans[] = new Transaction[victor.size()];
+	Transaction trans[] = new Transaction[siz];
 	victor.copyInto((Object[])trans);
 
-	if (account == null)     // nothing happened, no transactions found.
-	    return ;
-        WalletInterface wi = account.getWalletInterface(); // all accounts same
 	wi.cancel(trans);
 
         refresh();
@@ -312,7 +284,12 @@
         else if (mode == ACCOUNTMODE)
             tablemodel.refresh(info);
         else if (mode == CONTRACTMODE)
-            tablemodel.refresh(info, contract);
+        {
+            if (contract == null)
+                tablemodel.refresh(info, itemId);
+            else
+                tablemodel.refresh(info, contract);
+        }
     }
     
     



1.15      +242 -45   java/webfunds/client/ReceiptTableModel.java

Index: ReceiptTableModel.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/ReceiptTableModel.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- ReceiptTableModel.java	2001/03/07 00:10:16	1.14
+++ ReceiptTableModel.java	2001/03/17 22:05:13	1.15
@@ -1,5 +1,5 @@
 /*
- * $Id: ReceiptTableModel.java,v 1.14 2001/03/07 00:10:16 gelderen Exp $
+ * $Id: ReceiptTableModel.java,v 1.15 2001/03/17 22:05:13 iang Exp $
  *
  * Copyright (c) Systemics Ltd 1995-1999 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -11,35 +11,54 @@
 import java.util.Vector;
 import java.util.Enumeration;
 import java.text.DateFormat;
+import java.text.DecimalFormat;
 
 import webfunds.sox.ItemId;
+import webfunds.sox.ItemId;
+import webfunds.client.contracts.ChangeContractStore;
+import webfunds.ricardian.Contract;
 
+/**
+ *  Table model for WebFunds Transactions.
+ *  Can be applied to an account, or to an account/contract pair.
+ */
 public class ReceiptTableModel
     extends AbstractTableModel
 {
 
-    Vector data = new Vector();
+    private Vector data = new Vector();
 
-    String[] headers;
-    Class[] types;
+    private final String[] headers;
+    private final Class[] types;
 
-    String[] shortHeaders = {"Date", "TransactionID",
+    private static final String[] shortHeaders = {
+                             "Date", "TransactionID",
                              "Source", "Target",
-                             "Amount", "Description", "Status", "Type"};
-    Class[] shortTypes = {String.class, String.class,
+                             "Amount", "Description",
+                             "Status", "Type"};
+    private static final Class[] shortTypes = {
+                          String.class, String.class,
                           AccountInfo.class, AccountInfo.class,
-                          Long.class, String.class, String.class, String.class};
+                          String.class, String.class,
+                          String.class, String.class
+                          /*, Transaction */ };
 
-    String[] longHeaders =  {"Date", "TransactionID", "Contract",
+    private static final String[] longHeaders =  {
+                             "Date", "TransactionID", "Contract",
                              "Source", "Target",
-                             "Amount", "Description", "Status", "Type"};
-    Class[] longTypes =  {String.class, String.class, ItemId.class,
+                             "Amount", "Description",
+                             "Status", "Type"};
+    private static final Class[] longTypes =  {
+                          String.class, String.class, String.class,
                           AccountInfo.class, AccountInfo.class,
-                          Long.class, String.class, String.class, String.class};
+                          String.class, String.class,
+                          String.class, String.class
+                          /*, Transaction */ };
 
-    DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
-                                                   DateFormat.SHORT);
+    private final DateFormat df =
+            DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
 
+    private ChangeContractStore contracts = null;
 
     /** If set to true, show the cancel payments */
     protected boolean showCancels = false;
@@ -48,22 +67,48 @@
 
 
 
-    public ReceiptTableModel(WalletInterface wi)
+    /**
+     *  For a whole wallet - unused.
+     */
+    public ReceiptTableModel(WalletInterface wi, ChangeContractStore cs)
     {
         super();
         headers = longHeaders;
         types = longTypes;
+        contracts = cs;
         fillWallet(wi);
     }
 
-    public ReceiptTableModel(AccountInfo account)
+    /**
+     *  For a complete account (of many contract subaccounts).
+     */
+    public ReceiptTableModel(AccountInfo account, ChangeContractStore cs)
     {
         super();
         headers = longHeaders;
         types = longTypes;
+        contracts = cs;
         fillAccount(account);
+    }
+
+    /**
+     *  For a subaccount - account/contract pair.
+     */
+    public ReceiptTableModel(AccountInfo account, Contract contract)
+    {
+        super();
+        headers = shortHeaders;
+        types = shortTypes;
+        fillContract(account, contract);
     }
-    
+
+    /**
+     *  For a subaccount - account/contract pair.
+     *  This call is used where the contract is not available or
+     *  or is unknown for some reason, but, as there exists a
+     *  subaccount, it must be displayed properly, albeit with
+     *  less information.
+     */
     public ReceiptTableModel(AccountInfo account, ItemId item)
     {
         super();
@@ -71,7 +116,12 @@
         types = shortTypes;
         fillContract(account, item);
     }
-    
+
+
+
+    /*
+     *  Prepare the table, for an entire wallet.
+     */
     private void fillWallet(WalletInterface wi)
     {
         AccountInfo[] accounts = wi.getAccounts();
@@ -80,29 +130,67 @@
             fillAccount(accounts[i]);
         }
     }
-    
+
+    /*
+     *  Prepare the table, adding in a complete account.
+     */
     private void fillAccount(AccountInfo account)
     {
         WalletInterface wi = account.getWalletInterface();
         ItemId[] items = wi.getContracts(account);
         for(int c = 0; c < items.length;c++)
         {
-            fillContract(account, items[c]);   
+            /*
+             *  First, see if we can acquire the Contract for this Item.
+             */
+            ItemId item = items[c];
+            Contract con = null;
+            if (contracts != null)             // might lack a contract store
+                con = contracts.getContract(item);
+
+            if (con == null)
+               fillContract(account, item);
+            else
+               fillContract(account, con);
         }
     }
-    
+
+    /*
+     *  Call this if we just have the raw details (no contract).
+     */
     private void fillContract(AccountInfo account, ItemId item)
     {
         WalletInterface wi = account.getWalletInterface();
         Transaction[] transactions = wi.getTransactions(account, item);
         for (int t = 0; t < transactions.length;t++)
         {
-            fillTable(transactions[t], account);
+            fillTable(transactions[t], account, null);
         }
     }
-    
-    private void fillTable(Transaction trans, AccountInfo acct)
+
+    /*
+     *  Call this if we have the contract, normal case.
+     */
+    private void fillContract(AccountInfo account, Contract contract)
     {
+        WalletInterface wi = account.getWalletInterface();
+        ItemId item = contract.getItemId();
+        Transaction[] transactions = wi.getTransactions(account, item);
+        for (int t = 0; t < transactions.length;t++)
+        {
+            fillTable(transactions[t], account, contract);
+        }
+    }
+
+    /*
+     *  Seems messy.  Should decide whether this will get the contract
+     *  or not.
+     *  Also, as we are forced to store the Transaction, why not just
+     *  do it all dynamically instead of storing a table of the same
+     *  information?
+     */
+    private void fillTable(Transaction trans, AccountInfo acct, Contract con)
+    {
         AccountInfo source = trans.getSource();
         AccountInfo target = trans.getTarget();
 
@@ -119,87 +207,196 @@
             if (source.equals(target))
                 return ;
         }
+
+        /*
+         *  One for each column, and one for the Transaction.
+         */
+        Object[] row = new Object[headers.length + 1];
 
-        Object[] row = new Object[headers.length];
-        
         int i = 0;
-            
+
         row[i++] = df.format( trans.getDate() );
         row[i++] = trans.getTransId();
         if (headers == longHeaders)
-            row[i++] = trans.getContract();
+        {
+            if (con == null)
+            {
+                row[i++] = new String("" + trans.getContractId());
+            }
+            else
+            {
+                String name = con.getName();
+                row[i++] = name;
+            }
+        }
 
         row[i++] = (acct.equals(source) ? acct : source );
         row[i++] = (acct.equals(target) ? acct : target );
 
-        //
-        //   Yikes.  It looks like we have no access to Contracts,
-        //   so no way to work out unit of account.  Need to change
-        //   to plugin.
-        //
-        row[i++] = new Long(amount);
+        if (con == null)
+            row[i++] = new String("" + amount);
+        else
+        {
+            DecimalFormat fmt = con.getDecimalFormat();
+            double dub = con.getUnitsOfAccount((long)amount);
+            row[i++] = fmt.format(dub);
+        }
         row[i++] = new String( webfunds.utils.Hex.printable(trans.getDesc()) );
         row[i++] = trans.getStatusAsString();
         row[i++] = trans.getTypeAsString();
+
+        /*
+         *  Also sneak in the Transaction at the end of the row,
+         *  as row is selected for work that needs the precise
+         *  information.
+         */
+        row[i++] = trans;
+
         data.addElement(row);
     }
-    
 
+
+
+    /*
+     *  @return how many rows (transactions) in the table
+     */
     public int getRowCount()
     {
         return data.size();
     }
 
+    /*
+     *  There are different numbers of columns depending on how
+     *  the object was created.
+     *
+     *  @return how many columns in the table
+     */
     public int getColumnCount()
     {
-        return headers.length;
+        return headers.length; // note, there is a "hidden" Transaction column
     }
 
+    /*
+     *  @return the title for each column
+     */
     public String getColumnName(int col)
     {
         return headers[col];
     }
 
+    /*
+     *  Each column has a title.
+     *
+     *  @return the index of the column title of the given colname
+     */
     public int findColumn(String colname)
     {
         for(int i = 0; i < headers.length; i++)
         {
-            if(headers[i].equals(colname) )
+            if (headers[i].equals(colname))
                 return i;
         }
         return -1;
     }
 
-
-    public Class getColumnClass(int c)
-    {
-        return types[c];
-    }
 
+    /**
+     *  Find out what class is stored in the given column.
+     *
+     *  @throws IllegalArgumentException if column is out of range
+     */
+    public Class getColumnClass(int column)
+    {
+        /*
+         *  We have to check this one as there is a hidden element,
+         *  the transaction, and the caller isn't allowed it via
+         *  this call, must use getTransaction() below.
+         */
+        if ( ! (0 <= column || column < headers.length) )
+            throw new IllegalArgumentException("col out of range: " + column +
+                                               " (0, "+(headers.length-1)+")");
+        return types[column];
+    }
+
+    /**
+     *
+     *  @returns the Object at the row, column.
+     *  @throws IllegalArgumentException if row or column is out of range
+     */
     public Object getValueAt(int row, int column)
     {
+        if ( ! (0 <= row || row < data.size()) )
+            throw new IllegalArgumentException("row out of range: " + row +
+                                               " (0, "+(data.size()-1)+")");
+
         Object[] rowdata = (Object[])data.elementAt(row);
+
+        /*
+         *  We have to check this one as there is a hidden element,
+         *  the transaction, and the caller isn't allowed it via
+         *  this call, must use getTransaction() below.
+         */
+        if ( ! (0 <= column || column < headers.length) )
+            throw new IllegalArgumentException("col out of range: " + column +
+                                               " (0, "+(headers.length-1)+")");
         return rowdata[column];
     }
-    
+
+    /**
+     *
+     *  @returns the Transaction relating to the given row.
+     *  @throws IllegalArgumentException if row is out of range
+     */
+    public Transaction getTransaction(int row)
+    {
+        if ( ! (0 <= row || row < data.size()) )
+            throw new IllegalArgumentException("row out of range: " + row +
+                                               " (0, "+(data.size()-1)+")");
+
+        Object[] rowdata = (Object[])data.elementAt(row);
+        Transaction t = (Transaction)rowdata[headers.length]; // last hidden col
+        return t;
+    }
+
+
+
+    /**
+     *  Refresh with new information taken from the walllet.
+     */
     public void refresh(WalletInterface wi)
     {
         data.removeAllElements();
         fillWallet(wi);
         fireTableDataChanged();
     }
-    
+
+    /**
+     *  Refresh with new information taken from the account info.
+     */
     public void refresh(AccountInfo info)
     {
         data.removeAllElements();
         fillAccount(info);
         fireTableDataChanged();
     }
-    
+
+    /**
+     *  Refresh with new information taken from the subaccount info/item.
+     */
     public void refresh(AccountInfo info, ItemId item)
     {
         data.removeAllElements();
         fillContract(info, item);
+        fireTableDataChanged();
+    }
+
+    /**
+     *  Refresh with new information taken from the subaccount info/contract.
+     */
+    public void refresh(AccountInfo info, Contract contract)
+    {
+        data.removeAllElements();
+        fillContract(info, contract);
         fireTableDataChanged();
     }