webfunds.ricardian
Class Contract

java.lang.Object
  |
  +--webfunds.utils.Debug
        |
        +--webfunds.ricardian.Contract
Direct Known Subclasses:
Currency, ServerContract, Share

public class Contract
extends Debug

Ricardian Contract Base Class Rewritten from the sox.Contract and the Perl equivalents. Refer to: http://www.systemics.com/docs/ricardo/issuer/contract.html for the specification of a contract.


Field Summary
static java.lang.String BEGIN
           
protected static int BOND_TYPE
           
static java.lang.String BOND_WORD
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
static int CANHASH_CURRENT
           
static int CANHASH_WHITE_BUG
           
protected  byte[] contractData
           
protected static int CURRENCY_TYPE
           
static java.lang.String CURRENCY_WORD
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
protected  java.text.DecimalFormat decimalFormat
           
protected  java.lang.String decimalFormatPattern
           
static java.lang.String END
           
protected static java.lang.String errors
           
protected  double factor
           
static java.lang.String FIELD_CONTRACT
           
static java.lang.String FIELD_OPERATOR
           
static java.lang.String FIELD_SERVER
           
static java.lang.String FIELD_TOP_LEVEL
           
protected  IniFileReader fields
           
protected  java.lang.String fileName
           
protected  ItemId id
           
protected  byte[] localData
           
protected  java.lang.String logfix
           
protected  java.lang.String mixedModeErrors
           
protected  IniFileReader myFile
           
protected  java.lang.String name
           
static java.lang.String PGP_BEGIN
           
static java.lang.String PGP_END
           
protected  int power
           
static java.lang.String SECT_APPL
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
static java.lang.String SECT_ISSUE
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
static java.lang.String SECT_KEYS
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
static java.lang.String SECT_LOCAL
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
protected static int SERVER_TYPE
           
static java.lang.String SERVER_WORD
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
protected static int SHARE_TYPE
           
static java.lang.String SHARE_WORD
          Recognised section names (they appear in the contract with square brackets on a line by themselves).
protected  java.lang.String type
           
protected static int UNKNOWN_TYPE
           
protected  byte[] userData
           
static java.lang.String USERID_CONTRACT
          OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
static java.lang.String USERID_OPERATOR
          OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
static java.lang.String USERID_SERVER
          OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
static java.lang.String USERID_TOP_LEVEL
          OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
static java.lang.String X509_BEGIN
           
static java.lang.String X509_END
           
 
Fields inherited from class webfunds.utils.Debug
bug, debugAll, logfix
 
Constructor Summary
Contract(byte[] cData, byte[] lData, byte[] yData)
          A new Contract, made out of the contract data and any local/user data (null or empty is ok).
 
Method Summary
static byte[] doCanonicalDigest(byte[] txt)
          Do a canonical hash on the data.
static byte[] doCanonicalDigest(byte[] txt, int version)
          Do a canonical hash on the data.
 boolean equals(java.lang.Object obj)
          only checks the contract hash, does not test local file or fuz file!
static void error(java.lang.String e)
           
 java.lang.String fileNameFromDigest(byte[] hash)
           
protected  void flushMyFile()
           
 java.lang.String[] getAllNames()
          A contract is known by many names, including the hash and local name.
 double getAmount(long units)
          Return the Unit of Account, e.g., dollars.
 java.lang.String getApplicationName()
          Get the application-set name, if any.
 java.lang.String[] getArray(java.lang.String section, java.lang.String item)
          Get an array named item from section.
static java.lang.String getBase(java.lang.String contract)
          Take a string, interpret it is a Ricardian Contract, and extract out the base - the part from the BEGIN SIG to the keys.
 java.lang.String getContentErrors()
           
 java.lang.String getContents()
           
static Contract getContract(byte[] con, byte[] loc, byte[] my)
          Take the data, work out which type of contract it is, and invoke that object.
static Contract getContract(java.io.File contractfile)
          Read in a contract given a filename.
static Contract getContract(java.net.URL contracturl)
          Read in a contract given a URL
 java.text.DecimalFormat getDecimalFormat()
          Get a DecimalFormat object suitable for this Contract.
 java.lang.String getDecimalFormatPattern()
          Get the DecimalFormatpattern.
