JAZOON'13 - Anatole Tresch - Go for the money (JSR 354) !
description
Transcript of JAZOON'13 - Anatole Tresch - Go for the money (JSR 354) !
Go for the Money - JSR 354
Introduction & Overview
Jazoon 2013
23th October 2013
Anatole Tresch
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
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
Agenda
3
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
History and Motivation
4 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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/m
oney.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.
Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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
7 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Overview
8 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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
9 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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
10 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Currencies and Monetary Amounts
javax.money
11 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Currencies
Some Details about ISO 4217
12
Special Codes
Ambiguities
Unmodeled Aspects
Minor/Major
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)
Legal acceptance, e.g. Indian Rupees are legally accepted in Buthan/Nepal, but not vice versa.
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
Currencies (continued)
”Virtual” Currencies
13 13th June 2013
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
Currencies (continued)
API and Implementation
14
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
public interface CurrencyUnit{
public String getCurrencyCode();
}
API
public final class MoneyCurrency {
public String getCurrencyCode();
public int getNumericCode();
public int getDefaultFractionDigits();
}
RI
*not part of RI
Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Currencies (continued)
Usage Samples MoneyCurrency
MoneyCurrency currency1 = MoneyCurrency.of("USD");
MoneyCurrency currency2 = MoneyCurrency.of("1234");
MoneyCurrency.Builder builder = new MoneyCurrency.Builder();
builder.setCurrencyCode("BTC");
builder.setDefaultFractionDigits(8);
MoneyCurrency bitcoin = builder.build();
15
• Access a MoneyCurrency
• Create a MoneyCurrency
• Register a MoneyCurrency
MoneyCurrency bitcoin = builder.build(true);
Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Monetary Amounts
General Aspects
16
Amount = Currency + Numeric Value
Performance vs. Precision and scale
Wide Numeric Range
Rounding, non standard Rounding
Financial Calculations and Functions
ME Compatibility
Fluent API
Go for the money - JSR 354 - http://java.net/projects/javamoney
Original Rounded Remark
123.452 123.45 3. digit <3 -> round down
123.456 123.455 3<= 3. digit <=7 -> change to 5
123.459 123.46 3. digit >=8 -> round up
23th October 2013
Monetary Amounts (continued)
Decisions
17
• 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
Monetary Amounts (continued)
API
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);
}
18
• Interface MonetaryAmount for Interoperability
Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Monetary Amounts (continued)
RI: Money (based on BigDecimal)
public final class Money implements MonetaryAmount{
public CurrencyUnit getCurrency();
public Money add(MonetaryAmount amount);
public Money subtract(MonetaryAmount amount);
public Money multiply(MonetaryAmount amount);
public Money multiply(Number amount);
[…]
public boolean isGreaterThan(MonetaryAmount amount);
public boolean isLessThan(MonetaryAmount amount);
public boolean isLessThanOrEqual(MonetaryAmount amount);
[…]
public Money with (MonetaryAdjuster adjuster);
public <T> T query(MonetaryQuery<T> query);
[…]
public BigDecimal asNumber();
[…]
public static Money from(MonetaryAmount amount);
}
19 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Monetary Amounts (continued)
RI: FastMoney (based on long)
public final class FastMoney implements MonetaryAmount{
public CurrencyUnit getCurrency();
public FastMoney add(MonetaryAmount amount);
public FastMoney subtract(MonetaryAmount amount);
public FastMoney multiply(MonetaryAmount amount);
public FastMoney multiply(Number amount);
[…]
public boolean isGreaterThan(MonetaryAmount amount);
public boolean isLessThan(MonetaryAmount amount);
public boolean isLessThanOrEqual(MonetaryAmount amount);
[…]
public FastMoney with (MonetaryAdjuster adjuster);
public <T> T query(MonetaryQuery<T> query);
[…]
public BigDecimal asNumber();
[…]
public static FastMoney from(MonetaryAmount amount);
}
20 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Monetary Amounts (continued)
Usage Samples
Money amount1 = Money.of("USD", 1234566.15);
// USD 1234566.15
FastMoney fAmt = FastMoney.of("USD", 1234566.15);
// USD 1234566.15
Money amount1 = amount1.substract(fAmt);
MoneyCurrency currency = MoneyCurrency.of(“1234");
Money amount2 = Money.of(currency, 1234566.15);
// 1234 1234566.15
Amount2 = amount2.multiply(200)
.divide(0.5432)
.subtract(
Money.of("1234", 1234566.15));
21 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Extension Points
javax.money
22 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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
Extension Points (continued)
MonetaryAdjuster: Use Cases
Extend the algorithmic capabilities
• Percentages
• Permil
• Different Minor Units
• Different Major Units
• …
Rounding
Currency Conversion
…
24 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Extension Points (continued)
MonetaryAdjuster: Usage Examples
25
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
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
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;
}
}
27
*not part of RI, but in the javamoney OSS project
Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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
28 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
JavaMoney OSS Project
org.javamoney.*
29 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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!
30 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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);
31 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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
32 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
JavaMoney OSS Project (continued)
Flexible Formatting API with token based format builder
Predicates API
Auto-Rounding values
Financial Calculations (ongoing)
Compound Values
33 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
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
34 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
Q & A
35 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013
The End
36 Go for the money - JSR 354 - http://java.net/projects/javamoney 23th October 2013