go for the money - jsr 354

41
Go for the Money Introduction to JSR 354 2014 March 2014 Go for the money - JSR 354 - http://java.net/projects/javamoney

Upload: anatole-tresch

Post on 30-Oct-2014

231 views

Category:

Technology


1 download

DESCRIPTION

The presentation introduces JSR 354 (Currency and Money). It will discuss the API from a user perspective, and gives details on the design decisions done. The presentation will demonstrate how the JSR models monetary capabilities, monetary amounts, currencies, roundings, financial arithmetics as well as formatting and currency conversion in a platform independent and flexible way. The presentation is targeting more advanced developers being interested in modeling financial concerns in Java and advanced API design in general.

TRANSCRIPT

Page 1: Go for the Money - JSR 354

Go for the Money

Introduction to JSR 354

2014

March 2014

Go for the money - JSR 354 - http://java.net/projects/javamoney

Page 2: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Bio

Anatole Tresch

Consultant, Coach

Credit Suisse

Technical Coordinator & Architect

Specification Lead JSR 354

Regular Conference Speaker

Driving Java EE Config

Twitter/Google+: @atsticks

[email protected]

[email protected]

Java Config Discussion https://groups.google.com/forum/#!forum/java-config

Java Config Blog: http://javaeeconfig.blogspot.ch

Zurich Java Community (Google Community)

Zurich Hackergarten

2

Page 3: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Agenda

3

History and Motivation

Overview

Currencies and Monetary Amounts

Extension Points

Currency Conversion

Formatting & Parsing

JavaMoney OSS Project

Page 4: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

History and Motivation

4

Page 5: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Earlier Approaches

5

Martin Fowler: A large proportion of the computers in this world manipulate money, so it’s

always puzzled me that money isn’t

actually a first class data type in any

mainstream programming language.

The lack of a type causes problems,

the most obvious surrounding currencies…

see http://martinfowler.com/eaaCatalog/money.html

Eric Evans – Time and Money: On project after project, software developers have to reinvent the wheel, creating objects for

simple recurring concepts such as “money”

and “currency”. Although most languages have

a “date” or “time” object, these are

rudimentary, and do not cover many needs,

such as recurring sequences of time, durations of time, or intervals of time. …

To be quite frank, their code isn’t more than an academic POC, factories called dollars() or euros() are useless in real globally deployed

frameworks, but he made a good point.

Page 6: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Motivation

Monetary values are a key feature

Existing java.util.Currency class is strictly representing

ISO-4217 standard currencies.

No standard value type for monetary amounts

No support for monetary arithmetic or currency conversion

No support for historic currencies

JDK Formatting features lack of flexibility

6

Page 7: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Scope & Schedule

Standalone scope, minimum Java Version: 7

Targeting possible later platform inclusion

Started in 2012 by Victor Grazi

Early Draft Review May 2013

Public Review finished January 2013!

2nd Public Review on the way!

Final until end of 2014

7

Page 8: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Overview

8

Page 9: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

General Considerations

Minimal extendible API

Support Value Types, interfaces for interop

Design for the JDK, but stay flexible

Naming and some design aspects similar to ThreeTen

Suitable for SE, ME and EE!

Compatibility with JodaMoney would be a benefit

9

Page 10: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Overview of JSR 354 and Javamoney

API (javax.money):

CurrencyUnit, MonetaryAmount, MonetaryOperator,

MonetaryQuery, CurrencyConversion, ExchangeRate,

MonetaryAmountFormat, MonetaryException;

MonetaryCurrencies, MonetaryAmounts, MonetaryRoundings,

MonetaryConversions, MonetaryFormats

RI (org.javamoney.moneta): BuildableCurrencyUnit, Money, FastMoney, MonetaryFunctions

TCK (org.javamoney.tck):

Javamoney (GitHub OSS project): org.javamoney…

format (extended API)

currencies (mapping)

Regions

Validity

calc

10

Page 11: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currencies and Monetary Amounts

javax.money

11

Page 12: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currencies

Some Details about ISO 4217

12

Special Codes

Ambiguities

Unmodeled

Aspects

Minor units

Precious Metals (XAU, XAG) Testing (XTS) No Currency (XXX) Supranational currencies, e.g. East Caribbean dollar, the CFP franc, the CFA franc.