static java.lang.String getErrors()
           
 double getFactor()
           
 java.lang.String getField(java.lang.String section, java.lang.String item)
          Get a field named item from section.
 java.lang.String getFileName()
           
 ItemId getId()
           
 ItemId getItemId()
           
 java.lang.String getName()
          Get the single best name for display of this contract.
 java.lang.String getNameOfUnitOfAccount()
          Needs more support from the contract to do properly.
 java.lang.String getNameOfUnitOfContract()
          Needs more support from the contract to do properly.
static java.security.cert.Certificate getOpenPGPCertFromString(java.lang.String text, java.lang.String name, int errno, java.lang.String userIdTag)
           
 int getPower()
           
 java.lang.String getPrintableAmount(long qty)
          Get a printable string in unit of account.
static java.lang.String getRoot(java.lang.String name)
           
 java.lang.String[] getSectionItems(java.lang.String section)
          Get the fieldnames in a section Doesn't look in myFile.
 java.lang.String[] getSectionNames()
          Get all the section names.
protected  java.security.cert.Certificate getServerCert()
          This is the SOX Server [operator] key.
 java.lang.String getSymbol()
          Get the single shortest name for display of this contract.
 int getType()
          getType - returns type of this contract.
static int getType(byte[] contractData)
          Work out what type of contract this is.
 java.lang.String getUniqueName()
           
 long getUnits(double amount)
          Return the Unit of Contract, e.g., cents.
 double getUnitsOfAccount(long units)
          Consider casting the result to a float to clean FP errors.
 long getUnitsOfContract(double amount)
          unitsOfAccount = dollars, unitsOfContract = cents
static java.security.cert.Certificate getX509CertFromString(java.lang.String text, java.lang.String name, int errno)
           
 int hashCode()
           
protected  boolean isChanged(java.io.File f, byte[] data)
           
 boolean isPower()
           
static void main(java.lang.String[] arg)
           
