tag:blogger.com,1999:blog-6032548840630017162024-02-08T07:30:36.312+01:00Life in IDELoose and tight thoughts about software development.l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.comBlogger35125tag:blogger.com,1999:blog-603254884063001716.post-31173118415934311192016-12-29T00:47:00.000+01:002016-12-29T00:48:40.583+01:00Thank you, blogspotIt was almost seven years ago when I started to write on blogpost (Blogger right now).<br />
<br />
From the beginning it was a heavy technology blog about my software development, and I have never thought that someone would read these articles. Now, at the end of 2016 I have about <b>86.5K</b> unique views, what means more than 30 visitors daily, on average. This is amazing. <b>Thank you people</b> (and bots :D)!<br />
<br />
Anyway, I still plan to write and make a little more software. However I decided to move out from blogspot. Previously I wanted to write an article why I decided to leave blogspot, but I've recently found Trisha Gee post about <a href="https://trishagee.github.io/project/atom-to-hugo/" target="_blank">why she is moving from blogspot to hugo</a>. This is a perfect article, I can only repeat this explanation, so it's better to just put a link here :)<br />
<br />
So, I'm closing this blog, and moving to hugo (my own choice is hugo - however other static site generators look great as well) and my own domain <a href="http://lifeinide.com/">lifeinide.com</a>.l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-30742036991420305252016-08-03T13:27:00.002+02:002016-12-25T12:51:15.740+01:00Reads vs writes in production database of web applicationI recently think about CQRS-like patterns we partially used in current application, and pros'n'cons of migrating more towards full CQRS, which is mostly about separating reads from writes. Previously I assumed that in usual application "we may have probably 100 times more reads than writes", what would qualify to have a value from these two models separation. I wanted to check it later on the production, but I forgot. Now we are close to start a big redesign of the whole application, and I've just remembered about that. So, how does it look for real production? This is data from postgres pg_stat_database of one of my projects:<br />
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">tup_returned | 58956902163</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">tup_inserted | 3348809</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">tup_updated | 4557408</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">tup_deleted | 245501</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: inherit;">Does it look that I made a big mistake previously and we have ~7200 times more reads than writes? It will be funny to investigate that in the near future...</span></div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-58617272354441816902015-09-19T14:09:00.001+02:002015-09-20T00:40:11.750+02:00How to avoid subclasses join in Hibernate model<div style="text-align: justify;">
This article will be about multiple joins in Hibernate model during super class fetch in JOINED inheritance mapping strategy, and generally how I significantly improved our system performance using some simple patterns. There's a lot of stuff on internet about this (usually wrong approach), so here I'll present my working solution for this problem.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Few words about motivation. People from Hibernate claim that this is not necessary to avoid joins, because join in nowaday databases is fast. This might be not a problem for, for example, 4 subclasses to make 4 join on each query. But what I personally really like in Hibernate, is that you can really model your world with classes and automatically map it to database. Really modeling your world usually means that you have a really lot of super and subclasses, and you may end up with for example 30-40 joins in simple <span style="font-family: Courier New, Courier, monospace;">from BaseEntity </span><span style="font-family: inherit;">query, or even you may hit 61 joins limit (if you use mysql).</span></div>
<div style="text-align: justify;">
<span style="font-family: inherit;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: inherit;">And here comes the problem. First and foremost, even if join is fast, I don't want to have 40 joins on simple queries. Even if it didn't influence the performance (but after my tests on big system - it does), I would like to be able to debug some queries in plain SQL, and I wouldn't like to have queries extending to 5 screens for that. So, here start things like adjusting the model to queries, what means that our real world model is no longer a real world model, but it becomes hibernate oriented model. That's second thing I hate to have in the project. I like to keep things clean.</span></div>
<div style="text-align: justify;">
<span style="font-family: inherit;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: inherit;">OK, now we can delve into the problem.</span><br />
<span style="font-family: inherit;"><br /></span></div>
<h4 style="text-align: justify;">
Joined strategy defaults</h4>
<div>
<br />
Let's consider following simple model:</div>
<div>
<br /></div>
<script src="https://gist.github.com/l0co/cddc53353a3857d58575.js"></script>
<br />
<div>
<br /></div>
<div>
This is how it's reflected in database (I use postgresql for this example):</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">aero=> \d super;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Table "public.super"</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Column | Type | Modifiers </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">------------+------------------------+-----------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> classname | character varying(255) | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> id | bigint | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> super_prop | character varying(255) | </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Indexes:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "super_pkey" PRIMARY KEY, btree (id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Referenced by:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> TABLE "suba" CONSTRAINT "fk_5yjvt9lkf5b24nyxv59n3kbgj" FOREIGN KEY (id) REFERENCES super(id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> TABLE "subb" CONSTRAINT "fk_q4aajuitkvsk93mn07t66l0pi" FOREIGN KEY (id) REFERENCES super(id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">aero=> \d suba;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Table "public.suba"</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Column | Type | Modifiers </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+------------------------+-----------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subaprop | character varying(255) | </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> id | bigint | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Indexes:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "suba_pkey" PRIMARY KEY, btree (id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Foreign-key constraints:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "fk_5yjvt9lkf5b24nyxv59n3kbgj" FOREIGN KEY (id) REFERENCES super(id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">aero=> \d subb;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Table "public.subb"</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Column | Type | Modifiers </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+------------------------+-----------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subbprop | character varying(255) | </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> id | bigint | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Indexes:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "subb_pkey" PRIMARY KEY, btree (id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Foreign-key constraints:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "fk_q4aajuitkvsk93mn07t66l0pi" FOREIGN KEY (id) REFERENCES super(id)</span></div>
</div>
<div>
<br /></div>
<div>
So, we have a superclass table, and two subclasses tables (in JOINED inheritance mapping strategy).</div>
<div>
<br /></div>
<div>
I put some data there:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">sessionFactory.getCurrentSession().save(new SubA());</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">sessionFactory.getCurrentSession().save(new SubB());</span></div>
</div>
<div>
<br /></div>
<div>
And can observe how this data is distributed in database:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">aero=> select * from super; select * from suba; select * from subb;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> classname | id | super_prop </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">-----------+----+------------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> SubA | 1 | superProp</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> SubB | 2 | superProp</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">(2 rows)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subaprop | id </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+----</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subAProp | 1</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">(1 row)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subbprop | id </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+----</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subBProp | 2</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">(1 row)</span></div>
</div>
<div>
<br /></div>
<div>
So, as expected, the data is distributed around all tables, depending on subclass type.</div>
<div>
<br /></div>
<div style="text-align: justify;">
Now I ask hibernate about superclasses list from database using <span style="font-family: Courier New, Courier, monospace;">from Super</span> HQL query, and the final SQL query built by Hibernate looks as follows:</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">select [...] from SUPER super0_ left outer join SUBA super0_1_ on super0_.id=super0_1_.id left outer join SUBB super0_2_ on super0_.id=super0_2_.id</span></div>
<div>
<br /></div>
<div>
The example above shows the broached problem (we imagine now, that we have 50 subclasses here, of course :) ).<br />
<br /></div>
<h4>
Explicit polymorphism</h4>
<div>
<br /></div>
<div style="text-align: justify;">
People on the internet often try to avoid multiple joins problem using <a href="https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/annotations/PolymorphismType.html#EXPLICIT" target="_blank">explicit polymorphism</a>. To be completely honest, I tried to use this hibernate feature to check if it solves the problem. The misunderstanding about this feature is probably located in Hibernate javadoc, and it claims that explicit polymorphism means: <i>This entity is retrieved only if explicitly asked</i>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So if we don't ask about <span style="font-family: Courier New, Courier, monospace;">SubA</span> class, for example, we should fetch only instances of <span style="font-family: Courier New, Courier, monospace;">Super</span>. Let's try it. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I tested two models, first one with explicit polymorphism on superclass:</div>
<div style="text-align: justify;">
<br /></div>
<script src="https://gist.github.com/l0co/b85ae489e2847493b1d4.js"></script>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And second one is with explicit polymorphism on subclass:</div>
<div style="text-align: justify;">
<br /></div>
<script src="https://gist.github.com/l0co/f00425cffb25578a9f1c.js"></script>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Both neither influence the table model, nor the data. And for both in response to <span style="font-family: Courier New, Courier, monospace;">from Super</span> we have:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: Courier New, Courier, monospace;">select [...] from SUPER super0_ left outer join SUBA super0_1_ on super0_.id=super0_1_.id left outer join SUBB super0_2_ on super0_.id=super0_2_.id</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
It just doesn't work as the expected.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, what is the explicit polymorphism for? It looks that the only application of this features, is so called <a href="https://community.jboss.org/wiki/LightweightClass" target="_blank">lightweight class</a> pattern, and it may be used only in situation when two or more of classes are mapped to the same table. But it doesn't solve our N joins problem.<br />
<br /></div>
<h4 style="text-align: justify;">
Single table + secondary tables</h4>
<div>
<br /></div>
<div style="text-align: justify;">
So how to solve the problem of N joins? I use following pattern, involving SINGLE_TABLE inheritance mapping strategy and secondary tables. Let's first look on the class model:</div>
<div style="text-align: justify;">
<br /></div>
<script src="https://gist.github.com/l0co/eb0e3353a6baa56c9f0c.js"></script>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Everything is mapped to single table, but for all derived classes I define secondary table (using <span style="font-family: Courier New, Courier, monospace;">@SecondaryTable</span> annotation) and tell Hibernate that this table should be fetched using additional select (using <span style="font-family: Courier New, Courier, monospace;">@Table</span> annotation). The additional hassle here is that for all properties from subclasses, I need to mark them by <span style="font-family: Courier New, Courier, monospace;">@Column</span> (or <span style="font-family: Courier New, Courier, monospace;">@JoinColumn</span> - for single ended associations) to tell Hibernate to put this property to the secondary table. This really should be done automatically (if whole class has secondary table definition), but this is one of many other things that Hibernate people refuse to do.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's take a glance on the database model:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div>
<span style="font-family: Courier New, Courier, monospace;">aero=> \d super; \d suba; \d subb;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Table "public.super"</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Column | Type | Modifiers </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">------------+------------------------+-----------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> classname | character varying(255) | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> id | bigint | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> super_prop | character varying(255) | </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Indexes:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "super_pkey" PRIMARY KEY, btree (id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Referenced by:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> TABLE "suba" CONSTRAINT "fk_5yjvt9lkf5b24nyxv59n3kbgj" FOREIGN KEY (id) REFERENCES super(id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> TABLE "subb" CONSTRAINT "fk_q4aajuitkvsk93mn07t66l0pi" FOREIGN KEY (id) REFERENCES super(id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Table "public.suba"</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Column | Type | Modifiers </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+------------------------+-----------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subaprop | character varying(255) | </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> id | bigint | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Indexes:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "suba_pkey" PRIMARY KEY, btree (id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Foreign-key constraints:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "fk_5yjvt9lkf5b24nyxv59n3kbgj" FOREIGN KEY (id) REFERENCES super(id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Table "public.subb"</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Column | Type | Modifiers </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+------------------------+-----------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subbprop | character varying(255) | </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> id | bigint | not null</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Indexes:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "subb_pkey" PRIMARY KEY, btree (id)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Foreign-key constraints:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> "fk_q4aajuitkvsk93mn07t66l0pi" FOREIGN KEY (id) REFERENCES super(id)</span></div>
<div>
<br /></div>
<div>
The really good thing here is that the model is not changed at all, so if you experience problems with multiple joins, you may easily convert your JOINED hierarchy mapping strategy, to such model.</div>
<div>
<br /></div>
<div>
To be completely clean let's take a look on the data:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">aero=> select * from super; select * from suba; select * from subb;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> classname | id | super_prop </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">-----------+----+------------</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> SubA | 1 | superProp</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> SubB | 2 | superProp</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">(2 rows)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subaprop | id </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+----</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subAProp | 1</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">(1 row)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subbprop | id </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">----------+----</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> subBProp | 2</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">(1 row)</span></div>
</div>
<div>
<br /></div>
<div>
And finally on <span style="font-family: Courier New, Courier, monospace;">from Super</span> HQL translated to SQL:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">select [...] from SUPER super0_</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">select super_1_.subaprop as subaprop1_83_ from SUBA super_1_ where super_1_.id=1</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">select super_2_.subbprop as subbprop1_84_ from SUBB super_2_ where super_2_.id=2</span></div>
</div>
<div>
<br /></div>
<div>
There's no any joins here anymore.<br />
<br /></div>
<h4>
Is this right?</h4>
<div>
<br /></div>
<div>
If we don't want to have a big join, we need to consider that Hibernate needs to load all entities somehow. Here, we replaced the join with subclasses fetch in secondary selects, what is called the "N+1 select problem". So is this right or not to use this pattern?</div>
<div>
<br /></div>
<div>
I'd say: it depends. If you have 4-5 subclasses probably the join would be faster. If you have 50 joins, it probably wouldn't. Moreover if you hit 61 max joins in mysql, you cannot execute any query anymore, so this is the only sensible solution.</div>
<div>
<br /></div>
<div>
What I really do when I see such big joins in a project, I try to measure performance of both approaches, and choose the best solution for real database with real data and real queries we execute on underlying model. I cannot say that "a lot of joins" is an antipattern, or "N+1 select" is an antipattern. It just depends on some conditions. For example if you fetch data for the view with pagination, you usually don't fetch more that 10-20 entities in a single query, so N+1 select problem is very little here. If you want to fetch big amount of data, this probably will be a problem, but also there's probably something wrong with you app, if you need to fetch so much data from database.</div>
<div>
<br /></div>
<div>
So everything should be tested and used with thinking (what can be said about clearly everything in software development :) ).<br />
<br /></div>
<h4>
Further improvements</h4>
<div>
<br /></div>
<div>
This article I made after huge system refactor in current project. Translation from JOINED to the proposed model above was only one of the things I refactored. It turned out that uncontrolled eager fetch of various associations can also produce unbelievable queries. You may say that if one have uncontrolled eager fetch, one also have a bad model. That's true, this is why the refactor was needed - to convert bad model to best performing model. I always follow the pattern that we focus on business system value in a first place, and the optimization stage comes at the end.</div>
<div>
<br /></div>
<div>
So what I did more to optimize the model. First and foremost now I consider eager fetch for collections as a bad pattern. But this is not a problem, because all to-many associations are lazy by default, and if they become eager, this is a developer choice, so he should know what is he doing and why. But the problem is with single ended associations. All single ended associations are eager by default, and they can produce something really unwanted regarding application SQL.</div>
<div>
<br /></div>
<div>
You may control this "join depth" using <span style="font-family: Courier New, Courier, monospace;"><b>hibernate.max_fetch_depth</b></span> property. If you set it to 0, hibernate wouldn't make any deep joins fetching your entities. But this doesn't mean that you convert your single ended associations to lazily fetched. They still will be fetched (at least the first level of single-ended associations in relation to entity you want to fetch) using additional selects. To really convert them into lazy one, you also need to use additional annotation <span style="font-family: Courier New, Courier, monospace;">@LazyToOne</span>. That really converts the objects in the relations to lazy proxy (you have then very ugly lazy proxies in these relation ends, but this still can be overcome using hibernate instrumentation in compilation stage).</div>
<div>
<br /></div>
<div>
So, is this right to have everything lazy and how does it influence on queries performance? No, it's not right to say so. I just don't believe in good perfomance, when you once can say "this entity should have these relations fetched lazily, and these relations we will use frequently and they should be fetched eagerly". This simply depends on the given entity usage. Sometimes, when you develop your model, it seems you can say something like this (usually thinking about fetching the list for the view, where this entity is displayed), but then it turns out that you also use list of the same entities in various different services, and you just don't need these eagerly fetched association in these queries. </div>
<div>
<br /></div>
<div>
So I believe this is just not OK to define on your model what should be fetched eagerly and what should not. There's a different place where you can do it - in repository queries. For each query you make, you usually know the exact usage of this query, and you can define appropriate joins in HQL or by using <span style="font-family: Courier New, Courier, monospace;">setFetchMode()</span>, when you use Criteria API. And this is the right place where it should be defined.</div>
<div>
<br /></div>
<div>
So what I did, when I was doing this refactoring, can be limited to these activities:</div>
<div>
<ol>
<li>Convert some entity hierarchies from JOINED to SINGLE_TABLE with secondary table, to controll the subtree fetching.</li>
<li>Make everything lazy, and</li>
<li>Define appropriate joins on repository queries level, depending on the query usage.</li>
</ol>
<div>
After this job, with our high load database test we achieved about 560% of performance boost.</div>
</div>
</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-62614083396617047412015-08-28T20:43:00.000+02:002015-08-28T20:43:12.419+02:00Statistics queries with time range for PostgreSQL and Hibernate<div style="text-align: justify;">
Few days ago I was asked to implement charts with some finance data using JS charting library, in the application working on Postgres database. There's a lot of finance stuff in the database stored every minute and I just needed to show this data on charts.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
OK, but charts are nice if you can restrict amount of your data returned from the server to some limited number of items. Returning 1000 items would both - make chart very heavy and unreadable and consume a lot of net traffic. I assumed 50 as the average number of items that are nicely displayed on such charts and are also acceptable from the traffic point of view.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
It would be nice to split time data to some periods that always assert no more than 50 items and then return only such statistics to the client side. And here I discovered very nice and applicable postgres function, which is <span style="font-family: Courier New, Courier, monospace;"><a href="http://www.postgresql.org/docs/9.1/static/functions-datetime.html" target="_blank">date_trunc</a></span>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Equipped with this weapon I figured out universal solution to calculate such time-based statistics for postgres database using Hibernate. Firstly I designed a very simple enum to calculate right time-grouping criteria:</div>
<div style="text-align: justify;">
<br /></div>
<script src="https://gist.github.com/l0co/d1c0d7ca7004d322ef86.js"></script>
<div style="text-align: justify;">
It'd be nice then to have everything working with whatever entity type and to be able to customize grouping query with Hibernate criteria, because this is right abstraction to build SQL query step by step from filters hypothetically associated with chart filters:</div>
<div style="text-align: justify;">
<br /></div>
<script src="https://gist.github.com/l0co/2b48d79bf349c07d1073.js"></script>
<div style="text-align: justify;">
It's also quite simple to autodetect best data granulation for the chart (eg. if it is a hour, day, month or something else) depending on the base time range for the chart.</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-48850627421871105152015-07-26T03:11:00.000+02:002015-07-26T04:10:02.572+02:00Modal windows available by URL binding in AngularJS with ui-bootstrap and ui-routerIt's well known how ui-bootstrap <a href="https://angular-ui.github.io/bootstrap/#/modal" target="_blank">supports modal windows</a>. These modals don't have any URL and cannot be accessed by URL, though. This is very good, because they should stay as the main view subview only, don't mess with the browser history and first and foremost they shouldn't kill underlying main view controller, what would reset its current state (like filters applied, pagination, etc). This would be a problem using URL-based modals, especially with <a href="https://github.com/angular-ui/ui-router" target="_blank">ui-router</a> which seems to be a standard for now.<br />
<br />
On the other hand it's good to have a URL-bound modals for one usage. When you send to people notification emails with links to perform the requested action. I mean such emails like "Attention, you have to do something in the application. You can do it with this <i>link</i>.". In typical scenario this action is already available in the application, usually on modal window. You just want to send this modal link to the user, to trigger requested action, and if you can't bind your modal to the URL, you can only send him some more or less awkward message, like "Use this link to login to the application, and then ... dig yourself to find where you can do it.".<br />
<br />
Here is a little ui-router hack to achieve both things - normal, unobtrusive modals, and URL bindings.<br />
<br />
<b>NOTE</b>, that this is not about having modals with ui-router URL address. There're many implementations on stackoverflow, and also example in ui-router FAQ. But these solutions have a very big flaw - their modals kill underlying main view controller, and when you're back, you're really <b>back</b> (like with the back button) on the main view with new controller instance and reset whole state, what is unnacceptable for real world applications. Maybe next time I'll think a little about how to achieve this point without this problem, but now it's about having normal bootstrap modals <b>also</b> bound to URL addresses in ui-router.<br />
<br />
Firstly, you need to define in your main HTML the location where the modal will be rendered, if it's URL-bound. Let's make it simple as <i>modal.html</i> (all codes are inserted at the bottom of this post). You can define surrounding view as <i>main</i> view, and use it for the modal target (when the modal window is rendered) or the whole application layout target (for views other than modal windows) by appropriate router substates configuration and CSS.<br />
<br />
Afterwards, let's define simple <i>module.js</i> with modal content, one URL parameter and resolve function that provides the resolved <i>object</i> to the modal controller, from the server side. At this point your modal is exposed at <span style="font-family: Courier New, Courier, monospace;">/modal/{ID}</span> URL, and you may use it in your notification emails.<br />
<br />
Now, let's support our modal as the regular ui-boostrap modal for other application views. This is done in <i>modal.service.js </i>by simple hack and moving parameters from ui-router configuration to ui-bootstrap <span style="font-family: Courier New, Courier, monospace;">$modal</span> instance. In any view now, instead of calling <span style="font-family: Courier New, Courier, monospace;">$modal</span>, you can call <span style="font-family: Courier New, Courier, monospace;">modalService(viewName, stateParams)</span> to open your modal window previously defined in ui-router configuration, and at the same time you have this modal available by URL.<br />
<h2>
Source code</h2>
<script src="https://gist.github.com/l0co/7c64a2c2fcab4d449522.js"></script>l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com1tag:blogger.com,1999:blog-603254884063001716.post-52318493804851838482015-06-20T20:31:00.000+02:002015-06-20T22:41:40.235+02:00Distributed hibernate search with ApacheMQ and SpringThis catching title will be <b>not</b> about distributed hibernate search, but something really close :)<br />
<br />
The case I've recently solved was a quite different. I have a <i>frontend application</i> that uses hibernate database and hibernate search, and then I needed to add additional application - let's call it an <i>integration server</i>, which exposes some API webservices for the overall system. Integration server uses the same database as the frontend application, and enables clients to put data to the database using its webservices. Both applications exist on two different physical servers, as well.<br />
<br />
Everything looks simple unless you start thinking about hibernate search update from the integration server, while the index is located solely on the frontend application side, because only this part of the system uses it. When you put data to the database from the integration server, the frontend application full-text index is not updated, of course. I've been looking for simple solution to overcome this problem.<br />
<br />
Firstly, let's take a look at what the hibernate search proposes. It supports <a href="https://docs.jboss.org/hibernate/search/3.1/reference/en/html/jms-backend.html" target="_blank">distributed hibernate search index</a>, with master-slave replication, where all nodes are connected using JMS. This solution was something I didn't really need because only one node uses the index for searching. Moreover this solution is based on periodical index replication, what causes the index is up-to-date on each node only after some interval. Finally, I didn't like this solution because it uses JNDI, what is not really Spring way to solve the problems (I don't really like JEE, I only like to work with lighweight Java application stacks).<br />
<br />
So I figured out the solution with following prerequisites:<br />
<ol>
<li>I don't want to use replication because I only need to use search on frontend application side.</li>
<li>I want to keep index physically on the side really using it, ie. on the frontend application side.</li>
<li>When the integration server updates database data, I need to update the index.</li>
<li>I don't want to use JNDI.</li>
<li>We are already using ApacheMQ, I want to use it for this solution as well. AMQ broker is already located on the integration server side.</li>
</ol>
<div>
OK, let's delve into the solution. Here is the spring config of important beans on the frontend side:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/l0co/a15dc8dea6d96a4a95ed.js"></script></div>
<div>
<br /></div>
<div>
What do we have here? Standard hibernate session factory on which I'm showing the hibernate search config, that creates and uses local lucene index. Then AMQ connection factory, that connects to the broker running somewhere else. Nothing special. The only interesting bean is <span style="font-family: Courier New, Courier, monospace;">RemoteHibernateSearchController</span>, which is derived from standard <span style="font-family: Courier New, Courier, monospace;">AbstractJMSHibernateSearchController</span>, that already is a JMS message listener, and only needs to provide hibernate sesssion from our session factory:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/l0co/6b3a77b649ad41ebe44f.js"></script></div>
<div>
<br /></div>
<div>
Now let's take a look at integration server config, which is a little more interesting:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/l0co/e5745ef29d3d1706a935.js"></script></div>
<div>
<br /></div>
<div>
Same session factory, but configured in the other way. As the backend we use <span style="font-family: Courier New, Courier, monospace;">AMQBackendQueueProcessor</span> - our own implementation, shown for a while, not the standard "lucene" implementation. Our implementation will delegate all hibernate search insert/update requests to the listnening frontend <span style="font-family: 'Courier New', Courier, monospace;">RemoteHibernateSearchController</span><span style="font-family: inherit;">, through the JMS queue named "queue.search".</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">I need to mention here a thing. The integration server doesn't use hibernate search for searching at all (it is only insert/update oriented). But if we have enabled hibernate session for integration server, we need to have at least <b>some index</b> to work. This index won't be updated ever (</span><span style="font-family: 'Courier New', Courier, monospace;">AMQBackendQueueProcessor</span><span style="font-family: inherit;"> will delegate all updates to frontend index through JMS) and will never be read. So I decided to use "ram" provider, which holds whole this few-bytes index in RAM memory. You can, anyway, use any implementation you want - this is only a fake index.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">AMQ configuration comes then, and we define only one queue here (this config is redundant, but you can add some parametrization to the config made this way). This is the part really starting the broker using TCP transport (in test environment both servers are run on localhost). Note, that AMQ connection factory connects to the (local) broker using VM transport, and doesn't start its own broker itself.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Now few words about the initialization order. We will use a little trick to bind </span><span style="font-family: 'Courier New', Courier, monospace;">AMQBackendQueueProcessor</span><span style="font-family: inherit;"> to Spring for a while, so the order is important. When session factory bean creates the session factory, hibernate search worker backend needs to be able to work right away. Our backend will work using AMQ, so AMQ needs to be initialized before the session factory bean is initialized. In the example it is done by </span><span style="font-family: Courier New, Courier, monospace;">depends-on</span><span style="font-family: inherit;"> attribute, and </span><i>sessionFactory</i><span style="font-family: inherit;"> bean depends here on </span><i>amqBroker</i><span style="font-family: inherit;"> bean (indirectly, the dependency goes through </span><i>appContextProvider</i><span style="font-family: inherit;"> bean, which is also required to be initialized when session factory bean starts).</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">ApplicationContextProvider</span><span style="font-family: inherit;"> bean just accomplishes the commons hack to access Spring beans from non-spring aware code:</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;"><script src="https://gist.github.com/l0co/a73b63f64c6233a3643c.js"></script></span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">And finally </span><span style="font-family: 'Courier New', Courier, monospace;">AMQBackendQueueProcessor</span><span style="font-family: inherit;"> overrides JNDI-related code of standard </span><span style="font-family: Courier New, Courier, monospace;">JmsBackendQueueProcessor</span> <span style="font-family: inherit;">JMS connection factory lookup with spring-based implementation, using our container config and </span><i>appContextProvider</i><span style="font-family: inherit;"> hack:</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;"><script src="https://gist.github.com/l0co/cf7aa549d8db304783eb.js"></script></span></div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-11684622045880113382014-12-25T16:13:00.003+01:002014-12-25T16:37:57.106+01:00BIRT with Hibernate using POJO-s<div style="text-align: justify;">
In previous BIRT versions there were three ways to use BIRT with your Hibernate datasource:</div>
<ol>
<li>Just plain SQL on Hibernate database.</li>
<li>Scripting data source.</li>
<li><a href="http://docs.jboss.org/tools/OLD/3.0.1.GA/en/jboss_birt_plugin_ref_guide/html/hibernate_datasource.html" target="_blank">Hibernate ODA data source</a>.</li>
</ol>
<div style="text-align: justify;">
Previously I've been using plain SQL, but with complex database model it becomes very difficult (a lot of properties, joins and other relationships). Scripting data source using javascript is a bit too awkward for me, and certainly adds another level of application complexity, and another level of layers where "the things may go wrong". Finally, Hibernate ODA data source from JBoss tools - this is what I wanted to use in older times, when I was using Eclipse, but for plain no-jboss application there were a lot of problem with these tools. They seem to be related to SEAM. Anyway AFAIR I had more problems with maintaining proper hibernate configuration in Eclipse (especially that it was partially annotation, and partially XML based) than the value of having working hibernate queries in IDE.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Recently, during a work on another application using BIRT, I started to think about another approach: how to delegate BIRT datasources to pure Java providers, that could be parametrized easily from runtime (without BIRT API) and which return my own arbitrary Java object models. It can be hibernate entity model, it can be something else, like for example DTO objects model, whatever I want to use in report and I consider better structured for particular reports. The most important part here is that these models would refactor easily with compiler support during the application development.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After a little research and tests it turned out feasible using <b>BIRT POJO datasource</b>, and now I consider it the best way of making BIRT reports from Java. The full source code of my example is <a href="https://github.com/l0co/birt-hibernate-example" target="_blank">on github</a>, and the description is below.<br />
<br /></div>
<h4 style="text-align: justify;">
Model + Data Set</h4>
<div style="text-align: justify;">
<br />
First let's have a look on the model:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<script src="https://gist.github.com/l0co/842efab408345de89d85.js"></script></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<script src="https://gist.github.com/l0co/bffb48a3a515feb08134.js"></script></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I wanted to use some associated objects in the model, to see how it works in BIRT, so what we have here is the company under which there are few departments, and our target report will be the list of departments grouped by companies, displayed directly from the database. To be more specific - directly from Hibernate queries.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The first thing is that we need some data set that can be used on BIRT design time. POJO data source is pretty badly documented and to reveal how to do it I needed to read some of BIRT sources. But what I discovered during this work is that the data set for the BIRT design time can be any class providing <span style="font-family: Courier New, Courier, monospace;">public Object next()</span> method (it goes then through <span style="font-family: Courier New, Courier, monospace;"><a href="https://eclipse.googlesource.com/birt/org.eclipse.birt/+/f991893c494cfacc508f7dab9e1b6a7d2e00d5fc/data/org.eclipse.birt.data.oda.pojo/src/org/eclipse/birt/data/oda/pojo/impl/internal/PojoDataSetFromCustomClass.java" target="_blank">PojoDataSetFromCustomClass</a></span> in the BIRT engine). So here is my mock data set implementation:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<script src="https://gist.github.com/l0co/16e5a30fcd358b301662.js"></script></div>
<div style="text-align: justify;">
There are no bingings to Hibernate at all during this stage so we can prepare our object lists for the report design time independently from the database itself. My mock data set returns companies with "Mock" prefix to make it feasible to tell apart mock objects, from the real ones. Under every company there are three departments created (IT, HR and Sales).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now we need to package everything (entity model and mock dataset) to a single jar that will be connected to BIRT for a while.<br />
<br /></div>
<h4 style="text-align: justify;">
Report design</h4>
<div style="text-align: justify;">
<br />
Now we can start preparing new BIRT report starting from the POJO data source:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5FYpSjvQcAo78TQsc6KZ-z4YLi8vKm9qyRxfCueeZlkMAl3NUMuIhFI4MUd5gsvvgNwkeFYT7WBPtkQZkEM2yPGcPes5HlP4j3F-qUyitabKlpv7F_siby0jfGkO3xdP95QscRe6pTbA/s1600/pojo-source-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5FYpSjvQcAo78TQsc6KZ-z4YLi8vKm9qyRxfCueeZlkMAl3NUMuIhFI4MUd5gsvvgNwkeFYT7WBPtkQZkEM2yPGcPes5HlP4j3F-qUyitabKlpv7F_siby0jfGkO3xdP95QscRe6pTbA/s1600/pojo-source-1.png" height="640" width="585" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then we need to add our jar to data source config, and check the option below:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF5EWo8z3HwvF2vDhX_70xOrPcTRrgirbS5YhTqHEF29XakXvmWS4OnPl6aoqjp04VonFW5JQUpxmtArtsLH6BaJKk0POoVJY5OA8E9QTEQvvvXk5faEgvw0_jThNHBhWqCVp5qxrFymY/s1600/pojo-source-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjF5EWo8z3HwvF2vDhX_70xOrPcTRrgirbS5YhTqHEF29XakXvmWS4OnPl6aoqjp04VonFW5JQUpxmtArtsLH6BaJKk0POoVJY5OA8E9QTEQvvvXk5faEgvw0_jThNHBhWqCVp5qxrFymY/s1600/pojo-source-2.png" height="475" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now we need to configure POJO data set, giving our mock data set class name as the objects source:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB86eMXZzHv2Mzi2tg3H3XeTdoDGCFzgxssKwUL_go0ZQiL-WpvV8kzZPmQoOjvzuqPJRr1UgCswTKMiS-AqCPTlxN8o-FxivYumHAvekbTyTdRK16Ua6jqsyyob2vkZGh6zMkqFAdCLo/s1600/pojo-set-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB86eMXZzHv2Mzi2tg3H3XeTdoDGCFzgxssKwUL_go0ZQiL-WpvV8kzZPmQoOjvzuqPJRr1UgCswTKMiS-AqCPTlxN8o-FxivYumHAvekbTyTdRK16Ua6jqsyyob2vkZGh6zMkqFAdCLo/s1600/pojo-set-1.png" height="412" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The important part here is the key under which BIRT will look for the data set (<b>APP_CONTEXT_KEY_MOCKCOMPANYDATASET</b>). This is not important yet, but will be important in real runtime, where we will switch the mock data set to real one.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now we can just select the POJO class, and configure column mappings:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu7t381vK-3jl7v7LI3IzREWTGuzND7Zw2wR7srgqM0JsiAqewUp3Ia4T7cN8zolGz9q9XNPVd3Dhtjh8J-9jI4lpAe5Cx2xsayk21NQ8qsAu9JaZoQ3yeQLtpoKLT7LTHvfGcSr1UKV8/s1600/pojo-set-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu7t381vK-3jl7v7LI3IzREWTGuzND7Zw2wR7srgqM0JsiAqewUp3Ia4T7cN8zolGz9q9XNPVd3Dhtjh8J-9jI4lpAe5Cx2xsayk21NQ8qsAu9JaZoQ3yeQLtpoKLT7LTHvfGcSr1UKV8/s1600/pojo-set-2.png" height="412" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I used property of associated <span style="font-family: Courier New, Courier, monospace;">Department</span> entity here to see how the column mapping will be done. It looks good, and now on the <b>Preview Results</b> tab we can see how the column data is generated by BIRT from the underlying <span style="font-family: Courier New, Courier, monospace;">Company</span> objects:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCo5tEAS14TveXXSz_iqr1_m7F7l7zTJxLeHcLVu2u60DMXbkWQTRNh713OJ0_2V9y6wdP2hwN_cErI44PasDb44Y-EPw9lldkEZVzIhyphenhyphenW04N0UzVG3dug2x9ErQMU_JE0-BFC3xr5WJE/s1600/pojo-set-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCo5tEAS14TveXXSz_iqr1_m7F7l7zTJxLeHcLVu2u60DMXbkWQTRNh713OJ0_2V9y6wdP2hwN_cErI44PasDb44Y-EPw9lldkEZVzIhyphenhyphenW04N0UzVG3dug2x9ErQMU_JE0-BFC3xr5WJE/s1600/pojo-set-3.png" height="412" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
It fetches them as the list of departments that could be grouped by company, which seems to be good initial data set to create intended report.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
On the layout view I just put the list bound to this data set, and grouped items by company id:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYK4fHMQDF1gc83vpvkmbALNhJ-Dem9n3sNelF551NQGs1tKV-JAcz93EnwDBZwgzJa3Q_tFC2Hc3MalE-NZLsSK2i6PjXGYz_VXbTYR86g5VK-WsVD9iJ9sWnH9GmDAVFPZM45Oely-U/s1600/pojo-report-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYK4fHMQDF1gc83vpvkmbALNhJ-Dem9n3sNelF551NQGs1tKV-JAcz93EnwDBZwgzJa3Q_tFC2Hc3MalE-NZLsSK2i6PjXGYz_VXbTYR86g5VK-WsVD9iJ9sWnH9GmDAVFPZM45Oely-U/s1600/pojo-report-1.png" height="460" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now it's possible to generate mock report from the BIRT designer:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSxzlgyvpiWGIViaPlh4_B1spGBdAGnP_32umPy-R9-9MDktSo9KTVbUP4gXD8rez9P0q0u5InrzzHGqdWw9mnuYyoeX_pR2HTyH3E52GaGBSjJW2mIfRvXHjk0UF5y3biF3-upi1TxGw/s1600/pojo-report-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSxzlgyvpiWGIViaPlh4_B1spGBdAGnP_32umPy-R9-9MDktSo9KTVbUP4gXD8rez9P0q0u5InrzzHGqdWw9mnuYyoeX_pR2HTyH3E52GaGBSjJW2mIfRvXHjk0UF5y3biF3-upi1TxGw/s1600/pojo-report-2.png" height="640" width="494" /></a></div>
<h4 style="text-align: justify;">
The runtime</h4>
<div style="text-align: justify;">
<br />
In the runtime now what we want to do, is to replace the mock data set from the design stage, with some real data fetched from the database by Hibernate using entity model. A lot of this code is just to start the report engine, but I described below what's important here:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/l0co/246fa94dbfe7b5d51580.js"></script></div>
<div>
<br /></div>
<div style="text-align: justify;">
In line 2 we create BIRT application context, that is just a <span style="font-family: Courier New, Courier, monospace;">HashMap</span>. To this map we need to pass our objects collection, under the key configured on design time. My <span style="font-family: Courier New, Courier, monospace;">companyRepository.findAll()</span> method returns Hibernate <span style="font-family: Courier New, Courier, monospace;">Query</span>. The "collection" passed to the application context can be <span style="font-family: Courier New, Courier, monospace;">Collection</span> itself (so the <span style="font-family: Courier New, Courier, monospace;">list()</span> is an option here), but I prefer to use <span style="font-family: Courier New, Courier, monospace;">Iterator </span><span style="font-family: inherit;">(</span><span style="font-family: Courier New, Courier, monospace;">iterate()</span> option), because for bigger reports it'd fetch data from database sequentially, not in a big single list.<br />
<br />
For really inquisive people - BIRT can convert following objects to its internal <span style="font-family: 'Courier New', Courier, monospace;">IPojoDataSet</span> representation:<br />
<br />
<ol>
<li>Any object providing <span style="font-family: Courier New, Courier, monospace;">public Object next()</span> method, using <span style="font-family: Courier New, Courier, monospace;">PojoDataSetFromCustomClass</span>.</li>
<li><span style="font-family: Courier New, Courier, monospace;">Collection</span>, using <span style="font-family: Courier New, Courier, monospace;">PojoDataSetFromCollection</span>.</li>
<li>Array of objects, using <span style="font-family: Courier New, Courier, monospace;">PojoDataSetFromArray</span>.</li>
<li><span style="font-family: Courier New, Courier, monospace;">Iterator</span>, using <span style="font-family: Courier New, Courier, monospace;">PojoDataSetFromIterator</span>.</li>
</ol>
</div>
<div style="text-align: justify;">
In line 27, when the task is ready to run, we need to pass the application context to the task, to replace mock data set, with our real runtime data set.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The finally rendered report (all entities in database have "Company" prefix) looks this way:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg7MZKgluJ04QQ7VryvTO2VAw2mbv3F57vKSqpGk_ZcdLMZOSsMfZcDd5TQfNPpIBlP6ybt9lSlrsIo0PUmNeMgfeuwesyvRn85jzGH3u7RWo07nJTTYZqBaJwLu6vRhVeVqEJrNaRgMU/s1600/pojo-report-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg7MZKgluJ04QQ7VryvTO2VAw2mbv3F57vKSqpGk_ZcdLMZOSsMfZcDd5TQfNPpIBlP6ybt9lSlrsIo0PUmNeMgfeuwesyvRn85jzGH3u7RWo07nJTTYZqBaJwLu6vRhVeVqEJrNaRgMU/s1600/pojo-report-3.png" /></a></div>
<div style="text-align: justify;">
Everything above can be easily built and tested from the command line from my <a href="https://github.com/l0co/birt-hibernate-example" target="_blank">birt-hibernate-example</a> sources.</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com4tag:blogger.com,1999:blog-603254884063001716.post-56071412783679079732014-10-27T20:59:00.002+01:002014-10-27T23:20:25.568+01:00Database locks with Spring, Hibernate and Postgres<div style="text-align: justify;">
In the current project we faced the problem of concurrent changes to database, for the data that should be accessed sequentially. Imagine you have the customer's bank account where he can withdraw the money. If the customer is not a person, but company, and if he can have multiple users accessing the bank application, without any locks there's a chance for situation where two or more users depute transfers, that exceed the account balance, but because data is accessed concurrently, they both can make payoff. </div>
<br />
<div style="text-align: justify;">
This is the simplest example, but one can imagine a lot of more such cases, that influence a lot of different applications. The lock for the single customer is simple, but imagine if we need lock for more than one customer in the same time. For example if two customers make some transaction between them, and the transaction depends on the account balance on both accounts. In such instance in single database transaction there are both sides required to be locked while the transaction lasts, to avoid the same problem.</div>
<br />
<div style="text-align: justify;">
Regarding such case we need also to be aware of deadlock problem. If the single row lock is an atomic operation for database, two locks are two operations, and this can produce following deadlock:</div>
<br />
<ol>
<li>In transaction A customer 1 is locked.</li>
<li>In transaction B customer 2 is locked.</li>
<li>In transaction A customer 2 is locked (is waiting).</li>
<li>In transaction B customer 1 is locked (deadlock: A is waiting for 2, and B is waiting for 1, both are locked).</li>
</ol>
<br />
<div style="text-align: justify;">
But first let's review the possibilities of what can we use for dealing with this problem in usual database application. Our exemplary stack here is standard Java (Spring + Transactional AOP-s + Hibernate) and Postgres database.</div>
<br />
<ol>
<li><b>Language-level locks</b>, by usage of object monitors or <span style="font-family: Courier New, Courier, monospace;">java.util.concurrent.locks</span> package. Problems: doesn't work for clustered applications and dealing with deadlocks is not obvious and difficult.</li>
<li><b>Transaction isolation level</b>. Here we'd have following opportunities (see <a href="http://www.postgresql.org/docs/9.1/static/transaction-iso.html" target="_blank">postgres reference</a>):</li>
<ol>
<li><b>Read uncommited</b> - this would be rather a gambling, but for postgres this level doesn't exist.</li>
<li><b>Read commited</b> - this is the default transaction isolation level causing the problem, because both transactions we consider see only data not commited by other transactions, so they can both work on the same balance "snapshot" from transaction start, and they can read the same value for subtracting from database. This level introduces locks on database level by default, but only for update, not for select. After acquiring the lock during update by transaction A, the transaction B is waiting with its update, but after the transaction A is finished, the B proceeds with its update anyway. So we may have the situation: A reads 100, B reads 100, A subtracts 20 from 100 and updates db with 80, then B subtracts 20 from 100 and updates db with 80. In the result the value in db is 80, while should be 60.</li>
<li><b>Repeatable read</b> - looks even worse. Two transactions can never see their changes after they are started. But the update lock works in different way. If two transactions want to update the same row, one of them acquires the lock, and second one will fail with <span style="font-family: Courier New, Courier, monospace;">ERROR: could not serialize access due to concurrent update</span>. So it should be feasible to deal with our problem using this level and update lock, and even better is...</li>
<li><b>Serializable</b>. It works like repeatable read, but postgres tries to simulate sequential transaction execution. It tries to sort all queries in transaction, so that it looks that transactions are executed one by one. But this is only simulation, and transactions are really executed concurrently, though. Moreover if it comes across the situation where it can't perform two transactions "sequentially", it throw the same exception as for repeatable read.</li>
</ol>
<li><b>Explicit database locking</b>. There are many options, specified in <a href="http://www.postgresql.org/docs/9.1/static/explicit-locking.html" target="_blank">postgres reference</a>, but the most common is <span style="font-family: Courier New, Courier, monospace;">select for update</span>. This solution may cause deadlocks in the way I described above. Postgres fortunately detects such deadlocks and throws appropriate exception when it happens.</li>
</ol>
<div style="text-align: justify;">
So, it looks that we can use specific transaction isolation level here, or use the explicit locking. All these solutions require to have fail-safe scenario when exception is thrown (could not serialize or deadlock exception). But there are following things I don't like if I think about transaction isolation:</div>
<div>
<ul>
<li>They crash after doing a job, and the job can be significant. For example let's assume that the work costs 1 sec for each transaction, and on the end of this work we have this <span style="font-family: Courier New, Courier, monospace;">update</span> that fails. If we have for example 10000 users concurrently, we can waste a lot of CPU.</li>
<li>Serializable transaction level has its performance requirements. It consumes more RAM and CPU to fulfill its requirements. Again, assuming highly loaded application - do we really need to slow down the database with serializable isolation level to achieve our goals?</li>
</ul>
<div>
<div style="text-align: justify;">
The solution devoid of these issues is explicit locking and I decided to carry on with this solution, what I'll describe in further part.</div>
</div>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
The lock</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First let's implement the lock service. The <span style="font-family: Courier New, Courier, monospace;">select for update</span> clause in postgres locks the concrete row in database against other <span style="font-family: Courier New, Courier, monospace;">select for update</span>-s, but it is still unlocked for ordinary selects. So, for the code we need to acquire the lock we can use <span style="font-family: Courier New, Courier, monospace;">select for update</span><span style="font-family: inherit;">, what esures that the rest of application works fine while operation in the meanwhile.</span></div>
</div>
<div>
<br /></div>
<div>
<div style="text-align: justify;">
In the real world application we may have a lot of service methods that require lock, so I added here the code preventing to have more than one lock for given customer ID, using <span style="font-family: Courier New, Courier, monospace;">TransactionSynchronizationManager</span> resources. On first lock there's transaction listener registered, which cleans these resources. If the deadlock happens in postgres, it is indicated by <span style="font-family: Courier New, Courier, monospace;">LockAcquisitionException</span> in java code.<br />
<br /></div>
</div>
<script src="https://gist.github.com/l0co/a13329c7e8d5a92b0815.js"></script><br />
<div>
<h4>
Retry on deadlock</h4>
<br />
<div style="text-align: justify;">
<span style="font-family: inherit;">OK, nothing really interesting happened for now, but here comes this interesting part. How can we handle deadlocks properly? It'd be the best to retry whole transaction on deadlock few times, until the lock can be acquired and second transaction finishes.</span></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit; text-align: justify;">Here I need to mention the contributor from which I've caught some ideas for retrying transactions - </span><a href="http://sysout.be/2011/07/05/automatic-deadlock-retry-aspect-with-spring-and-jpahibernate/" style="font-family: inherit; text-align: justify;" target="_blank">Jelle Victoor</a><span style="font-family: inherit; text-align: justify;">. But I consider that his solution has some issues, so I extended it a little. </span><span style="font-family: inherit; text-align: justify;">I used the same idea, of using AOP aspect to repeat transaction, but </span><span style="font-family: inherit;">I want to have this working without putting everywhere additional annotations, because in the proposed way I'd need to have a lot of double </span><span style="font-family: Courier New, Courier, monospace;">@Transactional</span><span style="font-family: inherit;"> and </span><span style="font-family: Courier New, Courier, monospace;">@DeadLockRetry</span><span style="font-family: inherit;"> annotations. So, finally I'd like to have it working transparently with </span><span style="font-family: Courier New, Courier, monospace;">@Transactional</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit; text-align: justify;"><br /></span>
<span style="font-family: inherit; text-align: justify;">Moreover let's consider the situation of nested </span><span style="font-family: Courier New, Courier, monospace; text-align: justify;">@Transactional</span><span style="font-family: inherit; text-align: justify;"> services. The usual example is following:</span><br />
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">@Transactional ServiceA.doJob()</span><span style="font-family: inherit;"> -> calls...</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">@Transactional ServiceB.doJob()</span><span style="font-family: inherit;"> </span><span style="font-family: inherit;">-> calls...</span></li>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">@Transactional ServiceC.doJob()</span><span style="font-family: inherit;"> -> and here comes the deadlock exception.</span></li>
</ul>
</ul>
</ul>
<div style="text-align: justify;">
<span style="font-family: inherit;">The same problem is when you use separate </span><span style="font-family: Courier New, Courier, monospace;">@DeadLockRetry</span><span style="font-family: inherit;">, because the method with this annotation can be called from other service, and the real method that started the whole transaction is somewhere else, so repeating the code from method with </span><span style="font-family: Courier New, Courier, monospace;">@DeadLockRetry</span><span style="font-family: inherit;"> annotation may not work, because we want to retry whole transaction.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div style="text-align: justify;">
<span style="font-family: inherit;">The trick is how to detect the </span><span style="font-family: 'Courier New', Courier, monospace;">@Transactional ServiceA.doJob()</span><span style="font-family: inherit;"> service execution and after rolling back whole transaction, retry overall operation. I used similar idea to Jelle - to use AOP proxy (with Aspect4J annotations so remember to add </span><span style="font-family: Courier New, Courier, monospace;"><aop:aspectj-autoproxy /></span> to your Spring config) and to have transaction manager order 100 (<span style="font-family: Courier New, Courier, monospace;"><tx:annotation-driven order="100" transaction-manager="transactionManager" /></span>) and my deadlock aspect with order 99 to ensure it runs first.</div>
</div>
<div>
<br /></div>
<div style="text-align: justify;">
If the deadlock aspect comes before transactional, we may detect where is our <span style="font-family: 'Courier New', Courier, monospace;">ServiceA.doJob() </span>using the same <span style="font-family: Courier New, Courier, monospace;">TransactionSynchronizationManager</span> as previously. If we are on the top level method, the transaction no longer exists because transactional AOP proxy already rolled it back. If the transaction still exists, this mean that we are not on the top level method, but this is nested transactional method.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The complete source:</div>
<div style="text-align: justify;">
<br /></div>
<br /></div>
<script src="https://gist.github.com/l0co/71506c1f2e7c075589b5.js"></script>l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-6701775557764702732014-09-21T21:20:00.000+02:002014-09-22T10:17:07.470+02:00Tracking object references in JavaScriptIt is a common case in AngularJS to have some model loaded on the main view (like list of objects) and to use these objects in other controllers (like the object details view). Usually it's done by holding the reference of the list object in other controller scope, to interact with this reference. Until these both objects point to each other (both references point to the same object) it's very fine. The changes from the details controller are reflected in a list and contrarywise.<br />
<br />
But I frequently come across the situation where at least one of these objects is refreshed from the server (eg. in async comet event) and this relationship is lost. A lot of case-by-case code is required to be written to support such instances on the client side.<br />
<br />
Today I've been thinking about tracking the object references generally in JavaScript and how it can be done. Unfortunately it looks that it can't. JavaScript doesn't really support real references like eg. in C language, that could be used to achieve this. In JS function there's no way to have access to reference that carries the object as the function argument, and thus to modify this reference.<br />
<br />
But indeed there's a way to have access to the reference - using the <b>closure</b>. Closure holds references to all objects belonging to the closure scope. After a little time of playing I figured out some solution for such hypothetical reference tracker:<br />
<br />
<script src="https://gist.github.com/l0co/03c13af9bc4ba1b885a5.js"></script>
And it works :)<br />
<br />
Now, we have some more complex case. We are just re-assigning single object holding whole list, and we may have only the <i>item </i>(from the example above) assigned elsewhere. This is not as simple as the previous example, but feasible if we think about the model as persistent objects model. All persistent objects have some unique ID assigned. For example if you use UUID on server side, it can be UUID. If you use the numeric ID, it can be combination of ID and object type (class) etc. You can always figure out easily some other method to have unique ID for you objects some way.<br />
<br />
In such instance, to achieve the goal we need to have the previous JSON structure, and to scan new one, looking for objects with the same ID, and then reuse our "reference tracker" above. Here is full source including the new usage:<br />
<br />
<script src="https://gist.github.com/l0co/c29516c41a8593498d17.js"></script>
To have it clean, I also added <i>cleanup()</i> function to clean the objects from <i>$ref</i> reference, to have clean objects for JSON representation to be sent to server.l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-78532740095493270992014-07-27T02:40:00.000+02:002014-07-27T12:54:58.164+02:00Tomcat, Atmosphere and Spring SecurityHere I'd like to describe another interesting case I've been struggling with for recent few days. This involves the following use case: enable asynchronous events support for Tomcat/Spring multi-tenancy SaaS application, that can be pushed to listening client groups. To be specific, the event should be channeled to following groups: to specific user, to all users of specific tenant and to all users.<br />
<div>
<h2>
Atmosphere + Tomcat</h2>
<div>
The fancy new technology for async processing in Java world is <a href="https://github.com/Atmosphere/atmosphere" target="_blank">Atmosphere</a>, and I use it in this example. Unfortunately I started with horribly preconfigured Atmosphere which apparently locked Tomcat after making some number requests, and it wasn't able to serve more requests. It turned out that the working Tomcat + Atmosphere config is something not so obvious, so let's quickly describe all these problems to move on.</div>
</div>
<div>
<br /></div>
<div>
I started with the following maven dependency:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><dependency></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><groupId>org.atmosphere</groupId></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><artifactId>atmosphere-runtime</artifactId></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><version>2.1.7</version></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"></dependency></span></div>
</div>
<div>
<br /></div>
<div>
After a lot of struggling I came to conclusion that there's no way to properly run Tomcat with Atmosphere using this library (at least in 2.1.7 version). I started with standard Atmosphere configuration, which uses native Tomcat async implementation (Comet support). In this scenario there's <a href="https://vaadin.com/forum/#!/thread/4268603" target="_blank">a bug in Atmosphere</a> which results in using Tomcat BIO support (blocking IO) instead of NIO (non-blocking IO). Finally, you have a thread created for each async request, which is then suspended and moved to waiting pool. When you reach the tomcat thread pool capacity (default is 200) you end up with completely frozen application.</div>
<div>
<br /></div>
<div>
Afterward I changed the implementation from native Tomcat async support to Servlet 3 specification, using following flags:</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><init-param></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <param-name>org.atmosphere.useNative</param-name></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <param-value>false</param-value></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"></init-param></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><init-param></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <param-name>org.atmosphere.useWebSocketAndServlet3</param-name></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <param-value>true</param-value></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"></init-param></span></div>
</div>
<div>
<br /></div>
<div>
Using this config, it started to work through Tomcat NIO, but the odd things started to happen as well. For example random freezes on standard request processing, and a lot of <span style="font-family: Courier New, Courier, monospace;">java.lang.IllegalStateException: Cannot forward after response has been committed</span> exceptions. Something similar to <a href="https://groups.google.com/forum/#!msg/atmosphere-framework/mO2x4eAVHs4/YknHrUqBv2wJ" target="_blank">this guy</a><span id="goog_1491959995"></span><span id="goog_1491959996"></span><a href="https://www.blogger.com/"></a> situation.</div>
<div>
<br /></div>
<div>
After a lot of debugging what is really happening in the Atmosphere and Tomcat threads I gave up and I found the solution with so called "native" atmosphere implementation, what apparently is the same lib with only one class changed with fixed native Tomcat support for Atmosphere (scenario 1), which is called:</div>
<div>
<br /></div>
<div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><dependency></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><groupId>org.atmosphere</groupId></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><artifactId>atmosphere-runtime-native</artifactId></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><version>2.1.7</version></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"></dependency></span></div>
</div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">And is describe <a href="https://github.com/Atmosphere/atmosphere/wiki/Installing-AtmosphereServlet-with-or-without-native-support" target="_blank">here</a>. It finally works well using Tomcat <a href="http://tomcat.apache.org/tomcat-7.0-doc/aio.html" target="_blank">Comet support</a> and/or native Tomcat <a href="http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html" target="_blank">websockets support</a>. Additionally it requires </span><span style="font-family: Courier New, Courier, monospace;">/META-INF/context.xml</span><span style="font-family: inherit;"> with following content:</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><Context></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span><Loader delegate="true"/></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"></Context></span></div>
<h2>
Atmosphere + Spring</h2>
</div>
<div>
Now something which is simple and can be found in many examples on the net. How to configure Atmosphere so that it can route requests to Spring <span style="font-family: Courier New, Courier, monospace;">DispatcherServlet</span>. To skip unnecessary words, I'll make it quick:</div>
<div>
<br /></div>
<div>
<script src="https://gist.github.com/l0co/847caa6417faa873df04.js"></script>
<br />
<div>
Things that might be explained a little more are following:</div>
<div>
<ol>
<li><span style="font-family: Courier New, Courier, monospace;">org.atmosphere.useNative</span> + <span style="font-family: Courier New, Courier, monospace;">org.atmosphere.useWebSocketAndServlet3</span> make it finally clear that we want to go using Tomcat native async support.</li>
<li><span style="font-family: Courier New, Courier, monospace;">org.atmosphere.cpr.broadcaster.maxProcessingThreads</span> - this is the limitation to 10 for Atmosphere threads. Atmosphere spawns some threads sweeping suspended requests (eg. by flushing their response buffers).</li>
<li><span style="font-family: Courier New, Courier, monospace;">org.atmosphere.cpr.broadcasterLifeCyclePolicy=EMPTY_DESTROY</span> is the lifecycle policy for Atmosphere <span style="font-family: Courier New, Courier, monospace;">Broadcaster</span> objects. Usually <span style="font-family: Courier New, Courier, monospace;">Broadcaster</span> has assigned some <span style="font-family: Courier New, Courier, monospace;">AtmosphereResource</span>-s, representing opened async connections. When all connections for particular <span style="font-family: Courier New, Courier, monospace;">Broadcaster</span> are closed, the <span style="font-family: Courier New, Courier, monospace;">Broadcaster</span> object may still be held in memory and reused. For SaaS application, that may handle hundreds of tenants and thousands of users concurrently I consider it a bad pattern. <span style="font-family: 'Courier New', Courier, monospace;">EMPTY_DESTROY</span> tells Atmosphere to relase all <span style="font-family: Courier New, Courier, monospace;">Broadcaster</span> objects if they don't have assigned any resources, and remove them from memory.</li>
<li><span style="font-family: Courier New, Courier, monospace;">org.atmosphere.cpr.AtmosphereInterceptor</span> is the <b>important one here</b>, because after Atmosphere invokes broadcasting operation, the response buffers are flushed periodically with all data written, so they could contain more than a single message at one flush operation. In such instance your client would receive two or more messages in one event listener notification, what is usually unwanted. This can be overcome by using <span style="font-family: Courier New, Courier, monospace;">TrackMessageSizeInterceptor</span> on the server side, and <a href="https://github.com/Atmosphere/atmosphere/wiki/jQuery.atmosphere.js-atmosphere.js-API" target="_blank">trackMessageLength</a> parameter in Atmosphere client.</li>
<li><span style="font-family: Courier New, Courier, monospace;">AtmosphereSpringControllerResolver</span> enables direct <span style="font-family: Courier New, Courier, monospace;">AtmosphereResource</span> injection to Spring controller.</li>
</ol>
<h2>
Atmosphere + Spring Security</h2>
<div>
Now what we'd like to have is the Spring Security context injected to Atmosphere requests, in order to extract user from the <span style="font-family: Courier New, Courier, monospace;">SecurityContextHolder</span> and to apply broadcasting operations on suspended requests. The answer on the question how to do it is simple: <b>you can't</b>.</div>
<div>
<br /></div>
<div>
There are two problems I came across with this subject. First the Spring Security filters aren't applied to <span style="font-family: Courier New, Courier, monospace;">MeteorServlet</span>, because it's not a reguler servlet, but <a href="https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/catalina/comet/CometProcessor.html" target="_blank"><span style="font-family: Courier New, Courier, monospace;">CometProcessor</span></a>, supporting async requests. For such type of servlets only <span style="font-family: Courier New, Courier, monospace;">CometFilter</span> can be applied, not a reguler <span style="font-family: Courier New, Courier, monospace;">Filter</span>, which is implemented by Spring Security <span style="font-family: Courier New, Courier, monospace;"><a href="http://docs.spring.io/spring/docs/3.2.8.RELEASE/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html" target="_blank">DelegatingFilterProxy</a></span>. You can overcome this problem, though, by either wrapping the Spring Security filters with your own <span style="font-family: Courier New, Courier, monospace;">CometFilter</span>-s, or by overriding the default <span style="font-family: Courier New, Courier, monospace;">FilterChain</span> by your own implementation. Anyway, it doesn't work as well.</div>
<div>
<br /></div>
<div>
This is because the <span style="font-family: Courier New, Courier, monospace;">SecurityContextHolder</span> default storage strategy is <span style="font-family: Courier New, Courier, monospace;">ThreadLocalSecurityContextHolderStrategy</span>, which holds the <span style="font-family: Courier New, Courier, monospace;">SecurityContext</span> in <span style="font-family: Courier New, Courier, monospace;">ThreadLocal</span> (this is the only production implementation and one cannot imagine different working strategy for this problem). It works well for standard requests, processed in separate threads, but for suspended Atmosphere requests there's a problem. When the resources are swept and buffers are flushed, all this process happens in internal Atmosphere thread pool, and one thread supports many <span style="font-family: Courier New, Courier, monospace;">AtmosphereResource</span>-s in single execution, so the <span style="font-family: Courier New, Courier, monospace;">SecurityContext</span> can't be bound to the thread, because you end up with an exception, or much worse, with different user authorized than it should be.</div>
<div>
<br /></div>
<div>
So what I do, and I'll show in the further example, is how to extract user directly for HTTP session to be used with <span style="font-family: Courier New, Courier, monospace;">AtmosphereResource</span> to create appropriate broadcasters.</div>
<div>
<br /></div>
<div>
There's another remark about this overall architecture. If you can run <span style="font-family: Courier New, Courier, monospace;">DispatcherServlet</span> through Atmosphere, you might tend to run your whole application through <span style="font-family: Courier New, Courier, monospace;">MeteorServlet</span> wrapper. But, when you consider above facts, that you can't apply normal filters to this servlet, and moreover you can't apply security filters on it, the conclusion is simple: <b>just don't do it</b>. Define your "async" Atmosphere servlet context separately from another regular "sync" <span style="font-family: Courier New, Courier, monospace;">DispatcherServlet</span>, and everything will be fine.</div>
<h2>
Broadcast events to user groups</h2>
<div>
Before final implementation, we need to understand how Atmosphere and Atmosphere <a href="https://github.com/Atmosphere/atmosphere/wiki/Understanding-Broadcaster" target="_blank"><span style="font-family: Courier New, Courier, monospace;">Broadcaster</span>-s</a> work internally. </div>
<div>
<br /></div>
<div>
In regular request processing, when the request comes, Tomcat takes the free thread from the thread pool (or queues the job in the thread pool queue, if all threads from pool are busy), and delegates the request processing to this thread. The Spring Security filters extract the user from HTTP session and put him to the <span style="font-family: Courier New, Courier, monospace;">SecurityContext</span> held in current request thread <span style="font-family: Courier New, Courier, monospace;">ThreadLocal</span>. Then the work is delegated to your servlet, response buffers are filled, everything is cleaned out and thread is released back to the pool. The response buffer is then written to the client.</div>
<div>
<br /></div>
<div>
In async request processing Atmosphere waits for incoming requests with its own thread pool. When the request comes, one of these threads receives it (or, like in above situation, the job is queued waiting to release at least one thread from the pool), <b>suspends it</b>, and returns thread to the pool. The suspension figures on releasing the processing thread, while the TCP connection is still opened. All these suspended requests are stored in an internal storage, and can be accessed in any moment in application. For all of them the TCP connections are opened, and one can write to the opened <span style="font-family: Courier New, Courier, monospace;">Response</span> object to send async events to the client.</div>
<div>
<br /></div>
<div>
But, how to tell apart one suspended request from another? For our example - how to find all requests sent from all logged users of specific tenant? For such use cases Atmosphere introduces the <span style="font-family: Courier New, Courier, monospace;"><a href="https://github.com/Atmosphere/atmosphere/wiki/Understanding-Broadcaster" target="_blank">Broadcaster</a></span> concept. With a single suspended request (<span style="font-family: Courier New, Courier, monospace;">AtmosphereResource</span>) you can associate one or more broadcasters, and use these broadcasters to send events to choosen clients. With each <span style="font-family: Courier New, Courier, monospace;">AtmosphereResource</span> there's a single <span style="font-family: Courier New, Courier, monospace;">Broadcaster</span> created with random UUID. </div>
<div>
<br /></div>
<div>
Using this idea and knowing this UUID you may send the async event to each suspended request separately, by choosing appropriate broadcaster. Another Atmosphere concept is <span style="font-family: Courier New, Courier, monospace;"><a href="https://github.com/Atmosphere/atmosphere/wiki/Understanding-Broadcaster" target="_blank">MetaBroadcaster</a></span>. It can be used to send event using all broadcasters fitting to the expression. For example:</div>
<div>
<ol>
<li>User A connects to async service, the broadcaster with <span style="font-family: Courier New, Courier, monospace;">ID="/UUID-1"</span> is created.</li>
<li>User B connects to async service, the broadcaster with <span style="font-family: Courier New, Courier, monospace;">ID="/UUID-2"</span> is created.</li>
<li>Using <span style="font-family: Courier New, Courier, monospace;">MetaBroadcaster</span> you may send data to either first or second user by <span style="font-family: Courier New, Courier, monospace;">broadcastTo("/UUID-1", event)</span> or <span style="font-family: 'Courier New', Courier, monospace;">broadcastTo("/UUID-2", event)</span>.</li>
<li>Or you can send event to all users by <span style="font-family: 'Courier New', Courier, monospace;">broadcastTo("/*", event)</span><span style="font-family: inherit;">.</span></li>
</ol>
<div>
This well concept can be adapted to our use case. Let's assume we have a <span style="font-family: Courier New, Courier, monospace;">TENANT_ID</span> and <span style="font-family: Courier New, Courier, monospace;">USER_ID</span>, defining our tenant and its user. We need to assign only one broadcaster to each async request to achieve our goals:</div>
</div>
<div>
<ol>
<li>User connects to async service, the broadcaster with <span style="font-family: Courier New, Courier, monospace;">ID="/TENANT_ID/USER_ID"</span> is created.</li>
<li>To send event to this particular user, use <span style="font-family: 'Courier New', Courier, monospace;">broadcastTo("/TENANT_ID/USER_ID", event)</span><span style="font-family: inherit;">.</span></li>
<li>To send event to all logged users of specific tenant, use <span style="font-family: 'Courier New', Courier, monospace;">broadcastTo("/TENANT_ID/*", event)</span>.</li>
<li>To send event to all logged users, use <span style="font-family: 'Courier New', Courier, monospace;">broadcastTo("/*", event)</span>.</li>
</ol>
<div>
And here comes the implementation with all described above:</div>
<div>
<br /></div>
<script src="https://gist.github.com/l0co/6b9d19b1e0627b1095b0.js"></script><br />
<div>
Finally, in <span style="font-family: Courier New, Courier, monospace;">AsyncDispatcher</span> controller we just need to suspend request using <span style="font-family: Courier New, Courier, monospace;">AsyncService.suspend()</span> method, to make it all working together.</div>
</div>
</div>
</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-14469665207733853092014-05-09T15:10:00.000+02:002014-06-11T10:33:18.246+02:00Global state in AngularJS controllersSuprisingly for me the controller state in AngularJS is not preserved between the controller invocations. I at least expected an option to switch it on and off on demand. For the classic application it was difficult to achieve that we may restore the state for a given view (eg. to be on the same page as we were leaving the view), what sounds great for me from the application usability point of view.<br />
<br />
But, it's right there, so it can be implemented. However, I don't like using the $rootScope for this, what can be found in many examples on the net, in the same way I don't use globals, because they produce a mess. Here I'd like to propose an elegant solution for this.<br />
<br />
I have the service that holds all controller states, and provide the initialization function that may be used when the state hasn't been cached yet. The code snippet:<br />
<br />
<script src="https://gist.github.com/l0co/36f9405a34e66138ed46.js"></script>l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com1tag:blogger.com,1999:blog-603254884063001716.post-75419842222267351122013-10-24T20:11:00.001+02:002014-03-18T21:22:12.533+01:00Java Cryptography Architecture and common encryption usagesJCA can be really tricky to perform simple, common tasks. After latest usage of java cryptography I'd like to present below the simplest usage of cryptography methods, involving mainly symmetric (AES) and asymmetric (RSA/DSA) encryption plus some helper methods.<br />
<br />
I don't use specific JCA provider, but let it choose appropriate one. If you want to select specific provider, you must provide additional parameters, usually to getInstance() methods of various algorithm elements. In examples I use <b>RSA1024</b> (you might change it to DSA) and <b>AES256</b>.<br />
<br />
Note about <b>AES256</b> - to enable this for your VM you need <a href="http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html" target="_blank">Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files</a>. With default policy you can only use <b>AES128</b>.<br />
<br />
The amount of "things can go wrong" is pretty big, so if you write your own cryptography util, there's a good thing to wrap JCA exception in something that can be easy caught in the user code.<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">class</span> EncryptionException <span style="color: black; font-weight: bold;">extends</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">public</span> EncryptionException<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">public</span> EncryptionException<span style="color: #009900;">(</span><span style="color: #003399;">String</span> message<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">super</span><span style="color: #009900;">(</span>message<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">public</span> EncryptionException<span style="color: #009900;">(</span><span style="color: #003399;">String</span> message, <span style="color: #003399;">Throwable</span> cause<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">super</span><span style="color: #009900;">(</span>message, cause<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">public</span> EncryptionException<span style="color: #009900;">(</span><span style="color: #003399;">Throwable</span> cause<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">super</span><span style="color: #009900;">(</span>cause<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
Firstly a simple thing, BASE64 encoding wrappers (to be able to switch implementation, what of course will be never used):<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">String</span> encodeBase64<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> data<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: black; font-weight: bold;">new</span> BASE64Encoder<span style="color: #009900;">(</span><span style="color: #009900;">)</span>.<span style="color: #006633;">encode</span><span style="color: #009900;">(</span>data<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> decodeBase64<span style="color: #009900;">(</span><span style="color: #003399;">String</span> data<span style="color: #009900;">)</span> <span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: black; font-weight: bold;">new</span> BASE64Decoder<span style="color: #009900;">(</span><span style="color: #009900;">)</span>.<span style="color: #006633;">decodeBuffer</span><span style="color: #009900;">(</span>data<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error decoding base64"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
How to generate RSA 1024 keys with SecureRandom:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Generates new keypair
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">KeyPair</span> generateKeys<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
<span style="color: #003399;">KeyPairGenerator</span> keyGen <span style="color: #339933;">=</span> <span style="color: #003399;">KeyPairGenerator</span>.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"RSA"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003399;">SecureRandom</span> random <span style="color: #339933;">=</span> <span style="color: #003399;">SecureRandom</span>.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"SHA1PRNG"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
keyGen.<span style="color: #006633;">initialize</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">1024</span>, random<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> keyGen.<span style="color: #006633;">generateKeyPair</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error generating keypair"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
How to encrypt with asymmetric key (public or private):<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Encrypts data with key
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> encryptAsymmetric<span style="color: #009900;">(</span><span style="color: #003399;">Key</span> key, <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> data<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
Cipher cipher <span style="color: #339933;">=</span> Cipher.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"RSA"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
cipher.<span style="color: #006633;">init</span><span style="color: #009900;">(</span>Cipher.<span style="color: #006633;">ENCRYPT_MODE</span>, key<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> cipher.<span style="color: #006633;">doFinal</span><span style="color: #009900;">(</span>data<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error key encrypting"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
For above, how to decrypt with asymmetric key (public or private, the different one than used for encryption):<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Decrypts data with key
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> decryptAsymmetric<span style="color: #009900;">(</span><span style="color: #003399;">Key</span> key, <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> data<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
Cipher cipher <span style="color: #339933;">=</span> Cipher.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"RSA"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
cipher.<span style="color: #006633;">init</span><span style="color: #009900;">(</span>Cipher.<span style="color: #006633;">DECRYPT_MODE</span>, key<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> cipher.<span style="color: #006633;">doFinal</span><span style="color: #009900;">(</span>data<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error key decrypting"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
How to build symmetric key for AES256 encryption:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Builds a random secret key for symmetric algorithm
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">Key</span> buildSymmetricKey<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
KeyGenerator keyGen <span style="color: #339933;">=</span> KeyGenerator.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"AES"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
keyGen.<span style="color: #006633;">init</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">256</span>, <span style="color: #003399;">SecureRandom</span>.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"SHA1PRNG"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> keyGen.<span style="color: #006633;">generateKey</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error generating secret key"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
The building of the AES key based on user password is a little tricky. You need to have a salt (N-bytes array) that is used to generate a proper AES key (with a proper length). If you need to recover this key in the future, using just the same user password, you need to use exactly the same salt, so it's probably best to hardcode it somewhere and use for further keys generation (random 8 bytes):<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: black; font-weight: bold;">private</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> SALT <span style="color: #339933;">=</span> <span style="color: black; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span><span style="color: #009900;">{</span>
<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0xa1, <span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0x22, <span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0x33, <span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0xa4,
<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0x11, <span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0x22, <span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0x12, <span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">)</span> 0x22<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Builds a secret key for symmetric algorithm recoverable by password
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">Key</span> buildSymmetricKey<span style="color: #009900;">(</span><span style="color: #003399;">String</span> password<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
SecretKeyFactory factory <span style="color: #339933;">=</span>
SecretKeyFactory.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"PBKDF2WithHmacSHA1"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003399;">KeySpec</span> spec <span style="color: #339933;">=</span> <span style="color: black; font-weight: bold;">new</span> PBEKeySpec<span style="color: #009900;">(</span>password.<span style="color: #006633;">toCharArray</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>, SALT, <span style="color: #cc66cc;">256</span>,
<span style="color: #cc66cc;">256</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
SecretKey tmp <span style="color: #339933;">=</span> factory.<span style="color: #006633;">generateSecret</span><span style="color: #009900;">(</span>spec<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: black; font-weight: bold;">new</span> SecretKeySpec<span style="color: #009900;">(</span>tmp.<span style="color: #006633;">getEncoded</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>, <span style="color: blue;">"AES"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error encoding secret key"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
Now, how to encrypt the arbitrary length data block with AES:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Encrypts data with symmetric algorithm and password
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> encryptSymmetric<span style="color: #009900;">(</span><span style="color: #003399;">Key</span> key, <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> data<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
Cipher cipher <span style="color: #339933;">=</span> Cipher.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"AES/ECB/PKCS5Padding"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
cipher.<span style="color: #006633;">init</span><span style="color: #009900;">(</span>Cipher.<span style="color: #006633;">ENCRYPT_MODE</span>, key<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> cipher.<span style="color: #006633;">doFinal</span><span style="color: #009900;">(</span>data<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error symmetric encrypting"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
Note, that I use <b>ECB</b> as block cipher mode of operation. This is not the safest one, better would be <b>CBC</b> (refer <a href="http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation" target="_blank">wikipedia</a>). But if you need to recover your data only by AES key, you can't do this. To recover from CBC you need to store your CBC initialization vector together with the password. So, I use ECB for this simple example, to make all it working only with keys.<br />
<br />
The decryption for above symmetric encryption is similar:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Decrypts data with symmetric algorithm and password
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> decryptSymmetric<span style="color: #009900;">(</span><span style="color: #003399;">Key</span> key, <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> data<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
Cipher cipher <span style="color: #339933;">=</span> Cipher.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"AES/ECB/PKCS5Padding"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
cipher.<span style="color: #006633;">init</span><span style="color: #009900;">(</span>Cipher.<span style="color: #006633;">DECRYPT_MODE</span>, key<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> cipher.<span style="color: #006633;">doFinal</span><span style="color: #009900;">(</span>data<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Error symmetric descrypting"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
This is all about working encryption/decryption. Now about storing the keys in db. If you'd like to use BASE64 encoding or even to hold everything in BLOB-s, methods below will be useful.<br />
<br />
Converting the key to BASE64 is easy:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Converts key to base64 encoded string
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">String</span> keyToString<span style="color: #009900;">(</span><span style="color: #003399;">Key</span> key<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> encodeBase64<span style="color: #009900;">(</span>key.<span style="color: #006633;">getEncoded</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre>
<br />
But recovering the key from BASE64 or byte[] is another tricky part:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Converts base64 encoded string to assymetric key
*
* @param publicKey if true returns public key, private key otherwise
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">Key</span> asymmetricKeyFromString<span style="color: #009900;">(</span><span style="color: #003399;">String</span> s, <span style="color: #000066; font-weight: bold;">boolean</span> publicKey<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> asymmetricKeyFromBytes<span style="color: #009900;">(</span>decodeBase64<span style="color: #009900;">(</span>s<span style="color: #009900;">)</span>, publicKey<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Converts bytes to assymetric key
*
* @param publicKey if true returns public key, private key otherwise
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">Key</span> asymmetricKeyFromBytes<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> bytes, <span style="color: #000066; font-weight: bold;">boolean</span> publicKey<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>publicKey<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: #003399;">KeyFactory</span>.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"RSA"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">generatePublic</span><span style="color: #009900;">(</span>
<span style="color: black; font-weight: bold;">new</span> <span style="color: #003399;">X509EncodedKeySpec</span><span style="color: #009900;">(</span>bytes<span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: #003399;">KeyFactory</span>.<span style="color: #006633;">getInstance</span><span style="color: #009900;">(</span><span style="color: blue;">"RSA"</span><span style="color: #009900;">)</span>.<span style="color: #006633;">generatePrivate</span><span style="color: #009900;">(</span>
<span style="color: black; font-weight: bold;">new</span> <span style="color: #003399;">PKCS8EncodedKeySpec</span><span style="color: #009900;">(</span>bytes<span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">catch</span> <span style="color: #009900;">(</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> EncryptionException<span style="color: #009900;">(</span><span style="color: blue;">"Can't decode assymetric key"</span>, e<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
<br />
The same for symmetric key looks much easier:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: green; font-style: italic; font-weight: bold;">/**
* Converts base64 encoded string to symmetric key
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">Key</span> symmetricKeyFromString<span style="color: #009900;">(</span><span style="color: #003399;">String</span> s<span style="color: #009900;">)</span> <span style="color: black; font-weight: bold;">throws</span>
EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> symmetricKeyFromBytes<span style="color: #009900;">(</span>decodeBase64<span style="color: #009900;">(</span>s<span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Converts bytes to symmetric key
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">Key</span> symmetricKeyFromBytes<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> bytes<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> EncryptionException <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: black; font-weight: bold;">new</span> SecretKeySpec<span style="color: #009900;">(</span>bytes, <span style="color: blue;">"AES"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre>
<br />
Sometimes you also need to convert your private/public keys to PEM format for exporting. Without <a href="http://www.bouncycastle.org/" target="_blank">bouncycastle</a> you need your own method for this:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: #003399;">String</span> getPem<span style="color: #009900;">(</span><span style="color: #003399;">Key</span> key<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
StringBuilder sb <span style="color: #339933;">=</span> <span style="color: black; font-weight: bold;">new</span> StringBuilder<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>key <span style="color: black; font-weight: bold;">instanceof</span> <span style="color: #003399;">PrivateKey</span> <span style="color: #339933;">||</span> key <span style="color: black; font-weight: bold;">instanceof</span> <span style="color: #003399;">PublicKey</span><span style="color: #009900;">)</span>
sb.<span style="color: #006633;">append</span><span style="color: #009900;">(</span><span style="color: #003399;">String</span>.<span style="color: #006633;">format</span><span style="color: #009900;">(</span><span style="color: blue;">"-----BEGIN %s %s KEY-----<span style="color: #000099; font-weight: bold;">\n</span>"</span>, <span style="color: blue;">"RSA"</span>,
key <span style="color: black; font-weight: bold;">instanceof</span> <span style="color: #003399;">PublicKey</span> <span style="color: #339933;">?</span> <span style="color: blue;">"PUBLIC"</span> <span style="color: #339933;">:</span> <span style="color: blue;">"PRIVATE"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">else</span>
sb.<span style="color: #006633;">append</span><span style="color: #009900;">(</span><span style="color: blue;">"-----BEGIN KEY-----"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
sb.<span style="color: #006633;">append</span><span style="color: #009900;">(</span>encodeBase64<span style="color: #009900;">(</span>key.<span style="color: #006633;">getEncoded</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>key <span style="color: black; font-weight: bold;">instanceof</span> <span style="color: #003399;">PrivateKey</span> <span style="color: #339933;">||</span> key <span style="color: black; font-weight: bold;">instanceof</span> <span style="color: #003399;">PublicKey</span><span style="color: #009900;">)</span>
sb.<span style="color: #006633;">append</span><span style="color: #009900;">(</span><span style="color: #003399;">String</span>.<span style="color: #006633;">format</span><span style="color: #009900;">(</span><span style="color: blue;">"<span style="color: #000099; font-weight: bold;">\n</span>-----END %s %s KEY-----"</span>, <span style="color: blue;">"RSA"</span>,
key <span style="color: black; font-weight: bold;">instanceof</span> <span style="color: #003399;">PublicKey</span> <span style="color: #339933;">?</span> <span style="color: blue;">"PUBLIC"</span> <span style="color: #339933;">:</span> <span style="color: blue;">"PRIVATE"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">else</span>
sb.<span style="color: #006633;">append</span><span style="color: #009900;">(</span><span style="color: blue;">"<span style="color: #000099; font-weight: bold;">\n</span>-----END KEY-----"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> sb.<span style="color: #006633;">toString</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre>
<br />
And this was just last example of simple Java cryptography API.l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-67484081935903880942013-10-18T21:46:00.000+02:002013-10-18T21:46:01.303+02:00Convert document to HTML with Apache Tika<b><a href="http://tika.apache.org/" target="_blank">Apache Tika</a></b> has a wonderful feature, that can transform source document (PDF, MSOffice, Open Office etc.) into HTML during content extraction. Sound pretty simple, but I've dug through a lot of google search results and I can't find a simple working example anywhere.<br />
<br />
But, here is a working snippet I extracted from tika-app:<br />
<br />
<pre class="java" style="font-family: monospace;"><span style="color: #003399;">ByteArrayOutputStream</span> out <span style="color: #339933;">=</span> <span style="color: black; font-weight: bold;">new</span> <span style="color: #003399;">ByteArrayOutputStream</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
SAXTransformerFactory factory <span style="color: #339933;">=</span> <span style="color: #009900;">(</span>SAXTransformerFactory<span style="color: #009900;">)</span>
SAXTransformerFactory.<span style="color: #006633;">newInstance</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
TransformerHandler handler <span style="color: #339933;">=</span> factory.<span style="color: #006633;">newTransformerHandler</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
handler.<span style="color: #006633;">getTransformer</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>.<span style="color: #006633;">setOutputProperty</span><span style="color: #009900;">(</span>OutputKeys.<span style="color: #006633;">METHOD</span>, <span style="color: blue;">"html"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
handler.<span style="color: #006633;">getTransformer</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>.<span style="color: #006633;">setOutputProperty</span><span style="color: #009900;">(</span>OutputKeys.<span style="color: #006633;">INDENT</span>, <span style="color: blue;">"yes"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
handler.<span style="color: #006633;">getTransformer</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>.<span style="color: #006633;">setOutputProperty</span><span style="color: #009900;">(</span>OutputKeys.<span style="color: #006633;">ENCODING</span>, <span style="color: blue;">"UTF-8"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
handler.<span style="color: #006633;">setResult</span><span style="color: #009900;">(</span><span style="color: black; font-weight: bold;">new</span> StreamResult<span style="color: #009900;">(</span>out<span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
ExpandedTitleContentHandler handler1 <span style="color: #339933;">=</span> <span style="color: black; font-weight: bold;">new</span> ExpandedTitleContentHandler<span style="color: #009900;">(</span>handler<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
tikaParser.<span style="color: #006633;">parse</span><span style="color: #009900;">(</span><span style="color: black; font-weight: bold;">new</span> <span style="color: #003399;">ByteArrayInputStream</span><span style="color: #009900;">(</span>file<span style="color: #009900;">)</span>, handler1, <span style="color: black; font-weight: bold;">new</span> Metadata<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: black; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">(</span>out.<span style="color: #006633;">toByteArray</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>, <span style="color: blue;">"UTF-8"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
</pre>
It works pretty nicely. Here is an example of original MSOffice document:<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinWFHsVdrt9ejbbBKA-abgwr0dXzzxx1ibr7riGVp47rZ30aoKsgM70RMCOppLC47fi1lHvjaFP6NiREsNynHsN810b-yaoIlq3i2G5WTbFezoGUiHH5QCMViflbW3wQ716WsfLyiUo6E/s1600/tika-office.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="512" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinWFHsVdrt9ejbbBKA-abgwr0dXzzxx1ibr7riGVp47rZ30aoKsgM70RMCOppLC47fi1lHvjaFP6NiREsNynHsN810b-yaoIlq3i2G5WTbFezoGUiHH5QCMViflbW3wQ716WsfLyiUo6E/s640/tika-office.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
And here how the above looks in my webapp as HTML preview:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcaM6QdHPDjovZmz-8rJZBaj-V2QlbXcEfvsVq1qeiubpehhWE2mXsIidH5NizAQe9pNWCWbIvuwNPFlnIybUZQ8K7JcQ9tEDmGSr_dJSoyfWB1bjx7iT55wQ-2-xXwP-jrjaKd3CTc4o/s1600/tika-html.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="476" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcaM6QdHPDjovZmz-8rJZBaj-V2QlbXcEfvsVq1qeiubpehhWE2mXsIidH5NizAQe9pNWCWbIvuwNPFlnIybUZQ8K7JcQ9tEDmGSr_dJSoyfWB1bjx7iT55wQ-2-xXwP-jrjaKd3CTc4o/s640/tika-html.png" width="640" /></a></div>
<br />l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-14211961597989090322013-10-16T16:02:00.000+02:002013-10-19T20:49:30.056+02:00Play Framework on Heroku and custom dependenciesToday I was playing a little about <a href="http://www.playframework.com/" target="_blank">Play Framework</a>. This is very nice lightweight application framework for Java and Scala. I was trying to make an app and deploy to <a href="https://www.heroku.com/" target="_blank">Heroku</a>, which is a PaaS platform where you can host you Play applications for free (with some limitations of course).<br />
<br />
And here the problem happened. For the project I use my own lib, managed by maven, let's say:<br />
<br />
<pre class="xml" style="font-family: monospace;"><span style="color: #009900;"><span style="color: black; font-weight: bold;"><groupId<span style="color: black; font-weight: bold;">></span></span></span>com.blogspot.lifeinide<span style="color: #009900;"><span style="color: black; font-weight: bold;"></groupId<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><artifactId<span style="color: black; font-weight: bold;">></span></span></span>mylib<span style="color: #009900;"><span style="color: black; font-weight: bold;"></artifactId<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><version<span style="color: black; font-weight: bold;">></span></span></span>1.0-SNAPSHOT<span style="color: #009900;"><span style="color: black; font-weight: bold;"></version<span style="color: black; font-weight: bold;">></span></span></span>
</pre>
Now, how to use this lib for local Play project and then deploy it to Heroku with this dependency too? I don't want to put each time the new version to Play lib/ folder (it can be anyway cleaned up by "play dependencies") because this is still under development too. How to automate this? It is a bit tricky.<br />
<br />
Play Framework uses its own dependency resolving mechanism based on dependencies.yml file, but internally it uses maven too. The key here is to configure appropriately dependencies.yml to use different maven repository, for example:<br />
<br />
<pre class="winbatch" style="font-family: monospace;">require<span style="color: #ff1010; font-weight: bold;">:</span>
<span style="color: #66cc66;">-</span> play 1.2.5.3
<span style="color: #66cc66;">-</span> com.blogspot.lifeinide <span style="color: #66cc66;">-></span> mylib <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">-</span><span style="color: blue;">SNAPSHOT</span>
repositories<span style="color: #ff1010; font-weight: bold;">:</span>
<span style="color: #66cc66;">-</span> jboss<span style="color: #ff1010; font-weight: bold;">:</span>
type<span style="color: #ff1010; font-weight: bold;">: iBiblio</span>
root<span style="color: #ff1010; font-weight: bold;">: "file://${user.home}/.m2/repository/"</span>
contains<span style="color: #ff1010; font-weight: bold;">:</span>
<span style="color: #66cc66;">-</span> com.blogspot.lifeinide <span style="color: #66cc66;">-></span> <span style="color: #66cc66;">*</span>
</pre>
<br />
Now you can "mvn install" your project to your local maven repository, and Play dependency system can find it.<br />
<br />
But Heroku can't...<br />
<br />
But here is the trick for Heroku. In my heroku project I have following structure:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">|- heroku // my heroku project</span><br />
<span style="font-family: Courier New, Courier, monospace;"> |- .git // git repository for heroku deployment</span><br />
<span style="font-family: Courier New, Courier, monospace;"> |- repo // this is my local maven repository</span><br />
<br />
Now for the mylib project pom.xml I can configure appropriate deployment:<br />
<br />
<pre class="xml" style="font-family: monospace;"><span style="color: #009900;"><span style="color: black; font-weight: bold;"><build<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><plugins<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><plugin<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><groupId<span style="color: black; font-weight: bold;">></span></span></span>org.apache.maven.plugins<span style="color: #009900;"><span style="color: black; font-weight: bold;"></groupId<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><artifactId<span style="color: black; font-weight: bold;">></span></span></span>maven-deploy-plugin<span style="color: #009900;"><span style="color: black; font-weight: bold;"></artifactId<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><version<span style="color: black; font-weight: bold;">></span></span></span>2.7<span style="color: #009900;"><span style="color: black; font-weight: bold;"></version<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"></plugin<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"></plugins<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"></build<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><distributionManagement<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><repository<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><id<span style="color: black; font-weight: bold;">></span></span></span>local-lib-unmanaged<span style="color: #009900;"><span style="color: black; font-weight: bold;"></id<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><name<span style="color: black; font-weight: bold;">></span></span></span>local-lib-unmanaged<span style="color: #009900;"><span style="color: black; font-weight: bold;"></name<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"><url<span style="color: black; font-weight: bold;">></span></span></span>file:///path/to/heroku/repo<span style="color: #009900;"><span style="color: black; font-weight: bold;"></url<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"></repository<span style="color: black; font-weight: bold;">></span></span></span>
<span style="color: #009900;"><span style="color: black; font-weight: bold;"></distributionManagement<span style="color: black; font-weight: bold;">></span></span></span></pre>
<br />
So it basically deploys the artifact to my local "repo" repository under heroku project on "mvn deploy". Now the changes in dependencies.yml:<br />
<br />
<pre class="winbatch" style="font-family: monospace;">require<span style="color: #ff1010; font-weight: bold;">:</span>
<span style="color: #66cc66;">-</span> play 1.2.5.3
<span style="color: #66cc66;">-</span> com.blogspot.lifeinide <span style="color: #66cc66;">-></span> mylib <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">-</span><span style="color: blue;">SNAPSHOT</span>
repositories<span style="color: #ff1010; font-weight: bold;">:</span>
<span style="color: #66cc66;">-</span> jboss<span style="color: #ff1010; font-weight: bold;">:</span>
type<span style="color: #ff1010; font-weight: bold;">: iBiblio</span>
root<span style="color: #ff1010; font-weight: bold;">: "file://${application.path}/repo/"</span>
contains<span style="color: #ff1010; font-weight: bold;">:</span>
<span style="color: #66cc66;">-</span> com.blogspot.lifeinide <span style="color: #66cc66;">-></span> <span style="color: #66cc66;">*</span></pre>
<br />
And here you are. After adding the "repo" to git and pushing all this stuff to Heroku, it can resolve dependencies.l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-302946967512186802013-10-07T20:45:00.002+02:002016-12-28T22:43:22.347+01:00SOA vs. Domain design and OpenSessionInThreadExecution patternThis article describes some complementation for <b>Open Session In View</b> pattern for Java/Spring. But first I want to show just my point of view about the pattern itself.<br />
<br />
Many people consider this as an anti-pattern and tell that it never should be used. I think exactly opposite, and here are some explanations.<br />
<br />
I code java (JEE) almost 10 years and in general after this experience I can tell that there are two architectures for Java webapps which I worked in (and many variations of course): <b>service oriented architecture</b> (or <b>SOA</b>/service design) and <b>domain driven design </b>(<b>DDD</b>).<br />
<br />
<b>Service oriented architecure</b> is a perflectly layered application, with each layer with its own, and only one responsibility: we mostly have views, controllers, services and daos. A lot of people encourage this design, as the only valid one. It indeed looks very good on the paper and in diagrams - this is the cleanest one. But here are my experiences in working with such applications.<br />
<br />
I'm talking about standard design with such design guidelines (the most common):<br />
<ul>
<li>DAOs handle with persistence layer using Hibernate/JPA as the low level DB access API</li>
<li>services provide business interfaces, and uses DAOs internally</li>
<li>the usual session and transaction model is session-per-transaction, and transactions are established by AOP, when service methods are invoked</li>
</ul>
<div>
Second thing is that I'm talking about standard small-medium size webapps, they can be web portals or business application, they can be clustered using eg. standard tomcat clustering with load balancer. But I'm not talking about very big systems eg. for banking with 30 developers team and 2 mln of code lines, working on the server farm and integrating inside 15 standalone systems for various purposes. For such requirements I think the <b>SOA</b> is the right choice.</div>
<div>
<br /></div>
<div>
Now, what is wrong with this design for me? These projects, where we used such design were unnecessarily <b>HUGE</b>. The development team had to be much bigger than in <b>DDD</b>, the simple modifications to the application took a lot of hours and people spent 80% of time for doing mokey jobs, like moving data from one type of objects to another or struggling with LazyInitializationException. Sincerely, if I had chosen this design few years ago when I created my own application, I would have been out of the market already. I already know people who give up Java, and switched to different techs (like Python or Ruby) because "Java became the technology where you cannot do anything efficiently". I believe this is not true, this is only the design problem.</div>
<div>
<br /></div>
<div>
Where does all this bloat come from? The main problem here is exactly the hibernate session management design. I consider that almost 90% of this bloat code come from this way of handling with Hibernate. I think all this design was created when there was no sensible ORM yet, but when it appeared, people just don't understand how it could help to create applications really rapidly, using all benefits of ORM. And to create them with 20% of original team, and to have the product that really quickly can answer for the constantly changing requirements from the market.</div>
<div>
<br /></div>
<div>
So, what are my problems with <b>SOA</b>? Here are they:</div>
<div>
<ol>
<li>Hibernate gives you the database abstraction, which is the implementation of DAO pattern itself. I cannot undestand why still to write yet another DAO layer, doing the same things as Hibernate already does (the DAO over DAO). If you resign from this, you have a one pretty big layer less, what reduce your code significantly. And still the DAO is preserved - you can always switch to another database implementation changing the Hibernate engine (this is what the DAO is for).</li>
<li>If you spent a lot of time to design your beautiful domain model, why to give up using these objects in your whole application, and to develop another structure of objects? This problem comes from the session management design. If you close you session after leaving service layer, you can't rely on your domain objects anymore. You need to develop another structure of DTO objects and use DTO in higher layers. You need to develop also a lot of conversion code as well, which tosses the data between the Domain and DTO objects (in both ways). You finally end up with hundred of tons of code, two objects model hierarchies that looks almost exactly the same (Domain and DTO), that might just not be right there, if another model of session management had been choosen.</li>
<li>Another problem that if you write the standard web application, I mean the app which has the HTML user interface etc. (not pure service application, like web-services app only), the service layer becomes quickly very artifical and cluttered. For example let's say that I have the <span style="font-family: "courier new" , "courier" , monospace;">BlogEntry</span> entity with collections of <span style="font-family: "courier new" , "courier" , monospace;">Comment</span>. What is problem with this? If you have eg. service method:<br /><span style="font-family: "courier new" , "courier" , monospace;">BlogEntryDTO getBlogEntry(long id) {..}</span><br />What version of DTO object you should return from such service - with filled lazy comments collection or not? There is some client code that needs these comments, and others not. So, should you always load comments with another SQL, even for the <span style="font-family: "courier new" , "courier" , monospace;">BlogEntry</span> entity usage for the client code which doesn't need them? Hmm... no, and you finally end up with:<br /><span style="font-family: "courier new" , "courier" , monospace;">BlogEntryDTO getBlogEntry(long id) {..}</span><span style="font-family: inherit;"> </span><br /><span style="font-family: "courier new" , "courier" , monospace;">BlogEntryDTO getBlogEntryWithComments(long id) {..}</span><br />And with another dozen of <span style="font-family: "courier new" , "courier" , monospace;">getBlogEntry()</span> methods in a service, plus fifty other services. Finally to do a simple thing you need to dig through hundreds of code lines, to find what you exactly need (or write another <span style="font-family: "courier new" , "courier" , monospace;">getBlogEntry()</span> method if you can't).</li>
<li>Another example is getting collections from services. Let's consider a simple one:<br /><span style="font-family: "courier new" , "courier" , monospace;">List<BlogEntryDTO> getUserBlogEntries(long userid) {..}</span><br /><span style="font-family: inherit;">Looks nice and clean... but, wait a moment. We also needs the </span><span style="font-family: "courier new" , "courier" , monospace;">count(*)</span><span style="font-family: inherit;"> calculation and limits for pagination, and the sorting capability as well. How many method do we need to write more to achieve this? It's crazy.</span></li>
</ol>
<div>
And how does it look in the <b>DDD</b> design?</div>
</div>
<div>
<ol>
<li>You don't have to write the DAO layer. You may use your Hibernate DAO. This <b>doesn't </b>prevent you from having nice and well designed DAO layer. What you exactly need is the Session API and @NamedQueries for fetching items by queries.</li>
<li>Your service layer doesn't close the Session after each method invocation, but it's held opened to the end of the request. You don't have to write this unnecessary DTO and conversion code. This <b>doesn't</b> prevent you from having nice and well designed service layer.</li>
<li>You don't bother about this. If you client code decides that it needs comments, it invokes <span style="font-family: "courier new" , "courier" , monospace;">getComments()</span> and have them on demand, because session is still opened.</li>
<li>You also don't bother about this. You can use <span style="font-family: "courier new" , "courier" , monospace;">Query</span> or <span style="font-family: "courier new" , "courier" , monospace;">Criteria</span> objects to transfer collections from the service layer, and you can parametrize them later, depending on what your controller layer wants to achieve.</li>
</ol>
<div>
For the people who advise anyway to use <b>SOA</b>, I can tell that I know that <b>DDD</b> is not a pure layered solution. But greater benefits for me is to have an application that have 30% of original (<b>SOA</b>) lines of code (and all benefits from this - time and cost of development, time and cost of modification, testing etc), than have a big bloat, but "pure layered" medal on my chest.</div>
</div>
<div>
<br /></div>
<div>
Of course, every pot has two handles. Now few words about when the <b>SOA</b> might be better than <b>DDD </b>in my opinion. It's when you have a big part of application, where you don't handle with web requests (like standard user request, or webservice request), but the work is done in internal threads (eg. schedulers, ESB listeners etc). <b>DDD</b> is highly bound to open-session-in-view pattern, usualy done by <span style="font-family: "courier new" , "courier" , monospace;">OpenSessionInViewFilter</span> (eg. from the Spring) and the holding session opened just don't work for internal threads. So in <b>DDD</b> you can imagine that you may have inconsistent design, because you need to handle with service layer in different way from request-bound threads and from internal threads. While in <b>SOA</b>, if you already developed all this stuff required to implement this pattern, everything is handled in the same way from both kinds of threads. Well, you're right, but...</div>
<div>
<br /></div>
<div>
I have at least two solutions for this problem. The internal mechanisms usually use just some subset of your total business logic (like receiving tasks from some server and putting them to the db periodically). You can easily create small and thin layer of services, dedicated to work with internal threads, and expose the subset of logic that they need, in these services. Your internal services can be designed in standard <b>SOA</b> pattern, ie. to have session per transaction and AOP-ly defined transaction boundaries on methods. Your scheduler or whatever else can always start the work from some service method invocation, that does its job.</div>
<div>
<br /></div>
<div>
Another solution is my <span style="font-family: "courier new" , "courier" , monospace;">OpenSessionInThreadExecution</span> pattern, which is just the remake of <span style="font-family: "courier new" , "courier" , monospace;">OpenSessionOnViewFilter</span> from Spring. It assumes, that you always have some entry point in some background tasks, where you start doing you background work (like <span style="font-family: "courier new" , "courier" , monospace;">Runnable.run()</span>) - and this is perflectly true because somewhere you join to the internal thread with your logic. Using this bean you can simply wrap your execution with <span style="font-family: "courier new" , "courier" , monospace;">Runnable</span>, and pass to the <span style="font-family: "courier new" , "courier" , monospace;">execute()</span> method, to be executed with opened session throughout whole execution. Here is the code:<br />
<br />
<br /></div>
<pre class="java" style="font-family: monospace;"><span style="color: black; font-weight: bold;">package</span> <span style="color: #006699;">com.blogspot.lifeinide</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.log4j.Logger</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.FlushMode</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.Session</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.hibernate.SessionFactory</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.beans.factory.InitializingBean</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.beans.factory.annotation.Required</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.dao.DataAccessResourceFailureException</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.orm.hibernate3.SessionFactoryUtils</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.orm.hibernate3.SessionHolder</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">import</span> <span style="color: #006699;">org.springframework.transaction.support.TransactionSynchronizationManager</span><span style="color: #339933;">;</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* This is a util class to keep session opened during whole single thread
* execution (like scheduler or mule service thread), works in the same manner
* as {@link OpenSessionInViewFilter}.
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">class</span> OpenSessionInThreadExecution <span style="color: black; font-weight: bold;">implements</span> InitializingBean <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">protected</span> <span style="color: black; font-weight: bold;">static</span> <span style="color: black; font-weight: bold;">final</span> Logger logger <span style="color: #339933;">=</span>
Logger.<span style="color: #006633;">getLogger</span><span style="color: #009900;">(</span>OpenSessionInThreadExecution.<span style="color: black; font-weight: bold;">class</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">protected</span> <span style="color: black; font-weight: bold;">static</span> OpenSessionInThreadExecution instance <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> singleSession <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">protected</span> FlushMode flushMode <span style="color: #339933;">=</span> FlushMode.<span style="color: #006633;">MANUAL</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">protected</span> SessionFactory sessionFactory<span style="color: #339933;">;</span>
@Override
<span style="color: black; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> afterPropertiesSet<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: black; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>instance <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">)</span>
instance <span style="color: #339933;">=</span> <span style="color: black; font-weight: bold;">this</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">else</span>
<span style="color: black; font-weight: bold;">throw</span> <span style="color: black; font-weight: bold;">new</span> <span style="color: #003399;">IllegalStateException</span><span style="color: #009900;">(</span>
<span style="color: blue;">"OpenSessionInThreadExecution should be defined as "</span> <span style="color: #339933;">+</span>
<span style="color: blue;">"the only one singleton bean."</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">public</span> SessionFactory getSessionFactory<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> sessionFactory<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
@Required
<span style="color: black; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setSessionFactory<span style="color: #009900;">(</span>SessionFactory sessionFactory<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">this</span>.<span style="color: #006633;">sessionFactory</span> <span style="color: #339933;">=</span> sessionFactory<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Set whether to use a single session for each request. Default is "true".
* <p>If set to "false", each data access operation or transaction will use
* its own session (like without Open Session in View). Each of those
* sessions will be registered for deferred close, though, actually
* processed at request completion.
*
* @see SessionFactoryUtils#initDeferredClose
* @see SessionFactoryUtils#processDeferredClose
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setSingleSession<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">boolean</span> singleSession<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">this</span>.<span style="color: #006633;">singleSession</span> <span style="color: #339933;">=</span> singleSession<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Return whether to use a single session for each request.
*/</span>
<span style="color: black; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> isSingleSession<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: black; font-weight: bold;">this</span>.<span style="color: #006633;">singleSession</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Specify the Hibernate FlushMode to apply to this filter's
* {@link org.hibernate.Session}. Only applied in single session mode.
* <p>Can be populated with the corresponding constant name in XML bean
* definitions: e.g. "AUTO".
* <p>The default is "MANUAL". Specify "AUTO" if you intend to use
* this filter without service layer transactions.
*
* @see org.hibernate.Session#setFlushMode
* @see org.hibernate.FlushMode#MANUAL
* @see org.hibernate.FlushMode#AUTO
*/</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setFlushMode<span style="color: #009900;">(</span>FlushMode flushMode<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">this</span>.<span style="color: #006633;">flushMode</span> <span style="color: #339933;">=</span> flushMode<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Return the Hibernate FlushMode that this filter applies to its
* {@link org.hibernate.Session} (in single session mode).
*/</span>
<span style="color: black; font-weight: bold;">protected</span> FlushMode getFlushMode<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> <span style="color: black; font-weight: bold;">this</span>.<span style="color: #006633;">flushMode</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> execute<span style="color: #009900;">(</span><span style="color: #003399;">Runnable</span> command<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000066; font-weight: bold;">boolean</span> participate <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>isSingleSession<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">// single session mode</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>TransactionSynchronizationManager.<span style="color: #006633;">hasResource</span><span style="color: #009900;">(</span>sessionFactory<span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">// Do not modify the Session: just set the participate flag.</span>
participate <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
logger.<span style="color: #006633;">debug</span><span style="color: #009900;">(</span><span style="color: blue;">"Opening single Hibernate Session in "</span> <span style="color: #339933;">+</span>
<span style="color: blue;">"OpenSessionInViewFilter"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
Session session <span style="color: #339933;">=</span> getSession<span style="color: #009900;">(</span>sessionFactory<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
TransactionSynchronizationManager.<span style="color: #006633;">bindResource</span><span style="color: #009900;">(</span>
sessionFactory, <span style="color: black; font-weight: bold;">new</span> SessionHolder<span style="color: #009900;">(</span>session<span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">// deferred close mode</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>SessionFactoryUtils.<span style="color: #006633;">isDeferredCloseActive</span><span style="color: #009900;">(</span>sessionFactory<span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">// Do not modify deferred close: just set the participate flag.</span>
participate <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
SessionFactoryUtils.<span style="color: #006633;">initDeferredClose</span><span style="color: #009900;">(</span>sessionFactory<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
command.<span style="color: #006633;">run</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">finally</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!</span>participate<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>isSingleSession<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">// single session mode</span>
SessionHolder sessionHolder <span style="color: #339933;">=</span>
<span style="color: #009900;">(</span>SessionHolder<span style="color: #009900;">)</span> TransactionSynchronizationManager.
<span style="color: #006633;">unbindResource</span><span style="color: #009900;">(</span>sessionFactory<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
logger.<span style="color: #006633;">debug</span><span style="color: #009900;">(</span><span style="color: blue;">"Closing single Hibernate Session in "</span> <span style="color: #339933;">+</span>
<span style="color: blue;">"OpenSessionInViewFilter"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
closeSession<span style="color: #009900;">(</span>sessionHolder.<span style="color: #006633;">getSession</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>, sessionFactory<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: black; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
<span style="color: #666666; font-style: italic;">// deferred close mode</span>
SessionFactoryUtils.<span style="color: #006633;">processDeferredClose</span><span style="color: #009900;">(</span>sessionFactory<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Get a Session for the SessionFactory that this filter uses.
* Note that this just applies in single session mode!
* <p>The default implementation delegates to the
* <code>SessionFactoryUtils.getSession</code> method and
* sets the <code>Session</code>'s flush mode to "MANUAL".
* <p>Can be overridden in subclasses for creating a Session with a
* custom entity interceptor or JDBC exception translator.
*
* @param sessionFactory the SessionFactory that this filter uses
* @return the Session to use
* @throws DataAccessResourceFailureException
* if the Session could not be created
* @see org.springframework.orm.hibernate3.SessionFactoryUtils#
* getSession(SessionFactory, boolean)
* @see org.hibernate.FlushMode#MANUAL
*/</span>
<span style="color: black; font-weight: bold;">protected</span> Session getSession<span style="color: #009900;">(</span>SessionFactory sessionFactory<span style="color: #009900;">)</span>
<span style="color: black; font-weight: bold;">throws</span> DataAccessResourceFailureException <span style="color: #009900;">{</span>
Session session <span style="color: #339933;">=</span> SessionFactoryUtils.<span style="color: #006633;">getSession</span><span style="color: #009900;">(</span>sessionFactory, <span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
FlushMode flushMode <span style="color: #339933;">=</span> getFlushMode<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #009900;">(</span>flushMode <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
session.<span style="color: #006633;">setFlushMode</span><span style="color: #009900;">(</span>flushMode<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">return</span> session<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: green; font-style: italic; font-weight: bold;">/**
* Close the given Session.
* Note that this just applies in single session mode!
* <p>Can be overridden in subclasses, e.g. for flushing the Session before
* closing it. See class-level javadoc for a discussion of flush handling.
* Note that you should also override getSession accordingly, to set
* the flush mode to something else than NEVER.
*
* @param session the Session used for filtering
* @param sessionFactory the SessionFactory that this filter uses
*/</span>
<span style="color: black; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> closeSession<span style="color: #009900;">(</span>Session session, SessionFactory sessionFactory<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
SessionFactoryUtils.<span style="color: #006633;">closeSession</span><span style="color: #009900;">(</span>session<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: black; font-weight: bold;">public</span> <span style="color: black; font-weight: bold;">static</span> OpenSessionInThreadExecution getInstance<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: black; font-weight: bold;">return</span> instance<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
</pre>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-16622862769953607502013-09-20T19:40:00.001+02:002013-10-19T21:11:46.309+02:00Map Accepted-Language language codes to country codes in PHPToday I needed to perform some small task regarding country detection by Accepted-Language header in PHP. It quickly turned out that there's no (or I cannot find) the reliable source for such mapping. Finally I've found it <a href="http://download.geonames.org/export/dump/countryInfo.txt" target="_blank">here</a>.<br />
<br />
I parsed it to the php format, that can be used in the code. Here are the sources. First one is a country code to country info mapping:<br />
<br />
<pre class="php" style="font-family: monospace;"><span style="color: #000088;">$countries</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span>
<span style="color: blue;">'ad'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'and'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Andorra'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Andorra la Vella'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ae'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'are'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'United Arab Emirates'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Abu Dhabi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aed'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dirham'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'af'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'afg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Afghanistan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kabul'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'afn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Afghani'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ag'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'atg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Antigua and Barbuda'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">"St. John's"</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ai'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'aia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Anguilla'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'The Valley'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'al'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'alb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Albania'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tirana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'all'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lek'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'am'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'arm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Armenia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Yerevan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'amd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dram'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ao'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ago'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Angola'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Luanda'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aoa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kwanza'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'aq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ata'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Antarctica'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'arg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Argentina'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Buenos Aires'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ars'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'as'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'asm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'American Samoa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pago Pago'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'at'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'aut'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Austria'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vienna'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'au'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'aus'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Australia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Canberra'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'aw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'abw'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Aruba'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Oranjestad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'awg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guilder'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ax'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ala'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Aland Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mariehamn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'az'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'aze'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Azerbaijan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Baku'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'azn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Manat'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ba'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bih'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bosnia and Herzegovina'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sarajevo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bam'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Marka'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'brb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Barbados'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bridgetown'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bbd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bgd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bangladesh'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dhaka'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bdt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Taka'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'be'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bel'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Belgium'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Brussels'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bfa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Burkina Faso'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ouagadougou'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bgr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bulgaria'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sofia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bgn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lev'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bhr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bahrain'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Manama'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bhd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bdi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Burundi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bujumbura'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bif'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ben'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Benin'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Porto-Novo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'blm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Barthelemy'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Gustavia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bmu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bermuda'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Hamilton'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bmd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'brn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Brunei'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bandar Seri Begawan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bnd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bol'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bolivia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sucre'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bob'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Boliviano'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bes'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bonaire, Saint Eustatius and Saba '</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'br'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bra'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Brazil'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Brasilia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'brl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Real'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bs'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bhs'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bahamas'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nassau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bsd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'btn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bhutan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Thimphu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'btn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ngultrum'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bvt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bouvet Island'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nok'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krone'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'bwa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Botswana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Gaborone'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bwp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pula'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'by'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'blr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Belarus'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Minsk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'byr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ruble'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'blz'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Belize'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Belmopan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'bzd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ca'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'can'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Canada'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ottawa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'cad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cck'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cocos Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'West Island'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cod'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Democratic Republic of the Congo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kinshasa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'cdf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'caf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Central African Republic'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bangui'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xaf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cog'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Republic of the Congo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Brazzaville'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xaf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ch'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'che'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Switzerland'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Berne'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'chf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ci'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'civ'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ivory Coast'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Yamoussoukro'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ck'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cok'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cook Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Avarua'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nzd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'chl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Chile'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Santiago'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'clp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cmr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cameroon'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Yaounde'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xaf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'chn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'China'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Beijing'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'cny'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Yuan Renminbi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'co'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'col'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Colombia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bogota'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'cop'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cri'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Costa Rica'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'San Jose'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'crc'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Colon'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cub'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cuba'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Havana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'cup'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cpv'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cape Verde'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Praia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'cve'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Escudo'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cuw'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Curacao'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Willemstad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ang'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guilder'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cx'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cxr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Christmas Island'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Flying Fish Cove'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cyp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cyprus'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nicosia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cze'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Czech Republic'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Prague'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'czk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Koruna'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'deu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Germany'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Berlin'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'dji'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Djibouti'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Djibouti'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'djf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'dnk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Denmark'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Copenhagen'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'dkk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krone'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'dma'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dominica'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Roseau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'do'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'dom'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dominican Republic'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Santo Domingo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'dop'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'dza'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Algeria'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Algiers'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'dzd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ec'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ecu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ecuador'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Quito'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ee'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'est'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Estonia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tallinn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'eg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'egy'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Egypt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cairo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'egp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'eh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'esh'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Western Sahara'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'El-Aaiun'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dirham'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'er'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'eri'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Eritrea'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Asmara'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ern'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nakfa'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'esp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Spain'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Madrid'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'eth'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ethiopia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Addis Ababa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'etb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Birr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'fin'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Finland'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Helsinki'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'fji'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Fiji'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Suva'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'fjd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'flk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Falkland Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Stanley'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'fkp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'fsm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Micronesia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Palikir'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'fro'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Faroe Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Torshavn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'dkk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krone'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'fra'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'France'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Paris'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ga'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gab'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Gabon'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Libreville'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xaf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gbr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'United Kingdom'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'London'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gbp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'grd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Grenada'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">"St. George's"</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ge'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'geo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Georgia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tbilisi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gel'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lari'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'guf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'French Guiana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cayenne'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ggy'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guernsey'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'St Peter Port'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gbp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gha'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ghana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Accra'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ghs'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cedi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gib'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Gibraltar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Gibraltar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gip'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'grl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Greenland'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nuuk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'dkk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krone'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gmb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Gambia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Banjul'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gmd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dalasi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gin'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guinea'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Conakry'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gnf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'glp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guadeloupe'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Basse-Terre'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gnq'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Equatorial Guinea'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Malabo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xaf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'grc'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Greece'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Athens'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gs'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sgs'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'South Georgia and the South Sandwich Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Grytviken'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gbp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gtm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guatemala'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guatemala City'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gtq'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Quetzal'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gum'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guam'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Hagatna'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'gnb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guinea-Bissau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bissau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'guy'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guyana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Georgetown'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gyd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'hkg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Hong Kong'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Hong Kong'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'hkd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'hmd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Heard Island and McDonald Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'hnd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Honduras'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tegucigalpa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'hnl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lempira'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'hrv'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Croatia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Zagreb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'hrk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kuna'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ht'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'hti'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Haiti'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Port-au-Prince'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'htg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Gourde'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'hun'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Hungary'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Budapest'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'huf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Forint'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'id'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'idn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Indonesia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Jakarta'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'idr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rupiah'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ie'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'irl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ireland'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dublin'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'il'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'isr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Israel'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Jerusalem'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ils'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Shekel'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'im'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'imn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Isle of Man'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Douglas, Isle of Man'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gbp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ind'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'India'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'New Delhi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'inr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rupee'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'io'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'iot'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'British Indian Ocean Territory'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Diego Garcia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'iq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'irq'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Iraq'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Baghdad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'iqd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ir'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'irn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Iran'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tehran'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'irr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rial'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'is'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'isl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Iceland'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Reykjavik'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'isk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krona'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'it'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ita'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Italy'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rome'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'je'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'jey'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Jersey'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Helier'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'gbp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'jm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'jam'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Jamaica'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kingston'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'jmd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'jo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'jor'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Jordan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Amman'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'jod'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'jp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'jpn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Japan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tokyo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'jpy'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Yen'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ke'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ken'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kenya'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nairobi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'kes'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Shilling'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'kgz'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kyrgyzstan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bishkek'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'kgs'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Som'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'khm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cambodia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Phnom Penh'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'khr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Riels'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ki'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'kir'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kiribati'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tarawa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'km'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'com'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Comoros'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Moroni'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'kmf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'kna'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Kitts and Nevis'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Basseterre'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'prk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'North Korea'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pyongyang'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'kpw'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Won'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'kor'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'South Korea'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Seoul'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'krw'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Won'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'xk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'xkx'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kosovo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pristina'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'kwt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kuwait'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kuwait City'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'kwd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ky'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'cym'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cayman Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'George Town'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'kyd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'kaz'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kazakhstan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Astana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'kzt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tenge'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'la'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lao'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Laos'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vientiane'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'lak'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kip'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lbn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lebanon'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Beirut'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'lbp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lca'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Lucia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Castries'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'li'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lie'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Liechtenstein'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vaduz'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'chf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lka'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sri Lanka'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Colombo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'lkr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rupee'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lbr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Liberia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Monrovia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'lrd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ls'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lso'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lesotho'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Maseru'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'lsl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Loti'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ltu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lithuania'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vilnius'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ltl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Litas'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lux'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Luxembourg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Luxembourg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lva'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Latvia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Riga'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'lvl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lat'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ly'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'lby'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Libya'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tripolis'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'lyd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ma'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Morocco'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rabat'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dirham'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mco'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Monaco'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Monaco'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'md'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mda'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Moldova'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Chisinau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mdl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Leu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'me'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mne'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Montenegro'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Podgorica'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'maf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Martin'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Marigot'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mdg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Madagascar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Antananarivo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mga'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ariary'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mhl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Marshall Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Majuro'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mkd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Macedonia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Skopje'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mkd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Denar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ml'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mli'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mali'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bamako'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mmr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Myanmar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nay Pyi Taw'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mmk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kyat'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mng'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mongolia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ulan Bator'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mnt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tugrik'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mac'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Macao'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Macao'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mop'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pataca'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mnp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Northern Mariana Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saipan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mtq'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Martinique'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Fort-de-France'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mrt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mauritania'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nouakchott'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mro'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ouguiya'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ms'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'msr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Montserrat'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Plymouth'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mlt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Malta'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Valletta'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mus'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mauritius'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Port Louis'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rupee'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mdv'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Maldives'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Male'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mvr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rufiyaa'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mwi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Malawi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lilongwe'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mwk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kwacha'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mx'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mex'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mexico'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mexico City'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mxn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'my'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'mys'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Malaysia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kuala Lumpur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'myr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ringgit'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'moz'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mozambique'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Maputo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'mzn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Metical'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'na'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nam'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Namibia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Windhoek'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ncl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'New Caledonia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Noumea'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xpf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ne'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ner'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Niger'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Niamey'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nfk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Norfolk Island'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kingston'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ng'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nga'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nigeria'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Abuja'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ngn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Naira'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ni'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nic'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nicaragua'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Managua'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nio'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cordoba'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nld'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Netherlands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Amsterdam'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'no'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nor'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Norway'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Oslo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nok'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krone'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'np'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'npl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nepal'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kathmandu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'npr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rupee'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nru'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Nauru'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Yaren'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'niu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Niue'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Alofi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nzd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'nzl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'New Zealand'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Wellington'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nzd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'om'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'omn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Oman'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Muscat'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'omr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rial'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Panama'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Panama City'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'pab'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Balboa'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pe'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'per'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peru'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lima'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'pen'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sol'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pyf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'French Polynesia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Papeete'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xpf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'png'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Papua New Guinea'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Port Moresby'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'pgk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kina'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ph'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'phl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Philippines'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Manila'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'php'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pak'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pakistan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Islamabad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'pkr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rupee'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pol'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Poland'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Warsaw'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'pln'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Zloty'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'spm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Pierre and Miquelon'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint-Pierre'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pcn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pitcairn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Adamstown'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nzd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pri'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Puerto Rico'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'San Juan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ps'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pse'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Palestinian Territory'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'East Jerusalem'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ils'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Shekel'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'prt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Portugal'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lisbon'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'plw'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Palau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Melekeok'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'py'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'pry'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Paraguay'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Asuncion'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'pyg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guarani'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'qa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'qat'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Qatar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Doha'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'qar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rial'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'re'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'reu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Reunion'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint-Denis'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ro'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'rou'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Romania'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bucharest'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ron'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Leu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'rs'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'srb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Serbia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Belgrade'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'rsd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'rus'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Russia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Moscow'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'rub'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ruble'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'rw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'rwa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rwanda'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kigali'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'rwf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saudi Arabia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Riyadh'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'sar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rial'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'slb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Solomon Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Honiara'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'sbd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'syc'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Seychelles'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Victoria'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'scr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rupee'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sdn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sudan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Khartoum'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'sdg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ss'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ssd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'South Sudan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Juba'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ssp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'se'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'swe'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sweden'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Stockholm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'sek'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krona'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sgp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Singapore'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Singapur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'sgd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'shn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Helena'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Jamestown'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'shp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'si'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'svn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Slovenia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ljubljana'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sjm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Svalbard and Jan Mayen'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Longyearbyen'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nok'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Krone'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'svk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Slovakia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bratislava'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sle'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sierra Leone'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Freetown'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'sll'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Leone'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'smr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'San Marino'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'San Marino'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sen'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Senegal'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dakar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'so'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'som'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Somalia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mogadishu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'sos'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Shilling'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Suriname'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Paramaribo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'srd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'st'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'stp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sao Tome and Principe'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sao Tome'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'std'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dobra'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'slv'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'El Salvador'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'San Salvador'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sx'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'sxm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sint Maarten'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Philipsburg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ang'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guilder'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'syr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Syria'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Damascus'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'syp'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pound'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'swz'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Swaziland'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mbabane'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'szl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lilangeni'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tca'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Turks and Caicos Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Cockburn Town'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'td'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Chad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">"N'Djamena"</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xaf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'atf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'French Southern Territories'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Port-aux-Francais'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro '</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tgo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Togo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lome'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xof'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'th'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tha'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Thailand'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bangkok'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'thb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Baht'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tjk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tajikistan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dushanbe'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'tjs'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Somoni'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tkl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tokelau'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'nzd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tls'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'East Timor'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dili'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tkm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Turkmenistan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ashgabat'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'tmt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Manat'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tun'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tunisia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tunis'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'tnd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'to'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ton'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tonga'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">"Nuku'alofa"</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'top'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">"Pa'anga"</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Turkey'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ankara'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'try'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lira'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tto'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Trinidad and Tobago'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Port of Spain'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ttd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tuv'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tuvalu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Funafuti'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'aud'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'twn'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Taiwan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Taipei'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'twd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'tza'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tanzania'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dodoma'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'tzs'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Shilling'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ua'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ukr'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Ukraine'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kiev'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'uah'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Hryvnia'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ug'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'uga'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Uganda'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kampala'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ugx'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Shilling'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'um'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'umi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'United States Minor Outlying Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">''</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar '</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'us'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'usa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'United States'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Washington'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'uy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ury'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Uruguay'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Montevideo'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'uyu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Peso'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'uz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'uzb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Uzbekistan'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tashkent'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'uzs'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Som'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'va'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'vat'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vatican'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vatican City'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'vc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'vct'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Saint Vincent and the Grenadines'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kingstown'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xcd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ve'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ven'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Venezuela'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Caracas'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'vef'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Bolivar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'vg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'vgb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'British Virgin Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Road Town'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'vi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'vir'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'U.S. Virgin Islands'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Charlotte Amalie'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'usd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'vn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'vnm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vietnam'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Hanoi'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'vnd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dong'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'vu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'vut'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vanuatu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Port Vila'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'vuv'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Vatu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'wf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'wlf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Wallis and Futuna'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mata Utu'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'xpf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Franc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ws'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'wsm'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Samoa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Apia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'wst'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Tala'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ye'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'yem'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Yemen'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Sanaa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'yer'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rial'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'yt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'myt'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mayotte'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Mamoudzou'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'eur'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Euro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'zaf'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'South Africa'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Pretoria'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'zar'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Rand'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'zmb'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Zambia'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Lusaka'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'zmk'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Kwacha'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'zwe'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Zimbabwe'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Harare'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'zwl'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dollar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cs'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'scg'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Serbia and Montenegro'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Belgrade'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'rsd'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Dinar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'an'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iso3'</span><span style="color: #339933;">=></span><span style="color: blue;">'ant'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'name'</span><span style="color: #339933;">=></span><span style="color: blue;">'Netherlands Antilles'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'capital'</span><span style="color: #339933;">=></span><span style="color: blue;">'Willemstad'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyCode'</span><span style="color: #339933;">=></span><span style="color: blue;">'ang'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'currencyName'</span><span style="color: #339933;">=></span><span style="color: blue;">'Guilder'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
</pre>
Second one is the Accepted-Language language code to country code:<br />
<br />
<pre class="php" style="font-family: monospace;"><span style="color: #000088;">$languages</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span>
<span style="color: blue;">'aa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dj'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'aa-er'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'er'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ady'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'af'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'na'</span><span style="color: #339933;">,</span><span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ak'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'am'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dj'</span><span style="color: #339933;">,</span><span style="color: blue;">'eh'</span><span style="color: #339933;">,</span><span style="color: blue;">'er'</span><span style="color: #339933;">,</span><span style="color: blue;">'km'</span><span style="color: #339933;">,</span><span style="color: blue;">'tz'</span><span style="color: #339933;">,</span><span style="color: blue;">'ug'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-ae'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ae'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-bh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-dz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-eg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'eg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-il'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'il'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-iq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iq'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-jo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'jo'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-kw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-lb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-ly'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ly'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-ma'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ma'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-mr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-om'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'om'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-ps'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ps'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-qa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'qa'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-sa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sa'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-sd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sd'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-so'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'so'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-sy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sy'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-td'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'td'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-tn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ar-ye'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ye'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'arc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sy'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'as'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'av'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ava'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ay'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bo'</span><span style="color: #339933;">,</span><span style="color: blue;">'pe'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'az'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'az'</span><span style="color: #339933;">,</span><span style="color: blue;">'ge'</span><span style="color: #339933;">,</span><span style="color: blue;">'tr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ba'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bal'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'om'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'be'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'by'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bem'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bho'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'vu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ml'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bn-bd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bd'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'br'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'brh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bs'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ba'</span><span style="color: #339933;">,</span><span style="color: blue;">'me'</span><span style="color: #339933;">,</span><span style="color: blue;">'rs'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'bua'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ca'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">,</span><span style="color: blue;">'fr'</span><span style="color: #339933;">,</span><span style="color: blue;">'ad'</span><span style="color: #339933;">,</span><span style="color: blue;">'it'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cau'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ce'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ch-gu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ch-mp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mp'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'chk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'chm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cmn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'co'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fr'</span><span style="color: #339933;">,</span><span style="color: blue;">'it'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cs'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cs'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'cy-gb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'da'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'is'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'da-dk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'da-fo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fo'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'da-gl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dag'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'de'</span><span style="color: #339933;">,</span><span style="color: blue;">'ar'</span><span style="color: #339933;">,</span><span style="color: blue;">'is'</span><span style="color: #339933;">,</span><span style="color: blue;">'na'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de-at'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'at'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de-be'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'be'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de-ch'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ch'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de-dk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de-it'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'it'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de-li'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'li'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'de-lu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'diq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dje'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ne'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'doi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dta'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mv'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'dz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ee'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gh'</span><span style="color: #339933;">,</span><span style="color: blue;">'tg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'el'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'al'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'el-cy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cy'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'el-gr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gb'</span><span style="color: #339933;">,</span> <span style="color: blue;">'ae'</span><span style="color: #339933;">,</span><span style="color: blue;">'ar'</span><span style="color: #339933;">,</span><span style="color: blue;">'aw'</span><span style="color: #339933;">,</span><span style="color: blue;">'bd'</span><span style="color: #339933;">,</span><span style="color: blue;">'bh'</span><span style="color: #339933;">,</span><span style="color: blue;">'bq'</span><span style="color: #339933;">,</span><span style="color: blue;">'br'</span><span style="color: #339933;">,</span><span style="color: blue;">'cc'</span><span style="color: #339933;">,</span><span style="color: blue;">'cr'</span><span style="color: #339933;">,</span><span style="color: blue;">'cx'</span><span style="color: #339933;">,</span><span style="color: blue;">'cy'</span><span style="color: #339933;">,</span><span style="color: blue;">'dk'</span><span style="color: #339933;">,</span><span style="color: blue;">'eg'</span><span style="color: #339933;">,</span><span style="color: blue;">'gg'</span><span style="color: #339933;">,</span><span style="color: blue;">'gl'</span><span style="color: #339933;">,</span><span style="color: blue;">'gr'</span><span style="color: #339933;">,</span><span style="color: blue;">'gs'</span><span style="color: #339933;">,</span><span style="color: blue;">'hk'</span><span style="color: #339933;">,</span><span style="color: blue;">'id'</span><span style="color: #339933;">,</span><span style="color: blue;">'im'</span><span style="color: #339933;">,</span><span style="color: blue;">'is'</span><span style="color: #339933;">,</span><span style="color: blue;">'je'</span><span style="color: #339933;">,</span><span style="color: blue;">'jo'</span><span style="color: #339933;">,</span><span style="color: blue;">'kh'</span><span style="color: #339933;">,</span><span style="color: blue;">'kr'</span><span style="color: #339933;">,</span><span style="color: blue;">'kw'</span><span style="color: #339933;">,</span><span style="color: blue;">'la'</span><span style="color: #339933;">,</span><span style="color: blue;">'lb'</span><span style="color: #339933;">,</span><span style="color: blue;">'lk'</span><span style="color: #339933;">,</span><span style="color: blue;">'ly'</span><span style="color: #339933;">,</span><span style="color: blue;">'mc'</span><span style="color: #339933;">,</span><span style="color: blue;">'mv'</span><span style="color: #339933;">,</span><span style="color: blue;">'my'</span><span style="color: #339933;">,</span><span style="color: blue;">'ni'</span><span style="color: #339933;">,</span><span style="color: blue;">'np'</span><span style="color: #339933;">,</span><span style="color: blue;">'om'</span><span style="color: #339933;">,</span><span style="color: blue;">'pa'</span><span style="color: #339933;">,</span><span style="color: blue;">'sd'</span><span style="color: #339933;">,</span><span style="color: blue;">'ss'</span><span style="color: #339933;">,</span><span style="color: blue;">'sr'</span><span style="color: #339933;">,</span><span style="color: blue;">'sx'</span><span style="color: #339933;">,</span><span style="color: blue;">'sy'</span><span style="color: #339933;">,</span><span style="color: blue;">'th'</span><span style="color: #339933;">,</span><span style="color: blue;">'tl'</span><span style="color: #339933;">,</span><span style="color: blue;">'tv'</span><span style="color: #339933;">,</span><span style="color: blue;">'tz'</span><span style="color: #339933;">,</span><span style="color: blue;">'vn'</span><span style="color: #339933;">,</span><span style="color: blue;">'an'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ag'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ag'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ai'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ai'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-as'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'as'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-au'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'au'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-bb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-bm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-bn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-bs'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bs'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-bw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-bz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ca'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ca'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ck'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ck'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-cm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-dm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-et'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-fj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fj'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-fk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-fm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-gb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-gd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gd'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-gh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-gi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-gm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-gu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-gy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gy'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ie'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ie'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-il'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'il'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-in'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-io'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'io'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-jm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'jm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ke'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ke'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ki'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ki'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-kn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ky'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ky'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-lc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-lr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ls'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ls'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-mh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-mp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mp'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ms'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ms'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-mt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-mu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-na'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'na'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-nf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ng'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ng'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-nr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-nu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-nz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-pg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ph'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ph'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-pk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-pn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-pr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-pw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-rw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'rw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-sb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-sc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-sg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-sh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-sl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-so'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'so'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-sz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-tc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-tk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-to'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'to'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-tt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ug'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ug'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-um'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'um'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-us'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'us'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-vc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'vc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-vg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'vg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-vi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'vi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-vu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'vu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-ws'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ws'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-za'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-zm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'en-zw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">,</span><span style="color: blue;">'aw'</span><span style="color: #339933;">,</span><span style="color: blue;">'br'</span><span style="color: #339933;">,</span><span style="color: blue;">'bz'</span><span style="color: #339933;">,</span><span style="color: blue;">'gi'</span><span style="color: #339933;">,</span><span style="color: blue;">'qa'</span><span style="color: #339933;">,</span><span style="color: blue;">'tt'</span><span style="color: #339933;">,</span><span style="color: blue;">'an'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-ar'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ar'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-bo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bo'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-cl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-co'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'co'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-cr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-cu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-do'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'do'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-ec'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ec'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-es'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-gq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gq'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-gt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-hn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'hn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-mx'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mx'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-ni'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ni'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-pa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pa'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-pe'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pe'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-pr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-py'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'py'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-sv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sv'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-us'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'us'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-uy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'uy'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'es-ve'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ve'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ee'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'eu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">,</span><span style="color: blue;">'fr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ae'</span><span style="color: #339933;">,</span><span style="color: blue;">'bh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fa-af'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'af'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fa-ir'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ir'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ff'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gm'</span><span style="color: #339933;">,</span><span style="color: blue;">'ng'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'no'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fi-fi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fi-se'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'se'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fia'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sd'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fil'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mp'</span><span style="color: #339933;">,</span><span style="color: blue;">'ph'</span><span style="color: #339933;">,</span><span style="color: blue;">'pw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fj'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dk'</span><span style="color: #339933;">,</span><span style="color: blue;">'fo'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fr'</span><span style="color: #339933;">,</span><span style="color: blue;">'ar'</span><span style="color: #339933;">,</span><span style="color: blue;">'bl'</span><span style="color: #339933;">,</span><span style="color: blue;">'br'</span><span style="color: #339933;">,</span><span style="color: blue;">'eg'</span><span style="color: #339933;">,</span><span style="color: blue;">'gg'</span><span style="color: #339933;">,</span><span style="color: blue;">'gq'</span><span style="color: #339933;">,</span><span style="color: blue;">'gr'</span><span style="color: #339933;">,</span><span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'kh'</span><span style="color: #339933;">,</span><span style="color: blue;">'la'</span><span style="color: #339933;">,</span><span style="color: blue;">'ma'</span><span style="color: #339933;">,</span><span style="color: blue;">'mf'</span><span style="color: #339933;">,</span><span style="color: blue;">'mr'</span><span style="color: #339933;">,</span><span style="color: blue;">'mu'</span><span style="color: #339933;">,</span><span style="color: blue;">'sy'</span><span style="color: #339933;">,</span><span style="color: blue;">'tf'</span><span style="color: #339933;">,</span><span style="color: blue;">'tn'</span><span style="color: #339933;">,</span><span style="color: blue;">'tt'</span><span style="color: #339933;">,</span><span style="color: blue;">'us'</span><span style="color: #339933;">,</span><span style="color: blue;">'va'</span><span style="color: #339933;">,</span><span style="color: blue;">'vc'</span><span style="color: #339933;">,</span><span style="color: blue;">'vn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-be'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'be'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-bf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-bi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-bj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bj'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-ca'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ca'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-cd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cd'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-cf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-cg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-ch'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ch'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-ci'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ci'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-cm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-dj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dj'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-fr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-ga'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ga'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-gf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-gn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-gp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gp'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-ht'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ht'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-it'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'it'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-km'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'km'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-lb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-lu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-mc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-mg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-ml'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ml'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-mq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mq'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-nc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-ne'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ne'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-pf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-pm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-re'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'re'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-rw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'rw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-sc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sc'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-sn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-td'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'td'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-tg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-vu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'vu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-wf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'wf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fr-yt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'yt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'frp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fuc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mr'</span><span style="color: #339933;">,</span><span style="color: blue;">'sn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fud'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'wf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'fy-nl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ga-ie'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ie'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gag'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'md'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gil'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ki'</span><span style="color: #339933;">,</span><span style="color: blue;">'tv'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ar'</span><span style="color: #339933;">,</span><span style="color: blue;">'py'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'gv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'im'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ha'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ne'</span><span style="color: #339933;">,</span><span style="color: blue;">'ng'</span><span style="color: #339933;">,</span><span style="color: blue;">'tg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hak'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'haw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'us'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'he'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'il'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ae'</span><span style="color: #339933;">,</span><span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hna'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hns'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sr'</span><span style="color: #339933;">,</span><span style="color: blue;">'tt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ho'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'at'</span><span style="color: #339933;">,</span><span style="color: blue;">'me'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hr-ba'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ba'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hr-hr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'hr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ht'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ht'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'hu'</span><span style="color: #339933;">,</span><span style="color: blue;">'at'</span><span style="color: #339933;">,</span><span style="color: blue;">'me'</span><span style="color: #339933;">,</span><span style="color: blue;">'ro'</span><span style="color: #339933;">,</span><span style="color: blue;">'rs'</span><span style="color: #339933;">,</span><span style="color: blue;">'sk'</span><span style="color: #339933;">,</span><span style="color: blue;">'ua'</span><span style="color: #339933;">,</span><span style="color: blue;">'cs'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hu-hu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'hu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'am'</span><span style="color: #339933;">,</span><span style="color: blue;">'az'</span><span style="color: #339933;">,</span><span style="color: blue;">'ge'</span><span style="color: #339933;">,</span><span style="color: blue;">'iq'</span><span style="color: #339933;">,</span><span style="color: blue;">'lb'</span><span style="color: #339933;">,</span><span style="color: blue;">'sy'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'hz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'na'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'id'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'id'</span><span style="color: #339933;">,</span><span style="color: blue;">'tl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ig'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ng'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'inc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'inh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'is'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'is'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'it'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'it'</span><span style="color: #339933;">,</span><span style="color: blue;">'ar'</span><span style="color: #339933;">,</span><span style="color: blue;">'gi'</span><span style="color: #339933;">,</span><span style="color: blue;">'ly'</span><span style="color: #339933;">,</span><span style="color: blue;">'mc'</span><span style="color: #339933;">,</span><span style="color: blue;">'so'</span><span style="color: #339933;">,</span><span style="color: blue;">'va'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'it-ch'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ch'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'it-it'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'it'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'it-sm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'iu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ca'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ja'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'jp'</span><span style="color: #339933;">,</span><span style="color: blue;">'pw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'jv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'id'</span><span style="color: #339933;">,</span><span style="color: blue;">'sr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ka'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ge'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kbd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kbp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cd'</span><span style="color: #339933;">,</span><span style="color: blue;">'cf'</span><span style="color: #339933;">,</span><span style="color: blue;">'cg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'km'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kh'</span><span style="color: #339933;">,</span><span style="color: blue;">'vn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ko-kp'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kp'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ko-kr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kok'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kos'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kpg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ne'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'krc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ks'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ku'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'iq'</span><span style="color: #339933;">,</span><span style="color: blue;">'ir'</span><span style="color: #339933;">,</span><span style="color: blue;">'sy'</span><span style="color: #339933;">,</span><span style="color: blue;">'tr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kun'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'er'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'kv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ky'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'la'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'va'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ug'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ln'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cd'</span><span style="color: #339933;">,</span><span style="color: blue;">'cf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ln-cg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'la'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'loz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lt'</span><span style="color: #339933;">,</span><span style="color: blue;">'lv'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lue'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lun'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lus'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'lv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lv'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mdf'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'men'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'meu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mey'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'eh'</span><span style="color: #339933;">,</span><span style="color: blue;">'mr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ck'</span><span style="color: #339933;">,</span><span style="color: blue;">'nz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ml'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'my'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mni'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mnk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gm'</span><span style="color: #339933;">,</span><span style="color: blue;">'sn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mns'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ms-bn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ms-cc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cc'</span><span style="color: #339933;">,</span><span style="color: blue;">'cx'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ms-my'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'my'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ms-sg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'mwl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'my'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'myv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'na'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nan'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'naq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'na'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nb'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'no'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ne'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'np'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'niu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nu'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nkr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nl'</span><span style="color: #339933;">,</span><span style="color: blue;">'bq'</span><span style="color: #339933;">,</span><span style="color: blue;">'cw'</span><span style="color: #339933;">,</span><span style="color: blue;">'id'</span><span style="color: #339933;">,</span><span style="color: blue;">'sx'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nl-an'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'an'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nl-aw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'aw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nl-be'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'be'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nl-nl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'nl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nl-sr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'no'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'no'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'is'</span><span style="color: #339933;">,</span><span style="color: blue;">'no'</span><span style="color: #339933;">,</span><span style="color: blue;">'sj'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nog'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">,</span><span style="color: blue;">'zw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'nso'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ny'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mw'</span><span style="color: #339933;">,</span><span style="color: blue;">'zm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'oc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'es'</span><span style="color: #339933;">,</span><span style="color: blue;">'fr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'om-et'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'or'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'my'</span><span style="color: #339933;">,</span><span style="color: blue;">'pk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pap'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bq'</span><span style="color: #339933;">,</span><span style="color: blue;">'cw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pau'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pl'</span><span style="color: #339933;">,</span><span style="color: blue;">'lt'</span><span style="color: #339933;">,</span><span style="color: blue;">'ua'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pl-pl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pon'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pov'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ps'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'af'</span><span style="color: #339933;">,</span><span style="color: blue;">'pk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pt'</span><span style="color: #339933;">,</span><span style="color: blue;">'bm'</span><span style="color: #339933;">,</span><span style="color: blue;">'gi'</span><span style="color: #339933;">,</span><span style="color: blue;">'je'</span><span style="color: #339933;">,</span><span style="color: blue;">'mo'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-ao'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ao'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-br'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'br'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-cv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cv'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-gw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-mz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-pt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pt'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-st'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'st'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'pt-tl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'qu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bo'</span><span style="color: #339933;">,</span><span style="color: blue;">'pe'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'rm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ch'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'rmm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'rn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ro'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'md'</span><span style="color: #339933;">,</span><span style="color: blue;">'ro'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'rom'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'me'</span><span style="color: #339933;">,</span><span style="color: blue;">'ro'</span><span style="color: #339933;">,</span><span style="color: blue;">'rs'</span><span style="color: #339933;">,</span><span style="color: blue;">'ua'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span><span style="color: blue;">'az'</span><span style="color: #339933;">,</span><span style="color: blue;">'by'</span><span style="color: #339933;">,</span><span style="color: blue;">'ee'</span><span style="color: #339933;">,</span><span style="color: blue;">'ge'</span><span style="color: #339933;">,</span><span style="color: blue;">'kg'</span><span style="color: #339933;">,</span><span style="color: blue;">'kz'</span><span style="color: #339933;">,</span><span style="color: blue;">'lt'</span><span style="color: #339933;">,</span><span style="color: blue;">'lv'</span><span style="color: #339933;">,</span><span style="color: blue;">'md'</span><span style="color: #339933;">,</span><span style="color: blue;">'mn'</span><span style="color: #339933;">,</span><span style="color: blue;">'ru'</span><span style="color: #339933;">,</span><span style="color: blue;">'sj'</span><span style="color: #339933;">,</span><span style="color: blue;">'tj'</span><span style="color: #339933;">,</span><span style="color: blue;">'tm'</span><span style="color: #339933;">,</span><span style="color: blue;">'uz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ru-ua'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ua'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'rw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'rw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sa'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sah'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sat'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sc'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'it'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sd'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'pk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'se'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'no'</span><span style="color: #339933;">,</span><span style="color: blue;">'se'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'si'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'si'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'lk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sid'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sit'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cz'</span><span style="color: #339933;">,</span><span style="color: blue;">'sk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'at'</span><span style="color: #339933;">,</span><span style="color: blue;">'it'</span><span style="color: #339933;">,</span><span style="color: blue;">'si'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'as'</span><span style="color: #339933;">,</span><span style="color: blue;">'tv'</span><span style="color: #339933;">,</span><span style="color: blue;">'ws'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sma'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'se'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'smn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'snk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'so-dj'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'dj'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'so-et'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'so-so'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'so'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sov'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sq'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'al'</span><span style="color: #339933;">,</span><span style="color: blue;">'xk'</span><span style="color: #339933;">,</span><span style="color: blue;">'me'</span><span style="color: #339933;">,</span><span style="color: blue;">'mk'</span><span style="color: #339933;">,</span><span style="color: blue;">'cs'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'rs'</span><span style="color: #339933;">,</span><span style="color: blue;">'hr'</span><span style="color: #339933;">,</span><span style="color: blue;">'xk'</span><span style="color: #339933;">,</span><span style="color: blue;">'me'</span><span style="color: #339933;">,</span><span style="color: blue;">'mk'</span><span style="color: #339933;">,</span><span style="color: blue;">'cs'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sr-ba'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ba'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sre'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'td'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'srn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ss'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ss-sz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'st'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ls'</span><span style="color: #339933;">,</span><span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'is'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sv-ax'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ax'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sv-fi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fi'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sv-se'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'se'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'rw'</span><span style="color: #339933;">,</span><span style="color: blue;">'ug'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sw-ke'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ke'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'sw-tz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'swk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ta'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'lk'</span><span style="color: #339933;">,</span><span style="color: blue;">'my'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ta-sg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'te'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'my'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tem'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tet'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tl'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tj'</span><span style="color: #339933;">,</span><span style="color: blue;">'uz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'th'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'my'</span><span style="color: #339933;">,</span><span style="color: blue;">'th'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ti-er'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'er'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ti-et'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'et'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tig'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'er'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'af'</span><span style="color: #339933;">,</span><span style="color: blue;">'tm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tkl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mp'</span><span style="color: #339933;">,</span><span style="color: blue;">'ph'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tn-bw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'to'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'as'</span><span style="color: #339933;">,</span><span style="color: blue;">'to'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'toi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'zm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tox'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tpi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pg'</span><span style="color: #339933;">,</span><span style="color: blue;">'sb'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'md'</span><span style="color: #339933;">,</span><span style="color: blue;">'mk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tr-bg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'bg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tr-cy'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cy'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tr-tr'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tr'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ts'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tt'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tum'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tut'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span><span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tvl'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tv'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gh'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ty'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'tyv'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'udm'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ug'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'uk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ua'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'uli'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ur'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ae'</span><span style="color: #339933;">,</span><span style="color: blue;">'bh'</span><span style="color: #339933;">,</span><span style="color: blue;">'in'</span><span style="color: #339933;">,</span><span style="color: blue;">'om'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ur-pk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'pk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'uz'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'kg'</span><span style="color: #339933;">,</span><span style="color: blue;">'tm'</span><span style="color: #339933;">,</span><span style="color: blue;">'uz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'uz-af'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'af'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'ve'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'vi'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'vn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'vmw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mz'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'wls'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'wf'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'wo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gm'</span><span style="color: #339933;">,</span><span style="color: blue;">'mr'</span><span style="color: #339933;">,</span><span style="color: blue;">'sn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'woe'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'wof'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'gm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'wuu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'xal'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ru'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'xh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ls'</span><span style="color: #339933;">,</span><span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'yao'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'yap'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'fm'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'yo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ng'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'yue'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">,</span><span style="color: blue;">'hk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'za'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zh'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">,</span><span style="color: blue;">'cx'</span><span style="color: #339933;">,</span><span style="color: blue;">'hk'</span><span style="color: #339933;">,</span><span style="color: blue;">'mo'</span><span style="color: #339933;">,</span><span style="color: blue;">'mp'</span><span style="color: #339933;">,</span><span style="color: blue;">'my'</span><span style="color: #339933;">,</span><span style="color: blue;">'pw'</span><span style="color: #339933;">,</span><span style="color: blue;">'tt'</span><span style="color: #339933;">,</span><span style="color: blue;">'tw'</span><span style="color: #339933;">,</span><span style="color: blue;">'vn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zh-cn'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'cn'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zh-hk'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'hk'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zh-mo'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'mo'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zh-sg'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'sg'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zh-tw'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'tw'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: blue;">'zu'</span><span style="color: #339933;">=></span>array<span style="color: #009900;">(</span>
<span style="color: blue;">'ls'</span><span style="color: #339933;">,</span><span style="color: blue;">'za'</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">,</span>
<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
</pre>
And here is the parser for source file:<br />
<br />
<pre class="php" style="font-family: monospace;">#!/usr/bin/php
<span style="color: black; font-weight: bold;"><?</span>
<span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">(</span><span style="color: blue;">'langcodes.txt'</span><span style="color: #339933;">,</span> <span style="color: blue;">'r'</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$codes</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">(</span><span style="color: #009900;">(</span><span style="color: #000088;">$code</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fgetcsv</span><span style="color: #009900;">(</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: blue;">"t"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">!==</span><span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">)</span>
<span style="color: #000088;">$codes</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$code</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fclose</span><span style="color: #009900;">(</span><span style="color: #000088;">$handle</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$langs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">"<span style="color: #006699; font-weight: bold;">$countries</span> = array(n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">(</span><span style="color: #000088;">$codes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$code</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">(</span><span style="color: #000088;">$code</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" '"</span><span style="color: #339933;">.</span><span style="color: #000088;">$c</span><span style="color: #339933;">.</span><span style="color: blue;">"'=>array(n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" 'iso3'=>'"</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">(</span><span style="color: #000088;">$code</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">.</span><span style="color: blue;">"',n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" 'name'=>'"</span><span style="color: #339933;">.</span><span style="color: #000088;">$code</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">]</span><span style="color: #339933;">.</span><span style="color: blue;">"',n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" 'capital'=>'"</span><span style="color: #339933;">.</span><span style="color: #000088;">$code</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">]</span><span style="color: #339933;">.</span><span style="color: blue;">"',n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" 'currencyCode'=>'"</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">(</span><span style="color: #000088;">$code</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">.</span><span style="color: blue;">"',n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" 'currencyName'=>'"</span><span style="color: #339933;">.</span><span style="color: #000088;">$code</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">11</span><span style="color: #009900;">]</span><span style="color: #339933;">.</span><span style="color: blue;">"',n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" ),n"</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// parse language</span>
<span style="color: #000088;">$lang</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">(</span><span style="color: blue;">","</span><span style="color: #339933;">,</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">(</span><span style="color: #000088;">$code</span><span style="color: #009900;">[</span><span style="color: #cc66cc;">15</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">(</span><span style="color: #000088;">$lang</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$l</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">(</span><span style="color: #000088;">$langs</span><span style="color: #009900;">[</span><span style="color: #000088;">$l</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>
<span style="color: #000088;">$langs</span><span style="color: #009900;">[</span><span style="color: #000088;">$l</span><span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$langs</span><span style="color: #009900;">[</span><span style="color: #000088;">$l</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$c</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">");n"</span><span style="color: #339933;">;</span>
<span style="color: #990000;">ksort</span><span style="color: #009900;">(</span><span style="color: #000088;">$langs</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">"<span style="color: #006699; font-weight: bold;">$languages</span> = array(n"</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">(</span><span style="color: #000088;">$langs</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$langKey</span><span style="color: #339933;">=></span><span style="color: #000088;">$lang</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">" '"</span><span style="color: #339933;">.</span><span style="color: #000088;">$langKey</span><span style="color: #339933;">.</span><span style="color: blue;">"'=>array(n "</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">(</span><span style="color: #000088;">$lang</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$l</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">"'"</span><span style="color: #339933;">.</span><span style="color: #000088;">$l</span><span style="color: #339933;">.</span><span style="color: blue;">"',"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">"n ),n"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">echo</span> <span style="color: blue;">");n"</span><span style="color: #339933;">;</span>
</pre>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-56046895238909298922013-02-28T13:27:00.000+01:002013-02-28T13:28:13.839+01:00Lucene permissions and Hibernate Search / Compass<div style="text-align: justify;">
In our application we have some permissions system, restricting access to various entities for particular users. The permissions system consists of:</div>
<div style="text-align: justify;">
</div>
<ol>
<li>Users - entity contains a list of users that may access it.</li>
<li>Groups - entity contains a list of groups that may access it. Each group contains lists of users belonging to the group and can have subgroups.</li>
<li>Roles - entity contains a list of roles that may access it. Each roles contains list of users having a role, and may have parent roles.</li>
</ol>
<div>
To make it simple and efficient, the User, Group and Role shares one Actor table and have unique ID. The base Actor entity represents Hibernate relation to permitted actors:</div>
<div>
<br /></div>
<div>
<pre style="background-color: #f8f8f8; font-size: 13.333333015441895px; text-align: start;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">SecuredEntity</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Set<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Actor<span class="o" style="color: #ce5c00; font-weight: bold;">></span> getAllPermittedActors<span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="o" style="color: #ce5c00; font-weight: bold;">...;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre>
</div>
<div>
<br /></div>
<div style="text-align: justify;">
How the permissions filtering works internally for DB queries is not a subject of this article, but one can imagine it easily. Additionally we calculate all Id-s for given Actor, and use them in filters:</div>
<div>
<br /></div>
<div>
<pre style="background-color: #f8f8f8; font-size: 13.333333015441895px;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">Actor</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Collection<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">></span> getAllActorIds<span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="o" style="color: #ce5c00; font-weight: bold;">...;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre>
</div>
<div>
<br /></div>
<div style="text-align: justify;">
Now, all important entities are indexed by Lucene using Hibernate Search. It is crucial from security point of view to not to return in search result objects, that the current actor can't access, but Lucene doesn't provide any security mechanism. Hovewer it can be done easily in following way.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First we introduce indexed property, containing all permitted Id-s for given object. Let's define the appropriate interface, returning Id-s for Lucene:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-color: #f8f8f8; font-size: 13.333333015441895px; text-align: start;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">interface</span> <span class="nc">ISearchPerms</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{
</span>
<span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">public</span><span style="font-size: 13.333333015441895px;"> </span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">static</span><span style="font-size: 13.333333015441895px;"> </span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">final</span><span style="font-size: 13.333333015441895px;"> String FIELD_SEARCHPERMS </span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">=</span><span style="font-size: 13.333333015441895px;"> </span><span class="s" style="color: #4e9a06; font-size: 13.333333015441895px;">"searchPerms"</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">static</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">Helper</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">static</span> Set<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">></span> getDefaultSearchPerms<span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Set<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">></span> set <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> HashSet<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">>();</span>
set<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">add</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="mi" style="color: #0000cf; font-weight: bold;">0</span>l<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> set<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<pre style="font-size: 13.333333015441895px;"> <span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">static</span> Set<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">></span> getSearchPermsForActors<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Collection<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Actor<span class="o" style="color: #ce5c00; font-weight: bold;">></span> actors<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Set<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">></span> set <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> HashSet<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">>();</span>
<span class="k" style="color: #204a87; font-weight: bold;">for</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Actor <span class="nl" style="color: #f57900;">a:</span> actors<span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
set<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">add</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>a<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getId</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> set<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}
</span><span style="font-size: 13.333333015441895px;"><span style="color: #ce5c00;"><b>
}
</b></span></span><span style="font-size: 13.333333015441895px;"><span style="color: #ce5c00;"><b>
</b></span>Set</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;"><</span><span style="font-size: 13.333333015441895px;">Long</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">></span><span style="font-size: 13.333333015441895px;"> getSearchPerms</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">();
</span><span style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">
}</span></pre>
</pre>
</div>
<div style="text-align: justify;">
If you have different Id-s in your Actor classes, you may return strings representing Users, Groups and Roles: eg. "U1", "U2", "G1", "G2", "R1", "R2".</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now this interface needs to be implemented in your <span style="font-family: Courier New, Courier, monospace;">@Indexed</span> entities, with <span style="font-family: Courier New, Courier, monospace;">@Field</span> definition for Hibernate Search (or <span style="font-family: Courier New, Courier, monospace;">@SearchableProperty</span> for Compass).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-color: #f8f8f8; font-size: 13.333333015441895px; text-align: start;"><span class="kd" style="font-weight: bold;"><pre style="font-size: 13.333333015441895px; font-weight: normal;"><span class="nd" style="font-weight: bold;"><span style="color: #5c35cc;">@Indexed
</span></span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">public</span><span style="color: black; font-size: 13.333333015441895px;"> </span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">class</span><span style="color: black; font-size: 13.333333015441895px;"> </span><span class="nc" style="color: black; font-size: 13.333333015441895px;">SecuredEntity</span><span style="color: black; font-size: 13.333333015441895px;"> </span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">implements</span><span style="color: black; font-size: 13.333333015441895px;"> ISearchPerms </span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">{
</span><span style="color: #5c35cc; font-size: 13.333333015441895px; font-weight: bold;">
@Override
</span><span class="nd" style="color: #5c35cc; font-size: 13.333333015441895px; font-weight: bold;"> @Field</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">(</span><span style="font-size: 13.333333015441895px;">store </span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">=</span><span style="font-size: 13.333333015441895px;"> Store</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">YES</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">,</span><span style="font-size: 13.333333015441895px;"> name </span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">=</span><span style="font-size: 13.333333015441895px;"> ISearchPerms</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">FIELD_SEARCHPERMS</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">,</span><span style="font-size: 13.333333015441895px;">
</span><span style="font-size: 13.333333015441895px;"> index </span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">=</span><span style="font-size: 13.333333015441895px;"> Index</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">UN_TOKENIZED</span><span class="o" style="font-size: 13.333333015441895px; font-weight: bold;"><span style="color: #ce5c00;">)
</span></span><span class="nd" style="font-size: 13.333333015441895px; font-weight: bold;"><span style="color: #ce5c00;"> </span></span><span class="nd" style="color: #5c35cc; font-size: 13.333333015441895px; font-weight: bold;">@FieldBridge</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">(</span><span style="font-size: 13.333333015441895px;">impl </span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">=</span><span style="font-size: 13.333333015441895px;"> LongCollectionFieldBridge</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">class</span><span class="o" style="font-size: 13.333333015441895px; font-weight: bold;"><span style="color: #ce5c00;">)
</span></span><span class="kd" style="font-size: 13.333333015441895px; font-weight: bold;"><span style="color: #ce5c00;"> </span></span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">public</span><span style="font-size: 13.333333015441895px;"> Set</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;"><</span><span style="font-size: 13.333333015441895px;">Long</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">></span><span style="font-size: 13.333333015441895px;"> getSearchPerms</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">()</span><span style="font-size: 13.333333015441895px;"> </span><span class="o" style="font-size: 13.333333015441895px; font-weight: bold;"><span style="color: #ce5c00;">{
</span></span><span class="k" style="font-size: 13.333333015441895px; font-weight: bold;"><span style="color: #ce5c00;"> </span></span><span class="k" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">return</span><span style="font-size: 13.333333015441895px;"> ISearchPerms</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">Helper</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">getSearchPermsForActors</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">(</span><span style="font-size: 13.333333015441895px;">getAllPermittedActors</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">());
</span><span style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;"> }
</span><span style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">
}</span></pre>
</span></pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For non-secured objects <b>we need the same</b>, but we use common "non-secured-id", ie. 0, what means that the object is not secured, but should be always returned in the search results for all:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div>
<pre style="background-color: #f8f8f8; font-size: 13.333333015441895px; text-align: start;"><span class="kd" style="font-weight: bold;"><pre style="font-size: 13.333333015441895px; font-weight: normal;"><span class="nd" style="font-weight: bold;"><span style="color: #5c35cc;">@Indexed
</span></span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">public</span><span style="color: black; font-size: 13.333333015441895px;"> </span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">class</span><span style="color: black; font-size: 13.333333015441895px;"> Non</span><span class="nc" style="color: black; font-size: 13.333333015441895px;">SecuredEntity</span><span style="color: black; font-size: 13.333333015441895px;"> </span><span class="kd" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">implements</span><span style="color: black; font-size: 13.333333015441895px;"> ISearchPerms </span><span class="o" style="font-size: 13.333333015441895px;"><span style="color: #ce5c00;"><b><span style="color: black;">{</span>
</b></span></span><b><span style="color: #ce5c00;">
</span><span style="color: #5c35cc;">@Override
</span></b><span class="nd" style="color: #5c35cc; font-weight: bold;"> @Field</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>store <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> Store<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">YES</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> name <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> ISearchPerms<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">FIELD_SEARCHPERMS</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
index <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> Index<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">UN_TOKENIZED</span><span class="o" style="color: #ce5c00; font-weight: bold;">)
</span><span class="nd" style="color: #ce5c00; font-weight: bold;"> </span><span class="nd" style="color: #5c35cc; font-weight: bold;">@FieldBridge</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>impl <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> LongCollectionFieldBridge<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">class</span><span class="o" style="color: #ce5c00; font-weight: bold;">)
</span><span class="kd" style="color: #ce5c00; font-weight: bold;"> </span><span class="kd" style="color: #204a87; font-weight: bold;">public</span> Set<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">></span> getSearchPerms<span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{
</span><span class="k" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;"> </span><span class="k" style="color: #204a87; font-size: 13.333333015441895px; font-weight: bold;">return</span><span style="font-size: 13.333333015441895px;"> ISearchPerms</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">Helper</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: 13.333333015441895px;">getDefaultSearchPerms</span><span class="o" style="color: #ce5c00; font-size: 13.333333015441895px; font-weight: bold;">();
</span><span style="color: #ce5c00; font-weight: bold;"> }
</span><span style="color: #ce5c00; font-weight: bold;">
}</span></pre>
</span></pre>
</div>
<div>
<span class="o" style="color: #ce5c00; font-weight: bold;"><br /></span></div>
</div>
<div style="text-align: justify;">
As you can see, we need some field bridge (<span style="font-family: Courier New, Courier, monospace;">LongCollectionFieldBridge</span>) to implement. This is due to Hibernate Search can't map the <span style="font-family: Courier New, Courier, monospace;">Set<Long></span> using default bridges (while Compass has it out-of-the-box; it's unsupported for more than two years from now, though). We map particular <span style="font-family: Courier New, Courier, monospace;">Long</span> from collection to the separate lucene field, with the same name:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-color: #f8f8f8; font-size: 13.333333015441895px; text-align: start;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">LongCollectionFieldBridge</span> <span class="kd" style="color: #204a87; font-weight: bold;">implements</span> FieldBridge<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> StringBridge <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">set</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>String name<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> Object value<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> Document document<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
LuceneOptions luceneOptions<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Collection<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">></span> collection <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Collection<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">>)</span> value<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>collection <span class="o" style="color: #ce5c00; font-weight: bold;">==</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span> <span class="o" style="color: #ce5c00; font-weight: bold;">&&</span> luceneOptions<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">indexNullAs</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">!=</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
luceneOptions<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">addFieldToDocument</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>name<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> luceneOptions<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">indexNullAs</span><span class="o" style="color: #ce5c00; font-weight: bold;">(),</span>
document<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">else</span> <span class="nf">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>collection <span class="o" style="color: #ce5c00; font-weight: bold;">!=</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
<span class="k" style="color: #204a87; font-weight: bold;">for</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Long <span class="nl" style="color: #f57900;">l:</span> collection<span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
luceneOptions<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">addFieldToDocument</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>name<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> l<span class="o" style="color: #ce5c00; font-weight: bold;">+</span><span class="s" style="color: #4e9a06;">""</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> document<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> String <span class="nf">objectToString</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Object object<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>object <span class="k" style="color: #204a87; font-weight: bold;">instanceof</span> Long<span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="o" style="color: #ce5c00; font-weight: bold;">((</span>Long<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> object<span class="o" style="color: #ce5c00; font-weight: bold;">).</span><span class="na" style="color: #c4a000;">toString</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And this is how we have all required to perform Lucene query with permissions filtering (below the example using Hibernate Search <span style="font-family: Courier New, Courier, monospace;">QueryBuilder</span>):</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-color: #f8f8f8; font-size: 13.333333015441895px; text-align: start;"><span class="c1" style="color: #8f5902; font-style: italic;">// query builder
</span>QueryBuilder qb <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> fullTextSession<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getSearchFactory</span><span class="o" style="color: #ce5c00; font-weight: bold;">().</span><span class="na" style="color: #c4a000;">buildQueryBuilder</span><span class="o" style="color: #ce5c00; font-weight: bold;">().
</span><span class="na" style="color: #c4a000;"> forEntity</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>SecuredEntity<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">class</span><span class="o" style="color: #ce5c00; font-weight: bold;">).</span><span class="na" style="color: #c4a000;">get</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
BooleanJunction bool <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> qb<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">bool</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// add query
</span>bool <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> bool<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">must</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>qb<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">keyword</span><span class="o" style="color: #ce5c00; font-weight: bold;">().</span><span class="na" style="color: #c4a000;">onField</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>SomeMyField<span class="o" style="color: #ce5c00; font-weight: bold;">).
</span><span class="na" style="color: #c4a000;"> matching</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"my keywords to search"</span><span class="o" style="color: #ce5c00; font-weight: bold;">).</span><span class="na" style="color: #c4a000;">createQuery</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// filter perms
</span>BooleanJunction permBool <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> qb<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">bool</span><span class="o" style="color: #ce5c00; font-weight: bold;">().</span><span class="na" style="color: #c4a000;">should</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span> <span class="c1" style="color: #8f5902; font-style: italic;">// default perms = no perms, always
</span> qb<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">keyword</span><span class="o" style="color: #ce5c00; font-weight: bold;">().</span><span class="na" style="color: #c4a000;">onField</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>ISearchPerms<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">FIELD_SEARCHPERMS</span><span class="o" style="color: #ce5c00; font-weight: bold;">).</span><span class="na" style="color: #c4a000;">matching</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="mi" style="color: #0000cf; font-weight: bold;">0</span>l<span class="o" style="color: #ce5c00; font-weight: bold;">).</span><span class="na" style="color: #c4a000;">createQuery</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
<span class="k" style="color: #204a87; font-weight: bold;">for</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Long <span class="nl" style="color: #f57900;">id:</span> currentUser<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getAllActorIds</span><span class="o" style="color: #ce5c00; font-weight: bold;">())</span> <span class="c1" style="color: #8f5902; font-style: italic;">// current user perms
</span> permBool <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> permBool<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">should</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>
qb<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">keyword</span><span class="o" style="color: #ce5c00; font-weight: bold;">().</span><span class="na" style="color: #c4a000;">onField</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>ISearchPerms<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">FIELD_SEARCHPERMS</span><span class="o" style="color: #ce5c00; font-weight: bold;">).</span><span class="na" style="color: #c4a000;">matching</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>id<span class="o" style="color: #ce5c00; font-weight: bold;">).
</span><span class="na" style="color: #c4a000;"> createQuery</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
bool <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> bool<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">must</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>permBool<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createQuery</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> bool<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createQuery</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span></pre>
</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com1tag:blogger.com,1999:blog-603254884063001716.post-31486682657851749142012-09-11T19:28:00.000+02:002014-05-09T13:52:21.816+02:00SonOfObsidian color scheme mod for IDEA 11<div style="text-align: justify;">
After latest Eclipse Juno installation, and few weeks of working in this, experiencing big performance downgrade and seeing the direction of current product development (like new fancy UI with animations) I realized that this great product has become an overloaded crap (with installation file growth from 90 MB for Helios to 220 MB for Juno - what can acknowledge this), and after almost 10 years of my Eclipse adventure I decided to look for another IDE. I recently tried to test <a href="http://www.jetbrains.com/idea/" target="_blank">Intellij IDEA 11</a> (commercial), because I've bought already their other product <a href="http://www.jetbrains.com/phpstorm/" target="_blank">PhpStorm</a> (really great IDE for PHP).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Few remarks about this IDE after a week of work:</div>
<div style="text-align: justify;">
<ul>
<li>very fast</li>
<li>great refactoring / code browsing / autocomplete capabilites</li>
<li>highly configurable from A to Z</li>
<li>it has everything I use besides java (html/css, groovy, javascript, properties editor, svn/git integration, tomcat, hibernate/spring suport, trac integration etc.)</li>
</ul>
<div>
And some worse things:</div>
<ul>
<li>very hard to switch from Eclipse because of completely different keymap - but I accomplished fair comfort of work after this week</li>
<li>you need to spend at least a day to configure it for yourself, mainly because it has a big amount of code inspection hints displayed in editor, what makes it looking as the christmas tree (if everything is shown as w warning/hint, you cannot see anything worthful there)</li>
<li>I'd say that product is still wanting in some details, and reported few bugs/feature requests to them (but they are responsible)</li>
</ul>
<div>
But generally I find it a very useful and great IDE.</div>
<div>
<br /></div>
<div>
Unfortunately this IDE doesn't come with color schemes for editors, and only the default color scheme is available. I don't like to burn out my eyes with bright white and prefer some dark schemes. I've found one appropriate on the net - <b><a href="http://www.aremaitchconsulting.com/2011/02/color-schemes-for-intellij-idea/" target="_blank">SonOfObsidian</a></b> - translated from VisualStudio by some guy Roger (thanks, Roger).</div>
<div>
<br /></div>
<div>
Unfortunately after loading it into IDE, it turned out that only the Java editor is done well (in my opinion). Multiple editors have dark font on dark background. On the other hand other editors have a big amount of markers with light background, what completely kills the concept of "dark scheme". During this week of work I was trying to fix the most annoying parts, and make some standards between editors (eg. to have keywords, strings, number in similar colors in various editors), and I changed the font size as well to not to exhaust my eyes so much. Here are some examples of this work (before - after):</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgji0zdLpQ-Sg-I92VqJ-WzGIAVBI1DdFh1I3USt2KNZiXhpKG0Cq9WpB_u-jfQBLa_oHYgM38gGsGFsZhAra-65-Vh4sI1g2RzPUAXupAJY0ZRitVm_KyGti-qiqkx3rY00n90bQ_8xXg/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgji0zdLpQ-Sg-I92VqJ-WzGIAVBI1DdFh1I3USt2KNZiXhpKG0Cq9WpB_u-jfQBLa_oHYgM38gGsGFsZhAra-65-Vh4sI1g2RzPUAXupAJY0ZRitVm_KyGti-qiqkx3rY00n90bQ_8xXg/s640/1.png" height="136" width="640" /></a></div>
<div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhLT25jBHl5A3pwNGYi16xLp4Li3JFRzwKJMfWtai9CEM2EDy_iIDk3jSDtKbTKFeBSsMsUykSckjsvVPEFSwJLGKMmxqBHGdj2K9aDk6ZkU4lqh1uxKdVLQeynO0q1dev9W9QBgKPu60/s1600/1m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhLT25jBHl5A3pwNGYi16xLp4Li3JFRzwKJMfWtai9CEM2EDy_iIDk3jSDtKbTKFeBSsMsUykSckjsvVPEFSwJLGKMmxqBHGdj2K9aDk6ZkU4lqh1uxKdVLQeynO0q1dev9W9QBgKPu60/s640/1m.png" height="174" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh76oplKULwk6iBJ5eKJ8pP4halrJP8pxBgrIw5QIblySSsG-zzGmFwavhyB_0c7cmq7P9Vb7fcgTJm9kzwmod0OmnkG2DYJ_U2xKe-hVG-bRNaa-wArgWY20-hOjLCgABerj68ZylX3z0/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh76oplKULwk6iBJ5eKJ8pP4halrJP8pxBgrIw5QIblySSsG-zzGmFwavhyB_0c7cmq7P9Vb7fcgTJm9kzwmod0OmnkG2DYJ_U2xKe-hVG-bRNaa-wArgWY20-hOjLCgABerj68ZylX3z0/s640/2.png" height="630" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcxrl1bKC8vRDB6hARRs85VrzedayJpHBlEeqINHdlYe7TbIYFqBiryinB5zBfA2j8bHC_9Qn3AJsHIarPlIzDZaM39eHlMhc2Nd6h_ZFiI1NqVkjLVs7_tFOpBHfrer73dagR_-HX7Ok/s1600/2m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcxrl1bKC8vRDB6hARRs85VrzedayJpHBlEeqINHdlYe7TbIYFqBiryinB5zBfA2j8bHC_9Qn3AJsHIarPlIzDZaM39eHlMhc2Nd6h_ZFiI1NqVkjLVs7_tFOpBHfrer73dagR_-HX7Ok/s640/2m.png" height="640" width="618" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg27jhZOxAmMBxDqGLwg9vZwphbNmtcL3d6gi1sIAQAa_TJ4_a0hZ79wORN_3xuJVgbnQfzC74rQC2c_WHMLw50eJc3sXjYyrFEimJvm1UC43xgTqMkoJXughySQY3rfVv7bJU5TmHv8PM/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg27jhZOxAmMBxDqGLwg9vZwphbNmtcL3d6gi1sIAQAa_TJ4_a0hZ79wORN_3xuJVgbnQfzC74rQC2c_WHMLw50eJc3sXjYyrFEimJvm1UC43xgTqMkoJXughySQY3rfVv7bJU5TmHv8PM/s640/3.png" height="292" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCkZ_CZB1uP-PlbpKpVdO6rVXlp3KqNVaSvVPDwi_IxxIS_j1OgChaEiafY30O6wxo-R6o90zenZqFLiqzSxzfbTi1YVb05Kzxbictn9aMPXt4Xx_R8htKeZ9kSJ-4jXT0p5owoo3Ckyw/s1600/3m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCkZ_CZB1uP-PlbpKpVdO6rVXlp3KqNVaSvVPDwi_IxxIS_j1OgChaEiafY30O6wxo-R6o90zenZqFLiqzSxzfbTi1YVb05Kzxbictn9aMPXt4Xx_R8htKeZ9kSJ-4jXT0p5owoo3Ckyw/s640/3m.png" height="296" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1oVAckgljrCyvx0UEJcc1SRvlZ2FrJ0NiiFebhz7EKOvSDfZcHeAKfpU-FdYmvXWzGgiYuQMh61CFYDDvHVYZxV7WTRiHnTnKdrTvzTBcCSX4hijXeRy0imy0ymfLgGSnixtxppMhiAQ/s1600/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1oVAckgljrCyvx0UEJcc1SRvlZ2FrJ0NiiFebhz7EKOvSDfZcHeAKfpU-FdYmvXWzGgiYuQMh61CFYDDvHVYZxV7WTRiHnTnKdrTvzTBcCSX4hijXeRy0imy0ymfLgGSnixtxppMhiAQ/s640/4.png" height="300" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqxe_H2zVLsT5KAtJNTpHrNuNlXp7xnN_r-uJf6Sqxel5LSf2ISXPLyumbeJQ2FG86wIblVWBLcXFlbKIb2Q9XONizfL8Ek8ErXNL2PwQ7e0htap6ax52CuE9pQ_lxOVUFmaA_TAwMybo/s1600/4m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqxe_H2zVLsT5KAtJNTpHrNuNlXp7xnN_r-uJf6Sqxel5LSf2ISXPLyumbeJQ2FG86wIblVWBLcXFlbKIb2Q9XONizfL8Ek8ErXNL2PwQ7e0htap6ax52CuE9pQ_lxOVUFmaA_TAwMybo/s640/4m.png" height="322" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHeKGLRirQzmkLSwbMazAftn7GnSu-AkN6brwVjqdsVFQ3Bux9rUzl32x2EDSLmqdbl6w0nKc8K9ZYGDiIxbAh8VQ1DcFgzgFXbcPmb2LW0lCZgvxxA71F472nO2a-azbwZ31Ue5psd7M/s1600/5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHeKGLRirQzmkLSwbMazAftn7GnSu-AkN6brwVjqdsVFQ3Bux9rUzl32x2EDSLmqdbl6w0nKc8K9ZYGDiIxbAh8VQ1DcFgzgFXbcPmb2LW0lCZgvxxA71F472nO2a-azbwZ31Ue5psd7M/s640/5.png" height="207" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFrDsmnXLW1ehe6ltbBuFwAacPJRZW26FPMtvuwUC-hlX0FbrjSVT0F_4gJpRKfQxQxgqdrGNkqtm_GVrwOYPWV6ICEf0uwwQM_O8SbKab4D57hBTQ09kVYNof6mCruXljP0ZB4USiPy8/s1600/5m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFrDsmnXLW1ehe6ltbBuFwAacPJRZW26FPMtvuwUC-hlX0FbrjSVT0F_4gJpRKfQxQxgqdrGNkqtm_GVrwOYPWV6ICEf0uwwQM_O8SbKab4D57hBTQ09kVYNof6mCruXljP0ZB4USiPy8/s640/5m.png" height="210" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjutEY9GIiFp1LzIjV2VOlBpelBVV8wCFMDhanUvLpr8qGASWflRaNMOc_OVnrDBK2XsePG3sETPoDbYMFLT4STXCax4Oo2KhX8h_iKX-x0n5_ipPkyhCU6jKfVFCis6fw6_zM1Y2C0CS4/s1600/6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjutEY9GIiFp1LzIjV2VOlBpelBVV8wCFMDhanUvLpr8qGASWflRaNMOc_OVnrDBK2XsePG3sETPoDbYMFLT4STXCax4Oo2KhX8h_iKX-x0n5_ipPkyhCU6jKfVFCis6fw6_zM1Y2C0CS4/s640/6.png" height="378" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_w1Mz4H7GIdb2EzKkqz_O_1z7IA6eSj1WwBVIgAcWJdddD-hg9fCiZKtk7YcDC9lXMEfAQwjZQiNbgrXy6PGr_8vX6mkGWDVUqL9NK037zimV0KdZepmS_ug52qkpmsJTfmbHPDH1YaY/s1600/6m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_w1Mz4H7GIdb2EzKkqz_O_1z7IA6eSj1WwBVIgAcWJdddD-hg9fCiZKtk7YcDC9lXMEfAQwjZQiNbgrXy6PGr_8vX6mkGWDVUqL9NK037zimV0KdZepmS_ug52qkpmsJTfmbHPDH1YaY/s640/6m.png" height="374" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj84dkouuq8TGiCgzHD9hI8VfBLzCq9Q9ZDC4oVtGnyZFUxSbOsBcQhZ2AP00ngK_ltCrgT8tl-xw5p-cB6W-ZvW3DJqy3e3CpBH8maUS3D_-D8KqUef-JxF0vYDIRXN6QdirZ4zu80ClE/s1600/7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj84dkouuq8TGiCgzHD9hI8VfBLzCq9Q9ZDC4oVtGnyZFUxSbOsBcQhZ2AP00ngK_ltCrgT8tl-xw5p-cB6W-ZvW3DJqy3e3CpBH8maUS3D_-D8KqUef-JxF0vYDIRXN6QdirZ4zu80ClE/s640/7.png" height="350" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi02m9czSl38wkPHybstZ6uMFKeLNDDMHVs9igcmgbdZH_BI7PfcfvV6LX2Bc0j4ErKYA7Mn9gdpnFcXt0MetCDHJrgqyYqBiNCExfGyFVDUKShEOTQHTNPVqsRZJyxgpvPpWy3LE2lw9E/s1600/7m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi02m9czSl38wkPHybstZ6uMFKeLNDDMHVs9igcmgbdZH_BI7PfcfvV6LX2Bc0j4ErKYA7Mn9gdpnFcXt0MetCDHJrgqyYqBiNCExfGyFVDUKShEOTQHTNPVqsRZJyxgpvPpWy3LE2lw9E/s640/7m.png" height="378" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqTIA8kxsUJqC5qhj6WGrU_SkbMxRGWYvluEBKmqT1zCNQz8cZWXmpMkKOTJmjRwh1L9fP-wggOT24bWHaWImNIflXXNu0bz5PkGvpUAljBpGRIjpCU2HiMCUx__3wkKHmm1pe9neX_nY/s1600/8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqTIA8kxsUJqC5qhj6WGrU_SkbMxRGWYvluEBKmqT1zCNQz8cZWXmpMkKOTJmjRwh1L9fP-wggOT24bWHaWImNIflXXNu0bz5PkGvpUAljBpGRIjpCU2HiMCUx__3wkKHmm1pe9neX_nY/s640/8.png" height="110" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZT64S-8WYFA58WNE85hdVK-Wm-HNJYI7HofnqRTXqfzSupFhKoUEPbxoPzjQcfwqwEniwTmgRFFu2NnydiOiHqmbF5RhWHhgDjEpH23n7_il9IaJfXmubyHoG3bynsCXPcxJ8NJQlbPs/s1600/8m.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZT64S-8WYFA58WNE85hdVK-Wm-HNJYI7HofnqRTXqfzSupFhKoUEPbxoPzjQcfwqwEniwTmgRFFu2NnydiOiHqmbF5RhWHhgDjEpH23n7_il9IaJfXmubyHoG3bynsCXPcxJ8NJQlbPs/s640/8m.png" height="146" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://sites.google.com/site/lifeinide/home/SonOfObsidian_l0co.xml?attredirects=0&d=1">Here</a> are the sources for those who share my preferences. They need to be put into <i>~/.IntelliJIdea11/config/colors</i>.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
[UPDATE] <a href="https://sites.google.com/site/lifeinide/home/SonOfObsidian_idea13.zip?attredirects=0&d=1">Here</a> is the update for Idea 13. </div>
</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-72367671742662532912012-08-22T21:26:00.001+02:002016-12-25T17:03:21.441+01:00javax.mail and plain, STARTTLS, SSL/TSL connection for POP3 and SMTP without keystore<div style="text-align: justify;">
Today my target was to implement various connections for POP3/SMTP email accounts. incuding:</div>
<ul>
<li>plain connection with no encryption</li>
<li>STARTTLS</li>
<li>SSL/TSL</li>
</ul>
<div style="text-align: justify;">
The key requirement here was to have it without java <b>keystore</b> file configured for storing and accepting server certificates. This should work transparently for the user.</div>
<div>
<br /></div>
<div style="text-align: justify;">
Having dug through tons of not working examples on the net, and after trying figure out some solutions by trial and error, I decided to take my Plain Old Eclipse Debugger and dive into the javax.mail classes. Here are quick results of HOWTO.</div>
<div>
<br /></div>
<div style="text-align: justify;">
The environment you need is <b>Java Mail API 1.4.5</b> (1.4 doesn't work properly, due to inability to set custom socket factory for STARTTLS). On the other hand, I don't use plain SMTP connection, but Spring <b>JavaMailSender</b>, but it has exactly the same config (with properties).</div>
<h2>
AlwaysTrustSSLContextFactory</h2>
<div style="text-align: justify;">
First thing to have for encrypted connection is to have SSLContextFactory, that trusts all certificates, to skip the verification stage (this is not required for my application). Here is the code:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px; text-align: -webkit-auto;"><span class="kn" style="color: #204a87; font-weight: bold;">package</span> com<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">blogspot</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">lifeinide</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.io.IOException</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.net.InetAddress</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.net.Socket</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.net.UnknownHostException</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.security.KeyManagementException</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.security.NoSuchAlgorithmException</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.security.SecureRandom</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.security.cert.CertificateException</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.security.cert.X509Certificate</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">javax.net.SocketFactory</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">javax.net.ssl.KeyManager</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">javax.net.ssl.SSLContext</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">javax.net.ssl.SSLSocketFactory</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">javax.net.ssl.TrustManager</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">javax.net.ssl.X509TrustManager</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/**
* SSL socket factory accepting any certificate.
*/</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">AlwaysTrustSSLContextFactory</span> <span class="kd" style="color: #204a87; font-weight: bold;">extends</span> SSLSocketFactory <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">private</span> SSLSocketFactory factory<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">static</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">DefaultTrustManager</span> <span class="kd" style="color: #204a87; font-weight: bold;">implements</span> X509TrustManager <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">checkClientTrusted</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>X509Certificate<span class="o" style="color: #ce5c00; font-weight: bold;">[]</span> arg0<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> String arg1<span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
<span class="kd" style="color: #204a87; font-weight: bold;"> throws</span> CertificateException <span class="o" style="color: #ce5c00; font-weight: bold;">{}</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">checkServerTrusted</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>X509Certificate<span class="o" style="color: #ce5c00; font-weight: bold;">[]</span> arg0<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> String arg1<span class="o"><span style="color: #ce5c00;"><b>)</b></span>
</span><span class="kd"> </span><span class="kd" style="color: #204a87; font-weight: bold;">throws</span> CertificateException <span class="o" style="color: #ce5c00; font-weight: bold;">{}</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> X509Certificate<span class="o" style="color: #ce5c00; font-weight: bold;">[]</span> <span class="nf">getAcceptedIssuers</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> X509Certificate<span class="o" style="color: #ce5c00; font-weight: bold;">[</span><span class="mi" style="color: #0000cf; font-weight: bold;">0</span><span class="o" style="color: #ce5c00; font-weight: bold;">];</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="nf">AlwaysTrustSSLContextFactory</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span>
<span class="kd" style="color: #204a87; font-weight: bold;"> throws</span> NoSuchAlgorithmException<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> KeyManagementException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">super</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
SSLContext ctx <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> SSLContext<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getInstance</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"TLS"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
ctx<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">init</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="k" style="color: #204a87; font-weight: bold;">new</span> KeyManager<span class="o" style="color: #ce5c00; font-weight: bold;">[</span><span class="mi" style="color: #0000cf; font-weight: bold;">0</span><span class="o" style="color: #ce5c00; font-weight: bold;">],</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> TrustManager<span class="o" style="color: #ce5c00; font-weight: bold;">[]</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{
</span><span class="k" style="color: #204a87; font-weight: bold;"> new</span> DefaultTrustManager<span class="o" style="color: #ce5c00; font-weight: bold;">()},</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> SecureRandom<span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
factory <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>SSLSocketFactory<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> ctx<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getSocketFactory</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">static</span> SocketFactory <span class="nf">getDefault</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">try</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> <span class="nf">AlwaysTrustSSLContextFactory</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">catch</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Exception e<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">throw</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> <span class="nf">RuntimeException</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Cannot instantiate default AlwaysTrustSSLContextFactory"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> e<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Socket <span class="nf">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IOException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Socket <span class="nf">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>InetAddress address<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kt" style="color: #204a87; font-weight: bold;">int</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
InetAddress localAddress<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kt" style="color: #204a87; font-weight: bold;">int</span> localPort<span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
<span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IOException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>address<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> localAddress<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> localPort<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Socket <span class="nf">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>InetAddress host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kt" style="color: #204a87; font-weight: bold;">int</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IOException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Socket <span class="nf">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Socket s<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> String host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kt" style="color: #204a87; font-weight: bold;">int</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
<span class="kt" style="color: #204a87; font-weight: bold;"> boolean</span> autoClose<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IOException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>s<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> autoClose<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Socket <span class="nf">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>String host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kt" style="color: #204a87; font-weight: bold;">int</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> InetAddress localHost<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
<span class="kt" style="color: #204a87; font-weight: bold;"> int</span> localPort<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IOException<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> UnknownHostException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> localHost<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> localPort<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Socket <span class="nf">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>String host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kt" style="color: #204a87; font-weight: bold;">int</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IOException<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
UnknownHostException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createSocket</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">boolean</span> <span class="nf">equals</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Object obj<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">equals</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>obj<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> String<span class="o" style="color: #ce5c00; font-weight: bold;">[]</span> <span class="nf">getDefaultCipherSuites</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getDefaultCipherSuites</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> String<span class="o" style="color: #ce5c00; font-weight: bold;">[]</span> <span class="nf">getSupportedCipherSuites</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> factory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getSupportedCipherSuites</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The funny part is that the <b>getDefault()</b> static method is crucial here, because javax.mail classes get the SSLContextFactory from this static method, and not by creating the object using constructor. This is a big trap here that can consume a lot of time to conceive. This also can reveal how the rest of sources are written, what is pretty bad for me (strange initializations by static methods and poorly described string properties, with which you can build a lot of combinations to try make it work).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now, without a lot of complaining more, the revealed solutions. The thing we want to achieve is to get the connected <b>javax.mail.Store</b> from <b>javax.mail.Session</b> to work with POP3, and configured <b>JavaMailSender</b> (with javax.mail properties) for SMTP.</div>
<h2>
Plain connection</h2>
<div>
The easiest one. Implementation for POP3:</div>
<div>
<br /></div>
<div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;">Session session <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> Session<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getDefaultInstance</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="k" style="color: #204a87; font-weight: bold;">new</span> Properties<span class="o" style="color: #ce5c00; font-weight: bold;">(),</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Store store <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> session<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getStore</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"pop3"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
store<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">connect</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> username<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> password<span class="o" style="color: #ce5c00; font-weight: bold;">);</span><span style="color: #204a87;"><b>
</b></span></pre>
</div>
<div>
<br /></div>
<div>
And SMTP:</div>
<div>
<br /></div>
<div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;">JavaMailSenderImpl sender <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> JavaMailSenderImpl<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setHost</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>host<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setUsername</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>username<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setPassword</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>password<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setPort</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Properties props <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> Properties<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtp.auth"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> "true"<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setJavaMailProperties</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>props<span class="o" style="color: #ce5c00; font-weight: bold;">);</span></pre>
</div>
<h2>
SSL/TLS</h2>
<div>
Now the version working from the beginning through secure channel. POP3:</div>
<div>
<br /></div>
<div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;">Properties props <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> Properties<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.pop3s.socketFactory.class"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"com.blogspot.lifeinide.AlwaysTrustSSLContextFactory"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.pop3s.socketFactory.port"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.pop3.ssl.enable"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"true"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
URLName url <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> URLName<span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"pop3s"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">""</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> username<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> password<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Session session <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> Session<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getInstance</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>props<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Store store <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> session<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getStore</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>url<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
store<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">connect</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span></pre>
</div>
<div>
<br /></div>
<div>
And the SMTP likewise:</div>
<div>
<br /></div>
<div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;">JavaMailSenderImpl sender <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> JavaMailSenderImpl<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setHost</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>host<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setUsername</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>username<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setPassword</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>password<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setPort</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Properties props <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> Properties<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProtocol</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"smtps"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtps.auth"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"true"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtps.socketFactory.class"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"com.blogspot.lifeinide.AlwaysTrustSSLContextFactory"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtps.socketFactory.port"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtp.ssl.enable"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"true"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setJavaMailProperties</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>props<span class="o" style="color: #ce5c00; font-weight: bold;">);</span></pre>
</div>
<h2>
STARTTLS</h2>
<div>
The last one. POP3 version:</div>
<div>
<br /></div>
<div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;">Properties props <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> Properties<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.pop3.ssl.socketFactory.class"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"com.blogspot.lifeinide.AlwaysTrustSSLContextFactory"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.pop3.ssl.socketFactory.port"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.pop3.starttls.enable"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"true"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
URLName url <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> URLName<span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"pop3"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> host<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">""</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> username<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> password<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Session session <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> Session<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getInstance</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>props<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Store store <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> session<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getStore</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>url<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
store<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">connect</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span></pre>
</div>
<div>
<br /></div>
<div>
And SMTP:</div>
<div>
<br /></div>
<div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;">JavaMailSenderImpl sender <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> JavaMailSenderImpl<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setHost</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>host<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setUsername</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>username<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setPassword</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>password<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setPort</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Properties props <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> Properties<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtp.auth"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"true"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtp.ssl.socketFactory.class"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"com.blogspot.lifeinide.AlwaysTrustSSLContextFactory"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtp.ssl.socketFactory.port"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> port<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
props<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setProperty</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"mail.smtp.starttls.enable"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="s" style="color: #4e9a06;">"true"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
sender<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setJavaMailProperties</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>props<span class="o" style="color: #ce5c00; font-weight: bold;">);</span></pre>
</div>
<div>
<br /></div>
<div>
Looking for amount of questions and not working examples on the net, and amount of time I needed to solve it, the guys implemented it this way should get the prize for one of the most obscure solutions in java I was working with.</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com3tag:blogger.com,1999:blog-603254884063001716.post-91555255453961358822012-07-05T12:49:00.000+02:002012-08-22T21:37:41.034+02:00Spring 3 and Mule 2 initialized by SpringXmlConfigurationBuilder<div style="text-align: justify;">
If you have a Spring 2 application using MuleESB in 2.x version, and you initialize the mule using <span style="font-family: 'Courier New', Courier, monospace;">SpringXmlConfigurationBuilder</span>, ie. something like this:
</div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">startMule</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> MuleException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
SpringXmlConfigurationBuilder builder <span class="o" style="color: #ce5c00; font-weight: bold;">=</span>
<span class="k" style="color: #204a87; font-weight: bold;"> new</span> SpringXmlConfigurationBuilder<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>muleConfigResources<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>applicationContext<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
MuleContextFactory muleContextFactory <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> DefaultMuleContextFactory<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
muleContext <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> muleContextFactory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createMuleContext</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>builder<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
runtimeConfig<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>muleContext<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
muleContext<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">start</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre>
You may notice that this simply doesn't work in Spring 3;)<br />
After a lot of struggling I've discovered that this is because the <span style="font-family: 'Courier New', Courier, monospace;">DefaultBeanDefinitionDocumentReader</span> interface in spring has been changed from:<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;"><span class="kd" style="color: #204a87; font-weight: bold;">protected</span> BeanDefinitionParserDelegate <span class="nf">createHelper</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>XmlReaderContext readerContext<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> Element root<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">...</span>
</pre>
to:<br />
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;"><span class="kd" style="color: #204a87; font-weight: bold;">protected</span> BeanDefinitionParserDelegate <span class="nf">createHelper</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>XmlReaderContext readerContext<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> Element root<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> BeanDefinitionParserDelegate parentDelegate<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">...</span></pre>
<div style="text-align: justify;">
I don't want to migrate my whole application MuleESB 3.x, what seems to have Spring 3 compatible classes, so some fixes to existing mule initialization were required here. For those interested in the same, here is the solution:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: -webkit-auto;">
</div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; font-size: 13px;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">startMule</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> MuleException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Spring3XmlConfigurationBuilder builder <span class="o" style="color: #ce5c00; font-weight: bold;">=</span>
<span class="k" style="color: #204a87; font-weight: bold;"> new</span> Spring3XmlConfigurationBuilder<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>muleConfigResources<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>applicationContext<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
MuleContextFactory muleContextFactory <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> DefaultMuleContextFactory<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
muleContext <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> muleContextFactory<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">createMuleContext</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>builder<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
runtimeConfig<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>muleContext<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
muleContext<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">start</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre>
<div style="text-align: justify;">
For this you actually need to use my classes fixing this issue - they are available to download <a href="https://sites.google.com/site/lifeinide/home/spring3mule2.tar.gz">here</a>.</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-39163888943257220942012-06-22T18:02:00.000+02:002012-06-22T18:04:34.303+02:00High-availability architecure with mysql replication and C3P0<div style="text-align: justify;">
I've recently had a requirement of setting up the application to work in high-availability environment, which among the others involved hardiness for database (mysql) crash. We established with the customer that we want to have a second database server, where the mysql database mirror will be maintained, using <a href="http://dev.mysql.com/doc/refman/5.0/en/replication.html" target="_blank">master-slave mysql replication</a>. In this model the master mysql server takes care of synchronizing records from itself to the slave server, and the slave server is available in fail-scenario for the application in read-only mode.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is about database, but what about the code? If you establish a database connection each time the request comes, it sound easy, but we are talking about the Tomcat/Spring/Hibernate application with <i>SessionFactory</i> connected to polled<span style="background-color: white;"> JDBC datasource through </span><a href="http://www.mchange.com/projects/c3p0/" style="background-color: white;" target="_blank">c3p0 connection polling library</a>. <span style="background-color: white;">However, I realized that c3p0 allows to change the JDBC connection params on-the-fly, and when it is done, it resets the existing poll. In such scenario, new connection acquiring requests will be directed to empty poll, and new connections will be established with overwritten parameters.</span></div>
<div style="text-align: justify;">
<span style="background-color: white;"><br /></span></div>
<div style="text-align: justify;">
Therefore, the emerging idea was just to implement the connection supervisor, which can change the main c3p0 <i>ComboPooledDataSource</i> settings, when one of databases is unavailable. The implementation is below.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First class is only the connection configuration class:</div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial;"><span style="font-size: x-small;"><span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">com.mchange.v2.c3p0.ComboPooledDataSource</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">C3P0SupervisorConnectionConfig</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> String user<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> String password<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> String jdbcUrl<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/** Whether connection is read-only. */</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">boolean</span> readonly <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="kc" style="color: #204a87; font-weight: bold;">false</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="nf">C3P0SupervisorConnectionConfig</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">super</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="nf">C3P0SupervisorConnectionConfig</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>ComboPooledDataSource pds<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
<span class="kt"> </span><span class="kt" style="color: #204a87; font-weight: bold;">boolean</span> readonly<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{
</span><span class="k" style="color: #ce5c00; font-weight: bold;"> </span><span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">user</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> pds<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getUser</span><span class="o" style="color: #ce5c00; font-weight: bold;">();
</span><span class="k" style="color: #ce5c00; font-weight: bold;"> </span><span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">password</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> pds<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getPassword</span><span class="o" style="color: #ce5c00; font-weight: bold;">();
</span><span class="k" style="color: #ce5c00; font-weight: bold;"> </span><span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">jdbcUrl</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> pds<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getJdbcUrl</span><span class="o" style="color: #ce5c00; font-weight: bold;">();
</span><span class="k" style="color: #ce5c00; font-weight: bold;"> </span><span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">readonly</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> readonly<span class="o" style="color: #ce5c00; font-weight: bold;">;
</span><span style="color: #ce5c00; font-weight: bold;"> }
</span><i style="color: #8f5902;">
/** Let's omit here the getters and setters, doing nothing */
</i><span style="color: #ce5c00; font-weight: bold;">
}</span></span></pre>
<div>
<span style="background-color: white;">Then the supervisor itself.</span><br />
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial;"><span style="font-size: x-small;"><span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.sql.Connection</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.sql.DriverManager</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.sql.SQLException</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.util.Map</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">java.util.TreeMap</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">org.apache.log4j.Logger</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">org.quartz.JobDetail</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">org.springframework.beans.factory.BeanInitializationException</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">org.springframework.beans.factory.InitializingBean</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kn" style="color: #204a87; font-weight: bold;">import</span> <span class="nn">com.mchange.v2.c3p0.ComboPooledDataSource</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc">C3P0Supervisor</span> <span class="kd" style="color: #204a87; font-weight: bold;">implements</span> InitializingBean <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">static</span> <span class="kd" style="color: #204a87; font-weight: bold;">final</span> Logger logger <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> Logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getLogger</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>C3P0Supervisor<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">class</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/**
* Connections configuration with priorities.
*/</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> Map<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Integer<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> C3P0SupervisorConnectionConfig<span class="o" style="color: #ce5c00; font-weight: bold;">></span> connections<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/**
* Main datasource.
*/</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> ComboPooledDataSource pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/**
* Which one is live currently.
*/</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">int</span> live <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="mi" style="color: #0000cf; font-weight: bold;">0</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">afterPropertiesSet</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> Exception <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">==</span><span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
<span class="k" style="color: #204a87; font-weight: bold;">throw</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> <span class="nf">BeanInitializationException</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Pooled datasource cannot be null for C3P0Supervisor"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>connections<span class="o" style="color: #ce5c00; font-weight: bold;">!=</span><span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
connections <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> TreeMap<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Integer<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> C3P0SupervisorConnectionConfig<span class="o" style="color: #ce5c00; font-weight: bold;">>(</span>connections<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>connections<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">get</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="mi" style="color: #0000cf; font-weight: bold;">0</span><span class="o" style="color: #ce5c00; font-weight: bold;">)==</span><span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
connections<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">put</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="mi" style="color: #0000cf; font-weight: bold;">0</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> C3P0SupervisorConnectionConfig<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="kc" style="color: #204a87; font-weight: bold;">false</span><span class="o" style="color: #ce5c00; font-weight: bold;">));</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">poll</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">isDebugEnabled</span><span class="o" style="color: #ce5c00; font-weight: bold;">())</span>
logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">debug</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Starts polling JDBC connections..."</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">for</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Integer <span class="nl" style="color: #f57900;">priority:</span> connections<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">keySet</span><span class="o" style="color: #ce5c00; font-weight: bold;">())</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
C3P0SupervisorConnectionConfig cfg <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> connections<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">get</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>priority<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>test<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>cfg<span class="o" style="color: #ce5c00; font-weight: bold;">))</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// the connection was tested and it's current connection
</span> <span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>live <span class="o" style="color: #ce5c00; font-weight: bold;">==</span> priority<span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// something happened
</span> <span class="k" style="color: #204a87; font-weight: bold;">else</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>priority<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>live<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">isInfoEnabled</span><span class="o" style="color: #ce5c00; font-weight: bold;">())</span>
logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">info</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>String<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">format</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Higher priority connection: %d than "</span> <span class="o" style="color: #ce5c00; font-weight: bold;">+</span>
<span class="s" style="color: #4e9a06;">"current: %d is available again, reconnecting to: %s"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
priority<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> live<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getJdbcUrl</span><span class="o" style="color: #ce5c00; font-weight: bold;">()));</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">else</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">isInfoEnabled</span><span class="o" style="color: #ce5c00; font-weight: bold;">())</span>
logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">info</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>String<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">format</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Higher priority connection: %d is currently unavailable, "</span> <span class="o" style="color: #ce5c00; font-weight: bold;">+</span>
<span class="s" style="color: #4e9a06;">"switching to: %d and reconnecting to: %s"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
live<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> priority<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getJdbcUrl</span><span class="o" style="color: #ce5c00; font-weight: bold;">()));</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
switchTo<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>priority<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> cfg<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
live <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> Integer<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">MAX_VALUE</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">boolean</span> <span class="nf">test</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>C3P0SupervisorConnectionConfig cfg<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Connection c <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="k" style="color: #204a87; font-weight: bold;">try</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
c <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> DriverManager<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getConnection</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getJdbcUrl</span><span class="o" style="color: #ce5c00; font-weight: bold;">(),</span> cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getUser</span><span class="o" style="color: #ce5c00; font-weight: bold;">(),</span> cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getPassword</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">catch</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>SQLException e<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="kc" style="color: #204a87; font-weight: bold;">false</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">finally</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">try</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>c<span class="o" style="color: #ce5c00; font-weight: bold;">!=</span><span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
c<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">close</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">catch</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Exception e<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">error</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Cannot close connection"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> e<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="kc" style="color: #204a87; font-weight: bold;">false</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="kc" style="color: #204a87; font-weight: bold;">true</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">switchTo</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="kt" style="color: #204a87; font-weight: bold;">int</span> priority<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> C3P0SupervisorConnectionConfig cfg<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">isDebugEnabled</span><span class="o" style="color: #ce5c00; font-weight: bold;">())</span>
logger<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">debug</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>String<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">format</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Switching to priority=%d: %s"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> priority<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getJdbcUrl</span><span class="o" style="color: #ce5c00; font-weight: bold;">()));</span>
<span class="kd" style="color: #204a87; font-weight: bold;">synchronized</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
live <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> priority<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setJdbcUrl</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getJdbcUrl</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setUser</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getUser</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setPassword</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>cfg<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getPassword</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// TODO Handle readonly connections
</span> <span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Map<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Integer<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> C3P0SupervisorConnectionConfig<span class="o" style="color: #ce5c00; font-weight: bold;">></span> getConnections<span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> connections<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">setConnections</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Map<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>Integer<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> C3P0SupervisorConnectionConfig<span class="o" style="color: #ce5c00; font-weight: bold;">></span> connections<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">connections</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> connections<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> ComboPooledDataSource <span class="nf">getPooledDataSource</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf">setPooledDataSource</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>ComboPooledDataSource pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">pooledDataSource</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> pooledDataSource<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></span></pre>
</div>
<div style="text-align: justify;">
<span style="background-color: white;">The supervisor takes the bunch of prioritized JDBC configurations, and when the 0-priotity connection fails (which is the source </span><span style="background-color: white;"><i>ComboPooledDataSource</i> connection), it tries to connect to another connection, accordingly to their priorites. When the higher priority (lower <i>priority</i> number) connection is back, it reconnects main datasource to the higher priority connection.</span><br />
<br />
<span style="background-color: white;">The </span><i style="background-color: white;">readonly</i><span style="background-color: white;"> parameter is for further usage in application. One should, depending on this param, "do something" in application, like eg. remove "Save" buttons, or generate some message, that application works in read-only mode.</span><br />
<br />
<span style="background-color: white;">Now, what remains is to configure the supervisor bean and the </span><a href="http://quartz-scheduler.org/" style="background-color: white;" target="_blank">Quartz Scheduler</a><span style="background-color: white;"> job detail (or whatever scheduling technology the application uses). Here is the exemplary bean config together with quartz part:</span><br />
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; text-align: -webkit-auto;"><span style="font-size: x-small;"> <span class="c" style="color: #8f5902; font-style: italic;"><!-- the main application datasource --></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><bean</span> <span class="na" style="color: #c4a000;">id=</span><span class="s" style="color: #4e9a06;">"mainDataSource"</span> <span class="na" style="color: #c4a000;">class=</span><span class="s" style="color: #4e9a06;">"com.mchange.v2.c3p0.ComboPooledDataSource"</span> <span class="na" style="color: #c4a000;">destroy-method=</span><span class="s" style="color: #4e9a06;">"close"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"user"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"${db.main.username}"</span><span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"password"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"${db.main.password}"</span><span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"jdbcUrl"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"${db.main.url}"</span><span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"driverClass"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"${db.driverClassName}"</span><span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></bean></span>
<span class="c" style="color: #8f5902; font-style: italic;"><!-- the supervisor bean --></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><bean</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"c3p0Supervisor"</span> <span class="na" style="color: #c4a000;">class=</span><span class="s" style="color: #4e9a06;">"C3P0Supervisor"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"pooledDataSource"</span> <span class="na" style="color: #c4a000;">ref=</span><span class="s" style="color: #4e9a06;">"mainDataSource"</span><span class="nt" style="color: #204a87; font-weight: bold;">></property></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"connections"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><map></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><entry</span> <span class="na" style="color: #c4a000;">key=</span><span class="s" style="color: #4e9a06;">"1"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><bean</span> <span class="na" style="color: #c4a000;">class=</span><span class="s" style="color: #4e9a06;">"C3P0SupervisorConnectionConfig"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"user"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"${db.spare.username}"</span><span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"password"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"${db.spare.password}"</span><span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"jdbcUrl"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"${db.spare.url}"</span><span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"readonly"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"true"</span><span class="nt" style="color: #204a87; font-weight: bold;">></property></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></bean></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></entry></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></map></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></property></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></bean></span>
<span class="c" style="color: #8f5902; font-style: italic;"><!-- the quartz job and scheduler --></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><bean</span> <span class="na" style="color: #c4a000;">id=</span><span class="s" style="color: #4e9a06;">"c3p0SupervisorTask"</span>
<span class="na" style="color: #c4a000;"> class=</span><span class="s" style="color: #4e9a06;">"org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"targetObject"</span> <span class="na" style="color: #c4a000;">ref=</span><span class="s" style="color: #4e9a06;">"c3p0Supervisor"</span> <span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"targetMethod"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"poll"</span> <span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"concurrent"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"false"</span> <span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></bean></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><bean</span> <span class="na" style="color: #c4a000;">id=</span><span class="s" style="color: #4e9a06;">"c3p0SupervisorTrigger"</span> <span class="na" style="color: #c4a000;">class=</span><span class="s" style="color: #4e9a06;">"org.springframework.scheduling.quartz.SimpleTriggerBean"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"jobDetail"</span> <span class="na" style="color: #c4a000;">ref=</span><span class="s" style="color: #4e9a06;">"c3p0SupervisorTask"</span> <span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"repeatInterval"</span> <span class="na" style="color: #c4a000;">value=</span><span class="s" style="color: #4e9a06;">"60000"</span> <span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></bean></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><bean</span> <span class="na" style="color: #c4a000;">id=</span><span class="s" style="color: #4e9a06;">"schedulerFactoryBean"</span> <span class="na" style="color: #c4a000;">class=</span><span class="s" style="color: #4e9a06;">"org.springframework.scheduling.quartz.SchedulerFactoryBean"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><property</span> <span class="na" style="color: #c4a000;">name=</span><span class="s" style="color: #4e9a06;">"triggers"</span><span class="nt" style="color: #204a87; font-weight: bold;">></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><list></span>
<span class="nt" style="color: #204a87; font-weight: bold;"><ref</span> <span class="na" style="color: #c4a000;">bean=</span><span class="s" style="color: #4e9a06;">"c3p0SupervisorTrigger"</span> <span class="nt" style="color: #204a87; font-weight: bold;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></list></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></property></span>
<span class="nt" style="color: #204a87; font-weight: bold;"></bean></span></span></pre>
<span style="background-color: white;">Using the config above, after the first database failure, the application won't respond during 60secs and then will be switched to the second database. The "unavailibility time" depends on the scheduler </span><i style="background-color: white;">repeatInterval </i><span style="background-color: white;">settings.</span></div>l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-23340052146814918992012-02-15T19:07:00.003+01:002012-02-16T00:49:55.906+01:00Increase Trac productivity with plugins<div style="text-align: justify;">A substantial time amount passed since last post in this blog caused only because I'm recently very busy, although the list of interested subjects to describe in my Tomboy notes are extending monthly. Unfortunately I don't know when the appropriate time comes to make it...</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Anyway today I had some more free day and I needed to setup some Trac environments for the team and the customers. Casually I reviewed some Trac plugins, that seemed to me sensible, and should increase productivity with Trac. Bellow is the short list of those I've found useful.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><b><a href="http://trac-hacks.org/wiki/NeverNotifyUpdaterPlugin" target="_blank"><span class="Apple-style-span" style="font-size: large;">NeverNotifyUpdaterPlugin</span></a></b></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">First and foremost I always install this plugin. This is very annoying in Trac for me, that it always sends a notification to the person who updates the ticket. This is completely unnecessary feature, because I believe that if someone is updating the ticket, he <b>knows</b> about that, and doesn't require additional email notification. The installation of this plugin simply disables this feature.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><span class="Apple-style-span" style="font-size: large;"><b><a href="http://trac-hacks.org/wiki/AnnouncerPlugin" target="_blank">AnnouncerPlugin</a></b></span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span></div><div style="text-align: justify;">This is new for me, and I've installed this to fully verify the usefulness of the <b>FullBlogPlugin</b>, described below. This plugin basically adds a few great notification capabilities to Trac.<br />
<br />
First is the "watch" capability for the tickets and wiki pages. While the "watch" feature for tickets is available by default using CC field, I've found this more friendly using this plugin. For each ticket/wiki page you can just click "Watch/Unwatch" links on the top of the ticket/wiki page view, and you are then notified about all changes in the ticket/wiki page. This is especially great for wiki pages describing some important facilities in our application. By subscribing changes all team can be informed about updates in these mechanisms.<br />
<br />
Instead of subscribing all wiki pages by whole team (by clicking "Watch" on important pages), there's an option in Settings, that enables entering the names (also with using wildcards) of all wiki pages that should be by default watched by all team members.<br />
<br />
Another function that may be considered useful is the possibility of watching concrete users, and their changes in Trac (new tickets, updates etc...). Currently I see few usages of this - eg. if you need to manage some subset of Trac users, or you have Trac opened to the customers and you'd like to trace their updates.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><a href="http://trac-hacks.org/wiki/FullBlogPlugin" target="_blank"><b>FullBlogPlugin</b></a></span><br />
<br />
This plugin adds a blog feature to the Trac, which involves adding new blog posts, browsing and commenting them. This is the great feature, which I believe that can support scrum meetings, and even introduce scrum-meeting-like functionality for remote teams, working in different time zones.<br />
<br />
In recent project, to notify about some important changes in the project, new features, and deployment events we were using one big ticket with all team set on CC. This may be now changed to the blog, when this plugin is installed. If each developer is told to write blog entries about recent work, new mechanisms and important changes in existing ones, the whole team can keep up-to-date information about the project as totality (which is one of responses of the scrum meetings).<br />
<br />
The <b>FullBlogPlugin</b> lacks by default if the notification capabilities, but when you install the current trunk version of <b>AnnouncerPlugin</b> (described above), it introduces these lacking features. You can for example "watch" the blog entries, or follow some chosen bloggers. But for applying mentioned function of the blog feature in the team, the best are automatic options for subscribing blogs, which are following:<br />
<ul><li>always notify me when any blog is modified, changed, deleted or commented on</li>
<li>always notify me when any blog post is created</li>
<li>always notify me when any blog that I posted is modified or commented on</li>
<li>always notify me when a blog that I'm watching changes</li>
<li>always notify me when any blogger that I follow has a blog update</li>
</ul><span class="Apple-style-span" style="font-size: large;"><a href="http://trac-hacks.org/wiki/TracHoursPlugin" target="_blank"><b>TracHoursPlugin</b></a></span><br />
<br />
This is maybe less about productivity, but more about saving the time, of tracking the hours spent on the work. But first a little introduction...<br />
<br />
There's a much bigger Trac plugin for time tracking and estimation: <a href="http://trac-hacks.org/wiki/TimingAndEstimationPlugin" target="_blank"><b>TimingAndEstimationPlugin</b></a>. I was working with this once. This plugin allows you to estimate tickets time, add hours spent on ticket by particular developers, make some estimation and budget calculation using these information, and even connect another plugins making burn down charts, etc. This might be a better choice for someone, depending on what he wants to achieve, although in my personal opinion this plugin was not really good, and we used it just once for one project. AFAIR the information calculated/managed was not clear to us, it introduced some more complexity to Trac (and the power of this system is kept, when it's kept simple). Moreover, for estimation, requirements and user stories management, and generally managing project in scrum with burn down charts etc. I can much more recommend <a href="http://agilosoftware.com/" target="_blank">Agilo</a>, which is complete tool for scrum project management based on Trac, than the <b>TimingAndEstimationPlugin</b>.<br />
<br />
Now, returning to <b>TracHoursPlugin</b>, this is very simple one. It adds the "Add hours" link on the ticket view page, and the Hours view in menu, to calculate hours added to tickets with some query filters (like default query filters for Trac reports). So you can for example check the hours spent in some time range, spent by some developers, or spent on some ticket types or component.<br />
<br />
This plugin is really great when you make some project, and you base on hourly rate, but with no time commitment, so for example one week you can work 10 hrs, while another 30 hrs, etc. This plugin allows you to really easy track the time and to make the financial settlements with the customer.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b><a href="http://trac-hacks.org/wiki/ChildTicketsPlugin" target="_blank">ChildTicketsPlugin</a></b></span><br />
<br />
For a longer time I've been looking for better way to organize Trac tickets. This is the biggest problem in bigger projects managed with Trac, that it quickly becomes a mess with the plain "ticket list" views. only Unfortunately I didn't find anything that 100% satisfies me here, and if I manage project with Trac, I usually support myself with the mind mapping software, like <a href="http://freemind.sourceforge.net/wiki/index.php/Main_Page" target="_blank">Freemind</a> (on the other hand this is best project management tool I've been using until now ;) ).<br />
<br />
The <b>ChildTicketsPlugin</b> is an approach to introduce parent - child relations in the Trac tickets, and I 've currently chosen this plugin for test if it really helps with tickets organization in my new project. Maybe for some time I'll write a little more about this. For now I can just write that it looks simple. It allows you to define parent - child relations between tickets, and you can define what type of parent can have what type of children. Depending on how you like to organize your project, it can be eg. Requirement - User Story - Task, or Feature - Task + Feature - Bug etc. Whatever structure you find useful, you can configure here.<br />
<br />
Now, the rest is easy, adding new ticket you can enter the parent ID, and you create the parent - child relation between these tickets. However, this is not very usable workflow: add ticket - enter parent ID, because you'd need to know the parent ID first, but the plugin provides another way of adding tickets - you can first find the appropriate parent ticket, and add any of the allowed child ticket types using a button.<br />
<br />
This simple feature can be supported by additional reports, allowing us to view some kind of root ticket types, and "drill down" the project. We can also use empty/not empty parent ID filter, to determine orphaned tickets. Moreover there's a <a href="http://trac-hacks.org/wiki/ChildTicketTreeMacro" style="font-weight: bold;" target="_blank">ChildTicketTreeMacro</a> macro available, which can display the tickets tree structure in various places (like wiki pages, or ticket descriptions).<br />
<br />
There's an alternative plugin for Trac, which is called <b><a href="http://trac-hacks.org/wiki/MasterTicketsPlugin" target="_blank">MasterTicketsPlugin</a></b>, what might be useful for some situations, but looking on the description it does far to much than I need, and brings more complexity for Trac. However, I didn't tested it today because of lack of time.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">And more...</span></b><br />
<br />
There are a <a href="http://trac-hacks.org/" target="_blank">lot more</a> of Trac plugins that might be considered useful from the productivity point of view, which I didn't test. But currently these mentioned here appeases all my needs and fills the lacking functionality in Trac. However, I hope I'll extend this post in future.</div>l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com1tag:blogger.com,1999:blog-603254884063001716.post-22817565450281835462011-08-20T21:04:00.021+02:002011-08-20T22:07:58.270+02:00Transparent dynamic forms with LazyList<div class="post-outer"><div class="post hentry"><div style="text-align: justify;">Some time ago I wrote <a href="http://lifeinide.blogspot.com/2010/12/dynamic-forms-lazylist-and-transparent.html">few words</a> about some dynamic forms implementation methods using <a href="http://commons.apache.org/collections/apidocs/org/apache/commons/collections/list/LazyList.html">LazyList</a> or <a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/util/AutoPopulatingList.html">AutoPopulatingList</a> with items removing. The problem that interested me today was related to this subject, but concerned something else: <b>how to implement dynamic forms in the way, so that it can be used transparently for any object</b> (even a Hibernate entity) without creating specialized form beans for that.</div><div class="post-body entry-content" id="post-body-2281756545028183546"><div style="text-align: justify;"><br />
If you write a Hibernate application there are at least two schools about implementing forms backend. First tells you to create a object for each form, representing given form data, second lets you use directly Hibernate entities in forms. The first one is maybe cleaner than the second one from the "patterns compliance" point of view, but produces a lot of unnecessary code. There's s lot of stuff on the net to read about this. Some people do this, some that. I'm not eager to generalize things and give the best solution always, but from my point of view it just depends. It depends mainly on the project size and overall application requirements, but generally I believe that if you don't make a big financial system with 20+ developers, and if you can apply <a href="http://community.jboss.org/wiki/SessionsAndTransactions#The_scope_of_a_unit_of_work">session-per-request</a> (or session-per-conversation) model, (ie. you don't have eg. many databases and session factories, distributed transactions management etc.) working together with <a href="http://community.jboss.org/wiki/OpenSessionInView">OSIV</a>, you may consider using directly you business objects across the whole application.</div><div style="text-align: justify;"><br />
I can evaluate that 50-80% forms in the usual web application are just the domain object editors. In mentioned application, if you like to edit all these entities with form beans, you need to maintain large (1:1 with business model) class hierarchy, looking exactly the same like the domain object hierarchy. Moreover, you need to maintain a lot of conversion code, making one objects from another. Is this really needed? I consider not, as well as for example <a href="http://www.tutorialized.com/view/tutorial/Spring-MVC-Application-Architecture/11986">these guys</a>. I'm the follower of using domain objects throughout whole application, in as many places as you can, and write just a feature code, instead of maintaining every day tons of code that will never bring any benefits.</div><div style="text-align: justify;"><br />
Today I had a time to verify these assumptions in pure Spring environment. I previously made other projects with such approach, but never really used pure Spring in a web layer. I consider this as a very good (and lightweight in proportion to pure JEE) middleware, but about Spring MVC/WebFlow I had a different opinion, in which these are not well-rounded and very crude. For those people looking for better solutions I can recommend <a href="http://www.stripesframework.org/">Stripes Frameworks</a>, what is the best web framework I used until now in Java world. Spring guys could learn a lot from Stripes guys about how to create a greatly flexible web (layer) framework. But, let's don't gripe, I use also Spring in Stripes-based applications as a base framework (IOC, scheduling, webservice, you know ...) and it's great. The only caveat I can have to MVC/WebFlow part.</div><div style="text-align: justify;"><br />
Returning to the subject: how to implement transparent dynamic forms for any class used as form bean, I need to tell that this all is about the Binder you use. By the Binder I mean the code that converts your plain strings from HTTP request into an object property values. For example StripesFramework has its own binder that is very flexible and extendable, so I've never had problems with writing anything with this. Regarding Spring code it looks little worse, but this is for a while. Anyway, if you'd like to have dynamic forms handling transparent, you need to have appropriately configured binder, that is able to manage with these concerns. If you don't have a flexible Binder, you need to implement all stuff with your form beans with eg. <a href="http://commons.apache.org/collections/apidocs/org/apache/commons/collections/list/LazyList.html">LazyList</a> wrappers, and also all this stuff behind.</div><div style="text-align: justify;"><br />
In the Spring the main role in binding plays <a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/beans/BeanWrapperImpl.html">BeanWrapperImpl</a> class. If you take a glance <a href="https://src.springframework.org/svn/spring-framework/trunk/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java">at implementation</a>, you will see some code in getPropertyValue() method taking elements from the target bean collections. This is base implementation assuming that you have these elements already initialized, otherwise it throws exceptions (default Spring implementation).</div><div style="text-align: justify;"><br />
OK, this is the code that should be extended: the BeanWrapperImpl should be switched to a different implementation, considering dynamic lists for whatever objects playing "form bean" role. But, unfortunately, <b>not for Spring</b>. The BeanWrapperImpl class simply cannot be extended, because of its horrible design, like a lot of private methods and dependencies to other package-visible classes. In spring MVC, this (the most) important part of the request processing is completely monolith and not extendable. From the good framework I expect that if the behavior is undesirable, I can change this, but Spring doesn't give that.</div><div style="text-align: justify;"><br />
But, what if I want to have this in a Spring or whatever else badly designed binder? I just need to make it myself in the independent code. The working solution I applied is below. First thing is to get to a binding code. In your framework you will probably have somewhere some code looking like this:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"><pre style="background-color: #f8f8f8; margin: 0px;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc" style="color: black;">Binder</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">bind</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Object root<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> RawValues values<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
doBind<span class="o" style="color: #ce5c00; font-weight: bold;">(..);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre></span></span> </div><div style="text-align: justify;">This is the base binder call that requires a root object (form bean) and the request parameter values in some form. For example if you use WebFlow in FormAction the binder (WebDataBinder) is being created in createBinder() method. You can switch the implementation there to you binder class and override some behavior (the DataBinder in Spring can be easily inherited, but it internally uses BeanWrapperImpl that does all job, and it cannot). This is how does look my data binder implementation for Spring:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"><pre style="background-color: #f8f8f8; margin: 0px;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> Dynamic<span class="nc" style="color: black;">DataBinder</span> <span class="kd" style="color: #204a87; font-weight: bold;">extends</span> WebDataBinder <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">doBind</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="kd" style="color: #204a87; font-weight: bold;">final</span> MutablePropertyValues mpvs<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;"> new</span> <span class="nf" style="color: black;">DynamicBindingWrapper</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>getTarget<span class="o" style="color: #ce5c00; font-weight: bold;">(),</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> Runnable<span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">run</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
_doBind<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>mpvs<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">});</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">_doBind</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>MutablePropertyValues mpvs<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">super</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">doBind</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>mpvs<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre></span></span><br />
This is the Spring example, but of course you can use this for any framework you use, because binding needs always to look similar in any framework (requires an object to be bound and the parameters). What I do here clearly is to wrap the binding process (done in super.toBind() - I needed to put it into separate method because of anonymous Runnable class utilization), that can be done in its default way, with some code applying the dynamic forms behavior to form bean.<br />
<br />
The thing that enclosing code need to do is to:<br />
<ul><li>make all required collections appropriate for dynamic form binding</li>
<li>allow to execute the binding in the way that binder code in unaware of non-existing collection items</li>
<li>restore collections to previous state, to be further (after binding) processes in a regular way</li>
</ul>The last point is very important, because for Hibernate entities that are already persistent, we cannot switch a collection (eg. to HashSet) and disjoin the Hibernate persistent (eg. PersistentSet) implementation. For persistent entities we have to ensure that after binding all entity collections are in the same implementations as they were before binding.<br />
<br />
To mark the collections that during the binding should behave "dynamically" I use additional annotation, because only for some special collection we need to apply this. For example if we have an Invoice having InvoiceItem collection that we need to edit in a dynamic way on a single form. The annotation I use is very simple:<br />
<br />
<span style="font-size: small;"><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"><pre style="background-color: #f8f8f8; margin: 0px;"><span class="nd" style="color: #5c35cc; font-weight: bold;">@Target</span><span class="o" style="color: #ce5c00; font-weight: bold;">({</span>ElementType<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">FIELD</span><span class="o" style="color: #ce5c00; font-weight: bold;">})</span>
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Retention</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>RetentionPolicy<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">RUNTIME</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="nd" style="color: #5c35cc; font-weight: bold;">@interface</span> DynamicList <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Class <span class="nf" style="color: black;">value</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre></span></span></span><br />
In the value() attribute we will point the exact collection generic type, so that the list could produce new items. This also can be done by reflection, but here for simplify we will name exact class name. So, our exemplary Invoice for dynamic item handling should look like that:<br />
<br />
<span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-size: small; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"><pre style="background-color: #f8f8f8; margin: 0px;"><span style="font-size: small;"><span class="kd" style="color: #204a87; font-size: small; font-weight: bold;">private</span><span style="font-size: small;"> </span><span class="kd" style="color: #204a87; font-size: small; font-weight: bold;">class</span><span style="font-size: small;"> </span><span class="nc" style="color: black; font-size: small;">Invoice</span><span style="font-size: small;"> </span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">{</span>
<span class="nd" style="color: #5c35cc; font-size: small; font-weight: bold;">@DynamicList</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">(</span><span style="font-size: small;">InvoiceItem</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: small;">class</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">)</span>
<span class="kd" style="color: #204a87; font-size: small; font-weight: bold;">protected</span><span style="font-size: small;"> List</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;"><</span><span style="font-size: small;">InvoiceItem</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">></span><span style="font-size: small;"> items </span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">=</span><span style="font-size: small;"> </span><span class="k" style="color: #204a87; font-size: small; font-weight: bold;">new</span><span style="font-size: small;"> ArrayList</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;"><</span><span style="font-size: small;">InvoiceItem</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">>();</span>
<span class="kd" style="color: #204a87; font-size: small; font-weight: bold;">public</span><span style="font-size: small;"> List</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;"><</span><span style="font-size: small;">InvoiceItem</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">></span><span style="font-size: small;"> getItems</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">()</span><span style="font-size: small;"> </span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-size: small; font-weight: bold;">return</span><span style="font-size: small;"> items</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-size: small; font-weight: bold;">public</span><span style="font-size: small;"> </span><span class="kt" style="color: #204a87; font-size: small; font-weight: bold;">void</span><span style="font-size: small;"> </span><span class="nf" style="color: black; font-size: small;">setItems</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">(</span><span style="font-size: small;">List</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;"><</span><span style="font-size: small;">InvoiceItem</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">></span><span style="font-size: small;"> items</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">)</span><span style="font-size: small;"> </span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-size: small; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">.</span><span class="na" style="color: #c4a000; font-size: small;">items</span><span style="font-size: small;"> </span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">=</span><span style="font-size: small;"> items</span><span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-size: small; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></span></pre></span></span><br />
I've intentionally omitted Hibernate annotations, that should be put on this class and its fields (if you use annotation Hibernate configuration). We are currently interested only in dynamic forms.<br />
<br />
Now, I have to say something about how I assume this works. The dynamic collection for me is completely (also considering underlying objects graph) reflected in the HTML form. This may be not appropriate in some cases, so if it's not appropriate for you, you need to apply different "merging" mechanism. For my (usual) cases it's easy, because if we have all stuff held in the form (these already persisted items, together with a new ones), we may always produce the entity collection from the beginning: by clearing the existing collection and producing new one (the existing items will be deleted and re-created). This is the simplest approach and it's appropriate in most cases.<br />
<br />
Having all these assumptions, the final algorithm is following:<br />
<ul><li>we look for @DynamicList collection fields in target form bean, these ones we've found we wrap with <a href="http://lifeinide.blogspot.com/2010/12/dynamic-forms-lazylist-and-transparent.html">ShrinkableLazyList</a> to be "dynamic form aware",</li>
<li>when we produce new items by LazyList factory, we need also to wrap these entities in the same fashion, because we may have much longer objects graph requiring the same dynamic forms behavior,</li>
<li>on the end of process we need to "return" previous collection instances to the original form beans (if it's persistent Hibernate entity, it would very much like to have the same Persistent<i>Collection</i> instance that it assumes to be present in particular entity property).</li>
</ul>The implementation looks following:<br />
<br />
<span style="font-size: small;"><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"><pre style="background-color: #f8f8f8; margin: 0px;"><span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc" style="color: black;">DynamicBindingWrapper</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/** </span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="cm" style="color: #8f5902; font-style: italic;"> * A SkrinkableLazyList implementation for collections wrapping.</span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="cm" style="color: #8f5902; font-style: italic;"> * By this implementation we assert that this wrapping collection</span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="cm" style="color: #8f5902; font-style: italic;"> * </span><span class="cm" style="color: #8f5902; font-style: italic;">is compatible</span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"></span></span><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"></span></span><span class="cm" style="color: #8f5902; font-style: italic;"> with both Set and List.</span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="cm" style="color: #8f5902; font-style: italic;"> **/</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kd" style="color: #204a87; font-weight: bold;">class</span> <span class="nc" style="color: black;">DynamicBindingCollection</span> <span class="kd" style="color: #204a87; font-weight: bold;">extends</span> ShrinkableLazyList
<span class="kd" style="color: #204a87; font-weight: bold;">implements</span> Set <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> Object target<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> Field field<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> Collection wrapped<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> Class itemClass<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="nf" style="color: black;">DynamicBindingCollection</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Object target<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> Field field<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
<span class="kd" style="color: #204a87; font-weight: bold;">final</span> Class itemClass<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IllegalArgumentException<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
IllegalAccessException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// initialize on empty wrapped collection + init items factory</span> <span class="kd" style="color: #204a87; font-weight: bold;"> </span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="kd" style="color: #204a87; font-weight: bold;"> super</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="k" style="color: #204a87; font-weight: bold;">new</span> ArrayList<span class="o" style="color: #ce5c00; font-weight: bold;">(),</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> Factory<span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span> </pre><pre style="background-color: #f8f8f8; margin: 0px;">
<span class="nd" style="color: #5c35cc; font-weight: bold;">@Override</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> Object <span class="nf" style="color: black;">create</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">try</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Object o <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> itemClass<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">newInstance</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
begin<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>o<span class="o" style="color: #ce5c00; font-weight: bold;">);</span> <span class="c1" style="color: #8f5902; font-style: italic;">// all new instances need to be wrapped to assert </span> </pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="c1" style="color: #8f5902; font-style: italic;"> // </span><span class="c1" style="color: #8f5902; font-style: italic;">dynamic binding on nested</span><span class="c1" style="color: #8f5902; font-style: italic;"> paths</span> </pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="k" style="color: #204a87; font-weight: bold;"> return</span> o<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">catch</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Exception e<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
e<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">printStackTrace</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="k" style="color: #204a87; font-weight: bold;">return</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}
},</span> <span class="kc" style="color: #204a87; font-weight: bold;">true</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// init fields</span> <span class="k" style="color: #204a87; font-weight: bold;"> </span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="k" style="color: #204a87; font-weight: bold;"> this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">target</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> target<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">field</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> field<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">itemClass</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> itemClass<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// wrap the original object</span>
field<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setAccessible</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="kc" style="color: #204a87; font-weight: bold;">true</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
Object value <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> field<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">get</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>target<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>value <span class="k" style="color: #204a87; font-weight: bold;">instanceof</span> Set <span class="o" style="color: #ce5c00; font-weight: bold;">||</span> value <span class="k" style="color: #204a87; font-weight: bold;">instanceof</span> List<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">wrapped</span> <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Collection<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> value<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
field<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">set</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>target<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> <span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span> <span class="c1" style="color: #8f5902; font-style: italic;">// wrap the target bean collection
</span>register<span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span> <span class="c1" style="color: #8f5902; font-style: italic;">// register for unwrapping</span> <span class="o" style="color: #ce5c00; font-weight: bold;"> </span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="o" style="color: #ce5c00; font-weight: bold;"> }</span> <span class="k" style="color: #204a87; font-weight: bold;">else</span>
<span class="k" style="color: #204a87; font-weight: bold;">throw</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> <span class="nf" style="color: black;">IllegalArgumentException</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>
<span class="s" style="color: #4e9a06;">"Only Set and List instances can be wrapped for DynamicList"</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">unwrap</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="kd" style="color: #204a87; font-weight: bold;">throws</span> IllegalArgumentException<span class="o" style="color: #ce5c00; font-weight: bold;">,</span>
IllegalAccessException <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="c1" style="color: #8f5902; font-style: italic;"> // clear wrapped collection to be populated again from the form</span>
wrapped<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">clear</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="c1" style="color: #8f5902; font-style: italic;">// get real values (indirectly calls ShrinkableLazyList.shrink())</span> <span class="k" style="color: #204a87; font-weight: bold;"> </span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="k" style="color: #204a87; font-weight: bold;"> for</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Object o <span class="o" style="color: #ce5c00; font-weight: bold;">:</span> <span class="k" style="color: #204a87; font-weight: bold;">this</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
wrapped<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">add</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>o<span class="o" style="color: #ce5c00; font-weight: bold;">);</span> </pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="c1" style="color: #8f5902; font-style: italic;"> </span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="c1" style="color: #8f5902; font-style: italic;"> // restore original collection</span>
field<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">setAccessible</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="kc" style="color: #204a87; font-weight: bold;">true</span><span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
field<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">set</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>target<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> wrapped<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> List<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>DynamicBindingCollection<span class="o" style="color: #ce5c00; font-weight: bold;">></span> collections <span class="o" style="color: #ce5c00; font-weight: bold;">=</span>
<span class="k" style="color: #204a87; font-weight: bold;">new</span> ArrayList<span class="o" style="color: #ce5c00; font-weight: bold;"><</span>DynamicBindingWrapper<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">DynamicBindingCollection</span><span class="o" style="color: #ce5c00; font-weight: bold;">>();</span>
<span class="kd" style="color: #204a87; font-weight: bold;">public</span> <span class="nf" style="color: black;">DynamicBindingWrapper</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Object target<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> Runnable task<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
begin<span class="o" style="color: #ce5c00; font-weight: bold;">(</span>target<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
task<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">run</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
done<span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/** Main wrapping method **/</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">begin</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Object target<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">try</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
Class clazz <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> target<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getClass</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="k" style="color: #204a87; font-weight: bold;">while</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>clazz <span class="o" style="color: #ce5c00; font-weight: bold;">!=</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">for</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Field field <span class="o" style="color: #ce5c00; font-weight: bold;">:</span> clazz<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getDeclaredFields</span><span class="o" style="color: #ce5c00; font-weight: bold;">())</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
DynamicList annot<span class="o" style="color: #ce5c00; font-weight: bold;">;</span>
<span class="k" style="color: #204a87; font-weight: bold;">if</span> <span class="o" style="color: #ce5c00; font-weight: bold;">((</span>annot <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> field<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getAnnotation</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>DynamicList<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">class</span><span class="o" style="color: #ce5c00; font-weight: bold;">))</span> <span class="o" style="color: #ce5c00; font-weight: bold;">!=</span> <span class="kc" style="color: #204a87; font-weight: bold;">null</span><span class="o" style="color: #ce5c00; font-weight: bold;">)</span></pre><pre style="background-color: #f8f8f8; margin: 0px;"><span class="Apple-style-span" style="border-collapse: separate; color: black; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="Apple-style-span" style="font-family: Verdana,Arial,'Bitstream Vera Sans',Helvetica,sans-serif;"><pre style="background-color: #f8f8f8; margin: 0px;"><span class="c1" style="color: #8f5902; font-style: italic;"> // wrap the collection with lazy list</span></pre></span></span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> <span class="nf" style="color: black;">DynamicBindingCollection</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>target<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> field<span class="o" style="color: #ce5c00; font-weight: bold;">,</span> annot<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">value</span><span class="o" style="color: #ce5c00; font-weight: bold;">());</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
clazz <span class="o" style="color: #ce5c00; font-weight: bold;">=</span> clazz<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">getSuperclass</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">catch</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Exception e<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">throw</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> <span class="nf" style="color: black;">RuntimeException</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Cannot get properties from bean"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> e<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="cm" style="color: #8f5902; font-style: italic;">/** Ends binding session and unwraps instances */</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">done</span><span class="o" style="color: #ce5c00; font-weight: bold;">()</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">try</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">for</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>DynamicBindingCollection collection <span class="o" style="color: #ce5c00; font-weight: bold;">:</span> collections<span class="o" style="color: #ce5c00; font-weight: bold;">)</span>
collection<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">unwrap</span><span class="o" style="color: #ce5c00; font-weight: bold;">();</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span> <span class="k" style="color: #204a87; font-weight: bold;">catch</span> <span class="o" style="color: #ce5c00; font-weight: bold;">(</span>Exception e<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
<span class="k" style="color: #204a87; font-weight: bold;">throw</span> <span class="k" style="color: #204a87; font-weight: bold;">new</span> <span class="nf" style="color: black;">RuntimeException</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span><span class="s" style="color: #4e9a06;">"Cannot unwrap dynamic collection"</span><span class="o" style="color: #ce5c00; font-weight: bold;">,</span> e<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="kd" style="color: #204a87; font-weight: bold;">protected</span> <span class="kt" style="color: #204a87; font-weight: bold;">void</span> <span class="nf" style="color: black;">register</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>DynamicBindingCollection collection<span class="o" style="color: #ce5c00; font-weight: bold;">)</span> <span class="o" style="color: #ce5c00; font-weight: bold;">{</span>
collections<span class="o" style="color: #ce5c00; font-weight: bold;">.</span><span class="na" style="color: #c4a000;">add</span><span class="o" style="color: #ce5c00; font-weight: bold;">(</span>collection<span class="o" style="color: #ce5c00; font-weight: bold;">);</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span>
<span class="o" style="color: #ce5c00; font-weight: bold;">}</span></pre></span></span></span><br />
Today tests showed that this works nice both for transient and persistent Hibernate entities used as "form beans" (and of course for non-Hibernate form beans as well).</div><div style="text-align: justify;"></div><div style="clear: both;"></div></div></div></div>l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com0tag:blogger.com,1999:blog-603254884063001716.post-37441026227231881632011-08-06T15:18:00.005+02:002011-08-06T15:38:14.052+02:00Edit conflicts in eclipse using submerge<div style="text-align: justify;">Everyone using Eclipse + SVN (or other non-locking version control system) has gone through the hell of editing conflicts with default Eclipse tool. I don't know, maybe there are people liking this, but for me is very unhandy, messy and produces more work than doing the merge without any tool. I just cannot see what is currently merged, how it's done and what is to be done already in this editor window:<br />
<br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5J3GC52noQerbQzRs6b0JOYo7Pg8ZrxF8GOnpqzMhJI7fry7Cj69sdiZcdIDujPoMqARqskTpCS3l1yDVAjO0WQmHHhyphenhyphenC9ewbX0dSESLhkygQkcCsONanOYe1W7YGt4-C1fmF893L9ho/s1600/eclipse_edit_conflicts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5J3GC52noQerbQzRs6b0JOYo7Pg8ZrxF8GOnpqzMhJI7fry7Cj69sdiZcdIDujPoMqARqskTpCS3l1yDVAjO0WQmHHhyphenhyphenC9ewbX0dSESLhkygQkcCsONanOYe1W7YGt4-C1fmF893L9ho/s1600/eclipse_edit_conflicts.png" /></a></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Furthermore every important thing needs here to be done by manual copy & paste from right to left.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">I remember when once (and enoughs ;) ) I worked in company using Windows, where I was using TortoiseSVN integrated with Windows Explorer. The comfort between their "edit conflict" tool and this one just cannot be compared.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">For longer time I was looking for alternatives in Linux. I passed through all known tools like <b>kdiff3</b> or <b>meld</b> but in my opinion they are great for diff, but not for edit conflicts. However recently I've finally found appropriate editor and I'm very satisfied from using it. This is a <b>submerge</b> tool from <a href="http://subcommander.tigris.org/">subcommander</a>.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">In "edit conflicts" mode it provides three panels with "mine" and "theirs" version (at the top) and initial merge result (at the bottom). It's very convenient for usage - you can navigate change by change using buttons on toolbar. By default always the blue change is applied into a merged file. If you like to change this you just double click on the version you want to apply in "mine" or "their" file. All conflicting changes are highlighted with red color, and you can choose appropriate change also with double click. The exemplary conflict edition looks following:<br />
<br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBe-jitw_rBPA1Y0zX27_AecqPZEEd85n3CJV010NF9B1HbY-6-53BEa7jpdn0BF8J3dE0ZHgQhTbefh7FH3AHuaUEFQxbQuX_KHIcg0eM1ZvxFlW3NCGVT8wCQ1n9CMCkQPJhsp3HDaM/s1600/submerge_example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBe-jitw_rBPA1Y0zX27_AecqPZEEd85n3CJV010NF9B1HbY-6-53BEa7jpdn0BF8J3dE0ZHgQhTbefh7FH3AHuaUEFQxbQuX_KHIcg0eM1ZvxFlW3NCGVT8wCQ1n9CMCkQPJhsp3HDaM/s1600/submerge_example.png" /></a></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">To install <b>submerge</b> just download and install latests <a href="http://subcommander.tigris.org/">subcommander</a> from the website or from your package repository (it's available in Debian / Ubuntu repositories as <b>subcommander</b>). After installation you should have <b>submerge</b> command available from command line.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Last thing is to integrate <b>submerge</b> into Eclipse. This can be done using Windows | Preferences | Team | SVN | Diff Viewer. Add here new file association for all files ('*'):<br />
<br />
</div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNCl3gxqxKS8SLGd8HqvI6Qc9tMksQNY1UL5dkbBHkyxF9F1hKWwWu539kLsrEivJ6GQkj4SdISJTWb92vcF1wQx3vjOz3jKFaIJXZ9XYuS7lSs9zSQUrpj51tdDJf3n0dSr7HXOkLxF4/s1600/submerge_config.png" /></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">The arguments for both commands to copy&paste are following:</div><div style="text-align: justify;"></div><ul><li>diff ${base} ${mine}</li>
<li>merge ${base} ${mine} ${theirs} ${merged}</li>
</ul><div>You can then enjoy with <b>submerge</b> in "Compare with..." and "Edit conflicts" functions.</div>l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com1tag:blogger.com,1999:blog-603254884063001716.post-3097354000852241372011-06-07T18:58:00.000+02:002016-12-25T16:24:24.671+01:00Host and user name in log4j logs<div style="text-align: justify;">
In the production environment web application debuging is not so easy. Especially because when multiple users perform multiple actions in the same time, the output log is interleaved, and the step-by-step situation is hard to reproduce in development lab. The solution for that can be by injecting user name into the log, and then "grepping" the source log in looking for particular user paths. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you use <a href="http://logging.apache.org/log4j/1.2/">log4j</a> as your logging framework the implementation is not very obvious, but can be achieved using custom <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html">PatternLayout</a>, injecting additional variables to the logs. Here I'm presenting such class and config. We want to inject transparently <b>hostname</b> and <b>username</b> into the logs.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First the configuration (using <a href="http://wiki.apache.org/logging-log4j/Log4jXmlFormat">log4j xml config</a>). The only important is <i>appender</i> part:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: "lucida grande" , "arial" , sans-serif; font-size: 13px; line-height: 18px;"></span></div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-family: Monaco, monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 6px; padding-left: 6px; padding-right: 6px; padding-top: 6px;"><span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><appender</span> <span class="na" style="color: #c4a000; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">name=</span><span class="s" style="color: #4e9a06; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">"consoleAppender"</span> <span class="na" style="color: #c4a000; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">class=</span><span class="s" style="color: #4e9a06; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">"org.apache.log4j.ConsoleAppender"</span><span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">></span>
<span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><layout</span> <span class="na" style="color: #c4a000; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">class=</span><span class="s" style="color: #4e9a06; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">"ContextPatternLayout"</span><span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">></span>
<span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><param</span> <span class="na" style="color: #c4a000; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">name=</span><span class="s" style="color: #4e9a06; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">"ConversionPattern"</span> <span class="na" style="color: #c4a000; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">value=</span><span class="s" style="color: #4e9a06; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">"%d %p %h %u [%c] - %m %n"</span><span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">/></span>
<span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></layout></span>
<span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></appender></span>
</pre>
<div>
<span class="nt" style="color: #204a87; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><br />
</span></div>
<div>
<div style="text-align: justify;">
As you can see there're here two additional (regarding original <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html">PatternLayout</a>) parameters: %h representing hostname, and %u representing username.</div>
<br />
Now the implementation. All in one class with some anonymous members, to be as simple as possible:<br />
<br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: justify;">
</div>
<pre style="background-attachment: initial; background-clip: initial; background-color: #f8f8f8; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 6px; padding-left: 6px; padding-right: 6px; padding-top: 6px;"><span class="cm" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><span class="Apple-style-span" style="font-family: "monaco" , monospace;">import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.log4j.helpers.PatternConverter;
import org.apache.log4j.helpers.PatternParser;
import org.apache.log4j.spi.LoggingEvent;<i>
<span class="Apple-style-span" style="color: #8f5902;">
/**
* Context pattern layout with %h (hostname) and %u (username) variables.
*/</span></i></span></span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">public</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">class</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="nc" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">ContextPatternLayout</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">extends</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> PatternLayout </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"> </span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">protected</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> String host</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">;</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">protected</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> String </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">getUsername</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">()</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">return</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="s" style="color: #4e9a06; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">"username"</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">;</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">protected</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> String </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">getHostname</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">()</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">if</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">host</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">==</span><span class="kc" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">null</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">try</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
InetAddress addr </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> InetAddress</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">.</span><span class="na" style="color: #c4a000; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">getLocalHost</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">();</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">this</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">.</span><span class="na" style="color: #c4a000; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">host</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> addr</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">.</span><span class="na" style="color: #c4a000; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">getHostName</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">();</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">catch</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">UnknownHostException e</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">this</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">.</span><span class="na" style="color: #c4a000; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">host</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="s" style="color: #4e9a06; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">"localhost"</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">;</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">return</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> host</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">;</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}
</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
<span class="Apple-style-span" style="color: #5c35cc; font-weight: bold;">@Override</span>
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">protected</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> PatternParser </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">createPatternParser</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">String pattern</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">return</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">new</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">PatternParser</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">pattern</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="nd" style="color: #5c35cc; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@Override</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">protected</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="kt" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">void</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">finalizeConverter</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="kt" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">char</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> c</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
PatternConverter pc </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="kc" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">null</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">;</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">switch</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">c</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">case</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="sc" style="color: #4e9a06; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">'u'</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">:</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
pc </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">new</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> PatternConverter</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">()</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="nd" style="color: #5c35cc; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@Override</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">protected</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> String </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">convert</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">LoggingEvent event</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">return</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">getUsername</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">();</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">};</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">break</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">;
</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">case</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="sc" style="color: #4e9a06; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">'h'</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">:</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
pc </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">=</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">new</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> PatternConverter</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">()</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="nd" style="color: #5c35cc; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">@Override</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">protected</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> String </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">convert</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">LoggingEvent event</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">{</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">return</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">getHostname</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">();</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">};</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">break</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">;</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">if</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;"> </span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">pc</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">==</span><span class="kc" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">null</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">)</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="kd" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">super</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">.</span><span class="na" style="color: #c4a000; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">finalizeConverter</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">c</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">);</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="k" style="color: #204a87; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">else</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="nf" style="color: black; font-family: "monaco" , monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">addConverter</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">(</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">pc</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">);</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">};</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span><span class="o" style="color: #ce5c00; font-family: "monaco" , monospace; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">}</span><span class="Apple-style-span" style="color: #204a87; font-family: "monaco" , monospace;">
</span></pre>
<div style="color: #204a87;">
<span class="o" style="color: #ce5c00; font-weight: bold; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><br />
</span></div>
<div style="color: #204a87;">
</div>
Of course the getUsername() method need to be overriden to provide actual value.</div>
l0cohttp://www.blogger.com/profile/12633925472794511454noreply@blogger.com6