CFA franc: West African CFA franc und Central African

CFA franc = denotes 2 effectively interchangeable (!). Switzerland: CHF, CHE (WIR-EURO), CHW (WIR) USA: USD, USN (next day), USS (same day) Reassignments of Codes

Legal acceptance, e.g. Indian Rupees are legally accepted in Buthan/Nepal, but not vice versa. multiple minors, supermajors

Typically 1/100, rarely 1/1000, but also 1/5 (Mauritania, Madagaskar), 0.00000001 (BitCoin)

Page 13: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currencies (continued)

”Virtual” Currencies

13

Video Game Currencies Gold, Gil, Rupees, Credits, Gold Rings, Hearts, Zenny, Potch, Munny, Nuyen…

Facebook Credits Virtual currency you can use to buy virtual goods in any games or apps of the Facebook platform that accept payments. You can purchase Facebook Credits directly from within an app using your credit card, PayPal, mobile phone and many other local payment methods.

Bitcoin (sign: BTC) Bittcoin is a decentralized digital currency based on an open-source, peer-to-peer internet protocol. It was introduced by a pseudonymous developer named Satoshi Nakamoto in 2009.

Page 14: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currencies (continued)

API

14

Allow currencies with arbitrary other currency codes

Register additional Currency Units using an flexible SPI Fluent API using a Builder (RI only)

Historic Validity of currencies related to regions/countries and vice

versa (not part of JSR, but javamoney OSS project)

public interface CurrencyUnit{

public String getCurrencyCode();

public int getNumericCode();

public int getDefaultFractionDigits();

}

public final class MonetaryCurrencies{

public CurrencyUnit getCurrency(String currencyCode);

public CurrencyUnit getCurrency(Locale locale);

public boolean isCurrencyAvailable(String currencyCode);

public boolean isCurrencyAvailable(String locale);

}

Page 15: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currencies (continued)

API Samples

CurrencyUnit currency1 = MonetaryCurrencies.getCurrency("USD");

CurrencyUnit currency2 = MonetaryCurrencies.getCurrency(

Locale.GERMANY);

CurrencyUnit bitcoin = new BuildableCurrencyUnit.Builder("BTC")

.setNumericCode(123456)

.setDefaultFractionDigits(8)

.create();

15

Access a CurrencyUnit

Build a CurrencyUnit (RI only)

Register a CurrencyUnit

CurrencyUnit bitcoin = ….create(true);

Page 16: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Monetary Amounts

General Aspects

16

Amount = Currency + Numeric Value

+ Capabilities

Arithmetic Functions, Comparison

Fluent API

Financial Calculations and Functions

Rounding, non standard Rounding

Performance vs. Precision and scale

Wide Numeric Range

ME Compatibility

Page 17: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Monetary Amounts (continued)

Key Decisions

17

Support Several Numeric Representations (instead of one

single fixed value type)

Use functional design for extendible functionality (MonetaryOperator, MonetaryQuery)

Define Implementation Recommendations

• Rounding should to be modelled as separate concern (a MonetaryOperator)

• Ensure Interoperability by the MonetaryAmount

interface

• Precision/scale capabilities should be inherited to its

operational results.

Page 18: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Monetary Amounts (continued)

The API public interface MonetaryAmount{

public CurrencyUnit getCurrency();

public NumberValue getNumber();

public MonetaryContext getMonetaryContext();

public MonetaryAmount with(MonetaryOperator operator);

public <R> R query(MonetaryQuery<R> query);

public MonetaryAmountFactory<? extends MonetaryAmount> getFactory();

public boolean isLessThanOrEqualTo(MonetaryAmount amt);

public boolean isLessThan(MonetaryAmount amt);

public boolean isEqualTo(MonetaryAmount amt);

public int signum();

public MonetaryAmount add(MonetaryAmount amount);

public MonetaryAmount subtract(MonetaryAmount amount);

public MonetaryAmount divide(long number);

public MonetaryAmount multiply(Number number);

public MonetaryAmount remainder(double number);

public MonetaryAmount stripTrailingZeros();

}

18

Page 19: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Monetary Context

Model Amount Capabilities

19

Describes the capabilities of a MonetaryAmount.

Accessible from each MonetaryAmount instance.

Allows querying a feasible implementation type from