static byte[] prepareContractForCanonicalDigest(byte[] data, int v)
          This method prepares data to be canonically hashed: + all lines end with \r\n + all trailing whitespace is removed (codes <= BEFORE AFTER SIGNED USED ARMOURY.PREPAREDATATOSIGN().
static byte[] prepareContractForCanonicalDigest2(byte[] data)
           
 void readAndSetPower()
          Units of account / contract used to be part of the Currency contract, but have been since widened to be a basic function of all contracts (at least, as far as decimal goes).
 void removeFiles()
          Remove these files - only - from the store.
 void removeFiles(java.io.File dir)
          Remove these files - only - from dir.
protected  void removeFiles(java.io.File dir, java.lang.String name)
          Given a root name, remove all my files from dir.
 void reSaveAsFile(Contract contract)
          re-Save the contract if it has changed.
 void reSaveAsFile(java.io.File dir, Contract contract)
           
static void resetErrors()
           
 void saveAsFile(java.io.File dir)
          Save the contract into file(s) rooted in a unique name.
 void saveAsFile(java.io.File dir, java.lang.String name)
          Save the contract into file(s) rooted in name.
protected  void saveFile(java.io.File f, byte[] data)
          Save a file.
 void setApplicationName(java.lang.String name)
          Applications can add their own name for GUIs.
 void setDecimalFormat(java.text.DecimalFormat d)
           
 void setDecimalFormatPattern(java.lang.String s)
          Set the DecimalFormat(pattern) for all future get calls.
 void setField(java.lang.String section, java.lang.String item, java.lang.String value)
          Set a field that can be recorded and returned.
protected  void setPower(int p)
           
 java.lang.String toString()
           
 boolean verifyContract()
          Verify that the contract is signed correctly by the cert.
 boolean verifyOpenPGPSignatures()
          Verify that the OpenPGP contract is signed correctly and that all certs match our current path goodness criteria: 1.
 boolean verifyX509Signatures()
          Verify that the x509 contract is signed correctly and that all certs match our current path goodness criteria.
 
Methods inherited from class webfunds.utils.Debug
debug, debug, debug, debug, err, getDebug, logend, logmsg, logstart, logword
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

SECT_ISSUE

public static final java.lang.String SECT_ISSUE
Recognised section names (they appear in the contract with square brackets on a line by themselves).

SECT_KEYS

public static final java.lang.String SECT_KEYS
Recognised section names (they appear in the contract with square brackets on a line by themselves).

SECT_LOCAL

public static final java.lang.String SECT_LOCAL
Recognised section names (they appear in the contract with square brackets on a line by themselves).

SECT_APPL

public static final java.lang.String SECT_APPL
Recognised section names (they appear in the contract with square brackets on a line by themselves).

CURRENCY_WORD

public static final java.lang.String CURRENCY_WORD
Recognised section names (they appear in the contract with square brackets on a line by themselves).

BOND_WORD

public static final java.lang.String BOND_WORD
Recognised section names (they appear in the contract with square brackets on a line by themselves).

SHARE_WORD

public static final java.lang.String SHARE_WORD
Recognised section names (they appear in the contract with square brackets on a line by themselves).

SERVER_WORD

public static final java.lang.String SERVER_WORD
Recognised section names (they appear in the contract with square brackets on a line by themselves).

CURRENCY_TYPE

protected static final int CURRENCY_TYPE

BOND_TYPE

protected static final int BOND_TYPE

SHARE_TYPE

protected static final int SHARE_TYPE

SERVER_TYPE

protected static final int SERVER_TYPE

UNKNOWN_TYPE

protected static final int UNKNOWN_TYPE

contractData

protected byte[] contractData

localData

protected byte[] localData

userData

protected byte[] userData

fields

protected IniFileReader fields

myFile

protected IniFileReader myFile

id

protected ItemId id

name

protected java.lang.String name

fileName

protected java.lang.String fileName

type

protected java.lang.String type

power

protected int power

factor

protected double factor

decimalFormatPattern

protected java.lang.String decimalFormatPattern

decimalFormat

protected java.text.DecimalFormat decimalFormat

logfix

protected java.lang.String logfix

mixedModeErrors

protected java.lang.String mixedModeErrors

CANHASH_WHITE_BUG

public static final int CANHASH_WHITE_BUG

CANHASH_CURRENT

public static final int CANHASH_CURRENT

errors

protected static java.lang.String errors

BEGIN

public static final java.lang.String BEGIN

X509_BEGIN

public static final java.lang.String X509_BEGIN

PGP_BEGIN

public static final java.lang.String PGP_BEGIN

END

public static final java.lang.String END

X509_END

public static final java.lang.String X509_END

PGP_END

public static final java.lang.String PGP_END

USERID_TOP_LEVEL

public static final java.lang.String USERID_TOP_LEVEL
OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
See Also:

USERID_CONTRACT

public static final java.lang.String USERID_CONTRACT
OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
See Also:

USERID_SERVER

public static final java.lang.String USERID_SERVER
OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
See Also:

USERID_OPERATOR

public static final java.lang.String USERID_OPERATOR
OpenPGP User Id tags - special Ricardian strings that indicate what this key is used for.
See Also:

FIELD_TOP_LEVEL

public static final java.lang.String FIELD_TOP_LEVEL

FIELD_CONTRACT

public static final java.lang.String FIELD_CONTRACT

FIELD_SERVER

public static final java.lang.String FIELD_SERVER

FIELD_OPERATOR

public static final java.lang.String FIELD_OPERATOR
Constructor Detail

Contract

public Contract(byte[] cData,
                byte[] lData,
                byte[] yData)
         throws ContractException
A new Contract, made out of the contract data and any local/user data (null or empty is ok).
Method Detail

getPower

public int getPower()

isPower

public boolean isPower()

setPower

protected void setPower(int p)

getFactor

public double getFactor()

readAndSetPower

public void readAndSetPower()
                     throws ContractException
Units of account / contract used to be part of the Currency contract, but have been since widened to be a basic function of all contracts (at least, as far as decimal goes). Here, if we have an [issue] power, this is the number of digits after the decimal point.

setDecimalFormatPattern

public void setDecimalFormatPattern(java.lang.String s)
Set the DecimalFormat(pattern) for all future get calls.

setDecimalFormat

public void setDecimalFormat(java.text.DecimalFormat d)

getDecimalFormatPattern

public java.lang.String getDecimalFormatPattern()
Get the DecimalFormatpattern. If no call to setDecimalFormatPattern() has been made, one is initialised from the power of the Contract.

getDecimalFormat

public java.text.DecimalFormat getDecimalFormat()
Get a DecimalFormat object suitable for this Contract. If no call to setDecimalFormat() has been made, one is initialised from getDecimalFormatPattern().

getPrintableAmount

public java.lang.String getPrintableAmount(long qty)
Get a printable string in unit of account. Uses the DecimalFormat from getDecimalFormat(), and converts the long qty with getUnitsOfAccount().

getUnitsOfContract

public long getUnitsOfContract(double amount)
unitsOfAccount = dollars, unitsOfContract = cents

getUnitsOfAccount

public double getUnitsOfAccount(long units)
Consider casting the result to a float to clean FP errors.

getNameOfUnitOfContract

public java.lang.String getNameOfUnitOfContract()
Needs more support from the contract to do properly.
Returns:
a printable name for the unit of contract (cents), null if not available.

getNameOfUnitOfAccount

public java.lang.String getNameOfUnitOfAccount()
Needs more support from the contract to do properly.
Returns:
a printable name for the unit of account (dollars), null if not available.

fileNameFromDigest

public java.lang.String fileNameFromDigest(byte[] hash)

getContentErrors

public java.lang.String getContentErrors()
Returns:
null if no errors detected, else descriptive string

doCanonicalDigest

public static byte[] doCanonicalDigest(byte[] txt)
                                throws ContractException
Do a canonical hash on the data. A canonical hash (v = CANHASH_CURRENT) is: + requires a PGP signature (lines outside removed) + trailing whitespace removed + line endings are CR/LN It is slightly different to canonical signature preparation. This (code) was in sox.
Parameters:
txt - is the file data

doCanonicalDigest

public static byte[] doCanonicalDigest(byte[] txt,
                                       int version)
                                throws ContractException
Do a canonical hash on the data.
Parameters:
version - 3 is current 2 is without trailing whitespace stripped

getErrors

public static java.lang.String getErrors()
Returns:
"" if no errors detected, else descriptive string

resetErrors

public static void resetErrors()

error

public static void error(java.lang.String e)

prepareContractForCanonicalDigest

public static byte[] prepareContractForCanonicalDigest(byte[] data,
                                                       int v)
                                                throws ContractException
This method prepares data to be canonically hashed: + all lines end with \r\n + all trailing whitespace is removed (codes <= BEFORE AFTER SIGNED ARMOURY.PREPAREDATATOSIGN().
Parameters:
data - the original data
Returns:
canonical data

prepareContractForCanonicalDigest2

public static byte[] prepareContractForCanonicalDigest2(byte[] data)
                                                 throws java.io.IOException

getContract

public static Contract getContract(byte[] con,
                                   byte[] loc,
                                   byte[] my)
                            throws ContractException
Take the data, work out which type of contract it is, and invoke that object.
Returns:
a derivative contract object

getContract

public static Contract getContract(java.io.File contractfile)
                            throws ContractException
Read in a contract given a filename.
Parameters:
contractfile - name

getRoot

public static java.lang.String getRoot(java.lang.String name)
                                throws ContractException
Parameters:
name - is the filename or URL (string)
Returns:
a root name, with suffix dropped.

getContract

public static Contract getContract(java.net.URL contracturl)
                            throws ContractException
Read in a contract given a URL
Parameters:
contractfile - name with .asc suffix

getType

public static int getType(byte[] contractData)
                   throws ContractException
Work out what type of contract this is. An unknown one is not an exception, just something that we can't interpret further than being a contract.

getType

public int getType()
getType - returns type of this contract. Should be extended by subclasses.

getId

public ItemId getId()

getItemId

public ItemId getItemId()

getUniqueName

public java.lang.String getUniqueName()

getFileName

public java.lang.String getFileName()

getName

public java.lang.String getName()
Get the single best name for display of this contract. Can be overridden in subclass if better name in type field.

getSymbol

public java.lang.String getSymbol()
Get the single shortest name for display of this contract. Can be overridden in subclass if better name in type field.

getAllNames

public java.lang.String[] getAllNames()
A contract is known by many names, including the hash and local name. Only the hash is unique.
Returns:
an array containing all known names for this contract.

setApplicationName

public void setApplicationName(java.lang.String name)
                        throws ContractException
Applications can add their own name for GUIs.

getApplicationName

public java.lang.String getApplicationName()
Get the application-set name, if any.
Returns:
a name, or null of none set.

getServerCert

protected java.security.cert.Certificate getServerCert()
                                                throws ContractException
This is the SOX Server [operator] key. The verification capability of this cert should authenticate the server that is used (as indicated in the local file).

getOpenPGPCertFromString

public static java.security.cert.Certificate getOpenPGPCertFromString(java.lang.String text,
                                                                      java.lang.String name,
                                                                      int errno,
                                                                      java.lang.String userIdTag)
                                                               throws ContractException

getX509CertFromString

public static java.security.cert.Certificate getX509CertFromString(java.lang.String text,
                                                                   java.lang.String name,
                                                                   int errno)
                                                            throws ContractException

verifyContract

public boolean verifyContract()
                       throws ContractException
Verify that the contract is signed correctly by the cert. Also see getContentErrors().
Returns:
true if sig verifies, else false if sig fails
Throws:
ContractException, - set to the approximate causes

verifyOpenPGPSignatures

public boolean verifyOpenPGPSignatures()
                                throws ContractException
Verify that the OpenPGP contract is signed correctly and that all certs match our current path goodness criteria: 1. all keys {top, contract, server} are self-signed. 2. top-level certification key signs contract key. 3. contract key signs contract. 4. no other signatures are included. why is this: // @return true if sig verifies, else false if sig fails
Returns:
true
Throws:
ContractException, - set to the approximate cause

verifyX509Signatures

public boolean verifyX509Signatures()
                             throws ContractException
Verify that the x509 contract is signed correctly and that all certs match our current path goodness criteria.
Returns:
true if sig verifies, else false if sig fails
Throws:
ContractException, - set to the approximate cause

getUnits

public long getUnits(double amount)
Return the Unit of Contract, e.g., cents. Overridden in subclass. Some subclasses have distinct units of account - user units - from actual units of contract - represented here.

getAmount

public double getAmount(long units)
Return the Unit of Account, e.g., dollars. Overridden in subclass.

setField

public void setField(java.lang.String section,
                     java.lang.String item,
                     java.lang.String value)
              throws ContractException
Set a field that can be recorded and returned. This goes into a file.fuz that is independant of the external files. Can only be called if saveAsFile() is called first as the object needs a file name context to save to. We probably need a setArray and set multiline as well.

getField

public java.lang.String getField(java.lang.String section,
                                 java.lang.String item)
Get a field named item from section.

getArray

public java.lang.String[] getArray(java.lang.String section,
                                   java.lang.String item)
Get an array named item from section.

getSectionItems

public java.lang.String[] getSectionItems(java.lang.String section)
Get the fieldnames in a section Doesn't look in myFile.

getSectionNames

public java.lang.String[] getSectionNames()
Get all the section names. Doesn't look in myFile.

removeFiles

public void removeFiles()
Remove these files - only - from the store.

removeFiles

public void removeFiles(java.io.File dir)
Remove these files - only - from dir.

removeFiles

protected void removeFiles(java.io.File dir,
                           java.lang.String name)
Given a root name, remove all my files from dir.

saveAsFile

public void saveAsFile(java.io.File dir)
                throws java.io.IOException
Save the contract into file(s) rooted in a unique name.

saveAsFile

public void saveAsFile(java.io.File dir,
                       java.lang.String name)
                throws java.io.IOException
Save the contract into file(s) rooted in name. These files are saved if changed: name.asc name.loc This files is always written: name.fuz

reSaveAsFile

public void reSaveAsFile(java.io.File dir,
                         Contract contract)
                  throws java.io.IOException

reSaveAsFile

public void reSaveAsFile(Contract contract)
                  throws java.io.IOException
re-Save the contract if it has changed. These files are saved if changed: name.loc The rest are ignored.

saveFile

protected void saveFile(java.io.File f,
                        byte[] data)
                 throws java.io.IOException
Save a file. Don't overwrite an existing one, move it if it is different, and accept the existing file as OK if it is the same.

isChanged

protected boolean isChanged(java.io.File f,
                            byte[] data)
                     throws java.io.IOException

flushMyFile

protected void flushMyFile()
                    throws java.io.IOException

getContents

public java.lang.String getContents()
                             throws java.io.IOException

hashCode

public int hashCode()
Overrides:
hashCode in class java.lang.Object

equals

public boolean equals(java.lang.Object obj)
only checks the contract hash, does not test local file or fuz file!
Overrides:
equals in class java.lang.Object

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

getBase

public static java.lang.String getBase(java.lang.String contract)
                                throws ContractException
Take a string, interpret it is a Ricardian Contract, and extract out the base - the part from the BEGIN SIG to the keys.

main

public static void main(java.lang.String[] arg)
                 throws ContractException,
                        java.io.IOException