Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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!