MonetaryAmounts.

Contains

common aspects

Max precision, max scale, amount flavor

Arbitrary attributes

E.g. RoundingMode, MathContext, …

Page 20: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Monetary Context (continued)

The API

public final class MonetaryContext extends AbstractContext

implements Serializable {

public static enum AmountFlavor{ PRECISION, PERFORMANCE, UNDEFINED }

public int getPrecision();

public int getMaxScale();

public AmountFlavor getAmountFlavor();

public Class<? extends MonetaryAmount> getAmountType();

public static final class Builder{…}

}

public abstract class AbstractContext implements Serializable{

public <T> T getNamedAttribute(Class<T> type, Object key,

T defaultValue);

public <T> T getNamedAttribute(Class<T> type, Object key);

public <T> T getAttribute(Class<T> type, T defaultValue);

public <T> T getAttribute(Class<T> type);

public Set<Class<?>> getAttributeTypes();

}

20

Page 21: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Creating Monetary Amounts

Monetary Amount Factory

21

Creates new instances of MonetaryAmount.

Declares

The concrete MonetaryAmount implementation type

returned.

The min/max MonetaryContext supported.

Can be configured with a target

CurrencyUnit

A numeric value

MonetaryContext.

Page 22: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Creating Monetary Amounts (continued)

Monetary Amount Factory

public interface MonetaryAmountFactory<T extends MonetaryAmount> {

Class<? extends MonetaryAmount> getAmountType();

MonetaryAmountFactory<T> setCurrency(String currencyCode);

MonetaryAmountFactory<T> setCurrency(CurrencyUnit currency);

MonetaryAmountFactory<T> setNumber(double number);

MonetaryAmountFactory<T> setNumber(long number);

MonetaryAmountFactory<T> setNumber(Number number);

MonetaryAmountFactory<T> setContext(MonetaryContext monetaryContext);

MonetaryAmountFactory<T> setAmount(MonetaryAmount amount);

T create();

MonetaryContext getDefaultMonetaryContext();

MonetaryContext getMaximalMonetaryContext();

}

22

Page 23: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Creating Monetary Amounts

Usage Samples

// Using the default type

MonetaryAmount amount1 = MonetaryAmounts.getAmountFactory()

