Top Banner
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
44

JSR 354 LJC-Hackday

Oct 30, 2014

Download

Technology

Anatole Tresch

Introduction shown to LJC people on the Hackday end of June 2014.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: JSR 354 LJC-Hackday

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

Page 2: JSR 354 LJC-Hackday

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: JSR 354 LJC-Hackday

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

Page 4: JSR 354 LJC-Hackday

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

Introduction

javax.money

4

Page 5: JSR 354 LJC-Hackday

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);

}

Page 6: JSR 354 LJC-Hackday

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);

Page 7: JSR 354 LJC-Hackday

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)

Page 8: JSR 354 LJC-Hackday

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.

Page 9: JSR 354 LJC-Hackday

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

Page 10: JSR 354 LJC-Hackday

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, …

Page 11: JSR 354 LJC-Hackday

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

Page 12: JSR 354 LJC-Hackday

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.

Page 13: JSR 354 LJC-Hackday

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

Page 14: JSR 354 LJC-Hackday

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

Page 15: JSR 354 LJC-Hackday

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

Page 16: JSR 354 LJC-Hackday

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

Page 17: JSR 354 LJC-Hackday

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

Page 18: JSR 354 LJC-Hackday

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

Page 19: JSR 354 LJC-Hackday

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

Currency Conversion

javax.money.convert.*

19

Page 20: JSR 354 LJC-Hackday

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

Page 21: JSR 354 LJC-Hackday

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

Page 22: JSR 354 LJC-Hackday

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

Page 23: JSR 354 LJC-Hackday

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

Formatting and Parsing

javax.money.format.*

23

Page 24: JSR 354 LJC-Hackday

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

Page 25: JSR 354 LJC-Hackday

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

Page 26: JSR 354 LJC-Hackday

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

JavaMoney OSS Project

org.javamoney.*

26

Page 27: JSR 354 LJC-Hackday

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

Page 28: JSR 354 LJC-Hackday

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

Page 29: JSR 354 LJC-Hackday

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

Page 30: JSR 354 LJC-Hackday

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, …

Page 31: JSR 354 LJC-Hackday

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

Page 32: JSR 354 LJC-Hackday

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 ;-)

Page 33: JSR 354 LJC-Hackday

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

Page 34: JSR 354 LJC-Hackday

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)

Page 35: JSR 354 LJC-Hackday

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?

Page 36: JSR 354 LJC-Hackday

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

Page 37: JSR 354 LJC-Hackday

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

Page 38: JSR 354 LJC-Hackday

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

Page 39: JSR 354 LJC-Hackday

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 ?

Page 40: JSR 354 LJC-Hackday

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

Page 41: JSR 354 LJC-Hackday

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

Setup

41

Page 42: JSR 354 LJC-Hackday

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

Page 43: JSR 354 LJC-Hackday

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

Q & A

43

Page 44: JSR 354 LJC-Hackday

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

Go for it!

44