JAZOON'13 - Anatole Tresch - Go for the money (JSR 354) !
1. Jazoon 2013
Go for the Money - JSR 354
Introduction & Overview
Anatole Tresch
23th October 2013
2. Bio
Anatole Tresch
Consultant, Coach
Credit Suisse
Core Framework Engineer &
Architect
Specification Lead JSR 354
Regular Conference Speaker
Involved also in EE/Config
Twitter/Google+: @atsticks
atsticks@java.net
anatole.tresch@credit-suisse.com
Java Config JSR https://groups.google.com/forum/#!forum/java-config
Zurich Java Community
https://plus.google.com/u/0/communities/106363890913137321158
Looking for enthusiasts for DevoXX4Kids Zurich, Zurich Codegarten
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
2
3. Agenda
History and Motivation
Overview
Currencies and Monetary Amounts
Extension Points
Formatting & Parsing
JavaMoney OSS Project
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
3
4. History and Motivation
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
4
5. Earlier Approaches
Martin Fowler:
Eric Evans – Time and Money:
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/m
oney.html
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.
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
5
6. 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
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
6
7. Scope & Schedule
Standalone scope
Minimum Java Version: 7
Targeting Platform
Java SE 9: Early 2016
Java ME/Embedded 8 oder 9
Started in 2012 by Victor Grazi
Renewal Ballot in February 2013
Early Draft Review May 2013
Public Review starting now!
Final until end of 2013, early 2014
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
7
8. Overview
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
8
9. General Considerations
Minimal, extendible API
Design for the JDK! Use ValueTypes, Interfaces for Interoperation
Naming and Basic Design similar to ThreeTen
Suitable for SE, ME and EE!
Compatibitliy with JodaMoney would be a benefit
for the community
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
9
10. Overview of JSR 354 and Javamoney
API: javax.money
CurrencyUnit, MonetaryAmount, MonetaryAdjuster,
MonetaryQuery, MonetaryException
RI: org.javamoney.moneta
MoneyCurrency, Money, FastMoney, MonetaryRoundings,
MonetaryFunctions
TCK: org.javamoney.tck
Javamoney extensions (GitHub OSS project):
org.javamoney.conversion
org.javamoney.format
org.javamoney.ext
org.javamoney.regions
org.javamoney.validity
org.javamoney.calc
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
10
11. Currencies and Monetary Amounts
javax.money
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
11
12. Currencies
Some Details about ISO 4217
Special Codes
Precious Metals (XAU, XAG)
Testing (XTS)
No Currency (XXX)
Supranational currencies, e.g. East Caribbean dollar, the
CFP franc, the CFA franc.
Ambiguities
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)
Unmodeled
Aspects
Legal acceptance, e.g. Indian Rupees are legally accepted in
Buthan/Nepal, but not vice versa.
Minor/Major
units
Typically 1/100, rarely 1/1000, but also 1/5 (Mauritania,
Madagaskar), 0.00000001 (BitCoin), multiple minors,
supermajors
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
12
13. Currencies (continued)
”Virtual” Currencies
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.
Go for the money - JSR 354 - http://java.net/projects/javamoney
13th June 2013
13
14. Currencies (continued)
API and Implementation
Allow currencies with arbitrary other (non ISO 4217) currency
codes
Additional implementation Aspects
Register additional Currencies using an SPI
Fluent API using a Builder
Historic Validity of currencies related to regions/countries and
vice versa
API
RI
public interface CurrencyUnit{
public String getCurrencyCode();
}
public final class MoneyCurrency {
public String getCurrencyCode();
public int getNumericCode();
public int getDefaultFractionDigits();
}
*not part of RI
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
14
15. Currencies (continued)
Usage Samples MoneyCurrency
• Access a MoneyCurrency
MoneyCurrency currency1 = MoneyCurrency.of("USD");
MoneyCurrency currency2 = MoneyCurrency.of("1234");
• Create a MoneyCurrency
MoneyCurrency.Builder builder = new MoneyCurrency.Builder();
builder.setCurrencyCode("BTC");
builder.setDefaultFractionDigits(8);
MoneyCurrency bitcoin = builder.build();
• Register a MoneyCurrency
MoneyCurrency bitcoin = builder.build(true);
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
15
16. Monetary Amounts
General Aspects
Amount = Currency + Numeric Value
Performance vs. Precision and scale
Wide Numeric Range
Rounding, non standard Rounding
Financial Calculations and Functions
ME Compatibility
Fluent API
Rounded
Remark
123.452
123.45
3. digit <3 -> round down
123.456
123.455
3<= 3. digit <=7 -> change to 5
123.459
Go for the money - JSR 354 - http://java.net/projects/javamoney
Original
123.46
3. digit >=8 -> round up
23th October 2013
16
17. Monetary Amounts (continued)
Decisions
•
Allow Several Numeric Representations
•
Use functional design for extended functionality
(MonetaryAdjuster, MonetaryQuery)
•
Add Implementation Recommendations
•
Rounding should to be modelled as separate concern
(a MonetaryAdjuster)
•
Interoperability by the MonetaryAmount interface
•
Precision/scale capabilities should be inherited to its
operational results.
• …
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
17
18. Monetary Amounts (continued)
API
• Interface MonetaryAmount for Interoperability
public interface MonetaryAmount{
public CurrencyUnit getCurrency();
public long getAmountWhole();
public long getAmountFractionNumerator();
public long getAmountFractionDenumerator();
public MonetaryAmount with (MonetaryAdjuster adjuster);
public <T> T query(MonetaryQuery<T> query);
}
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
18
19. Monetary Amounts (continued)
RI: Money (based on BigDecimal)
public final class Money implements MonetaryAmount{
public CurrencyUnit getCurrency();
public
public
public
public
[…]
public
public
public
[…]
public
public
[…]
public
[…]
public
Money
Money
Money
Money
add(MonetaryAmount amount);
subtract(MonetaryAmount amount);
multiply(MonetaryAmount amount);
multiply(Number amount);
boolean isGreaterThan(MonetaryAmount amount);
boolean isLessThan(MonetaryAmount amount);
boolean isLessThanOrEqual(MonetaryAmount amount);
Money with (MonetaryAdjuster adjuster);
<T> T query(MonetaryQuery<T> query);
BigDecimal asNumber();
static Money from(MonetaryAmount amount);
}
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
19
20. Monetary Amounts (continued)
RI: FastMoney (based on long)
public final class FastMoney implements MonetaryAmount{
public CurrencyUnit getCurrency();
public
public
public
public
[…]
public
public
public
[…]
public
public
[…]
public
[…]
public
FastMoney
FastMoney
FastMoney
FastMoney
add(MonetaryAmount amount);
subtract(MonetaryAmount amount);
multiply(MonetaryAmount amount);
multiply(Number amount);
boolean isGreaterThan(MonetaryAmount amount);
boolean isLessThan(MonetaryAmount amount);
boolean isLessThanOrEqual(MonetaryAmount amount);
FastMoney with (MonetaryAdjuster adjuster);
<T> T query(MonetaryQuery<T> query);
BigDecimal asNumber();
static FastMoney from(MonetaryAmount amount);
}
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
20
23. Extension Points
MonetaryAdjuster
A MonetaryAdjuster takes an amount and procudes some other amount.
With different value
With different currency
Or both
public interface MonetaryAdjuster {
public MonetaryAmount adjustInto(MonetaryAmount amount);
}
Adjusters then can be applied on every MonetaryAmount:
public interface MonetaryAmount {
…
public MonetaryAmount with (MonetaryAdjuster adjuster);
…
}
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
24. Extension Points (continued)
MonetaryAdjuster: Use Cases
Extend the algorithmic capabilities
• Percentages
• Permil
• Different Minor Units
• Different Major Units
• …
Rounding
Currency Conversion
…
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
24
25. Extension Points (continued)
MonetaryAdjuster: Usage Examples
MonetaryAdjuster rounding =
MoneyRoundings.getRounding(
MoneyCurrency.of(“USD”));
MontaryAmount myAmount = …;
MonetaryAmount rounded = myAmount.with(myAmount);
// MonetaryFunctions, e.g. calculate 3% of it
MonetaryAmount threePercent = rounded.with(
MonetaryFunctions.getPercent(3));
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
25
26. Extension Points (continued)
MonetaryQuery
A MonetaryQuery takes an amount and procuces an arbitrary result.
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);
…
}
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
27. Extension Points (continued)
MonetaryQuery: Usage Example
Predicates*, e.g. for usage in the JDK 8 Streaming API, can be
implemented as MonetaryQuery:
public final class CHFAmountsOnly
implements MonetaryQuery<Boolean>{
private static final MoneyCurrency chf =
MoneyCurrency.of(«CHF»);
public Boolean select(MonetaryAmount amount){
if(amount.getCurrency().equals(chf)){
return Boolean.TRUE;
}
return Boolean.FALSE;
}
}
*not part of RI, but in the javamoney OSS project
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
27
28. Formatting and Parsing
MonetaryAmountFormat (Reference Implementation)
Similar to java.text.DecimalFormat.
With extended functionality for
currency placement
Number grouping
Enabling fluent API with builders
Example:
MonetaryAmountFormat inrFormat = new
MonetaryAmountFormat.Builder(new Locale(“”, “in”))
.withNumberGroupSizes(3,4)
.build();
String formatted = inrFormat.format(
Money.of("INR", 123456789101112.123456)));
Result:
INR 12,34,56,78,91,01,112.10
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
28
30. JavaMoney OSS Project
General
During the JSR many features were discussed
And implemented
This ensured the design is powerful enough
Helped to consolidate discussions
But…
exceeeds a JSR scope
So we created an OSS project!
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
30
31. JavaMoney OSS Project (continued)
Currency Conversion (org.javamoney.conversion)
ExchangeRateType rateType = ExchangeRateType.of("EZB");
ConversionProvider convProvider =
MonetaryConversion.getConversionProvider(rateType);
// conversion is a MonetaryAdjuster
CurrencyConversion chfConversion =
convProvider.getConverter()
.getCurrencyConversion(MoneyCurrency.of("EUR");
Money chfAmount = …;
Money eurAmount = chfAmount.with(chfConversion);
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
31
32. JavaMoney OSS Project (continued)
Currency Services
Provide Access to Currency Meta-Data
• access currency namespaces
• access currencies within a namespace
• access of historic currency data related to regions
Support mapping of currencies
Region API
Provides a region hierarchy (region forest)
Unicode CLDR region tree
ISO 2-, 3-letter countries
Custom trees
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
32
33. JavaMoney OSS Project (continued)
Flexible Formatting API with token based format builder
Predicates API
Auto-Rounding values
Financial Calculations (ongoing)
Compound Values
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
33
34. Contact Details
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
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
34
35. Q&A
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
35
36. The End
Go for the money - JSR 354 - http://java.net/projects/javamoney
23th October 2013
36