.setCurrency("USD“)

.setNumber(1234566.15)

.create();

// Using an explicit type

Money amount2 = MonetaryAmounts.getAmountFactory(Money.class)

.setCurrency("USD“)

.setNumber(1234566.15)

.create();

// Query a matching implementation type

Class<? extends MonetaryAmount> type = MonetaryAmounts.queryAmontType(

new MonetaryContext.Builder()

.setAmountFlavor(

AmountFlavor.PERFORMANT)

.create());

MonetaryAmount amount3 = MonetaryAmounts.getAmountFactory(type)

.setCurrency("USD“)

.setNumber(1234566.15)

.create();

23

Page 24: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Extension Points

javax.money

24

cmp Components

Component1

ProvidedInterface1

RequiredInterface

Component2

RequiredInterface

Page 25: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Extension Points

MonetaryOperator

Takes an amount and procudes some other amount.

• With different value

• With different currency

• Or both

// @FunctionalInterface

public interface MonetaryOperator {

public MonetaryAmount apply(MonetaryAmount amount);

}

• Operators then can be applied on every MonetaryAmount:

public interface MonetaryAmount{

public MonetaryAmount with (MonetaryOperator operator);

}

25

Page 26: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Extension Points (continued)

MonetaryOperator: Use Cases

Extend the algorithmic capabilities

• Percentages

• Permil

• Different Minor Units

• Different Major Units

• Rounding

• Currency Conversion

• Financial Calculations

• …

26

Page 27: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Extension Points (continued)

MonetaryOperator Example: Rounding and Percentage

27

// round an amount

MonetaryOperator rounding =

MoneyRoundings.getRounding(

MonetaryCurrencies.getCurrency(“USD”));

Money amount = Money.of(“USD”, 12.345567);

Money rounded = amount.with(rounding); // USD 12.35

// MonetaryFunctions, e.g. calculate 3% of it

Money threePercent = rounded.with(

MonetaryFunctions.getPercent(3));

// USD 0.3705

Page 28: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Extension Points (continued)

MonetaryQuery

A MonetaryQuery takes an amount and procuces an arbitrary

result:

// @FunctionalInterface

public interface MonetaryQuery<T> {

public T queryFrom(MonetaryAmount amount);

}

Queries then can be applied on every MonetaryAmount:

public interface MonetaryAmount {

public <T> T query (MonetaryQuary<T> query);

}

28

Page 29: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currency Conversion

javax.money.convert.*

29

Page 30: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currency Conversion

ExchangeRate

A ExchangeRate models a conversion between two currencies:

• Base CurrencyUnit

• Terminating/target CurrencyUnit

• Provider

• Conversion Factor, where M(term) = M(base) * f

• Additional attributes (ConversionContext)

• Rate chain (composite rates)

Rates may be direct or derived (composite rates)

30

Page 31: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currency Conversion

ExchangeRateProvider

// access default provider (chain)

ExchangeRateProvider prov =

MonetaryConversions.getExchangeRateProvider();

// access a provider explicitly

prov = MonetaryConversions.getExchangeRateProvider("IMF");

// access explicit provider chain

prov = MonetaryConversions.getExchangeRateProvider("ECB", "IMF");

// access Exchange rates

ExchangeRate rate = provider.getExchangeRate("EUR", "CHF");

// Passing additional parameters

ExchangeRate rate = provider.getExchangeRate("EUR", "CHF",

ConversionContext.of(

System.currentTimeMillis() + 2000L) );

31 Go for the money - JSR 354 - http://java.net/projects/javamoney

Page 32: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Currency Conversion (continued)

Performing Conversion

Accessing a CurrencyConversion (always targeted to a terminating CurrencyUnit):

// access from a ExchangeRateProvider

ExchangeRateProvider prov = …;

CurrencyConversion conv = prov.getCurrencyConversion("INR");

// access it directly (using default rate chain)

conv = MonetaryConversions.getConversion("INR");

// access it, using explicit provider chain

conv = MonetaryConversions.getConversion("INR", "ECB", "IMF");

Performing conversion:

MonetaryAmount chfAmount = MonetaryAmounts.of("CHF",10.50);

MonetaryAmount inrAmount = chfAmount.with(conv); // around EUR 8.75

32

Page 33: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Formatting and Parsing

javax.money.format.*

33

Page 34: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Formatting and Parsing

MonetaryAmountFormat

Similar to java.text.DecimalFormat, but also ME

compatible

Configured by AmountStyle, CurrencyStyle,

AmountFormatSymbols

Supports also custom formats

Building AmountStyle using a fluent API

Preconfigured format access is also possible

34 Go for the money - JSR 354 - http://java.net/projects/javamoney

Page 35: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Formatting and Parsing (continued)

MonetaryAmountFormat: Usage Example

// Access a provided format

MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(

new Locale(“”, “in”));

System.out.println(format.format(

Money.of("INR", 39101112.123456))));

output> INR 3,91,01,112.10

35 Go for the money - JSR 354 - http://java.net/projects/javamoney

Page 36: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

JavaMoney OSS Project

org.javamoney.*

36

Page 37: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

JavaMoney OSS Project

General

During the JSR additional features were discussed…

… and implemented!

This ensured the design is working

Helped to consolidate discussions

But…

exceeeds the JSR’s scope

So we created an OSS project!

37

Page 38: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

JavaMoney OSS Project

Extended Currency Services

Currency namespaces (e.g. ISO, VIRTUAL, …)

Currency namespace mapping

Validity Services (Historization API)

• access of historic currency data related to regions

Region Services

Region Forest

• Unicode CLDR region tree

• ISO 2-, 3-letter countries

• Custom Trees

Extendible token-based Formatting API

Financial Calculations & Formulas

38

Page 39: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Links

Umbrella Page: http://javamoney.org JSR 354: http://jcp.org

Java.net Project: http://java.net/projects/javamoney GitHub Project (JSR and JavaMoney):

https://github.com/JavaMoney/javamoney JUG Chennai Adoption (TrakStok): https://github.com/jugchennaiadoptjava/TrakStok

Twitter: @jsr354 Cash Rounding: http://en.wikipedia.org/wiki/Swedish_rounding

39

Page 40: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

Q & A

40

Page 41: Go for the Money - JSR 354

Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014

The End

41