Download Groovy Money - Linux Foundation Events

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Groovy Money
JSR 354 Support for Groovy and Grails
Werner Keil | Anatole Tresch
@wernerkeil | @atsticks | @jsr354
OCTOBER 1-2 , 2015
Agenda
• Introduction
• History
• Overview
• JavaMoney Shelter
• Groovy & Grails
• Demo
• Q&A
2
© 2012-2015 JavaMoney contributors
Werner Keil
• Consultant – Coach
• Creative Cosmopolitan
• Open Source Evangelist
• Software Architect
• JCP EC Member
• JSR 354 EG Member
• Java EE | DevOps Guy …
Twitter @wernerkeil | Email [email protected]
3
© 2012-2015 JavaMoney contributors
3
Anatole Tresch
• Principal Consultant, Trivadis AG
(Switzerland)
• Star Spec Lead JSR 354
• Technical Architect, Lead Engineer
• PMC Member Apache Tamaya
• JUG Switzerland, Zurich Java Community
Twitter @atsticks | Email [email protected]
4
© 2012-2015 JavaMoney contributors
4
History and Motivation
5
© 2012-2015 JavaMoney contributors
Image: Wikipedia
Earlier Approaches
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
6
© 2012-2015 JavaMoney contributors
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.
Motivation
7
•
Monetary values are a key feature to many applications
•
Existing java.util.Currency class is strictly a structure used for
representing ISO-4217 standard currencies.
•
No standard value type to represent a monetary amount
•
No support for currency arithmetic or conversion
•
JDK Formatting features lack of flexibility
© 2012-2015 JavaMoney contributors
Schedule
•
Java SE 7 and 8+
•
Java ME/Embedded 8 oder 9
– Following the EC Merge and Standard/Embedded harmonization,
no JSR should be SE/EE or ME only. Money is so important, and
has almost no legacy in the JDK except java.util.Currency,
that it should be supported by all possible platforms, except
maybe JavaCard for now.
• Final Release: May 2015
8
© 2012-2015 JavaMoney contributors
Overview
9
© 2012-2015 JavaMoney contributors
Overview of JSR 354
•
Core API: javax.money
– CurrencyUnit, MonetaryAmount, MonetaryRounding and
Monetary singleton
•
Conversion: javax.money.convert
– ExchangeRate, CurrencyConverter,
MonetaryConversions singleton
•
Formatting: javax.money.format
– MonetaryAmountFormat, AmountFormatContext,
AmountFormatQuery, MonetaryAmountFormats singleton
•
Reference Implementation: org.javamoney.moneta
•
TCK: org.javamoney.tck
10
© 2012-2015 JavaMoney contributors
Currencies and Amounts
11
© 2012-2015 JavaMoney contributors
Currencies
ISO 4217
Special Codes
Ambiguities
Unmodeled
Aspects
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
Bhutan/Nepal, but not vice versa!
Typically 1/100, rarely 1/1000, but also 1/5 (Mauritania,
Madagascar), 0.00000001 (Bitcoin)
•
•
•
•
Minor units
12
© 2012-2015 JavaMoney contributors
Virtual Currencies
•
Video Game Currencies (Gold, Gil, Rupees, Credits, Gold Rings,
Hearts, Zenny, Potch, Munny, Nuyen…)
•
Facebook Credits are a 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) 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.
13
© 2012-2015 JavaMoney contributors
Improve java.util.Currency
Current Limitations
•
•
•
•
•
•
14
No support for historical Currencies
No support for non standard
Currencies (e.g. cows or camels)
No support for virtual
Currencies (Lindon Dollars Brixton
Pound, Bitcoin, Social Currencies)
No support for custom
schemes (e.g. legacy codes)
Only access by currency
code, or Locale
No support for special use
cases/extensions
© 2012-2015 JavaMoney contributors
Implementation:
JDKCurrencyAdapter
public interface CurrencyUnit{
public String getCurrencyCode();
public int getNumericCode();
public int getDefaultFractionDigits();
// new methods
public CurrencyContext getContext();
}
Access/Create Currencies
Usage
/**
* Shows simple creation of a CurrencyUnit for ISO, backed by JDK
* Currency implementation.
*/
public void forISOCurrencies() {
CurrencyUnit currency = Monetary.getCurrency("USD");
// backed by util.Currency!
}
public void buildACurrencyUnit() {
CurrencyUnitBuilder builder = CurrencyUnitBuilder.of("GeeCoin",
"BuildingCurrenciesExample").setCurrencyCode("GCC").setDefaultFractionDigits(2).
build());
Monetary.getCurrencies(CurrencyQueryBuilder.of().setProviderNames("ConfigurableCur
rencyUnitProvider").build()).forEach(
ConsoleUtils::printDetails
);
}
15
© 2012-2015 JavaMoney contributors
Monetary Amount
Amount = Number + Currency + Operations
How to represent the numeric amount?
Contradictory requirements:
– Performance (e.g. for trading)
– Precision and Scale (e.g. for calculations)
– Must model small numbers (e.g. web shop)
– Must support large Numbers (e.g. risk calculations, statistics)
– Rounding
– Financial Operations and Functions, function chaining
Solution:
• support several numeric representations!
• MonetaryQuery similar to java.function.Function
• MonetaryOperator similar to java.function.UnaryOperator
16
© 2012-2015 JavaMoney contributors
Monetary Amount (continued)
public interface MonetaryAmount{
public CurrencyUnit getCurrency();
public NumberValue getNumber();
[…]
public MonetaryAmount abs();
public MonetaryAmount min(…);
public MonetaryAmount max(…);
public MonetaryAmount add(…);
public MonetaryAmount substract(…);
public MonetaryAmount divide(…);
public MonetaryAmount[] divideAndRemainder(…);
public MonetaryAmount divideToIntegralValue(…);
public MonetaryAmount remainder(…);
public MonetaryAmount multiply(…);
public MonetaryAmount withAmount(Number amount);
[…]
public int getScale(); public int getPrecision();
[…]
public boolean isPositive(); public boolean isPositiveOrZero();
public boolean isNegative(); public boolean isNegativeOrZero();
public boolean isLessThan(…);
public boolean isLessThanOrEqualTo(…);
[…]
public MonetaryAmount with(MonetaryOperator op);
}
17
© 2012-2015 JavaMoney contributors
Data Access.
Implementation:
Money
Algorithmic
Operations…
Data Representation
and Comparison.
Monetary Query, Monetary Operator
//@FunctionalInterface for Java 8
public interface MonetaryQuery<R> {
public R queryFrom(MonetaryAmount value);
}
Implementations:
Minimum
Maximum
Average
SeparateAmount
SeparateCurrencies
Total
//@FunctionalInterface for Java 8
public interface MonetaryOperator
extends MonetaryFunction<MonetaryAmount,MonetaryAmount> {
Implementations:
MinorPart
MajorPart
Reciprocal
MonetaryRounding
CurrencyConversion
}
18
© 2012-2015 JavaMoney contributors
Creating Amounts
Usage
/**
* Simplest case create an amount with an ISO currency.
*/
public void forISOCurrencies() {
Money amount = Money.of("USD", 1234566.15); // using ISO namespace by default
}
/**
* Create an amount using a custom currency.
*/
public void forCustomCurrencies() {
CurrencyUnit currency = Monetary.getCurrency("myCode");
Money amount = Money.of(currency, 1234566.15);
}
19
© 2012-2015 JavaMoney contributors
Precision and Rounding
javax.money
20
© 2012-2015 JavaMoney contributors
Numeric Precision
•
Internal Precision (implied by internal number type)
•
External Precision (Rounding applied, when the numeric part is
accessed/passed outside)
•
Formatting Precision (Rounding for display and output)
•
Interoperability
– Different precision/scale
– Distinct numeric representations
– Serialization
By default
• only internal rounding is applied automatically.
• The precision/scale capabilities of a MonetaryAmount are
inherited to its operational results
21
© 2012-2015 JavaMoney contributors
Rounding
•
External Rounding and Formatting Rounding can be implemented in many
ways,
depending on the use cases
•
Monetary Rounding extends MonetaryOperator
Example for non standard-rounding Argentina:
• If the third digit is 2 or less, change it to
0 or drop it.
• If the third digit is between 3 and 7,
change it to 5.
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
• If the third digit is 8 or more, add one to
the second digit and drop the third digit or
change it to 0.
Example:
MonetaryRounding rounding = Monetary.getDefaultRounding();
MonetaryAmount rounded = rounding.round(amount);
MonetaryAmount halfConvertAndRound =
amount.divide(2).with(conversion).with(rounding);
22
© 2012-2015 JavaMoney contributors
Formatting and Parsing
Challenges
•
Multiple Locale instances for Translation, Dates, Time, Numbers,
Currencies
•
Additional parameters, e.g. Currency Placement, Rounding, Lenient
Fractions, Min, Max etc.
•
Natural language support for non-decimal valuations for example
– Lakhs, Crores (1 Lakh = 100,000, 1 Crore = 100 Lakh)
– INR 12,34,56,000.21 is written
12 Crore, 34 Lakh, 56 Thousand
Rupees and 21 Paise
•
How to deal with different formatting
styles?
– AmountFormatContext
– AmountFormatQuery
23
© 2012-2015 JavaMoney contributors
Currency Conversion
javax.money.convert
24
© 2012-2015 JavaMoney contributors
Currency Conversion
•
ExchangeRateType
•
ExchangeRate:
– ExchangeRateType
– Base, Term currency
– Conversion factor
– Validity (from/until)
public interface ExchangeRate {
public ExchangeRateType getExchangeRateType();
public CurrencyUnit getBase();
public CurrencyUnit getTerm();
public NumberValue getFactor();
public Long getValidFrom();
public Long getValidUntil();
public boolean isValid();
public String getProvider();
public List<ExchangeRate> getExchangeRateChain();
public boolean isDerived();
}
– Provider (optional)
– Direct/Derived Rates
•
ConversionProvider/CurrencyConverter
•
MonetaryConversions accessor singleton
25
© 2012-2015 JavaMoney contributors
Currency Conversion
/**
* Shows accessing exchange rates and doing conversions.
*/
public class CurrencyConversion {
MonetaryAmount amt = Money.of(2000, "EUR");
System.out.println("2000 EUR -(ECB)-> HUF = "
amt.with(MonetaryConversions.getConversion("HUF",
System.out.println("2000 EUR -(IMF)-> HUF
amt.with(MonetaryConversions.getConversion("HUF",
+
"ECB")));
= " +
"IMF")));
System.out.println("2000 EUR -(ECB, at 5th Jan 2015)->
HUF = " +
amt.with(MonetaryConversions.getConversion(ConversionQueryBui
lder.of().setTermCurrency("HUF")
.set(LocalDate.of(2015, 01, 05)).build())));
}
26
© 2012-2015 JavaMoney contributors
Users
Zalando
27
© 2012-2015 JavaMoney contributors
Image: Zalando
Gimme Shelter
Adopt-a-JSR and similar Efforts
28
© 2012-2015 JavaMoney contributors
Groovy / Grails Support
29
•
Guillaume Laforge outlined on DZone a while ago how to create a
Domain-Specific Language for the Pharmaceutical industry based
on Groovy and JSR 275
https://dzone.com/articles/domain-specific-language-unit-
•
Even earlier he mentioned money in a similar Groovy DSL post:
http://glaforge.appspot.com/article/from-named-parameters-todomain-specific-languages
•
So adding Groovy support to JSR 354 was done accordingly.
© 2012-2015 JavaMoney contributors
Groovy / Grails Modules?
•
Prior approaches especially for Grails include
– http://grails.org/plugin/currencies
or a slightly more recent approach to the same problem
– https://github.com/ticketbis/grails-money
Neither of them look bad, but they are pretty simple and lack
many powerful aspects of JSR 354.
•
30
As Groovy is now an Apache Incubator project and several subprojects exist for features like Swing, JMX or SQL, one could
imagine other such modules for JSR 354 and JavaMoney.
© 2012-2015 JavaMoney contributors
Demo
31
© 2012-2015 JavaMoney contributors
???
Links
JSR-354
https://jcp.org/en/jsr/detail?id=354
JavaMoney
http://javamoney.org
JavaMoney – Shelter
http://javamoney.github.io/shelter.html
Apache Groovy (Incubating)
http://incubator.apache.org/projects/groovy.
html
THANK YOU!