jsr 354 ljc-hackday
DESCRIPTION
Introduction shown to LJC people on the Hackday end of June 2014.TRANSCRIPT
Go for the Money
JSR 354 Hackday
London Java Community 2014
June 2014
Go for the money –JSR 354 Hackday
http://java.net/projects/javamoney
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
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
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Agenda
3
Introduction
Possible Topics
Easy:
API Challenge: Moneymachine
Medium:
Adding functonalities to the RI, e.g. Special Roundings
BitCoin and other currencies
Test Financial Formulas in JavaMoney
Hard Improve FastMoney
Measure CPU and Memory Consumption
Write a Complex Integration Sample
Setup
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Introduction
javax.money
4
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Currencies
API
5
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);
}
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();
6
Access a CurrencyUnit
Build a CurrencyUnit (RI only)
Register a CurrencyUnit
CurrencyUnit bitcoin = ….create(true);
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Monetary Amounts
General Aspects
7
Amount = Currency + Numeric Value
+ Capabilities
Arithmetic Functions, Comparison
Fluent API
Functional design for extendible functionality
(MonetaryOperator, MonetaryQuery)
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Monetary Amounts (continued)
Key Decisions
8
Support Several Numeric Representations (instead of one
single fixed value type)
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.
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();
}
9
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Monetary Context
Modeling Amount Capabilities
10
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, implementation type
Arbitrary attributes
E.g. RoundingMode, MathContext, …
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 int getPrecision();
public int getMaxScale();
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();
}
11
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Creating Monetary Amounts
Monetary Amount Factory
12
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.
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);
MonetaryContext getDefaultMonetaryContext();
MonetaryContext getMaximalMonetaryContext();
T create();
}
13
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
MonetaryContext monCtx = new MonetaryContext.Builder()
.setAmountFlavor(
AmountFlavor.PERFORMANT)
.create();
Class<? extends MonetaryAmount> type = MonetaryAmounts.queryAmontType(
monCtx);
MonetaryAmountFactory<?> fact = MonetaryAmounts.queryAmountFactory(
monCtx);
14
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);
…
}
15
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
• …
16
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Extension Points (continued)
MonetaryOperator Example: Rounding and Percentage
17
// 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
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);
…
}
18
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Currency Conversion
javax.money.convert.*
19
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)
20
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) );
21 Go for the money - JSR 354 - http://java.net/projects/javamoney
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
22
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Formatting and Parsing
javax.money.format.*
23
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Formatting and Parsing
MonetaryAmountFormat
Similar to java.text.DecimalFormat accessible by Locale
Configured by AmountFormatContext
Supports also custom formats (configured an accessed using
AmountFormatContext)
Building AmountFormatContext using a fluent API
Thread safe!
24 Go for the money - JSR 354 - http://java.net/projects/javamoney
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))));
-> INR 3,91,01,112.10
// Access a custom format
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(
AmountFormatContext.of(“myCustomFormat”));
25 Go for the money - JSR 354 - http://java.net/projects/javamoney
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
JavaMoney OSS Project
org.javamoney.*
26
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
27
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Links
Current Spec (work in progress, comments allowed): https://docs.google.com/document/d/1FfihURoCYrbkDcSf1W
XM6fHoU3d3tKooMnZLCpmpyV8/edit GitHub Project (JSR and JavaMoney):
https://github.com/JavaMoney/javamoney Umbrella Page: http://javamoney.org JSR 354: http://jcp.org
Java.net Project: http://java.net/projects/javamoney JUG Chennai Adoption (TrakStok):
https://github.com/jugchennaiadoptjava/TrakStok
Twitter: @jsr354 Cash Rounding: http://en.wikipedia.org/wiki/Swedish_rounding
28
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
HackDay - Possible Topics
29
Easy
- Money Machine Medium
- Extending RI - RI User Guide - JavaMoney Lib
- TCK
Hard
- L & P - Create Sample App - Implement a RI
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – The Easy Way
API Challenge: MoneyMachine
30
Objective: Test the API for usability, make proposals to
improve
How:
Checkout/update the MoneyMachine project from https://github.com/atsticks/moneymachine.git
Implement the classes in the src/main/java to
make the tests green (skeletons are already there) The challenge will guide you throughout the whole JSR
Overall 40+ test cases of different complexity (easy to medium), you may also select only a subset ;-)
Add improvement proposals to the JSRs JIRA on
java.net Blog your (hopefully positive) experience, twitter, …
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – The Easy Way
API Challenge: MoneyMachine Example
31
/**
* This class has to be implemented and helps us giving feedback on the JSR's API. This
* part of the
* project deals with basic aspects such as getting currencies and amounts.
* Created by Anatole on 07.03.14.
*/
public class Basics{
/**
* Get a CurrencyUnit using a currency code.
*
* @param currencyCode the currency code
* @return the corresponding CurrencyUnit instance.
*/
public CurrencyUnit getProvidedCurrency(String currencyCode){
throw new UnsupportedOperationException();
}
/**
* Get a CurrencyUnit using a Locale, modeling a country.
*
* @param locale The country locale.
* @return the corresponding CurrencyUnit instance.
*/
public CurrencyUnit getProvidedCurrency(Locale locale){
throw new UnsupportedOperationException();
}
...
}
Describes
the task to
be done
(incl. Some
hints)
Replace this
with
according
code
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – The Easy Way
API Challenge: MoneyMachine Testing
32
To check your
implementation is correct,
simply execute the test suite
Correct ;-)
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 - Medium
Extending the Reference Implementation
33
Objective: Extend the RI
How:
Discuss your ideas with me to see where your idea fits
best Additional Roundings
Additional Currencies
Additional Exchange Rate Providers Additional Formats
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 - Medium
Documenting the Reference Implementation
34
Objective: Document the RI (user guide)
How:
Take a Topic
Write documentation (asciidoc)
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – Medium Level
Helping on JavaMoney Library
35
Objective: Help on JavaMoney
How:
Financial calculations in calc need tests
Factor out Dataservice Layer All Modules require check on JavaDocs, Tests
Enhance APIs with Java 8 features (e.g. 310 types)
Write/enhance user guide (asciidoc) New functionalities, ideas?
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – Medium Level
Help on the TCK
36
Objective: Help finalizing the TCK
How:
Write TCK tests (only a few missing)
Check Test Failure Messages Check Test Semantics
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – Medium Level
Helping on the TCK (continued)
37
/**
* Test successful conversion for possible currency pairs.<br/>
* Hint: you may only check for rate factory, when using a hardcoded
* ExchangeRateProvider, such a provider
* must be also implemented and registered as an SPI.
*/
@Test @SpecAssertion(id = "432-A1", section="4.3.2")
public void testConversion(){
Assert.fail();
}
Describes the test
very briefly
References the according
section in the spec
Add your test code here.
Hint 1: if you are unsure first write a story line
Hint 2: some aspects may require to implement multiple
tests, just ensure the annotations are on all tests
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – The Hard Way
Analyze and Improve Performance
38
Objective: Improve Performance
How:
Measure Performance and Memory Consumption Define corresponding improvement ideas Implement improvements Known aspects:
FastMoney implementation could be faster, especially for division
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – The Hard Way
Write an Overall Example Application
39
Objective: Implement a Deployable Example Application
How:
Define Application Storyline Define Screens etc. Implement everything needed Deploy on CloudBees ?
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Adoption Areas JSR 354 – The Hard Way
Write an Implementation
40
Objective: Ensure Specification / API Quality
How:
Implement whole or parts of the specification Check the implementation against the TCK
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Setup
41
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Setup
42
• Install VirtualBox, if not yet done, download from https://www.virtualbox.org
• Download the prepared image and start it • Login with debian/debian • Open the IDE of your choice (Eclipse, IntelliJ and
Netbeans are preinstalled and setup) • Update the projects/repositories
• For Contributors:
• Ensure you have a GitHub user account • Create your own Branch of the corresponding repositories
• Switch your local repositories on your VM, on which you want to commit, to your branched repos
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Q & A
43
Go for the money - JSR 354 - http://java.net/projects/javamoney March 2014
Go for it!
44