001/*
002 * Copyright 2014 Global Biodiversity Information Facility (GBIF)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.gbif.api.vocabulary;
017
018import java.io.IOException;
019import java.util.List;
020import java.util.Locale;
021
022import com.google.common.annotations.VisibleForTesting;
023import com.google.common.base.Strings;
024import com.google.common.collect.ImmutableList;
025import org.codehaus.jackson.JsonGenerationException;
026import org.codehaus.jackson.JsonGenerator;
027import org.codehaus.jackson.JsonParser;
028import org.codehaus.jackson.map.DeserializationContext;
029import org.codehaus.jackson.map.JsonDeserializer;
030import org.codehaus.jackson.map.SerializerProvider;
031import org.codehaus.jackson.map.annotate.JsonDeserialize;
032import org.codehaus.jackson.map.annotate.JsonSerialize;
033import org.codehaus.jackson.map.ser.std.SerializerBase;
034
035/**
036 * Enumeration for all ISO 639-1 language codes using 2 lower case letters.
037 * The enumeration maps to 3 letter codes and Locales.
038 *
039 * @see <a href="http://en.wikipedia.org/wiki/ISO_639">Wikipedia on ISO-639</a>
040 * @see <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Locale.html">Locale javadoc</a>
041 */
042@JsonSerialize(using = Language.IsoSerializer.class)
043@JsonDeserialize(using = Language.LenientDeserializer.class)
044public enum Language {
045
046  /**
047   * Abkhazian.
048   */
049  ABKHAZIAN("ab"),
050
051  /**
052   * Afar.
053   */
054  AFAR("aa"),
055
056  /**
057   * Afrikaans.
058   */
059  AFRIKAANS("af"),
060
061  /**
062   * Akan.
063   */
064  AKAN("ak"),
065
066  /**
067   * Albanian.
068   */
069  ALBANIAN("sq"),
070
071  /**
072   * Amharic.
073   */
074  AMHARIC("am"),
075
076  /**
077   * Arabic.
078   */
079  ARABIC("ar"),
080
081  /**
082   * Aragonese.
083   */
084  ARAGONESE("an"),
085
086  /**
087   * Armenian.
088   */
089  ARMENIAN("hy"),
090
091  /**
092   * Assamese.
093   */
094  ASSAMESE("as"),
095
096  /**
097   * Avaric.
098   */
099  AVARIC("av"),
100
101  /**
102   * Avestan.
103   */
104  AVESTAN("ae"),
105
106  /**
107   * Aymara.
108   */
109  AYMARA("ay"),
110
111  /**
112   * Azerbaijani.
113   */
114  AZERBAIJANI("az"),
115
116  /**
117   * Bambara.
118   */
119  BAMBARA("bm"),
120
121  /**
122   * Bashkir.
123   */
124  BASHKIR("ba"),
125
126  /**
127   * Basque.
128   */
129  BASQUE("eu"),
130
131  /**
132   * Belarusian.
133   */
134  BELARUSIAN("be"),
135
136  /**
137   * Bengali.
138   */
139  BENGALI("bn"),
140
141  /**
142   * Bihari.
143   */
144  BIHARI("bh"),
145
146  /**
147   * Bislama.
148   */
149  BISLAMA("bi"),
150
151  /**
152   * Bosnian.
153   */
154  BOSNIAN("bs"),
155
156  /**
157   * Breton.
158   */
159  BRETON("br"),
160
161  /**
162   * Bulgarian.
163   */
164  BULGARIAN("bg"),
165
166  /**
167   * Burmese.
168   */
169  BURMESE("my"),
170
171  /**
172   * Catalan.
173   */
174  CATALAN("ca"),
175
176  /**
177   * Chamorro.
178   */
179  CHAMORRO("ch"),
180
181  /**
182   * Chechen.
183   */
184  CHECHEN("ce"),
185
186  /**
187   * Chinese.
188   */
189  CHINESE("zh"),
190
191  /**
192   * Church Slavic.
193   */
194  CHURCH_SLAVIC("cu"),
195
196  /**
197   * Chuvash.
198   */
199  CHUVASH("cv"),
200
201  /**
202   * Cornish.
203   */
204  CORNISH("kw"),
205
206  /**
207   * Corsican.
208   */
209  CORSICAN("co"),
210
211  /**
212   * Cree.
213   */
214  CREE("cr"),
215
216  /**
217   * Croatian.
218   */
219  CROATIAN("hr"),
220
221  /**
222   * Czech.
223   */
224  CZECH("cs"),
225
226  /**
227   * Danish.
228   */
229  DANISH("da"),
230
231  /**
232   * Divehi.
233   */
234  DIVEHI("dv"),
235
236  /**
237   * Dutch.
238   */
239  DUTCH("nl"),
240
241  /**
242   * Dzongkha.
243   */
244  DZONGKHA("dz"),
245
246  /**
247   * English.
248   */
249  ENGLISH("en"),
250
251  /**
252   * Esperanto.
253   */
254  ESPERANTO("eo"),
255
256  /**
257   * Estonian.
258   */
259  ESTONIAN("et"),
260
261  /**
262   * Ewe.
263   */
264  EWE("ee"),
265
266  /**
267   * Faroese.
268   */
269  FAROESE("fo"),
270
271  /**
272   * Fijian.
273   */
274  FIJIAN("fj"),
275
276  /**
277   * Finnish.
278   */
279  FINNISH("fi"),
280
281  /**
282   * French.
283   */
284  FRENCH("fr"),
285
286  /**
287   * Frisian.
288   */
289  FRISIAN("fy"),
290
291  /**
292   * Fulah.
293   */
294  FULAH("ff"),
295
296  /**
297   * Gallegan.
298   */
299  GALLEGAN("gl"),
300
301  /**
302   * Ganda.
303   */
304  GANDA("lg"),
305
306  /**
307   * Georgian.
308   */
309  GEORGIAN("ka"),
310
311  /**
312   * German.
313   */
314  GERMAN("de"),
315
316  /**
317   * Greek.
318   */
319  GREEK("el"),
320
321  /**
322   * Greenlandic.
323   */
324  GREENLANDIC("kl"),
325
326  /**
327   * Guarani.
328   */
329  GUARANI("gn"),
330
331  /**
332   * Gujarati.
333   */
334  GUJARATI("gu"),
335
336  /**
337   * Haitian.
338   */
339  HAITIAN("ht"),
340
341  /**
342   * Hausa.
343   */
344  HAUSA("ha"),
345
346  /**
347   * Hebrew.
348   */
349  HEBREW("he"),
350
351  /**
352   * Herero.
353   */
354  HERERO("hz"),
355
356  /**
357   * Hindi.
358   */
359  HINDI("hi"),
360
361  /**
362   * Hiri Motu.
363   */
364  HIRI_MOTU("ho"),
365
366  /**
367   * Hungarian.
368   */
369  HUNGARIAN("hu"),
370
371  /**
372   * Icelandic.
373   */
374  ICELANDIC("is"),
375
376  /**
377   * Ido.
378   */
379  IDO("io"),
380
381  /**
382   * Igbo.
383   */
384  IGBO("ig"),
385
386  /**
387   * Indonesian.
388   */
389  INDONESIAN("id"),
390
391  /**
392   * Interlingua.
393   */
394  INTERLINGUA("ia"),
395
396  /**
397   * Interlingue.
398   */
399  INTERLINGUE("ie"),
400
401  /**
402   * Inuktitut.
403   */
404  INUKTITUT("iu"),
405
406  /**
407   * Inupiaq.
408   */
409  INUPIAQ("ik"),
410
411  /**
412   * Irish.
413   */
414  IRISH("ga"),
415
416  /**
417   * Italian.
418   */
419  ITALIAN("it"),
420
421  /**
422   * Japanese.
423   */
424  JAPANESE("ja"),
425
426  /**
427   * Javanese.
428   */
429  JAVANESE("jv"),
430
431  /**
432   * Kannada.
433   */
434  KANNADA("kn"),
435
436  /**
437   * Kanuri.
438   */
439  KANURI("kr"),
440
441  /**
442   * Kashmiri.
443   */
444  KASHMIRI("ks"),
445
446  /**
447   * Kazakh.
448   */
449  KAZAKH("kk"),
450
451  /**
452   * Khmer.
453   */
454  KHMER("km"),
455
456  /**
457   * Kikuyu.
458   */
459  KIKUYU("ki"),
460
461  /**
462   * Kinyarwanda.
463   */
464  KINYARWANDA("rw"),
465
466  /**
467   * Kirghiz.
468   */
469  KIRGHIZ("ky"),
470
471  /**
472   * Komi.
473   */
474  KOMI("kv"),
475
476  /**
477   * Kongo.
478   */
479  KONGO("kg"),
480
481  /**
482   * Korean.
483   */
484  KOREAN("ko"),
485
486  /**
487   * Kurdish.
488   */
489  KURDISH("ku"),
490
491  /**
492   * Kwanyama.
493   */
494  KWANYAMA("kj"),
495
496  /**
497   * Lao.
498   */
499  LAO("lo"),
500
501  /**
502   * Latin.
503   */
504  LATIN("la"),
505
506  /**
507   * Latvian.
508   */
509  LATVIAN("lv"),
510
511  /**
512   * Limburgish.
513   */
514  LIMBURGISH("li"),
515
516  /**
517   * Lingala.
518   */
519  LINGALA("ln"),
520
521  /**
522   * Lithuanian.
523   */
524  LITHUANIAN("lt"),
525
526  /**
527   * Luba-Katanga.
528   */
529  LUBA_KATANGA("lu"),
530
531  /**
532   * Luxembourgish.
533   */
534  LUXEMBOURGISH("lb"),
535
536  /**
537   * Macedonian.
538   */
539  MACEDONIAN("mk"),
540
541  /**
542   * Malagasy.
543   */
544  MALAGASY("mg"),
545
546  /**
547   * Malay.
548   */
549  MALAY("ms"),
550
551  /**
552   * Malayalam.
553   */
554  MALAYALAM("ml"),
555
556  /**
557   * Maltese.
558   */
559  MALTESE("mt"),
560
561  /**
562   * Manx.
563   */
564  MANX("gv"),
565
566  /**
567   * Maori.
568   */
569  MAORI("mi"),
570
571  /**
572   * Marathi.
573   */
574  MARATHI("mr"),
575
576  /**
577   * Marshallese.
578   */
579  MARSHALLESE("mh"),
580
581  /**
582   * Moldavian.
583   */
584  MOLDAVIAN("mo"),
585
586  /**
587   * Mongolian.
588   */
589  MONGOLIAN("mn"),
590
591  /**
592   * Nauru.
593   */
594  NAURU("na"),
595
596  /**
597   * Navajo.
598   */
599  NAVAJO("nv"),
600
601  /**
602   * Ndonga.
603   */
604  NDONGA("ng"),
605
606  /**
607   * Nepali.
608   */
609  NEPALI("ne"),
610
611  /**
612   * North Ndebele.
613   */
614  NORTH_NDEBELE("nd"),
615
616  /**
617   * Northern Sami.
618   */
619  NORTHERN_SAMI("se"),
620
621  /**
622   * Norwegian Bokmål.
623   */
624  NORWEGIAN_BOKMAL("nb"),
625
626  /**
627   * Norwegian Nynorsk.
628   */
629  NORWEGIAN_NYNORSK("nn"),
630
631  /**
632   * Norwegian.
633   */
634  NORWEGIAN("no"),
635
636  /**
637   * Nyanja.
638   */
639  NYANJA("ny"),
640
641  /**
642   * Occitan.
643   */
644  OCCITAN("oc"),
645
646  /**
647   * Ojibwa.
648   */
649  OJIBWA("oj"),
650
651  /**
652   * Oriya.
653   */
654  ORIYA("or"),
655
656  /**
657   * Oromo.
658   */
659  OROMO("om"),
660
661  /**
662   * Ossetian.
663   */
664  OSSETIAN("os"),
665
666  /**
667   * Pali.
668   */
669  PALI("pi"),
670
671  /**
672   * Panjabi.
673   */
674  PANJABI("pa"),
675
676  /**
677   * Persian.
678   */
679  PERSIAN("fa"),
680
681  /**
682   * Polish.
683   */
684  POLISH("pl"),
685
686  /**
687   * Portuguese.
688   */
689  PORTUGUESE("pt"),
690
691  /**
692   * Pushto.
693   */
694  PUSHTO("ps"),
695
696  /**
697   * Quechua.
698   */
699  QUECHUA("qu"),
700
701  /**
702   * Raeto-Romance.
703   */
704  RAETO_ROMANCE("rm"),
705
706  /**
707   * Romanian.
708   */
709  ROMANIAN("ro"),
710
711  /**
712   * Rundi.
713   */
714  RUNDI("rn"),
715
716  /**
717   * Russian.
718   */
719  RUSSIAN("ru"),
720
721  /**
722   * Samoan.
723   */
724  SAMOAN("sm"),
725
726  /**
727   * Sango.
728   */
729  SANGO("sg"),
730
731  /**
732   * Sanskrit.
733   */
734  SANSKRIT("sa"),
735
736  /**
737   * Sardinian.
738   */
739  SARDINIAN("sc"),
740
741  /**
742   * Scottish Gaelic.
743   */
744  SCOTTISH_GAELIC("gd"),
745
746  /**
747   * Serbian.
748   */
749  SERBIAN("sr"),
750
751  /**
752   * Shona.
753   */
754  SHONA("sn"),
755
756  /**
757   * Sichuan Yi.
758   */
759  SICHUAN_YI("ii"),
760
761  /**
762   * Sindhi.
763   */
764  SINDHI("sd"),
765
766  /**
767   * Sinhalese.
768   */
769  SINHALESE("si"),
770
771  /**
772   * Slovak.
773   */
774  SLOVAK("sk"),
775
776  /**
777   * Slovenian.
778   */
779  SLOVENIAN("sl"),
780
781  /**
782   * Somali.
783   */
784  SOMALI("so"),
785
786  /**
787   * South Ndebele.
788   */
789  SOUTH_NDEBELE("nr"),
790
791  /**
792   * Southern Sotho.
793   */
794  SOUTHERN_SOTHO("st"),
795
796  /**
797   * Spanish.
798   */
799  SPANISH("es"),
800
801  /**
802   * Sundanese.
803   */
804  SUNDANESE("su"),
805
806  /**
807   * Swahili.
808   */
809  SWAHILI("sw"),
810
811  /**
812   * Swati.
813   */
814  SWATI("ss"),
815
816  /**
817   * Swedish.
818   */
819  SWEDISH("sv"),
820
821  /**
822   * Tagalog.
823   */
824  TAGALOG("tl"),
825
826  /**
827   * Tahitian.
828   */
829  TAHITIAN("ty"),
830
831  /**
832   * Tajik.
833   */
834  TAJIK("tg"),
835
836  /**
837   * Tamil.
838   */
839  TAMIL("ta"),
840
841  /**
842   * Tatar.
843   */
844  TATAR("tt"),
845
846  /**
847   * Telugu.
848   */
849  TELUGU("te"),
850
851  /**
852   * Thai.
853   */
854  THAI("th"),
855
856  /**
857   * Tibetan.
858   */
859  TIBETAN("bo"),
860
861  /**
862   * Tigrinya.
863   */
864  TIGRINYA("ti"),
865
866  /**
867   * Tonga.
868   */
869  TONGA("to"),
870
871  /**
872   * Tsonga.
873   */
874  TSONGA("ts"),
875
876  /**
877   * Tswana.
878   */
879  TSWANA("tn"),
880
881  /**
882   * Turkish.
883   */
884  TURKISH("tr"),
885
886  /**
887   * Turkmen.
888   */
889  TURKMEN("tk"),
890
891  /**
892   * Twi.
893   */
894  TWI("tw"),
895
896  /**
897   * Uighur.
898   */
899  UIGHUR("ug"),
900
901  /**
902   * Ukrainian.
903   */
904  UKRAINIAN("uk"),
905
906  /**
907   * Urdu.
908   */
909  URDU("ur"),
910
911  /**
912   * Uzbek.
913   */
914  UZBEK("uz"),
915
916  /**
917   * Venda.
918   */
919  VENDA("ve"),
920
921  /**
922   * Vietnamese.
923   */
924  VIETNAMESE("vi"),
925
926  /**
927   * Volapük.
928   */
929  VOLAPÜK("vo"),
930
931  /**
932   * Walloon.
933   */
934  WALLOON("wa"),
935
936  /**
937   * Welsh.
938   */
939  WELSH("cy"),
940
941  /**
942   * Wolof.
943   */
944  WOLOF("wo"),
945
946  /**
947   * Xhosa.
948   */
949  XHOSA("xh"),
950
951  /**
952   * Yiddish.
953   */
954  YIDDISH("yi"),
955
956  /**
957   * Yoruba.
958   */
959  YORUBA("yo"),
960
961  /**
962   * Zhuang.
963   */
964  ZHUANG("za"),
965
966  /**
967   * Zulu.
968   */
969  ZULU("zu"),
970
971  /**
972   * Unknown or Invalid language.
973   */
974  UNKNOWN("");
975
976  public static final List<Language> LANGUAGES;
977
978  private final String code;
979
980  static {
981    LANGUAGES = ImmutableList.copyOf(Language.values());
982  }
983
984  /**
985   * @param code the case insensitive 2 or 3 letter codes
986   *
987   * @return the matching language or UNKNOWN
988   */
989  public static Language fromIsoCode(String code) {
990    if (!Strings.isNullOrEmpty(code)) {
991      String codeLower = code.toLowerCase().trim();
992      if (codeLower.length() == 2){
993        for (Language language : Language.values()) {
994          if (codeLower.equals(language.getIso2LetterCode())) {
995            return language;
996          }
997        }
998      } else if (codeLower.length() == 3) {
999        for (Language language : Language.values()) {
1000          if (codeLower.equals(language.getIso3LetterCode())) {
1001            return language;
1002          }
1003        }
1004      }
1005    }
1006    return UNKNOWN;
1007  }
1008
1009  Language(String code) {
1010    this.code = code;
1011  }
1012
1013  /**
1014   * @return the 2 letter iso 639-1 code in lower case.
1015   */
1016  public String getIso2LetterCode() {
1017    return code;
1018  }
1019
1020  /**
1021   * @return the 3 letter iso 639-2 code in lower case.
1022   */
1023  public String getIso3LetterCode() {
1024    return getLocale().getISO3Language();
1025  }
1026
1027  public Locale getLocale() {
1028    return new Locale(code);
1029  }
1030
1031  /**
1032   * @return the language title in the English language.
1033   */
1034  public String getTitleEnglish() {
1035    return getLocale().getDisplayLanguage(Locale.ENGLISH);
1036  }
1037
1038  /**
1039   * @return the language title in the native language.
1040   */
1041  public String getTitleNative() {
1042    Locale loc = getLocale();
1043    return loc.getDisplayLanguage(loc);
1044  }
1045
1046  /**
1047   * Serializes the value in a 3 letter ISO format.
1048   */
1049  public static class IsoSerializer extends SerializerBase<Language> {
1050
1051    public IsoSerializer() {
1052      super(Language.class);
1053    }
1054
1055    @Override
1056    public void serialize(Language value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
1057      JsonGenerationException {
1058      jgen.writeString(value.getIso3LetterCode());
1059    }
1060
1061  }
1062
1063  /**
1064   * Deserializes the value from a 3 letter ISO format or the enumeration name itself to maintain as much
1065   * backwards compatibility as possible with e.g. the registry api.
1066   */
1067  public static class LenientDeserializer extends JsonDeserializer<Language> {
1068
1069    @Override
1070    public Language deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
1071      try {
1072        if (jp != null && jp.getTextLength() > 0) {
1073          return lenientParse(jp.getText());
1074        } else {
1075          return Language.UNKNOWN; // none provided
1076        }
1077      } catch (Exception e) {
1078        throw new IOException("Unable to deserialize language from provided value (hint: not an ISO 2 or 3 character?): "
1079                              + jp.getText());
1080      }
1081    }
1082
1083    @VisibleForTesting
1084    static Language lenientParse(String value) {
1085      Language l = Language.fromIsoCode(value);
1086      // backwards compatible
1087      if (UNKNOWN == l) {
1088        try {
1089          l = valueOf(value);
1090        } catch( IllegalArgumentException e) {
1091          l = UNKNOWN;
1092        }
1093      }
1094      return l;
1095    }
1096  }
1097}