tag:blogger.com,1999:blog-34526423468349774452024-03-13T21:39:16.377-07:00JSR 354Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.comBlogger1125tag:blogger.com,1999:blog-3452642346834977445.post-67583274726474965942013-09-03T06:37:00.002-07:002013-09-03T15:11:49.041-07:00Introduction to the JSR 354 Region API<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">JSR 354 Region API</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Today I would like to introduce you the Region API that is part of JSR 354. First many of you might ask, why we need a Region API at all. The answer is when you are working with monetary values and currencies, regions are a natural part that requires also a flexible and extensible design. </span><span style="font-family: Arial, Helvetica, sans-serif;">Mapping everything into</span><span style="font-family: Courier New, Courier, monospace;"> java.util.Locale</span><span style="font-family: Arial, Helvetica, sans-serif;"> might be easy for many use cases, but obviously has its limits, when you start thinking of what a Region really can be:</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A country, e.g. modelled by ISO</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A region containing multiple countries, e.g. Central Europe, EMEA, ...</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A continent</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A completely different grouping, e.g. legal units (grouped by similar laws or international contracts)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Regions with political instability</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Regions with high economic growth</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">etc.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Of course this list is endless. The important point is, that depending on your use cases, you will have completely different requirements, what kind of regions you want to model and how they should be organized. </span></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">The Region Interface</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">A Region should be very simple, so JSR 354 defines it as</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> public interface</b> Region{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> RegionType <b><span style="color: #a64d79;">getRegionType</span></b>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> String <b><span style="color: #a64d79;">getRegionCode</span></b>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>int <span style="color: #a64d79;">getNumericRegionCode</span></b>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Locale <b><span style="color: #a64d79;">getLocale</span></b>();<br /> Collection<String> <b><span style="color: #a64d79;">getTimezoneIds</span></b>();</span></div>
<div>
<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;">Hereby</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The <i>regionCode </i>must be unique in combination with the </span><span style="font-family: Courier New, Courier, monospace;">RegionType</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The <i>numericCode </i>must be unique</span><span style="font-family: Arial, Helvetica, sans-serif;"> in combination with the </span><span style="font-family: Courier New, Courier, monospace;">RegionType</span><span style="font-family: Arial, Helvetica, sans-serif;">, but may also be undefined (-1).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">A region's </span><span style="font-family: Courier New, Courier, monospace;">getLocale </span><span style="font-family: Arial, Helvetica, sans-serif;">maps a </span><span style="font-family: Courier New, Courier, monospace;">Region </span><span style="font-family: Arial, Helvetica, sans-serif;">with the corresponding </span><span style="font-family: 'Courier New', Courier, monospace;">Locale. </span><span style="font-family: Arial, Helvetica, sans-serif;">Since not every </span><span style="font-family: Courier New, Courier, monospace;">Region </span><span style="font-family: Arial, Helvetica, sans-serif;">can be mapped to a </span><span style="font-family: Courier New, Courier, monospace;">Locale</span><span style="font-family: Arial, Helvetica, sans-serif;">, the method is allowed to return </span><span style="font-family: Courier New, Courier, monospace;">null</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The timezone ids finally allow to map a region to its containing time zones, e.g. </span><span style="font-family: Courier New, Courier, monospace;">Europe/Berlin, Europe/London</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The </span><span style="font-family: Courier New, Courier, monospace;">RegionType </span><span style="font-family: Arial, Helvetica, sans-serif;">used above is very simple:</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> public final class </b>RegionType </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> implements </b>Comparable<RegionType>, Serializable{</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"><b>public </b></span><span style="font-family: 'Courier New', Courier, monospace;">RegionType</span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #a64d79;">of</span></b><span style="font-family: 'Courier New', Courier, monospace;">(String type);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>public <span style="color: #a64d79;">RegionType</span></b>(</span><span style="font-family: 'Courier New', Courier, monospace;">String type</span><span style="font-family: 'Courier New', Courier, monospace;">);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public </b><span style="font-family: 'Courier New', Courier, monospace;">String </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #a64d79;">getId</span></b><span style="font-family: 'Courier New', Courier, monospace;">();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> [...]</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
</div>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So this allows to define a Region very easily. We will later have look how to access regions. First we want to discuss how regions are organized...</span></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">The Region Forest</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">First lets have a look to the following structure:</span></div>
<div>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">WORLD (world)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">EUROPE (continent)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">CH - Switzerland (country)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">ZH - Zurich(Canton)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">Wetzikon (Town)</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">GE - Geneva (Canton)</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">[...]</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">DE - Germany (country)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">[...]</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">[...]</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">ASIA</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">[...]</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">[...]</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">ISO (standard)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">DE - Germany</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">CH - Switzerland</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">US - United States</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">ISO3 (standard)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">DEU - Germany</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">USA - United States</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">ECONOMIC UNIONS (state unions)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">EU - European Union (economic union)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">DE - Germany (country)</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">[...]</span></li>
</ul>
<li><span style="font-family: Courier New, Courier, monospace;">EFTA (economic union)</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">CH - Switzerland (country)</span></li>
</ul>
</ul>
</ul>
</div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Experience has shown that the following aspects are important:</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Regions may have a hierarchical relationship to each other.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The hierarchical relationship often has a geographical nature, but any other classification are similarly feasible, e.g. based on economic, legal aspects.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The definition of a region must be independent from its hierarchical organization, since a region can be contained in multiple trees.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">And finally regions are organized in a region forest, containing, depending on the use cases several trees.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As a consequence JSR 354 defines a </span><span style="font-family: Courier New, Courier, monospace;">RegionTreeNode</span><span style="font-family: Arial, Helvetica, sans-serif;">:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> public interface</b> RegionTreeNode {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Region <b><span style="color: #a64d79;">getRegion</span></b>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> RegionTreeNode <b><span style="color: #a64d79;">getParent</span></b>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Collection<RegionTreeNode> <b><span style="color: #a64d79;">getChildren</span></b>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>boolean <span style="color: #a64d79;">contains</span></b>(Region region);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> RegionTreeNode <b><span style="color: #a64d79;">selectParent</span></b>(RegionFilter filter);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Collection<RegionTreeNode> <b><span style="color: #a64d79;">select</span></b>(RegionFilter filter);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> RegionTreeNode <b><span style="color: #a64d79;">getRegionTree</span></b>(String path);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Hereby</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the </span><span style="font-family: Courier New, Courier, monospace;">Region </span><span style="font-family: Arial, Helvetica, sans-serif;">related to a node is accessible calling </span><span style="font-family: Courier New, Courier, monospace;">getRegion</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">getParent, getChildren</span><span style="font-family: Arial, Helvetica, sans-serif;"> allow to navigate within the tree.</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">getRegionTree </span><span style="font-family: Arial, Helvetica, sans-serif;">allows to access any direct or indirect child node, using a path constructed of the region codes, e.g. </span><span style="font-family: Georgia, Times New Roman, serif;">WORLD/EUROPE/CH/ZH</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">select, selectParent </span><span style="font-family: Arial, Helvetica, sans-serif;">allow to search for parent or collect child regions using a </span><span style="font-family: Courier New, Courier, monospace;">RegionFilter </span><span style="font-family: Arial, Helvetica, sans-serif;">predicate. contains simply allows to evaluate if a given </span><span style="font-family: Courier New, Courier, monospace;">Region </span><span style="font-family: Arial, Helvetica, sans-serif;">is contained within the current <span style="font-family: 'Courier New', Courier, monospace;">Region</span>.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So now the questions is how can I access regions and region trees...</span></div>
</div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">The Regions Singleton</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Accessing regions and region trees is done using the </span><span style="font-family: Courier New, Courier, monospace;">javax.money.ext.Regions</span><span style="font-family: Arial, Helvetica, sans-serif;"> singleton. </span><span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Arial, Helvetica, sans-serif;">The following examples illustrate how to do that. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">First lets access all defined </span><span style="font-family: Courier New, Courier, monospace;">RegionTypes</span><span style="font-family: Arial, Helvetica, sans-serif;">:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Set<RegionType> regionTypes Regions.getRegionTypes();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Given a </span><span style="font-family: Courier New, Courier, monospace;">RegionType </span><span style="font-family: Arial, Helvetica, sans-serif;">we can access all corresponding regions :</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> Collection<Region> regions =<br /> Regions.getRegios(RegionType.CONTINENT);</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Since region codes in combination with a </span><span style="font-family: Courier New, Courier, monospace;">RegionType </span><span style="font-family: Arial, Helvetica, sans-serif;">are required to be unique, a </span><span style="font-family: Courier New, Courier, monospace;">Region </span><span style="font-family: Arial, Helvetica, sans-serif;">can be accessed directly:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Region region = Regions.getRegion(RegionType.TERRITORY, "US");</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">And, if a </span><span style="font-family: Courier New, Courier, monospace;">Region</span><span style="font-family: Arial, Helvetica, sans-serif;">'s numeric id or </span><span style="font-family: Courier New, Courier, monospace;">Locale </span><span style="font-family: Arial, Helvetica, sans-serif;">is defined, it is also possible to access a Region accordingly:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> Region region = Regions.getRegion(RegionType.TERRITORY, 2);</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> Region region2 = Regions.getRegion(Locale.GERMANY);</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Finally region trees can be accessed similarly:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> RegionTreeNode isoTree= Regions.getRegionTree("ISO");</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"> </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Hereby the available region trees can also be evaluated:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> Set<String> treeIds = Regions.getRegionTreeIds();</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Extended Region Data</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Finally there is also an API for accessing additional data that is related to a </span><span style="font-family: Courier New, Courier, monospace;">Region</span><span style="font-family: Arial, Helvetica, sans-serif;">. Similarly to the other API functionality the available data can be queried, given a </span><span style="font-family: 'Courier New', Courier, monospace;">Region </span><span style="font-family: Arial, Helvetica, sans-serif;">instance:</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Region region = ...;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Collection<Class> data = getExtendedRegionDataTypes(region);</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Given such a data type class the concrete data 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;"> MyExtendedData data = <br /> getExtendedRegionData(</span><span style="font-family: 'Courier New', Courier, monospace;">MyExtendedData.<b>class</b></span><span style="font-family: 'Courier New', Courier, monospace;">);</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Additional Info</span></h3>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">It remains to mention that all the APIs are mapped to a set of SPI interfaces. Also the </span><span style="font-family: Courier New, Courier, monospace;">Regions </span><span style="font-family: Arial, Helvetica, sans-serif;">singleton is feeded by a </span><span style="font-family: Courier New, Courier, monospace;">RegionsSingletonSpi</span><span style="font-family: Arial, Helvetica, sans-serif;">, which must be registrated using the JDK's </span><span style="font-family: Courier New, Courier, monospace;">ServiceLoader</span><span style="font-family: Arial, Helvetica, sans-serif;">. I might add a second post adding more details on this later.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In the meantime you may refer to the <b>current JSR's source code repository</b> located under</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><a href="https://github.com/JavaMoney/javamoney">https://github.com/JavaMoney/javamoney</a> for more details, or go to the </span><b style="font-family: Arial, Helvetica, sans-serif;">JSR 354 project page</b><span style="font-family: Arial, Helvetica, sans-serif;"> lcoated at: </span><a href="http://java.net/projects/javamoney" style="font-family: Arial, Helvetica, sans-serif;">http://java.net/projects/javamoney</a></div>
<div>
<ul><ul><ul></ul>
</ul>
</ul>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com0