tag:blogger.com,1999:blog-59422480252117120112024-03-12T18:45:48.153-07:00Java RemarkablesJava Remarkables: Different topics about Java, the JDK or JSRs...Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-5942248025211712011.post-17555090616554639042014-06-20T01:18:00.000-07:002014-06-21T04:14:41.676-07:00JSR 363 Unit of Measurement API - a FIrst Glance<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">JSR 363 Unit of Measurement API - a First Glance</span></h2>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">During the last Hackergarten in Zurich I had the chance to look at the current <a href="https://github.com/unitsofmeasurement/unit-api">GitHub Repository of JAR 363</a>. Hereby I focused on the API only. This JSR is quite young, nevertheless there is already a code base available, which was originally forked from <a href="https://code.google.com/p/unitsofmeasure/">https://code.google.com/p/unitsofmeasure/</a> . My objective hereby was relatively simple: look at the main abstractions and get a gut feeling on it, so here it is:</span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Main Concepts</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">One main artifact is the Quantity interface, which is defined as follows:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Courier New, Courier, monospace;"><b>public interface <span style="color: #660000;">Quantity</span></b><Q <b>extends </b>Quantity<Q>> </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>extends </b>Measurement<Q, Number> { <br /> Quantity<?> divide(Quantity<?> that); <br />}</span></div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Arial, Helvetica, sans-serif;">The according JavaDoc describes this interface with</span><i><span style="font-family: Arial, Helvetica, sans-serif;">Represents a quantitative properties or attributes of thing. Mass, time, distance, heat, and angular separation are among the familiar examples of quantitative properties.</span></i></blockquote>
<span style="font-family: Arial, Helvetica, sans-serif;"><br />As we have seen this interface hereby extends Measurement:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Courier New, Courier, monospace;"><b>public interface <span style="color: #660000;">Measurement</span></b><Q <b>extends </b>Quantity<Q>, V> <br /><b>extends </b>UnitSupplier<Q>,</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ValueSupplier<V>, <br /> ConversionOperator<Measurement<Q, V>, Unit<Q>> { </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">Measurement<Q, V> add(Measurement<Q, V> that); </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">Measurement<Q, V> substract(Measurement<Q, V> that);</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">Measurement<?, V> multiply(Measurement<?, V> that); </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">Measurement<Q, V> multiply(V that); </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">Measurement<Q, V> divide(V that); </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">Measurement<Q, V> inverse(); </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<pre style="box-sizing: border-box; overflow: auto;"><pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Arial, Helvetica, sans-serif;">Whereas </span><span style="font-family: Courier New, Courier, monospace;">Supplier </span><span style="font-family: Arial, Helvetica, sans-serif;">are common concepts also known from other APIs, Additionally </span><span style="font-family: Courier New, Courier, monospace;">ConversionOperator, </span><span style="font-family: 'Courier New', Courier, monospace; white-space: normal;">Measurement </span><span style="font-family: Arial, Helvetica, sans-serif;">and </span><span style="font-family: Courier New, Courier, monospace;">Unit</span><span style="font-family: Arial, Helvetica, sans-serif;">:must be explained:</span></pre>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: 'Courier New', Courier, monospace;">// equivalent to @FunctionalInterface
<b style="font-family: 'Courier New', Courier, monospace;">public interface <span style="color: #660000;">ConversionOperator</span></b>
<T, U> {
T to(U unit);
}
<b style="font-family: 'Courier New', Courier, monospace;">public interface <span style="color: #660000;">Unit</span></b><Q extends Quantity<Q>>
<b style="font-family: 'Courier New', Courier, monospace;">extends </b>UnitTransformer<Q>, Nameable {
String getSymbol();
Dimension getDimension();
Unit<Q> getSystemUnit();
Map<? extends Unit<?>, Integer> getProductUnits();
<b>boolean </b>isCompatible(Unit<?> that);
<T extends Quantity<T>> Unit<T> asType(Class<T> type)
<b>throws </b>ClassCastException;
UnitConverter getConverterTo(Unit<Q> that)
<b>throws </b>UnconvertibleException;
UnitConverter getConverterToAny(Unit<?> that)
<b>throws </b>IncommensurableException, UnconvertibleException;
Unit<Q> alternate(String symbol);
Unit<Q> shift(double offset);
Unit<Q> multiply(double factor);
Unit<?> multiply(Unit<?> that);
Unit<Q> divide(double divisor);
Unit<?> divide(Unit<?> that);
Unit<?> inverse(); Unit<?> root(int n);
Unit<?> pow(int n);
}
</span></pre><span style="font-family: Arial, Helvetica, sans-serif;">But we still have not everything covered, there is also a </span><span style="font-family: Courier New, Courier, monospace;">Dimension</span><span style="font-family: Arial, Helvetica, sans-serif;">, modelling the algorithmic relations between units:</span></pre>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Courier New, Courier, monospace;">
<b>public interface <span style="color: #660000;">Dimension </span></b>{
Dimension multiply(Dimension that);
Dimension divide(Dimension that);
Dimension pow(int n);
Dimension root(int n);
Map<? extends Dimension, Integer> getProductDimensions();
}</span></pre>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: Arial, Helvetica, sans-serif;">Summarizing we have the following main artifacts involved:</span>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A </span><span style="font-family: Courier New, Courier, monospace;">Quantity</span><span style="font-family: Arial, Helvetica, sans-serif;">, which describes the flavor or type of measurement, e.g. <b>Length, Weight</b> or <b>Volume</b>.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A Unit, which defines a concrete unit of a specific measurement, e.g. <b>Nanometer, Tons, Gallons</b>..</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A concrete </span><span style="font-family: Courier New, Courier, monospace;">Measurement</span><span style="font-family: Arial, Helvetica, sans-serif;">, which can be seen as a concrete <i>value</i> <i>measured </i>of a Unit, e.g. <b>10 Meters, 3 tons or 4 Gallons</b>. Measurements also provide simple arithmetics for adding, subtracting, division and multiplication with other measures of compatible units.</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">Dimension </span><span style="font-family: Arial, Helvetica, sans-serif;">defines the <b>numeric relationships between a set of related units.</b></span></li>
</ul>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">My Feedback</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically defining an API for all measures and units available is a tough thing. Also there was already a lot of work done, and I am looking forward how this JSR will evolve. Nevertheless my first impression is that the </span>API<span style="font-family: Arial, Helvetica, sans-serif;"> mixes up a few concerns that I think should be separated:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">I would expect to have such general and defining concepts like quantities and units being separated from more concrete aspects like measurements and dimensions. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Another element that was present on the former measurement API was the </span><span style="font-family: Courier New, Courier, monospace;">SystemOfUnits</span><span style="font-family: Arial, Helvetica, sans-serif;"> concept. or some kind of </span>accessor<span style="font-family: Arial, Helvetica, sans-serif;">, which acts as an entry point. I think the API requires some entry point, e.g. in form of a singleton to make it complete. Basically a programmer should be able to program against the API without having to know any details on the implementations.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">I would like the quantity to be modeled as the more general but basically independent concept and let </span><span style="font-family: Courier New, Courier, monospace;">Unit </span><span style="font-family: Arial, Helvetica, sans-serif;">refer to its corresponding Quantity. This would resolve the circular dependency between </span><span style="font-family: Courier New, Courier, monospace;">Quantity </span><span style="font-family: Arial, Helvetica, sans-serif;">and </span><span style="font-family: Courier New, Courier, monospace;">Unit</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Furthermore I would really ensure that the </span><span style="font-family: 'Courier New', Courier, monospace;">Quantity </span><span style="font-family: Arial, Helvetica, sans-serif;">and </span><span style="font-family: 'Courier New', Courier, monospace;">Unit </span><span style="font-family: Arial, Helvetica, sans-serif;">types are always evaluable at runtime (be aware of type erasure). </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">For me it is also arguable if we really have enough benefits of </span><span style="font-family: Courier New, Courier, monospace;">Nameable</span><span style="font-family: Arial, Helvetica, sans-serif;">. If the idea was to provide functional support for </span><span style="font-family: Courier New, Courier, monospace;">getName()</span><span style="font-family: Arial, Helvetica, sans-serif;">, maybe it makes sense, but I would try to reduce the number of artifacts needed to the minimum. Just start small and if you really have to add something add it later. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">I do not like the idea of adding arithmetic operations on units, since I concern units as well as quantities as the metadata level, similar to currencies in the money world. I would expect them to be on measurements, which for me would be the same concept as monetary amount.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">FInally I think the naming of system unit and product units is confusing. I would prefer more something like a </span><i style="font-family: Arial, Helvetica, sans-serif;">main </i><span style="font-family: Arial, Helvetica, sans-serif;">or</span><i style="font-family: Arial, Helvetica, sans-serif;"> leading unit</i><span style="font-family: Arial, Helvetica, sans-serif;">, and </span><i style="font-family: Arial, Helvetica, sans-serif;">derived units</i><span style="font-family: Arial, Helvetica, sans-serif;">.(or somebody can tell me, that the semantics is different here, I am not sure, if I understood these concepts fully here...).</span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;">So I would come up with something like:</span></div>
</pre>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Courier New, Courier, monospace;"> <b>public interface</b> Quantity {
</span><span style="font-family: 'Courier New', Courier, monospace;"> String getName();
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: 'Courier New', Courier, monospace;">isCompatible(Unit<?> that); // needed here ?
</span><span style="font-family: 'Courier New', Courier, monospace;"> }</span></pre>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Courier New, Courier, monospace;"> <b>public </b>Unit<Q <b>extends </b>Quantity>{
Class<Q> getQuantity();
Unit<Q> getLeadingUnit();
Collection<Unit<Q>> getDerivedUnits();
<b>boolean </b>isCompatible(Unit<Q> that);
}</span></pre>
</pre>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Arial, Helvetica, sans-serif;">The management of quantities and units, including the mappings of units, quantities I would handle as a separate concern, e.g. something similar like</span></pre>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Arial, Helvetica, sans-serif;">
</span></pre>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Courier New, Courier, monospace;"> <b>public final class <span style="color: #990000;">Quantities </span></b>{
</span><span style="font-family: 'Courier New', Courier, monospace;"> <b>public static </b>Collection<Quantity> getQuantities();
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">Collection<String> getQuantityNames();
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">Quantitiy getQuantity(String name);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;"><Q extends Quantity> Q getQuantity(
</span><span style="font-family: 'Courier New', Courier, monospace;"> Class<Q> type);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: 'Courier New', Courier, monospace;">isCompatible(Quantity quantity,
</span><span style="font-family: 'Courier New', Courier, monospace;"> Unit<?> that);
</span><span style="font-family: 'Courier New', Courier, monospace;"> }</span></pre>
<pre style="box-sizing: border-box; overflow: auto;"><pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Courier New, Courier, monospace;"><b> public final class <span style="color: #990000;">Units</span></b>{
</span><span style="font-family: 'Courier New', Courier, monospace;"><b> public static </b></span><span style="font-family: 'Courier New', Courier, monospace;"><Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity>
</span><span style="font-family: 'Courier New', Courier, monospace;"> Collection<Unit<Q>> </span><span style="font-family: 'Courier New', Courier, monospace;">getUnits(Quantity);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;"><Q <b>extends </b>Quantity>
</span><span style="font-family: 'Courier New', Courier, monospace;"> Collection<Unit<Q>> getLeadingUnits(</span><span style="font-family: 'Courier New', Courier, monospace;">Q quantity</span><span style="font-family: 'Courier New', Courier, monospace;">);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;"><Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity>
</span><span style="font-family: 'Courier New', Courier, monospace;"> Collection<Unit<Q>></span><span style="font-family: 'Courier New', Courier, monospace;"> getDerivedUnits(</span><span style="font-family: 'Courier New', Courier, monospace;">Unit<Q> unit</span><span style="font-family: 'Courier New', Courier, monospace;">);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: 'Courier New', Courier, monospace;">isCompatible(Quantity quantity,
</span><span style="font-family: 'Courier New', Courier, monospace;"> Unit<?> that);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;"><Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity>
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: 'Courier New', Courier, monospace;">isDerived(Unit<Q> mainUnit, </span><span style="font-family: 'Courier New', Courier, monospace;">Unit<Q> derivedUnit);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;"><Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity>
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: 'Courier New', Courier, monospace;">isLeadingUnit(Unit<Q> unit</span><span style="font-family: 'Courier New', Courier, monospace;">);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;"><Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity>
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: 'Courier New', Courier, monospace;">isLeadingUnit(Unit<Q> unit</span><span style="font-family: 'Courier New', Courier, monospace;">);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">SystemOfUnits getSystemOfUnits(String name);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">SystemOfUnits getSystemOfUnits(Locale country);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">Collection<</span><span style="font-family: 'Courier New', Courier, monospace;">SystemOfUnits> getSystemOfUnits(
</span><span style="font-family: 'Courier New', Courier, monospace;"> Unit<?> unit);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">Collection<</span><span style="font-family: 'Courier New', Courier, monospace;">SystemOfUnits> getSystemOfUnits(
</span><span style="font-family: 'Courier New', Courier, monospace;"> Unit<?> unit);
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">Collection<String> getSystemOfUnitNames();
</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public static </b><span style="font-family: 'Courier New', Courier, monospace;">SystemOfUnits getDefaultSystemOfUnits();
</span><span style="font-family: 'Courier New', Courier, monospace;"> }</span></pre>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public final class <span style="color: #990000;">Dimensions</span></b><span style="font-family: 'Courier New', Courier, monospace;">{
</span><span style="font-family: 'Courier New', Courier, monospace;"> ...
</span><span style="font-family: 'Courier New', Courier, monospace;"> }</span></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">Compared to what we have above this is much more simpler and comprehensive. Additionally there are also more advantages:</span>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">All these singleton can be backed up by spis. With this it should be easily possible to support partial implementations and overrides. E.g. when an additional unit type is defined, e.g. for measuring black materia in super-light speed mode (e.g. "WARPS") it would be possible to implement the parts required to support this additional unit.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Basically such a structure could allow also additional functionality such as contextual behaviour in a multi-tenancy/ee context.</span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;">Given an artifact </span><span style="font-family: Courier New, Courier, monospace;">SystemOfUnits</span><span style="font-family: Arial, Helvetica, sans-serif;"> it probably would be possible to support accessing units by their literal symbols, e.g.</span>
<pre style="box-sizing: border-box; overflow: auto;"><b style="font-family: 'Courier New', Courier, monospace;"> public interface </b><span style="font-family: 'Courier New', Courier, monospace;">SystemOfUnits{</span>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"><Q <b>extends </b>Quantity><b>
</b> Collection<</span><span style="font-family: 'Courier New', Courier, monospace;">Unit<Q>> getLeadingUnits(Quantity quantity);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"><Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity></span><b style="font-family: 'Courier New', Courier, monospace;"> </b><span style="font-family: 'Courier New', Courier, monospace;">Unit<Q> getUnit(String symbol);</span>
<span style="font-family: 'Courier New', Courier, monospace;"> ...</span>
<span style="font-family: 'Courier New', Courier, monospace;"> }</span>
<span style="font-family: Arial, Helvetica, sans-serif;"> </span></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">Now let us focus again on the next artifact: </span><span style="font-family: Courier New, Courier, monospace;">Measurement.</span><span style="font-family: Arial, Helvetica, sans-serif;"> Here</span></pre>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">I would reduce the arithmetic methods</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Arial, Helvetica, sans-serif;">to the absolute minimum. Instead of having operations on it like <i>shift, alternate</i> I would prefer an extension mechanism, similar to </span><span style="font-family: Courier New, Courier, monospace;">MonetaryQuery </span><span style="font-family: Arial, Helvetica, sans-serif;">or </span><span style="font-family: Courier New, Courier, monospace;">MonetaryOperator </span><span style="font-family: Arial, Helvetica, sans-serif;">in JSR 354.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">I would heavily recommend to separate the concern of conversion. Basically this might also be doable based on the extension mechanism above, or it can be modeled as a separate API, but also provided by a separate accessor singleton.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally I would like to see, if we really need alternate values than decimal numbers to represent the values of measurements. Even if there are rare cases, where measures are not modeled as decimal numbers, I would see, if it is possible to map them nevertheless somehow to decimal numbers in a feasible way. If, I hope so, most of the measurements can be modeled in a unified way, I would tend to take this as the leading use case. For speciayou can still have an additional complex measurement model. This would IMO make the API simpler for the majority of use cases, which I think is better than trying to include also edge cases that pollute the API at the end (making more difficult to use).</span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;">So summarizing I would propose something like the following:</span>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Courier New, Courier, monospace;">
<b>public interface <span style="color: #660000;">Measurement</span></b><Q <b>extends </b>Quantity,
U <b>extends </b>Unit<Q>>
<b>extends </b>UnitSupplier<U>, ValueSupplier<Number>{
Measurement<Q, U> add(Measurement<Q, ?> that);
Measurement<Q, U> subtract(Measurement<Q, ?> that);
Measurement<Q, U> multiply(Measurement<Q, ?> that);
Measurement<Q, U> multiply(double that);
Measurement<Q, U> multiply(long that);
</span><span style="font-family: 'Courier New', Courier, monospace;"> Measurement<Q, U> multiply(Number that);
</span><span style="font-family: 'Courier New', Courier, monospace;"> Measurement<Q, U> divide(double that);
</span><span style="font-family: 'Courier New', Courier, monospace;"> Measurement<Q, U> divide(long that);
</span><span style="font-family: 'Courier New', Courier, monospace;"> Measurement<Q, U> divide(Number that);
Measurement<Q, U> inverse();
Measurement<Q, U> pow(int n);
Measurement<Q, U> with(MeasurementOperator op);
<T> T query(MeasurementQuery<T, Q> query);
}</span></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">, whereas</span>
<pre style="box-sizing: border-box; overflow: auto;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-size: x-small;"> </span><b>public interface</b> </span><span style="font-family: 'Courier New', Courier, monospace;">Measurement</span><span style="font-family: 'Courier New', Courier, monospace;">Operator<Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity,
</span><span style="font-family: 'Courier New', Courier, monospace;"> U </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Unit<Q>>{
</span><span style="font-family: 'Courier New', Courier, monospace;"> <T </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Measurement<Q, U>> T apply(T unit);
</span><span style="font-family: 'Courier New', Courier, monospace;"> }
</span><span style="font-family: Courier New, Courier, monospace;"> <b>public interface</b> </span><span style="font-family: 'Courier New', Courier, monospace;">Measurement</span><span style="font-family: 'Courier New', Courier, monospace;">Query<Q </span><b style="font-family: 'Courier New', Courier, monospace;">extends </b><span style="font-family: 'Courier New', Courier, monospace;">Quantity,
</span><span style="font-family: 'Courier New', Courier, monospace;"> U extends Unit<Q>, R>{
</span><span style="font-family: 'Courier New', Courier, monospace;"> R query(U unit);
</span><span style="font-family: 'Courier New', Courier, monospace;"> }</span></pre>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Also I would definitively recommend handling formatting and conversion as separate concerns, but I will stop here for now. I think the JSR's Expert Group has enough input for discussion and I hope, they will catch up at least some of my concerns, so we get a simple, comprehensive, </span><span style="font-family: Arial, Helvetica, sans-serif;">easy to use, but nevertheless powerful measurement API.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Of course, as always, any comments are welcome!</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span></div>
</pre>
</div>Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com11tag:blogger.com,1999:blog-5942248025211712011.post-10951124396083872042013-04-22T10:58:00.004-07:002013-04-22T12:09:42.956-07:00Overview JSR 354 (Money and Currency) Core API<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">What is JSR 354?</span></h2>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">JSR 354 is the upcoming standard, how money and currencies should be modelled and handled in Java. You can find more details here:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Project Page on Java.net: <a href="http://java.net/projects/javamoney">http://java.net/projects/javamoney</a></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">JCP main page: <a href="http://jcp.org/en/jsr/detail?id=354">http://jcp.org/en/jsr/detail?id=354</a></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">GitHub Repository: <a href="https://github.com/JavaMoney/javamoney">https://github.com/JavaMoney/javamoney</a></span></li>
</ul>
</div>
<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Why this blog?</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Within JSR 354 we had a lot of discussions. I wanted to show with some examples how this API feels. And finally, if someone has input or ideas, we want to be aware of, so we finally build the right API !</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Dealing with Currencies</span></h2>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Basic Design Decisions</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">The JSR basically models many of the key artifacts using interfaces. Nevertheless we provide concrete value types implementing the interfaces which in concrete code are referenced. The interfaces typically are for interoperability:</span><br />
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">CurrencyUnit </span><span style="font-family: Arial, Helvetica, sans-serif;">and </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmout </span><span style="font-family: Arial, Helvetica, sans-serif;">are modelled by interfaces for interoperability.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The classes <span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency </span>and <span style="font-family: 'Courier New', Courier, monospace;">Money </span>implement these interfaces.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">In the case of <span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency</span>, also an according <span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency.Builder </span>is defined.</span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;">This will be shown in more detail within the following sections.</span><br />
<br />
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Interface javax.money.CurrencyUnit</span></h3>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically the interface directly models the same aspects as available on the existing </span><span style="font-family: Courier New, Courier, monospace;">java.util.Currency</span><span style="font-family: Arial, Helvetica, sans-serif;"> class, but adds some additional methods to support additional aspects not covered by </span><span style="font-family: 'Courier New', Courier, monospace;">java.util.Currency</span><span style="font-family: Arial, Helvetica, sans-serif;">. Some of the considerations are:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">not renaming existing methods of <span style="font-family: 'Courier New', Courier, monospace;">java.util.Currency </span>enables maximal backward compatibility and makes it more easy to let implement <span style="font-family: 'Courier New', Courier, monospace;">java.util.Currency </span>the new interface for interoperability. This would also allow</span><span style="font-family: Arial, Helvetica, sans-serif;"> existing code to remain as is, if none of the extended features are required.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the other methods added should be the minimum required and be basically easily implementable, If feasible, also undefined values should be possible as method results. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">In the area of currencies there are a couple of complexities that were not obvious at a first glance, but can not be neglected, if currency should model the reality at least to some extent. For example think on the following aspects:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">currencies come and go during human history. Even during the last years there were quite important changes that requires that historic and current currencies can be distinguished.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">ISO-4217 currency codes also have some imminent aspects to be considered:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">ISO codes (the identifiers!) are not guaranteed over time, the can be reused after some defined time.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Rounding modes and fraction digits can change during time, even when the currency is still the same.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Historic currencies are not mapped by ISO at all.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">ISO also maps things that are not effectively currencies, like precious metals (e.g. AUG), no currency (XXX) or testing codes.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">ISO also is ambiguous e.g. CFA is a code that basically is backed up by two different bank notes.</span></li>
</ul>
</ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the biggest change is that we introduced an additional <i>namespace </i>on top of the currency code, because:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">namespaces can be used to separate concerns. This makes sense since ISO currencies are real currencies, whereas Social or Video Game Currencies are completely virtual. BitCoin even is more special, since it started as a virtual currency but lately is accepted more and more as real currency.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">namespaces also allow to manage legacy currency schemes as they are in use by all financial organizations that must deal with money in a time range and scope that is longer than 10 years.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">One might argue, that we could simply extend the existing currency code. But this also has some severe drawbacks:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the existing currency code of the JDK class can not be adapted correspondingly since this would break behavioral compatibility. But if the code can not be extended, we would have currencies with a namespace prefix (all non ISO), and ones without (ISO, as before).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Additionally the JSR should definitely not impose anything on how currency codes will be defined in the future. But when extending the existing currency code with some optional namespace, an according separation criteria must be defined. Obviously this could easily clash with future namespace or code identifiers.</span></li>
</ul>
</ul>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So summarizing a currency must implement the following interface:</span></div>
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>public interface public</b> CurrencyUnit{<br /> <b>public </b>String <b><span style="color: #660000;">getNamespace</span></b>(); <span style="color: #999999;">// new</span><br /> <b>public </b>String <b><span style="color: #660000;">getCurrencyCode</span></b>();<br /> <b>public int </b><b><span style="color: #660000;">getNumericCode</span></b>();<br /> <b>public int </b><b><span style="color: #660000;">getDefaultFractionDigits</span></b>();<br /> <b>public boolean </b><b><span style="color: #660000;">isVirtual</span></b>(); <span style="background-color: white; color: #999999;">// new</span><br /> <b>public boolean </b><b><span style="color: #660000;">isLegalTender</span></b>(); <span style="color: #999999;">// new</span><br /> <b>public </b>Long <b><span style="color: #660000;">getValidFrom</span></b>(); <span style="color: #999999;">// new</span><br /> <b>public </b>Long <b><span style="color: #660000;">getValidUntil</span></b>(); <span style="background-color: white;"><span style="color: #999999;">// new</span></span><br />}</span><br />
<div>
<b style="font-weight: normal;"><span style="color: #333333; font-family: Consolas; font-size: 12px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;"><br /></span></b></div>
<span style="color: #333333; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">There are a couple of remarks:</span></span><br />
<ul>
<li><span style="color: #333333; font-family: Arial, Helvetica, sans-serif;"><span style="white-space: pre-wrap;">the numeric code, if not defined, should be -1.</span></span></li>
<li><span style="color: #333333;"><span style="white-space: pre-wrap;"><span style="font-family: Arial, Helvetica, sans-serif;">the timestamps are modelled as </span><span style="font-family: Courier New, Courier, monospace;">Long </span><span style="font-family: Arial, Helvetica, sans-serif;">due to the following reasons:</span></span></span></li>
<ul>
<li><span style="color: #333333; font-family: Arial, Helvetica, sans-serif;"><span style="white-space: pre-wrap;">the JSR wants to be backward compatible with SE 7 (which will also cover SE6).</span></span></li>
<li><span style="color: #333333; font-family: Arial, Helvetica, sans-serif;"><span style="white-space: pre-wrap;">SE 8 is not yet final.</span></span></li>
<li><span style="color: #333333;"><span style="white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace;">Long </span><span style="font-family: Arial, Helvetica, sans-serif;">can be </span><span style="font-family: Courier New, Courier, monospace;">null</span><span style="font-family: Arial, Helvetica, sans-serif;">, which means not defined. This is also the correct value for current currency instances.</span></span></span></li>
<li><span style="color: #333333; font-family: Arial, Helvetica, sans-serif;"><span style="white-space: pre-wrap;">UTC timestamps are commonly understood and well supported by all kind of time and date frameworks. They can easily converted to any other kind of objects required.
<i><span style="font-size: x-small;">Note: there is quite discussion ongoing, if the new JSR 310 APIs should be used here. We require definitively here better information, if we can go for the new date and time types, without preventing usage of the new API for years.</span></i></span></span></li>
</ul>
</ul>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Class javax.money.MoneyCurrency</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This class is the implementation of </span><span style="font-family: Courier New, Courier, monospace;">CurrencyUnit</span><span style="font-family: Arial, Helvetica, sans-serif;">, also including an according </span><span style="font-family: Courier New, Courier, monospace;">Builder </span><span style="font-family: Arial, Helvetica, sans-serif;">and an internal cache for reusing instances created. It is also where, by default, in the new API ISO currencies can be accessed:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency </span><span style="font-family: Courier New, Courier, monospace;">currency = MoneyCurrency.of("USD");</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">For ISO currencies this will work out of the box, since the ISO currencies are implicitly backed up by </span><span style="font-family: Courier New, Courier, monospace;">java.util.Currency</span><span style="font-family: Arial, Helvetica, sans-serif;">. Also the call above does implicitly add 'ISO-4217' as namespace, so basically the call below is aequivalent:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency </span><span style="font-family: 'Courier New', Courier, monospace;">currency = MoneyCurrency.of("ISO-4217", "USD");</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Defining alternate </span><span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency </span><span style="font-family: Arial, Helvetica, sans-serif;">instances and namespaces can be done using the </span><span style="font-family: Courier New, Courier, monospace;">MoneyCurrency.Builder</span><span style="font-family: Arial, Helvetica, sans-serif;">:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<span style="font-family: Courier New, Courier, monospace;">MoneyCurrency.Builder builder = <b>new </b>MoneyCurrency.Builder();</span><br />
<span style="font-family: Courier New, Courier, monospace;">builder.setNamespace("myNamespace");</span><br />
<span style="font-family: Courier New, Courier, monospace;">builder.setCurrencyCode("myCode");</span><br />
<span style="font-family: Courier New, Courier, monospace;">builder.setDefaultFractionDigits(4);</span><br />
<span style="font-family: Courier New, Courier, monospace;">builder.setLegalTender(<b>false</b>);</span><br />
<span style="font-family: Courier New, Courier, monospace;">builder.setVirtual(<b>true</b>);</span><br />
<span style="font-family: Courier New, Courier, monospace;">builder.setAttribute("test-only", true);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency </span><span style="font-family: Courier New, Courier, monospace;">unit = builder.build();</span><br />
<span style="color: #999999; font-family: Courier New, Courier, monospace;">// however MoneyCurrency.of("myNamespace", "myCode"); </span><br />
<span style="color: #999999;"><span style="font-family: Courier New, Courier, monospace;">// still returns</span><span style="font-family: 'Courier New', Courier, monospace;"> null!</span></span><br />
<span style="font-family: Courier New, Courier, monospace;">builder.build(<b>true</b>);</span><br />
<span style="color: #999999; font-family: Courier New, Courier, monospace;">// no it is registered</span><br />
<span style="font-family: Courier New, Courier, monospace;">unit = MoneyCurrency.of("myNamespace", "myCode");</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Extended API: javax.money.ext.MonetaryCurrencies</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This <i>singleton </i>class allow to access currencies in a more service like fashion as required for more advanced use cases, such as accessing historic currencies or mapping of currencies between or within namespaces. Also it is possible to access all currencies within a namespace. Extended functionality is not part of the JSR's platform part and therefore is designed as standalone module, usable in multiple usage contexts (SE, EE etc):</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public final class</b> MonetaryCurrencies {</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span style="font-family: 'Courier New', Courier, monospace;"><b>public static </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>boolean</b> <b><span style="color: #660000;">isNamespaceDefined</span></b>(String namespace){..}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> <b> </b></span><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>static</b> </span><span style="font-family: Courier New, Courier, monospace;">Collection<String> <b><span style="color: #660000;">getNamespaces</span></b>()</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>static</b> </span><span style="font-family: Courier New, Courier, monospace;">CurrencyUnit <b><span style="color: #660000;">get</span></b>(String namespace, <br /> String code)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>static</b> </span><span style="font-family: Courier New, Courier, monospace;">Collection<CurrencyUnit> <b><span style="color: #660000;">getAll</span></b>(</span><br />
<span style="font-family: Courier New, Courier, monospace;"> String namespace)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>static </b></span><span style="font-family: Courier New, Courier, monospace;"><b>boolean</b> <b><span style="color: #660000;">isDefined</span></b>(String code)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> <b> </b></span><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>static </b></span><span style="font-family: Courier New, Courier, monospace;"><b>boolean</b> <b><span style="color: #660000;">isDefined</span></b>(String namespace, </span><br />
<span style="font-family: Courier New, Courier, monospace;"> String code)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>static</b> </span><span style="font-family: Courier New, Courier, monospace;">Collection<CurrencyUnit> <b><span style="color: #660000;">getAll</span></b>(String namespace, <br /> String code)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;"><b>static </b></span><span style="font-family: Courier New, Courier, monospace;">Collection<CurrencyUnit> <b><span style="color: #660000;">getAll</span></b>(String code)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;"> <span style="color: #999999;">// historic access</span></span></div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"><b>boolean</b> <b><span style="color: #660000;">isNamespaceDefined</span></b>(String namespace</span><span style="font-family: 'Courier New', Courier, monospace;">, </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Long timestamp</span><span style="font-family: 'Courier New', Courier, monospace;">)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">Collection<String> <b><span style="color: #660000;">getNamespaces</span></b>(</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Long timestamp</span><span style="font-family: 'Courier New', Courier, monospace;">)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">CurrencyUnit <b><span style="color: #660000;">get</span></b>(String namespace, String code, <br /> Long timestamp)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">CurrencyUnit <b><span style="color: #660000;">get</span></b>(String code, Long timestamp)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">Collection<CurrencyUnit> <b><span style="color: #660000;">getAll</span></b>(String namespace, <br /> Long timestamp)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">boolean <b><span style="color: #660000;">isDefined</span></b>(String namespace, String code, <br /> Long timestamp)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">boolean <b><span style="color: #660000;">isDefined</span></b>(String code, </span><br />
<span style="font-family: Courier New, Courier, monospace;"> Long timestamp)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">Collection</span><span style="font-family: Courier New, Courier, monospace;"><CurrencyUnit> <b><span style="color: #660000;">getAll</span></b>(Locale locale, </span><br />
<span style="font-family: Courier New, Courier, monospace;"> Long timestamp)</span><span style="font-family: 'Courier New', Courier, monospace;">{..}</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #999999;">// mapping of currrencies</span></span><br />
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">CurrencyUnit <b><span style="color: #660000;">map</span></b>(CurrencyUnit unit, </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> String targetNamespace);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">List<CurrencyUnit> <b><span style="color: #660000;">mapAll</span></b>(String targetNamespace, </span><br />
<span style="font-family: Courier New, Courier, monospace;"> CurrencyUnit... units);</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">CurrencyUnit <b><span style="color: #660000;">map</span></b>(CurrencyUnit unit, </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> String targetNamespace, </span><br />
<span style="font-family: Courier New, Courier, monospace;"> Long timestamp);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b></span><b style="font-family: 'Courier New', Courier, monospace;">static</b><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">List</span><span style="font-family: Courier New, Courier, monospace;"> CurrencyUnit> <b><span style="color: #660000;">mapAll</span></b>(String targetNamespace, </span><br />
<span style="font-family: Courier New, Courier, monospace;"> Long timestamp, </span><br />
<span style="font-family: Courier New, Courier, monospace;"> CurrencyUnit... units);</span></div>
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
<span style="font-family: Arial, Helvetica, sans-serif;">The singleton's implementation itself can be determined by registering an instance of </span><span style="font-family: 'Courier New', Courier, monospace;">MonetaryCurrencies.</span><span style="font-family: Courier New, Courier, monospace;">MonetaryCurrenciesSpi </span><span style="font-family: Arial, Helvetica, sans-serif;">using </span><span style="font-family: Courier New, Courier, monospace;">java.util.ServiceLoader</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></div>
<div>
<h2 style="font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;">Monetary Amounts</span></h2>
<h3 style="font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;">Some Basic Design Decisions</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Monetary amounts basically follow the same design as </span><span style="font-family: Courier New, Courier, monospace;">CurrencyUnit</span><span style="font-family: Arial, Helvetica, sans-serif;">::</span></div>
<ul>
<li style="font-family: 'Times New Roman';"><span style="font-family: Courier New, Courier, monospace;">MonetaryAmout </span><span style="font-family: Arial, Helvetica, sans-serif;">is modelled by interface for interoperability.</span></li>
<li style="font-family: 'Times New Roman';"><span style="font-family: Arial, Helvetica, sans-serif;">Aims look and feel from </span><span style="font-family: Courier New, Courier, monospace;">java.math.BigDecimal</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span></li>
<li><span style="font-family: Courier New, Courier, monospace;">Money </span><span style="font-family: Arial, Helvetica, sans-serif;">implements the <span style="font-family: 'Courier New', Courier, monospace;">MonetaryAmout </span>interface, using</span> <span style="font-family: Courier New, Courier, monospace;">java.math.BigDecimal</span><span style="font-family: Arial, Helvetica, sans-serif;"> for numeric representation.</span></li>
</ul>
<div style="font-family: 'Times New Roman';">
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Interface javax.money.MonetaryAmount</span></h3>
</div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically the interface models similar aspects as </span><span style="font-family: 'Courier New', Courier, monospace;">java.math.BigDecimal</span><span style="font-family: Arial, Helvetica, sans-serif;">, but targeting monetary amounts:</span></div>
<span style="font-family: Courier New, Courier, monospace;"><br /><b>public interface</b> MonetaryAmount{<br /> CurrencyUnit <b><span style="color: #660000;">getCurrency</span></b>()<br /> MonetaryAmount <b><span style="color: #660000;">add</span></b>(MonetaryAmount);<br /> MonetaryAmount <b><span style="color: #660000;">subtract</span></b>(MonetaryAmount);<br /> </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount <b><span style="color: #660000;">multiply</span></b>(MonetaryAmount);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> MonetaryAmount <b><span style="color: #660000;">multiply</span></b>(Number);</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount <b><span style="color: #660000;">divide</span></b>(MonetaryAmount);</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> MonetaryAmount <b><span style="color: #660000;">divide</span></b>(Number);</span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount <b><span style="color: #660000;">remainder</span></b>(MonetaryAmount);</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> MonetaryAmount <b><span style="color: #660000;">remainder</span></b>(Number);</span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount <b><span style="color: #660000;">scaleByPowerOfTen</span></b>(int);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"> MonetaryAmount <b><span style="color: #660000;">abs</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"><br /> MonetaryAmount <b><span style="color: #660000;">negate</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"> MonetaryAmount <b><span style="color: #660000;">pow</span></b>(int); </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount <b><span style="color: #660000;">ulp</span></b>(); // unit in the last place</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> boolean <span style="color: #660000;">isGreater</span></b>(MonetaryAmount);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #660000;">isGreaterOrEquals</span></b>(MonetaryAmount);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<b style="font-family: 'Courier New', Courier, monospace;"> boolean </b><span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #660000;">isLess</span></b>(MonetaryAmount), </span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b>boolean <span style="color: #660000;">isLessOrEquals</span></b>(MonetaryAmount);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;">...</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">boolean </b><span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #660000;">isEqualTo</span></b>(MonetaryAmount);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<b style="font-family: 'Courier New', Courier, monospace;"> boolean </b><span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #660000;">isNotEqualTo</span></b>(MonetaryAmount);</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<b style="font-family: 'Courier New', Courier, monospace;"> boolean </b><span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #660000;">isNegative</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<b style="font-family: 'Courier New', Courier, monospace;"> boolean </b><span style="font-family: Courier New, Courier, monospace;"><span style="color: #660000;"><b>isPositive</b></span>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<b style="font-family: 'Courier New', Courier, monospace;"> boolean </b><span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #660000;">isZero</span></b>(); </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> byte</b> <b><span style="color: #660000;">byteValue</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> short <span style="color: #660000;">shortValue</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> short <span style="color: #660000;">shortValueExact</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> int <span style="color: #660000;">intValue</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><b> int <span style="color: #660000;">intValueExact</span></b>();</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"><b>long <span style="color: #660000;">longValue</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> long <span style="color: #660000;">longValueExact</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> float <span style="color: #660000;">floatValue</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> double <span style="color: #660000;">doubleValue</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"> <T> T <b><span style="color: #660000;">asType</span></b>(Class<T>);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Class<?> <b><span style="color: #660000;">getNumberType</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> int <span style="color: #660000;">getPrecision</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> int <span style="color: #660000;">getScale</span></b>();</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"><b>int <span style="color: #660000;">signum</span></b>();</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"> MonetaryAmount <b><span style="color: #660000;">from</span></b>(Number);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">MonetaryAmount <b><span style="color: #660000;">from</span></b>(CurrencyUnit, Number);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">MonetaryAmount <b><span style="color: #660000;">with</span></b>(MonetaryOperator);</span><span style="font-family: Courier New, Courier, monospace;"><br />}</span><span style="font-family: Courier New, Courier, monospace;"><span id="internal-source-marker_0.5569909845944494"></span></span><br />
<div>
<br /><span style="vertical-align: baseline;"></span>
<span style="vertical-align: baseline;">
</span></div>
<div style="font-family: 'Times New Roman';">
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Hereby the last method </span><span style="font-family: 'Courier New', Courier, monospace;">with</span><span style="font-family: Arial, Helvetica, sans-serif;">, allows to combine amount instances with arbitrary external manipulation logic, implemented as </span><span style="font-family: Courier New, Courier, monospace;">MonetaryOperator</span><span style="font-family: Arial, Helvetica, sans-serif;">. This is explained in more detail later.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Class javax.money.Money</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This class is the implementation of </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount</span><span style="font-family: Arial, Helvetica, sans-serif;">, using </span><span style="font-family: Courier New, Courier, monospace;">java.math.BigDecimal </span><span style="font-family: Arial, Helvetica, sans-serif;">for numeric representation. The method signature look similar to the interface, but return the according value object, e.g.:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><b>public final class</b> Money <b>implements </b>MonetaryAmount,...{</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [...]</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b>public </b>Money <b><span style="color: #660000;">add</span></b>(MonetaryAmount amount);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [...]</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Creation of </span><span style="font-family: Courier New, Courier, monospace;">Money </span><span style="font-family: Arial, Helvetica, sans-serif;">instance hereby is done using the </span><span style="font-family: Courier New, Courier, monospace;">of() </span><span style="font-family: Arial, Helvetica, sans-serif;">factory methods, e.g.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">Money </span><span style="font-family: 'Courier New', Courier, monospace;">amount1 = Money.of("USD", 12); <span style="color: #999999;">// int</span></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Money </span><span style="font-family: 'Courier New', Courier, monospace;">amount2 = Money.of("USD", 12.5); <span style="color: #999999;">// float</span></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Money </span><span style="font-family: 'Courier New', Courier, monospace;">amount3 = Money.of("USD", (byte)12); <span style="color: #999999;">// int</span></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Money </span><span style="font-family: 'Courier New', Courier, monospace;">amount4 = Money.of("USD", BigDecimal.valueOf(100.15d)); </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> <span style="color: #999999;">// BigDecimal</span></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Arial, Helvetica, sans-serif;">Hereby the above calls also include some convenience, since the ISO namespace is used implicitly. The first call basically is equivalent to:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">Money </span><span style="font-family: 'Courier New', Courier, monospace;">amount1 = Money.of(MoneyCurrency.of("USD"), 12);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">or to the full fledged version:</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
<span style="font-family: 'Courier New', Courier, monospace;">Money </span><span style="font-family: 'Courier New', Courier, monospace;">amount1 = </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> Money.of(</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> MoneyCurrency.of(</span><span style="font-family: 'Courier New', Courier, monospace;">MoneyCurrency.ISO_NAMESPACE, </span><span style="font-family: 'Courier New', Courier, monospace;">"USD"), 12); </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Interface javax.money.MonetaryOperator</span></h3>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As seen before an instance of </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount </span><span style="font-family: Arial, Helvetica, sans-serif;">also has a with method taking a </span><span style="font-family: 'Courier New', Courier, monospace;">MonetaryOperator </span><span style="font-family: Arial, Helvetica, sans-serif;">as a parameter. The type </span><span style="font-family: Courier New, Courier, monospace;">MonetaryOperator </span><span style="font-family: Arial, Helvetica, sans-serif;">is modelled similarly to the </span><span style="font-family: Courier New, Courier, monospace;">UnaryOperator </span><span style="font-family: Arial, Helvetica, sans-serif;">functional interface from Java 8, extending the corresponding base type </span><span style="font-family: Courier New, Courier, monospace;">MonetaryFunction</span><span style="font-family: Arial, Helvetica, sans-serif;">:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<span style="color: #999999; font-family: Courier New, Courier, monospace;">//@FunctionalInterface</span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>public interface </b>MonetaryFunction<T, R> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>R apply(T value);</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #999999;">//@FunctionalInterface</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>public interface</b> MonetaryOperator </span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>extends </b>MonetaryFunction<MonetaryAmount,MonetaryAmount> {</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br /></div>
</div>
</div>
</div>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This looks not very spectacular, but when combined with functionalities like currency exchange, rounding and more complex operations the concepts renders to a powerful weapon against complexity:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">CurrencyConversion convertToYen = ...;</span><br />
<span style="font-family: Courier New, Courier, monospace;">Money m = Money.of("USD", 12345.25)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> .multiply(10.34563)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">.with(MajorPart.of())</span><br />
<span style="font-family: Courier New, Courier, monospace;"> .with(</span><span style="font-family: 'Courier New', Courier, monospace;">convertToYen</span><span style="font-family: Courier New, Courier, monospace;">)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">.divide(7)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> .with(MoneyRounding.of());</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">This operational chain creates an amount in USD, multiplies it by </span><span style="font-family: 'Courier New', Courier, monospace;">10.34563</span><span style="font-family: Arial, Helvetica, sans-serif;">, takes the major part only, converts it to YEN, divides by </span><span style="font-family: Courier New, Courier, monospace;">7</span><span style="font-family: Arial, Helvetica, sans-serif;"> and finally rounds according the default rounding rules defined for YEN. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">When dealing with monetary functions there are also some built-in functions provided by default (if you have some hints or ideas, what else would be useful please drop me a mail):</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">Collection<MonetaryAmount> amounts = ...;</span><br />
<span style="font-family: Courier New, Courier, monospace;">Map<CurrencyUnit, MonetaryAmount> sepResult = </span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #660000;">SeparateCurrencies</span></b>.apply(amounts);</span><br />
<span style="font-family: Courier New, Courier, monospace;">// Get amounts > 100 in USD</span><br />
<span style="font-family: Courier New, Courier, monospace;">Collection<MonetaryAmount> allUSDAmounts = </span><br />
<span style="font-family: Courier New, Courier, monospace;"> sepResult.get(MoneyCurrency.of("USD"</span><span style="font-family: 'Courier New', Courier, monospace;">));</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Collection<MonetaryAmount></span><span style="font-family: 'Courier New', Courier, monospace;"> bigAmounts =</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"><b>new </b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #660000;"><b> AmountFilter</b></span>(</span><span style="font-family: 'Courier New', Courier, monospace;">allUSDAmounts </span><span style="font-family: Courier New, Courier, monospace;">).apply(</span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> new </b>MonetaryFunction<MonetaryAmount, Boolean>(){</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b>public Boolean</b> apply(MonetaryAmount amount){</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b>return </b>amount.intValue()>100;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;"> });</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><span style="font-family: Arial, Helvetica, sans-serif;">Finally also rounding can be modelled similar as </span><span style="font-family: Courier New, Courier, monospace;">MonetaryOperator</span><span style="font-family: Arial, Helvetica, sans-serif;">, thus being only a special case of operation not adding basic additional complexity on this API level. Hereby the class </span><span style="font-family: Courier New, Courier, monospace;">MoneyRounding </span><span style="font-family: Arial, Helvetica, sans-serif;">provides access to rounding algorithms:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><b>public final class </b>MoneyRounding <b>implements </b>MonetaryOperator{</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b>public </b>MonetaryAmount <b><span style="color: #660000;">apply</span></b>(MonetaryAmount amount){</span><br />
<span style="font-family: Courier New, Courier, monospace;"> [.. ]</span><br />
<span style="font-family: Courier New, Courier, monospace;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Different Numeric Representations</span></h3>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Different implementations of </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount </span><span style="font-family: Arial, Helvetica, sans-serif;">can model the numeric representation using different numeric types. This allows to cover the varieties of use cases identified. Nevertheless it should be possible to mix up different implementations by applying some relatively simple rules:</span><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The numeric representation is not part of the </span><span style="font-family: Courier New, Courier, monospace;">MonetaryAmount </span><span style="font-family: Arial, Helvetica, sans-serif;">interface.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The target instance's class of an operation performed, determines the resulting instance type of an operation (which should be the same as the target type itself).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">If an arithmetic operation exceeds the capabilities of the target instance, an </span><span style="font-family: Courier New, Courier, monospace;">ArithmeticException </span><span style="font-family: Arial, Helvetica, sans-serif;">should be thrown.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Precision/Scale information should never be lost.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Automatic rounding is only valid, when required by the internal representation. By default no rounding should ever happen, despite internal rounding, implied by the numeric representation type.</span></li>
</ul>
</div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">As an example, refer to the example below:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">Money mm = Money.of("USD", "1222222222222222222323232.23232323");</span><br />
<span style="font-family: Courier New, Courier, monospace;">IntegralMoney im = IntegralMoney.of("USD", 2345);</span><br />
<span style="font-family: Courier New, Courier, monospace;">mm.divide(im); <span style="color: #999999;">// should work</span></span><br />
<span style="font-family: Courier New, Courier, monospace;">im.divide(mm);<span style="color: #999999;"> // throws ArithmeticException</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">So hopefully, this creates some appetite for more. So go to our <a href="http://java.net/projects/javamoney">project page</a> on java.net or check out our <a href="https://github.com/JavaMoney/javamoney">GitHub repository</a> and try things out, and of course, if you have any questions, or even better feedback or improvement, feel free to <a href="mailto:atsticks@java.net">contact me</a>. </span></div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com8tag:blogger.com,1999:blog-5942248025211712011.post-57262009370623346552013-02-06T23:50:00.002-08:002013-02-06T23:50:43.660-08:00Interesting Aspects on Locale Extensions<h2>
Locale Extensions</h2>
<h3>
What can be done</h3>
Extensions allow to add additional information to a Locale as also described in the Java Doc:<br />
<blockquote class="tr_bq">
<span style="font-family: Verdana, sans-serif; font-size: x-small;"><i>The Locale class implements IETF BCP 47 which is composed of <a href="http://tools.ietf.org/html/rfc4647">RFC 4647 "Matching of Language Tags"</a> and <a href="http://tools.ietf.org/html/rfc5646">RFC 5646 "Tags for Identifying Languages"</a> with support for the LDML (UTS#35, "Unicode Locale Data Markup Language") BCP 47-compatible extensions for locale data exchange.</i></span></blockquote>
Now what you can do, is adding extension tags as follows:<br />
<br />
<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">b.setExtension('x', "myExt-myCal-myCur");</span></blockquote>
<br />
But there are some things to be aware of:<br />
<br />
<ul>
<li>extensions are not case sensitive (The JDK <span style="font-family: Courier New, Courier, monospace;">Locale </span><b>converts them all implicitly to lower case</b>!)</li>
<li>there is<b> no defined order</b> of extension tags, so dont rely on!</li>
<li>tags can be separated by '-' or '_' (the standard requires '-', Java accepts both as input, but then <b>translates all '_' to '-'</b>).</li>
<li><b>valid characters for tags are restricted</b> to [a-z][A-Z][0-9], so there are no special characters like '?' or '=' or similar possible (Java checks this).</li>
<li><b><b>tags are a minimum of 2 characters long</b><span style="font-weight: normal;"> (this is also checked by the JDK)</span></b></li>
<li><b>tags are a maximum of 8 characters long</b> (this is also checked by the JDK)</li>
<li>each <b>extension is identified by a singleton character</b> (not a digit)</li>
</ul>
<div>
So all the following inputs are accepted by the JDK:</div>
<div>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">b.setExtension('x', "mi");</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">b.setExtension('a', "maxmaxma");</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">b.setExtension('b', "de-US");</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">b.setExtension('d', "aa1-bb2_cc3_dd4");</span></blockquote>
<br /></div>
<br />
<br />
<h3>
Strange Behavior</h3>
Some days ago I played around with <span style="font-family: Courier New, Courier, monospace;">Locale </span>extensions (JDK 7/8):<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">Locale.Builder b = <b>new </b>Locale.Builder();</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// b.setRegion("DE");</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// b.setLanguage("de");</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">b.setExtension('x', "gr2-spPrepen-nldeDE");</span><span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;">System.out.println("Locale: " + b.build())</span><span style="font-family: Georgia, Times New Roman, serif;">;</span></span><span style="font-size: x-small;"><span style="font-family: 'Courier New', Courier, monospace;">System.out.println("Locale</span><span style="font-family: 'Courier New', Courier, monospace;">'s </span><span style="font-family: 'Courier New', Courier, monospace;">extension: " + b.build().getExtension('x'));</span></span></blockquote>
<br />
The outputput is a bit surprising (the <b>extension does NOT appear in the <span style="font-family: Courier New, Courier, monospace;">toString</span>-output</b>):<br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;">> </span><span style="font-family: 'Courier New', Courier, monospace;">Locale:</span><span style="font-family: 'Courier New', Courier, monospace;"> </span></span><span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;">> </span><span style="font-family: 'Courier New', Courier, monospace;">Locale</span><span style="font-family: 'Courier New', Courier, monospace;">'s </span><span style="font-family: 'Courier New', Courier, monospace;">extension:</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">gr2-spprepen-nldede</span></span></blockquote>
<br />
At a first glue this seem to be a bug, but when reading the spec in <a href="http://tools.ietf.org/html/rfc5646#page-16">http://tools.ietf.org/html/rfc5646#page-16</a>, especially section 2.2.6:<br />
<br />
<blockquote class="tr_bq">
<i> An extension MUST follow at least a primary language subtag.<br /> That is, a language tag cannot begin with an extension.</i></blockquote>
<br />
this can be a hint, why this behaves as shown above, though, if a <span style="font-family: Courier New, Courier, monospace;">Locale </span>is invalid, then it should not be possible to create/build it...<br />
<br />
Now, when <b>setting a language</b> in our example with:<br />
<blockquote class="tr_bq">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-size: x-small;">b.setLanguage("de")</span>;</span></blockquote>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span>
the <span style="font-family: Courier New, Courier, monospace;">toString()</span> result now seem to be correct:<br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;">> </span><span style="font-family: 'Courier New', Courier, monospace;">Locale:</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">de__#x-gr2-spprepen-nldede</span></span><span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;">> </span><span style="font-family: 'Courier New', Courier, monospace;">Locale</span><span style="font-family: 'Courier New', Courier, monospace;">'s </span><span style="font-family: 'Courier New', Courier, monospace;">extension:</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">gr2-spprepen-nldede</span></span><span style="font-family: 'Courier New', Courier, monospace;"> </span></blockquote>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
The same applies, when <b>setting a region only...</b><br />
<span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;"></span></span><br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;">> Locale: _DE_#x-gr2-spprepen-nldede</span></span>> Locale's extension: gr2-spprepen-nldede</blockquote>
<br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">...or when setting both, a region and a language, also of the output is as expected:</span><br />
<span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;"></span></span><br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="font-family: Courier New, Courier, monospace;">> Locale: de_DE_#x-gr2-spprepen-nldede</span></span>> Locale's extension: gr2-spprepen-nldede</blockquote>
<br />
Finally I also was trying some special inputs based on the constraints defined by the specification, and I was able to create other invalid <span style="font-family: Courier New, Courier, monospace;">Locale </span>instances realtively easily:<br />
<br />
<blockquote class="tr_bq">
<ul>
<li><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b.setExtension('c', "de-DE");</span> will be converted to <i>c-de-de</i>, which is invalid since <i>de</i> is duplicated in the final representation (but required to be unique).</li>
<li><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b.setExtension('c', "c-de");</span> will be converted to <i>c-c-de-de</i>, which is invalid since the extension singleton <i>c</i> is duplicated in the final representation (but required to be unique).</li>
<li><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">b.setExtension('c', "x-de");</span> will be converted to <i>c-x-de-de</i>, which is invalid since an extension singleton must contain some tags, which is not the case for <i>c-x-de</i>, which in this case is the final representation. </li>
</ul>
</blockquote>
So be careful, when using the <span style="font-family: Courier New, Courier, monospace;">Locale </span>extension mechanism. I will also post this to the i18n colleagues at OpenJDK, I am wondering what they think...<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com0tag:blogger.com,1999:blog-5942248025211712011.post-86788818051427212212013-01-18T01:12:00.002-08:002013-01-29T00:07:37.702-08:00java.util.Timezone<h2>
What happens when calling <span style="font-family: Courier New, Courier, monospace;">Timezone.getTimezone("blabla")?</span></h2>
Even seen, what happens when you access a Timezone using <span style="font-family: Courier New, Courier, monospace;">java.uil.Timezone.getTimezone("blabla")</span>? I would expect an exception to be thrown, since the input is completely invalid, but nothing similar happens. The method silently returns a <span style="font-family: 'Courier New', Courier, monospace;">TimeZone </span>initialized to <i>GMT+0</i>.<br />
But there are other flaws in <span style="font-family: Courier New, Courier, monospace;">TimeZone</span>. At a first look, it looks like an immutable object, but when look at it carefully, there is a <span style="font-family: Courier New, Courier, monospace;">setId(String) </span>method. This allows to set the time zone ID to an arbitrary value:<br />
<span style="font-family: Courier New, Courier, monospace;">TimeZone tz = </span><span style="font-family: 'Courier New', Courier, monospace;">Timezone</span><span style="font-family: Courier New, Courier, monospace;">.getTimezone("Europe/Zurich"); </span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #999999;">// will return a zone with GMT+1 offset (DST ignored)</span></span><br />
<span style="font-family: Courier New, Courier, monospace;">tz.setId("blabla");</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #999999;">// now we have a time zone 'blabla' with identical offsets.</span></span><br />
<span style="font-family: Courier New, Courier, monospace;">System.out.println(tz);</span><br />
<br />
This results in the following output:<br />
<span style="font-family: Courier New, Courier, monospace;">sun.util.calendar.ZoneInfo[id="blabla",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=119,lastRule=java.util.SimpleTimeZone[id=blabla,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]</span><br />
<br />
Obviously this API is very dangerous. So looking forward what JSR 310 will bring...<br />
<br />
<i>JDK used was 1.7.09 and jdk-8-ea-bin-b74-windows-x64-24_jan_2013, but it is similarly also the case in earlier versions.</i><br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com1tag:blogger.com,1999:blog-5942248025211712011.post-39747125603322679842013-01-16T16:45:00.002-08:002013-01-17T01:20:03.028-08:00Complex Formatting and Parsing<h2>
Complex Formatting and Parsing</h2>
<h3>
Problem</h3>
In the area of internationalization (i18n) formatting and parsing is a typical use case. Unfortunately <span style="font-family: Courier New, Courier, monospace;">java.util.Locale</span> as the only parameter controlling such a process has shown not to be sufficient. Refer to the following use cases:<br />
<br />
<ul>
<li>Formatting of an monetary amount contains of a numeric part, as well as a currency part. Now both can be required to be formatted using different locales, e.g. </li>
<ul>
<li>German numeric format and </li>
<li>English currency symbol.</li>
</ul>
<li>But when considering display requirements for financial applications very different formats are required</li>
<ul>
<li>based on the usage scenario, e.g. numbers included into balances may be totally different than numbers formatted on a account summary (different number groups, signs and symbol placements etc).</li>
<li>based on individual user settings.</li>
<li>based on the type of formatting, e.g. for display, print out or for textual representation within legacy systems.</li>
</ul>
<li>When parsing a literal representation back into a type instance similar scenarios may be possible. Additionally, especially when parsing user input, the things can get even more complex:</li>
<ul>
<li>the currency symbol may be English, similar to above, but...</li>
<li>the number formats supported can be in several formats, since users do not always enter the 100% correct format (which is totally OK from a user's perspective!).</li>
<li>additionally depending on use case different number precision may ve required, that must not match the fraction digits defined by the currency entered (e.g. 2 for Swiss Francs, but 0 for Japanese Yen). In some usage scenarios one even wants lenient fraction parsing to be possible.</li>
</ul>
</ul>
<div>
Summarizing a <span style="font-family: Courier New, Courier, monospace;">Locale </span>with its country, language, variant scheme is not sufficient to define the scenarios above. </div>
<div>
<br /></div>
<h3>
Solution: Defining a LocalizationStyle</h3>
<div>
I propose to model such things as <span style="font-family: Courier New, Courier, monospace;">LocalizationStyle</span>, containing the following data:</div>
<div>
<ul>
<li>an <b>identifier </b>defining the style. Different use cases (e.g. different display scenarios, as well as technical scenarios can be separated).</li>
<li>a <b>target type</b>, since a style typically is bound to a specific type and should not be mixed up.</li>
<li>a <b>leading </b>Locale, or<b> translation Locale.</b></li>
<li>an (optional) <b>number Locale</b>, if missing falling back to the translation Locale</li>
<li>an (optional) <b>date Locale</b>, if missing falling back to the translation Locale</li>
<li>an (optional) <b>time Locale</b>, if missing falling back to the date Locale</li>
<li>any <b>additional optional attributes</b></li>
</ul>
<div>
Additionally a Locale is an <i>immutable </i>instance. With a <span style="font-family: Courier New, Courier, monospace;">LocalizationStyle </span>this would be also be feasible:</div>
</div>
<div>
<ul>
<li>by defining a <span style="font-family: Courier New, Courier, monospace;">LocalizationStyleFactory</span> to create immutable instances.</li>
<li>or by setting a <span style="font-family: Courier New, Courier, monospace;">LocaliuationStyle </span>to read-only, when it is completely initialized and configured.</li>
</ul>
<div>
Consequently the most simple and common variant of a <span style="font-family: Courier New, Courier, monospace;">LocalizationStyle </span>is basically very similar as a <span style="font-family: Courier New, Courier, monospace;">Locale</span>:</div>
</div>
<div>
<ul>
<li>it's identifier is set to <span style="font-family: Courier New, Courier, monospace;">"default". </span><span style="font-family: inherit;">This is also visible by the corresponding method </span><span style="font-family: Courier New, Courier, monospace;">boolean isDefault(); </span><span style="font-family: inherit;">which returns </span><span style="font-family: Courier New, Courier, monospace;">true</span><span style="font-family: inherit;">.</span></li>
<li>Its leading translation <span style="font-family: 'Courier New', Courier, monospace;">Locale</span>is set to the required <span style="font-family: Courier New, Courier, monospace;">Locale</span>.</li>
<li>Since this functionaliy is quite common, it can be provided using a static factory method:<br /><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">LocalizationStyle style = <b>LocalizationStyle .valueOf</b>(Locale.GERMAN);</span></li>
</ul>
<div>
<br />
<h4>
Using the <span style="font-family: Courier New, Courier, monospace;">LocalizationStyle </span>for Configuring Complex Formatting and Parsing</h4>
<br />
As a consequence according formatters and parsers only must support <span style="font-family: Courier New, Courier, monospace;">LocalizationStyle </span>as valid input parameters (<span style="font-family: Courier New, Courier, monospace;">Locale</span> can still be supported for convenience), e.g.</div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> String format(T item, LocalizationStyle style);</span></div>
<div>
or</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> String getLocalized(LocalizationStyle style);</span></div>
<div>
<br />
But now it is possible to pass much more detailed configuration what how formatter or parser must behave. Nevertheless in mny cases such formatters/parsers are not to be implemented as big and complex single data types. It is recommended to implement something like a FormatterManager/ParserManager that is able to manage the different implementations. Nevertheless since a Formatter/Parser instance can be identified by the duplet <span style="font-family: Courier New, Courier, monospace;">[style-id, target-type]</span> this is not as complex as it seems on a first look.</div>
<h4>
Detailed interface</h4>
<div>
The proposed class would be as follows:<br />
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public class</b> LocalizationStyle <b>implements </b>Serializable {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * serialVersionUID.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>private static final</b> long serialVersionUID = 8612440355369457473L;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/** The internal key used for a time locale set. */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public static final</b> String TIME_LOCALE = "timeLocale";</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/** The internal key used for a date locale set. */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public static final</b> String DATE_LOCALE = "dateLocale";</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/** The internal key used for a number locale set. */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public static final</b> String NUMBER_LOCALE = "numberLocale";</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/** The internal key used for a translation locale set (default). */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public static final</b> String TRANSLATION_LOCALE = "locale";</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/** The internal key used for a formatting/parsing style. */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span class="Apple-tab-span" style="white-space: pre;"> </span>private static final</b> String DEFAULT_ID = "default";</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/** The style's name, by default ({@link #DEFAULT_ID}. */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>private </b>String id;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/** The style's generic properties. */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>private </b>Map<String, Object> attributes = Collections</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>.synchronizedMap(new HashMap<String, Object>());</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Flag to make a localization style read only, so it can be used (and</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * cached) similar to a immutable object.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span class="Apple-tab-span" style="white-space: pre;"> </span>private boolean</b> readOnly = false;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Creates a new instance of a style. This method will use the Locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * returned from {@link Locale#getDefault()} as the style's default locale.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param id</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The style's identifier (not null).</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>LocalizationStyle(String id) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>this</b>(id, Locale.getDefault());</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Creates a new instance of a style.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param id</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The style's identifier (not null).</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * the default locale to be used for all locale usages.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>LocalizationStyle(String id, Locale locale) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>this</b>(id, locale, locale);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Creates a new instance of a style.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param id</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The style's identifier (not null).</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param translationLocale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * the default locale (translation locale) to be used for all</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * locale usages.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param numberLocale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * the locale to be used for numbers.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>LocalizationStyle(String id, Locale translationLocale,</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Locale numberLocale) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(id == null) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>throw new</b> IllegalArgumentException("ID must not be null.");</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>this.id = id;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Creates a new instance of a style. This method will copy all attributes</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * and properties from the given style. The style created will not be</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * read-only, even when the base style is read-only.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param baseStyle</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The style to be used as a base style.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>LocalizationStyle(LocalizationStyle baseStyle) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>this</b>.attributes.putAll(baseStyle.getAttributes());</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>this</b>.id = baseStyle.getId();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Allows to evaluate if a style is a default style. A style is a default</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * style, if its id equals to {@link #DEFAULT_ID}.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * <p></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Note that nevertheless multiple default style instances may be defined</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * that are not equal, since its attributes may differ.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return true, if this style is a default style.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public boolean</b> isDefault() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>DEFAULT_ID.equals(getId());</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * This method allows to check, if the given style can be changed or, if it</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * read only.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return true, if the style is read-only.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final boolean</b> isReadOnly() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>readOnly;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * This method renders this style instance into an immutable instance.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Subsequent calls to {@link #setAttribute(String, Serializable)},</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * {@link #setDateLocale(Locale)}, {@link #setNumberLocale(Locale)},</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * {@link #setTimeLocale(Locale)}or {@link #removeAttribute(String)} will</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * throw an {@link IllegalStateException}.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span class="Apple-tab-span" style="white-space: pre;"> </span>public void</b> setImmutable() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>this</b>.readOnly = true;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Method used to simply create a {@link IllegalStateException}, if this</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * instance is read-only. This prevents duplicating the corresponding code.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>private void</b> throwsExceptionIfReadonly() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(readOnly) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>throw new</b> IllegalStateException(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>"This instance is immutable and can not be ^changed.");</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Get the style's identifier, not null.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the style's id.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>String getId() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>id;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Get the style's (default) locale used for translation of textual values,</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * and (if not specified explicitly as a fallback) for date, time and</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * numbers.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the translation (default) locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span class="Apple-tab-span" style="white-space: pre;"> </span>public final</b> Locale getTranslationLocale() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Locale locale = (Locale) getAttribute(TRANSLATION_LOCALE);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(locale != null) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>locale;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>Locale.getDefault();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Get the style's locale used for formatting/parsing of numbers.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the number locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final</b> Locale getNumberLocale() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Locale locale = (Locale) getAttribute(NUMBER_LOCALE);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(locale != null) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>locale;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>getTranslationLocale();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Get the style's locale for formatting/parsing of date instances.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the date locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final</b> Locale getDateLocale() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Locale locale = (Locale) getAttribute(DATE_LOCALE);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(locale != null) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>locale;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>getTranslationLocale();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Set the style's locale for formatting/parsing of dates.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The date locale to be used, or null for falling back to the</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * translation locale.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the date locale previously set, or null.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final</b> Locale setDateLocale(Locale locale) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>(Locale) setAttribute(DATE_LOCALE, locale);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Set the style's locale for formatting/parsing of time.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The time locale to be used, or null for falling back to the</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * translation locale.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the time locale previously set, or null.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final</b> Locale setTimeLocale(Locale locale) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>(Locale) setAttribute(TIME_LOCALE, locale);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Set the style's locale for formatting/parsing of numbers.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The number locale to be used, or null for falling back to the</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * number locale.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the number locale previously set, or null.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final</b> Locale setNumberLocale(Locale locale) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>(Locale) setAttribute(NUMBER_LOCALE, locale);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Get the style's locale for formatting/parsing of time data.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the time locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final</b> Locale getTimeLocale() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>Locale locale = (Locale) getAttribute(TIME_LOCALE);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(locale != null) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>locale;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>getDateLocale();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Get the current defined properties fo this style.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the properties defined</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public final</b> Map<String, Object> getAttributes() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>synchronized </b>(attributes) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return new </b>HashMap<String, Object>(attributes);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Sets the given property. This method is meant for adding custom</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * properties. Setting a predefined property, e.g. {@link #DATE_LOCALE} will</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * throw an {@link IllegalArgumentException}.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param key</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The target key</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param value</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The target value</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return The object previously set, or null.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @throws IllegalArgumentException</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * if the key passed equals to a key used for a predefined</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * property.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>Object setAttribute(String key, Serializable value) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>throwsExceptionIfReadonly();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>synchronized </b>(attributes) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>attributes.put(key, value);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Read a property from this style.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param key</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The property's key</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return the current property value, or null.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>Object getAttribute(String key) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>synchronized </b>(attributes) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>attributes.get(key);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Removes the given property. This method is meant for removing custom</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * properties. Setting a predefined property, e.g. {@link #DATE_LOCALE} will</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * throw an {@link IllegalArgumentException}.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param key</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * The key to be removed</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return The object previously set, or null.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @throws IllegalArgumentException</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * if the key passed equals to a key used for a predefined</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * property.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>Object removeAttribute(String key) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>throwsExceptionIfReadonly();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>synchronized </b>(attributes) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>attributes.remove(key);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/*</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * (non-Javadoc)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @see java.lang.Object#hashCode()</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@Override</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>public int hashCode() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>final int prime = 31;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>int result = 1;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>synchronized (attributes) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>result = prime * result</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>+ ((attributes == null) ? 0 : attributes.hashCode());</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return result;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/*</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * (non-Javadoc)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @see java.lang.Object#equals(java.lang.Object)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@Override</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public boolean</b> equals(Object obj) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(this == obj)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>true;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(obj == null)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>false;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>if </b>(getClass() != obj.getClass())</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>false;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>LocalizationStyle other = (LocalizationStyle) obj;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>synchronized </b>(attributes) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if (attributes == null) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if (other.attributes != null)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>false;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>} else if (!attributes.equals(other.attributes))</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>false;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>true;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/*</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * (non-Javadoc)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @see java.lang.Object#toString()</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@Override</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public </b>String toString() {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>synchronized </b>(attributes) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return </b>"LocalizationContext [id=" + id + ", properties="</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>+ attributes + "]";</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>/**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * Factory method to create a {@link LocalizationStyle} using a single</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * {@link Locale}.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @param locale</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> * @return</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>public static</b> LocalizationStyle of(Locale locale) {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><b>return new </b>LocalizationStyle(DEFAULT_ID, locale);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com2