[Webfunds-commits] java/webfunds/sox/value StateReceiptStore.java StateReceipt.java StoreAccountStore.java ValueManager.java AccountStore.java ReceiptsStore.java
Ian Grigg
iang@cypherpunks.ai
Sun, 25 Mar 2001 23:29:55 -0400 (AST)
iang 01/03/25 23:29:55
Modified: webfunds/sox AbstractPayment.java
webfunds/sox/value StateReceipt.java StoreAccountStore.java
ValueManager.java
Added: webfunds/sox/value StateReceiptStore.java
Removed: webfunds/sox/value AccountStore.java ReceiptsStore.java
Log:
All compiled with:
1. StoreReceiptStore moved to StateReceiptStore and modified for only
StateReceipts, so that Pending/Receipts are hidden
2. ValueManager now uses only StateReceipts
3. got rid of useless interfaces
Revision Changes Path
1.6 +3 -2 java/webfunds/sox/AbstractPayment.java
Index: AbstractPayment.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/AbstractPayment.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- AbstractPayment.java 2001/03/23 15:06:03 1.5
+++ AbstractPayment.java 2001/03/26 03:29:52 1.6
@@ -1,5 +1,5 @@
/*
- * $Id: AbstractPayment.java,v 1.5 2001/03/23 15:06:03 iang Exp $
+ * $Id: AbstractPayment.java,v 1.6 2001/03/26 03:29:52 iang Exp $
*
* Copyright (c) Systemics Inc 1995-2000 on behalf of
* the WebFunds Development Team. All Rights Reserved.
@@ -83,7 +83,8 @@
* Get the Payment Id.
* should be overridden for identified payments.
*/
- public String getId() { return paymentId; }
+ public String getId() { return paymentId; } // DEPRECATE
+ public String getPaymentId() { return paymentId; }
/**
* Get the date from which the payment is valid.
1.5 +60 -22 java/webfunds/sox/value/StateReceipt.java
Index: StateReceipt.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/value/StateReceipt.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- StateReceipt.java 2001/03/24 23:57:24 1.4
+++ StateReceipt.java 2001/03/26 03:29:53 1.5
@@ -1,17 +1,29 @@
/*
- * $Id: StateReceipt.java,v 1.4 2001/03/24 23:57:24 iang Exp $
+ * $Id: StateReceipt.java,v 1.5 2001/03/26 03:29:53 iang Exp $
*
* Copyright (c) 2000 Systemics Inc on behalf of
* the WebFunds Development Team. All Rights Reserved.
*/
package webfunds.sox.value;
-import java.io.*;
-import java.security.*;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.ByteArrayOutputStream;
+// import java.security.*;
+
+import webfunds.utils.Panic;
+
+import webfunds.sox.Encodable;
+import webfunds.sox.Receipt;
+import webfunds.sox.AccountId;
+import webfunds.sox.ItemId;
+import webfunds.sox.SOXPacketException;
+import webfunds.sox.Utils;
-import webfunds.sox.*;
-
/**
* This class represents a payment issued and maybe settled.
* If pending, only pending information is included.
@@ -39,7 +51,6 @@
public boolean isCancelling() { return (state == CANCELLING); }
public boolean isCancelled() { return (state == CANCELLED); }
public boolean isSucceeded() { return (state == SUCCEEDED); }
-
public boolean isComplete() { return isSucceeded() || isCancelled(); }
@@ -51,7 +62,7 @@
protected PendingReceipt pendingReceipt;
/**
- * Get the Pending if there.
+ * Get the Receipt if there.
* @return the Receipt, else null if not settled as yet
*/
public Receipt getReceipt() { return receipt; }
@@ -59,23 +70,52 @@
public void setReceipt(Receipt r)
{
- state = SUCCEEDED;
+ if (!pid.equals(r.getPaymentId()))
+ throw new Panic("not my Receipt: " + r);
+
+ if (receipt != null)
+ {
+ /*
+ * We already have a Receipt.
+ * As we are idempotent, just check that they are the same.
+ * If they are, just return, the good works are already done.
+ */
+ if (!receipt.equals(r))
+ throw new Panic("Receipts not equiv: \n\n" + r +
+ "\n\n" + receipt);
+ return ;
+ }
+
+ state = getState(r);
receipt = r;
pendingReceipt = null;
}
+ /* what is the point of this? it is an application choice, not here */
+ /*
public void setCancelled(Receipt r)
{
- state = CANCELLED;
+ state = r.getState(r);
receipt = r;
pendingReceipt = null;
}
+ */
public void setCancelling()
{
state = CANCELLING;
}
+ protected static int getState( Receipt rec )
+ {
+ AccountId tgt = rec.getTarget();
+ AccountId src = rec.getSource();
+ if (rec.getQty() == 0 && tgt.equals(src))
+ return CANCELLED;
+ else
+ return SUCCEEDED;
+ }
+
/**
@@ -94,11 +134,9 @@
* Create a new StateReceipt.
* This constructor used when making a Payment committment.
*
- * @param pendingReceipt the deposit request for which this is the receipt
- * @param transactionId the transaction identifier
- * @param date the time of the transaction
+ * @param pr the PendingReceipt indicating the committment
*/
- public StateReceipt( PendingReceipt pr )
+ /* family */ StateReceipt( PendingReceipt pr )
{
this.pendingReceipt = pr;
this.receipt = null;
@@ -109,18 +147,16 @@
/**
* Create a new StateReceipt.
- * This constructor used when making a Payment committment.
+ * This constructor used when transaction already complete.
*
- * @param pendingReceipt the deposit request for which this is the receipt
- * @param transactionId the transaction identifier
- * @param date the time of the transaction
+ * @param rec the Receipt received from the Issuance Server
*/
/* family */ StateReceipt( Receipt rec )
{
this.pendingReceipt = null;
this.receipt = rec;
- this.pid = rec.getPaymentId();
+ this.pid = rec.getPaymentId(); // my unique id
AccountId tgt = rec.getTarget();
AccountId src = rec.getSource();
@@ -130,6 +166,10 @@
this.state = SUCCEEDED;
}
+
+
+//////////// Encode & Decode /////////////////////////////////////
+
/**
* Construct the object from a byte array
* that was previously returned from the encode()
@@ -266,11 +306,9 @@
StateReceipt obj = new StateReceipt(pending);
int state = Utils.exampleByte() & 0x03;
+
+ obj.setReceipt(Receipt.example());
- if (state == SUCCEEDED)
- obj.setReceipt(Receipt.example());
- if (state == CANCELLED)
- obj.setCancelled(Receipt.example());
if (state == CANCELLING)
obj.setCancelling();
1.25 +15 -29 java/webfunds/sox/value/StoreAccountStore.java
Index: StoreAccountStore.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/value/StoreAccountStore.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- StoreAccountStore.java 2001/03/24 23:57:24 1.24
+++ StoreAccountStore.java 2001/03/26 03:29:54 1.25
@@ -1,5 +1,5 @@
/*
- * $Id: StoreAccountStore.java,v 1.24 2001/03/24 23:57:24 iang Exp $
+ * $Id: StoreAccountStore.java,v 1.25 2001/03/26 03:29:54 iang Exp $
*
* Copyright (c) Systemics Ltd 1995-1999 on behalf of
* the WebFunds Development Team. All Rights Reserved.
@@ -11,18 +11,23 @@
import webfunds.utils.Debug;
import webfunds.utils.Hex;
-import webfunds.sox.*;
-import webfunds.client.*;
+import webfunds.utils.Panic;
+
+import webfunds.sox.Account;
+import webfunds.sox.AccountId;
+import webfunds.sox.SOXPacketException;
+
import webfunds.store.Store;
import webfunds.store.StoreException;
public class StoreAccountStore
- extends Debug implements AccountStore
+ extends Debug
{
+ static final String ACCOUNTS_NAME = "Accounts"; // a standard name
+
Store store;
-// IssuerFinder finder;
/**
* Store for accounts.
@@ -33,49 +38,31 @@
if (store == null)
throw new IllegalArgumentException("StoreAccountStore store==null");
this.store = store;
-// this.finder = null;
-//logmsg("SAS " + this.getClass().getClassLoader());
- }
-
- /**
- * Store for accounts.
- * @option finder is set in all accounts that are requested.
- public StoreAccountStore(Store store, IssuerFinder finder)
- {
- if (store == null)
- throw new IllegalArgumentException("StoreAccountStore store==null");
- this.store = store;
- this.finder = finder;
}
- */
public Account[] getAllAccounts()
- // throws StoreException
+ throws StoreException
{
Account[] retval = new Account[store.size()];
-//logmsg("there are " + retval.length + " accounts in store...");
-//logmsg(" CL " + this.getClass().getClassLoader());
int i = 0;
try
{
for (Enumeration e = store.elements();e.hasMoreElements(); i++)
{
-//logmsg(" get: " + i);
retval[i] = new Account((byte[])e.nextElement());
-//logmsg(" got: " + i);
}
}
catch (SOXPacketException ex)
{
- ex.printStackTrace(err());
- System.exit(1);
- // throw new StoreException("Couldn't decode data");
+ throw new Panic(" lost accounts? " + ex);
}
return retval;
}
- // idempotent, saves changes.
+ /**
+ * idempotent, saves changes.
+ */
public void addAccount(Account acct)
throws StoreException
{
@@ -153,7 +140,6 @@
throw new StoreException("Unknown object from " + key + ": " +
obj.getClass().getName());
- // ac.setFinder(finder);
return ac;
}
1.2 +38 -41 java/webfunds/sox/value/ValueManager.java
Index: ValueManager.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/value/ValueManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ValueManager.java 2001/03/24 23:57:24 1.1
+++ ValueManager.java 2001/03/26 03:29:54 1.2
@@ -1,4 +1,4 @@
-/* $Id: ValueManager.java,v 1.1 2001/03/24 23:57:24 iang Exp $
+/* $Id: ValueManager.java,v 1.2 2001/03/26 03:29:54 iang Exp $
*
* Copyright (c) Systemics Inc. 1995-2000 on behalf of
* The WebFunds Development Team. All Rights Reserved.
@@ -60,7 +60,7 @@
*
* (Was the SOXWallet -- attempt to separate and make simple!)
*
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public class ValueManager
extends Debug
@@ -71,9 +71,9 @@
*/
protected Store store;
- protected AccountStore accountStore;
+ protected StoreAccountStore accountStore;
protected SOXServerStore soxes;
- protected ReceiptsStore receiptStore;
+ protected StateReceiptStore receiptStore;
protected Properties properties;
protected IssuerFinder finder;
@@ -163,24 +163,28 @@
// Account store.
// Failures here are unrecoverable.
//
- logmsg("Trying to get 'Accounts' store");
- Store st = store.getStore("Accounts");
- logmsg(
+ logmsg("Trying to get 'Accounts' store");
+ Store st = store.getStore(StoreAccountStore.ACCOUNTS_NAME);
+ logmsg(
" We got: " + st +
", with size: " + st.size() );
- StoreAccountStore accs;
- accs = new StoreAccountStore(st);
- accs.debug(bug);
+ // StoreAccountStore accs;
+ accountStore = new StoreAccountStore(st);
+ accountStore.debug(bug);
- accountStore = (AccountStore)accs;
+ //accountStore = (AccountStore)accs;
//
// Receipt store.
// Failures here are unrecoverable.
//
- receiptStore = new StoreReceiptStore(store.getStore("Receipts"));
- //receiptStore.debug(bug);
+ Store s = store.getStore(StateReceiptStore.RECEIPTS_NAME);
+ receiptStore = new StateReceiptStore(s);
+ receiptStore.debug(bug);
+
+ // not an issue currently: migrate();
+
//
// An old store is Issuers. We should remove that some time.
//
@@ -438,7 +442,7 @@
{
StateReceipt sr;
try {
- sr = receiptStore.getReceipt(src, item, pid);
+ sr = receiptStore.getStateReceipt(src, item, pid);
} catch (StoreException ex) {
throw new webfunds.utils.Panic("get StateReceipt for " + pid);
}
@@ -501,8 +505,10 @@
pay.getQty(),
pay.getDesc(),
new Date());
+ StateReceipt sr = new StateReceipt(pending);
+
try {
- receiptStore.addPendingReceipt(pending, src);
+ receiptStore.addStateReceipt(sr, src);
} catch (StoreException ex) {
ex.printStackTrace();
throw new PaymentException(PaymentException.UNKNOWN,
@@ -983,7 +989,7 @@
{
StateReceipt sr;
try {
- sr = receiptStore.getReceipt(acct, item, id);
+ sr = receiptStore.getStateReceipt(acct, item, id);
} catch (StoreException ex) {
throw new webfunds.utils.Panic("get StateReceipt for " + id);
}
@@ -1012,7 +1018,7 @@
String pid = pids[i];
StateReceipt sr;
try {
- sr = receiptStore.getReceipt(acct, item, pid);
+ sr = receiptStore.getStateReceipt(acct, item, pid);
} catch (StoreException ex) {
storex = ex ;
errors += "\nStoreEx: " + ex;
@@ -1055,7 +1061,7 @@
}
// hey, is this necessary? It gets updated later anyway.
- sr.setCancelled(receipt);
+ // sr.setReceipt(receipt);
// put new sr!
for (int j = 0; j < mails.length; j++)
@@ -1103,7 +1109,7 @@
StateReceipt sr;
try {
- sr = receiptStore.getReceipt(acct, item, pid);
+ sr = receiptStore.getStateReceipt(acct, item, pid);
} catch (StoreException ex) {
throw new CancelException(CancelException.INTERNAL,ex.getMessage());
}
@@ -1615,8 +1621,19 @@
protected boolean handleReceipt(Receipt rec, AccountId acct)
{
+
+ ItemId item = rec.getItem();
+ String pid = rec.getPaymentId();
+
try {
- receiptStore.addReceipt(rec, acct);
+ StateReceipt sr = receiptStore.getStateReceipt(acct, item, pid);
+
+ if (sr == null)
+ sr = new StateReceipt(rec);
+ else
+ sr.setReceipt(rec);
+
+ receiptStore.addStateReceipt(sr, acct);
} catch (StoreException ex) {
ex.printStackTrace();
logmsg("losing receipts for " + acct.fp() + ": " + ex);
@@ -1645,14 +1662,14 @@
*
* @return a list of Receipt within this subaccount
*/
- public Receipt[] getReceipts(AccountId acct, ItemId item)
+ public StateReceipt[] getReceipts(AccountId acct, ItemId item)
throws AccountException
{
- Receipt[] receipts;
+ StateReceipt[] receipts;
try
{
- receipts = receiptStore.getReceipts(acct, item);
+ receipts = receiptStore.getStateReceipts(acct, item);
}
catch (StoreException ex)
{
@@ -1662,26 +1679,6 @@
return receipts;
}
- /**
- *
- * @return a list of Pendings within this subaccount
- */
- public PendingReceipt[] getPending(AccountId acct, ItemId item)
- throws AccountException
- {
- PendingReceipt[] pendings;
-
- try
- {
- pendings = receiptStore.getPendingReceipts(acct, item);
- }
- catch (StoreException ex)
- {
- throw new AccountException("no pendings: " + ex);
- }
-
- return pendings;
- }
public String toString()
1.1 java/webfunds/sox/value/StateReceiptStore.java
Index: StateReceiptStore.java
===================================================================
/*
* $Id: StateReceiptStore.java,v 1.1 2001/03/26 03:29:53 iang Exp $
*
* Copyright (c) Systemics Ltd 1999 on behalf of
* the WebFunds Development Team. All Rights Reserved.
*/
package webfunds.sox.value;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.ByteArrayOutputStream;
import webfunds.utils.Hex;
import webfunds.utils.Debug;
import webfunds.utils.Panic;
import webfunds.sox.Receipt;
import webfunds.sox.AccountId;
import webfunds.sox.ItemId;
import webfunds.sox.SOXPacketException;
import webfunds.store.Store;
import webfunds.store.StoreException;
/**
* A place to persistantly store SOX receipts.
*
* Data-compatible with StoreReceiptStore, but distinct API.
*
* It has persistant stores, one each for pending and confirmed receipts.
* This is a kludge.
*/
public final class StateReceiptStore
extends Debug
{
Store store;
static final String RECEIPTS_NAME = "Receipts";
static final String PENDING = "Pending";
public StateReceiptStore(Store store, PrintWriter bug)
{
debug(bug);
init(store);
}
public StateReceiptStore(Store store)
{
init(store);
}
protected void init(Store store)
{
this.store = store;
}
////////////// Store Manipulation //////////////////////////
/**
* Get the sub account store.
*/
protected Store getSub(AccountId acct, ItemId item)
throws StoreException
{
String acctName = Hex.data2hex(acct.getByteArray());
String subName = Hex.data2hex(item.getByteArray());
Store sub;
sub = store.getStore(acctName).getStore(subName);
return sub ;
}
/**
* Get the Pending store from the sub account store.
*/
protected Store getPen(Store sub)
throws StoreException
{
return sub.getStore(PENDING);
}
/**
* Get the Pending store from the account details.
*/
protected Store getPen(AccountId acct, ItemId item)
throws StoreException
{
return getPen(getSub(acct, item));
}
////////////// Receipts ///////////////////////////////////////
/**
* Add this signed receipt into the store.
* @except StoreException if for any reason the receipt doesn't get added
*/
protected void addReceipt(Store sub, Receipt receipt)
throws StoreException
{
//
// Encode it.
//
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
receipt.encode(baos);
} catch (IOException ex) {
throw new StoreException("dud receipt: " + ex);
}
//
// Is this right? We should be storing according to
// our id, not the issuer id?
//
String tid = receipt.getTransactionId();
logmsg("storing receipt " + tid);
// xid is only unique within issuer. Lucky this is a subaccount
sub.put(tid, baos.toByteArray());
if (store.checkErrors() )
throw new StoreException("Couldn't add receipt: " + receipt);
}
/**
* A signed receipt has arrived.
* Add it to the normal store, then drop any applicable pending.
* Idempotent. Also used by convert().
*/
protected void addReceipt(Receipt receipt, AccountId acct)
throws StoreException
{
// I think there is a bug here somewhere. A receipt
// was not stored but was signed for :( P956094425072 / xid: 46748
ItemId item = receipt.getItem();
logmsg("getting sub " + acct + " / " + item);
Store sub = getSub(acct, item);
addReceipt(sub, receipt);
//
// Remove the pending.
//
String pid = receipt.getPaymentId();
removePending(pid, acct, item);
}
/**
* Get a list of receipts for a subaccount (acct / item).
*/
protected Receipt[] getReceipts(AccountId acct, ItemId item)
throws StoreException
{
Store sub = getSub(acct, item);
Receipt[] retval = new Receipt[sub.size() ];
int i = 0;
for (Enumeration e = sub.keys(); e.hasMoreElements(); i++)
{
String key = (String)e.nextElement();
if (PENDING.equals(key))
continue ;
byte[] data = (byte[])sub.get(key);
try {
retval[i] = new Receipt(data);
} catch (SOXPacketException pex) {
System.err.println(pex.getMessage());
throw new StoreException("Couldn't get file");
}
}
if (store.checkErrors())
{
throw new StoreException("Errors in store");
}
return retval;
}
////////////// StateReceipts ///////////////////////////////////////
/**
* A StateReceipt has arrived, add it in.
*
* Idempotent. Also used by convert().
*/
public void addStateReceipt(StateReceipt sr, AccountId acct)
throws StoreException
{
Receipt rec = sr.getReceipt();
if (rec == null)
{
PendingReceipt pr = sr.getPendingReceipt();
if (pr == null)
throw new Panic("no PR nor R in SR: " + sr);
addPendingReceipt(pr, acct);
}
else
{
addReceipt(rec, acct);
}
}
/**
* Get a receipts for (acct / item / pid).
*
* XXX: stored indexed with xid not pid, needs to search
*
* @return the StateReceipt for that pid, else null if not found
*/
protected StateReceipt getStateReceipt(AccountId acct, ItemId item, String pid)
throws StoreException
{
Store sub = getSub(acct, item);
for (Enumeration e = sub.keys(); e.hasMoreElements(); )
{
String key = (String)e.nextElement();
if (PENDING.equals(key))
continue ;
byte[] data = (byte[])sub.get(key);
Receipt r;
try {
r = new Receipt(data);
} catch (SOXPacketException pex) {
throw new StoreException("Could not get receipt: " + pex);
}
if (r.getPaymentId().equals(pid))
{
return new StateReceipt(r);
}
}
Store pen = getPen(acct, item);
for (Enumeration e = pen.keys(); e.hasMoreElements(); )
{
String key = (String)e.nextElement();
if (PENDING.equals(key))
continue ;
byte[] data = (byte[])sub.get(key);
PendingReceipt p;
try {
p = new PendingReceipt(data);
} catch (SOXPacketException pex) {
throw new StoreException("Could not get receipt: " + pex);
}
if (p.getPaymentId().equals(pid))
{
return new StateReceipt(p);
}
}
if (store.checkErrors())
{
throw new StoreException("Errors in store");
}
return null;
}
/**
* Get a list of receipts for a subaccount (acct / item).
*/
public StateReceipt[] getStateReceipts(AccountId acct, ItemId item)
throws StoreException
{
Store sub = getSub(acct, item);
Vector v = new Vector();
for (Enumeration e = sub.keys(); e.hasMoreElements();)
{
String key = (String)e.nextElement();
if (PENDING.equals(key))
continue ;
byte[] data = (byte[])sub.get(key);
Receipt r;
try {
r = new Receipt(data);
} catch (SOXPacketException pex) {
throw new StoreException("Failed to recover Receipt: " + pex);
}
StateReceipt sr = new StateReceipt(r);
v.addElement(sr);
}
Store pen = getPen(acct, item);
for (Enumeration e = pen.elements(); e.hasMoreElements();)
{
PendingReceipt pr;
try {
pr = new PendingReceipt((byte[])e.nextElement());
} catch(SOXPacketException pex) {
throw new StoreException("Pending failed decode: " + pex);
}
StateReceipt sr = new StateReceipt(pr);
v.addElement(sr);
}
StateReceipt[] receipts = new StateReceipt[v.size()];
v.copyInto(receipts);
return receipts;
}
////////////// PendingReceipts ////////////////////////////////////
/**
* A payment has been made/signed, indicating a receipt will
* come at some stage. Store the receipt as pending.
* Pending receipts are only for payments we write, not for deposits.
*/
protected void addPendingReceipt(PendingReceipt pending, AccountId acct)
throws StoreException
{
Store pen = getPen(acct, pending.item);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
pending.encode(baos);
} catch (IOException ex) {
throw new StoreException("dud pending: " + ex);
}
pen.put(pending.transid, baos.toByteArray());
if (store.checkErrors())
{
throw new StoreException("Errors in store");
}
}
/**
* Remove a pending receipt, presumably because it failed or
* or it has moved to the normal store.
* Was public but there is no reason for this.
*/
protected void removePending(String id, AccountId acct, ItemId item)
throws StoreException
{
Store pen = getPen(acct, item);
//System.err.println("REMOVE: " + id + " ( " + acct + " / " + item + " )");
pen.remove(id);
if (store.checkErrors())
{
throw new StoreException("Errors in store");
}
}
/**
* Return a list of pending receipts for a subaccount.
*/
protected PendingReceipt[] getPendingReceipts(AccountId acct, ItemId item)
throws StoreException
{
Store pen = getPen(acct, item);
PendingReceipt[] retval = new PendingReceipt[pen.size()];
int i = 0;
PendingReceipt pend;
for (Enumeration e = pen.elements(); e.hasMoreElements(); i++)
{
try {
pend = new PendingReceipt((byte[])e.nextElement());
} catch(SOXPacketException pex) {
throw new StoreException("Pending failed decode: " + pex);
}
retval[i] = pend;
}
if (store.checkErrors() )
{
throw new StoreException("Couldn't get file");
}
return retval;
}
////////////////////////////////////////////////////////////////////
//
// Get Values
//
/**
* Does not check the subaccounts? Not Needed?
* @return true if the contents of the account's store have changed.
*/
protected boolean isChanged(AccountId acct)
{
String acctName = Hex.data2hex(acct.getByteArray());
Store thisstore;
try {
thisstore = store.getStore(acctName);
} catch (StoreException ex) {
return true;
}
// Store pendstore = pendingstore.getStore(acctName);
return ( thisstore.isChanged() ) ; //|| pendstore.isChanged() );
}
/**
* Used to see if a re-count of value is needed.
* @return true if the contents of the SubAccount's store have changed.
*/
protected boolean isChanged(AccountId acct, ItemId item)
{
Store sub;
Store pen;
try {
sub = getSub(acct, item);
pen = getPen(acct, item);
} catch (StoreException ex) {
return true;
}
return ( sub.isChanged() || pen.isChanged() );
}
Hashtable pendvaluecache = null;
Hashtable confvaluecache = null;
/**
* What this returns is peculiar.
* It is the sum of payments going out, so all pending
* committments made, but not received.
* As it is a committment out, it should be negative.
*/
public long pendingValue(AccountId acct, ItemId item)
throws StoreException
{
Store pen;
pen = getPen(acct, item);
if (pendvaluecache == null)
pendvaluecache = new Hashtable();
else if (!pen.isChanged())
{
//
// used cached values if the store hasn't changed.
//
Object obj = null;
Hashtable temp = (Hashtable)pendvaluecache.get(acct);
if (temp != null)
obj = temp.get(item);
if (obj != null)
return ((Long)obj).longValue();
}
//
// No cached value, or it is out of date.
// Got to count them up again.
//
PendingReceipt[] pendings = null;
pendings = getPendingReceipts(acct, item);
long amount = 0;
PendingReceipt pending = null;
for (int i = 0; i < pendings.length; i++)
{
pending = pendings[i];
AccountId src = pending.src;
AccountId tgt = pending.tgt;
boolean fromMe = acct.equals(src);
boolean toMe = acct.equals(tgt);
if (fromMe) // from this account
{
if (!toMe) // to someone else
amount -= pending.amount;
}
else if (toMe) // to this account
{ } // ignore, not useful as pending
else
logmsg("huh? not " + acct + "'s pending: " +
pending + "\n( " + src + " ==> " + tgt + " )");
}
//
// Now cache the amount.
//
Long value = new Long(amount);
Hashtable temp = (Hashtable)pendvaluecache.get(acct);
if (temp == null)
{
temp = new Hashtable();
pendvaluecache.put(acct, temp);
}
temp.put(item, value);
return amount;
}
public long confirmedValue(AccountId acct, ItemId item)
throws StoreException
{
Store sub;
sub = getSub(acct, item);
if (confvaluecache == null)
confvaluecache = new Hashtable();
else if (!sub.isChanged())
{
//
// used cached values if the store hasn't changed.
//
Object obj = null;
Hashtable temp = (Hashtable)confvaluecache.get(acct);
if (temp != null)
obj = temp.get(item);
if (obj != null)
return ((Long)obj).longValue();
}
//
// No cached value, or it is out of date.
// Got to count them up again.
//
Receipt[] receipts;
receipts = getReceipts(acct, item);
long amount = 0;
for (int i = 0; i < receipts.length; i++)
{
Receipt receipt = receipts[i];
boolean fromMe = acct.equals(receipt.getSource());
boolean toMe = acct.equals(receipt.getTarget());
//
// if an internal transfer, both are true!
//
if (fromMe)
amount -= receipt.getQty();
if (toMe)
amount += receipt.getQty();
if (!fromMe && !toMe)
logmsg("huh? not " + acct + "'s receipt: " +
receipt);
}
//
// Now cache the amount.
//
Long value = new Long(amount);
Hashtable temp = (Hashtable)confvaluecache.get(acct);
if (temp == null)
{
temp = new Hashtable();
confvaluecache.put(acct, temp);
}
temp.put(item, value);
return amount;
}
}