From: simonbrandhof Date: Tue, 26 Apr 2011 15:32:27 +0000 (+0200) Subject: Fix rendering of age (variable {count} not interpreted) X-Git-Tag: 2.8~123 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=b17802d66f0d7d75ca7a8581f146e5147e1e56e9;p=sonarqube.git Fix rendering of age (variable {count} not interpreted) --- diff --git a/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/es-PE.yml b/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/es-PE.yml index 356546ab727..455f74b5ce5 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/es-PE.yml +++ b/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/es-PE.yml @@ -52,34 +52,34 @@ es-PE: half_a_minute: "medio minuto" less_than_x_seconds: one: "menos de 1 segundo" - other: "menos de {{count}} segundos" + other: "menos de %{count} segundos" x_seconds: one: "1 segundo" - other: "{{count}} segundos" + other: "%{count} segundos" less_than_x_minutes: one: "menos de 1 minuto" - other: "menos de {{count}} minutos" + other: "menos de %{count} minutos" x_minutes: one: "1 minuto" - other: "{{count}} minutos" + other: "%{count} minutos" about_x_hours: one: "cerca de 1 hora" - other: "cerca de {{count}} horas" + other: "cerca de %{count} horas" x_days: one: "1 día" - other: "{{count}} días" + other: "%{count} días" about_x_months: one: "cerca de 1 mes" - other: "cerca de {{count}} meses" + other: "cerca de %{count} meses" x_months: one: "1 mes" - other: "{{count}} meses" + other: "%{count} meses" about_x_years: - other: "cerca de {{count}} años" + other: "cerca de %{count} años" one: "cerca de 1 año" over_x_years: one: "más de 1 año" - other: "más de {{count}} años" + other: "más de %{count} años" prompts: hour: 'Hora' minute: 'Minuto' @@ -92,7 +92,7 @@ es-PE: template: header: one: "{{model}} no pudo guardarse debido a 1 error" - other: "{{model}} no pudo guardarse debido a {{count}} errores" + other: "{{model}} no pudo guardarse debido a %{count} errores" body: "Revise que los siguientes campos sean válidos:" messages: record_invalid: "Falla de validación: {{errors}}" @@ -106,19 +106,19 @@ es-PE: empty: "no puede estar vacío" not_a_number: "no es un número" taken: "ya ha sido tomado" - less_than: "debe ser menor que {{count}}" - less_than_or_equal_to: "debe ser menor o igual que {{count}}" - greater_than: "debe ser mayor que {{count}}" - greater_than_or_equal_to: "debe ser mayor o igual que {{count}}" + less_than: "debe ser menor que %{count}" + less_than_or_equal_to: "debe ser menor o igual que %{count}" + greater_than: "debe ser mayor que %{count}" + greater_than_or_equal_to: "debe ser mayor o igual que %{count}" too_short: one: "es demasiado corto (mínimo 1 caracter)" - other: "es demasiado corto (mínimo {{count}} caracteres)" + other: "es demasiado corto (mínimo %{count} caracteres)" too_long: one: "es demasiado largo (máximo 1 caracter)" - other: "es demasiado largo (máximo {{count}} caracteres)" - equal_to: "debe ser igual a {{count}}" + other: "es demasiado largo (máximo %{count} caracteres)" + equal_to: "debe ser igual a %{count}" wrong_length: one: "longitud errónea (debe ser de 1 caracter)" - other: "longitud errónea (debe ser de {{count}} caracteres)" + other: "longitud errónea (debe ser de %{count} caracteres)" even: "debe ser un número par" odd: "debe ser un número non" \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/eu.yml b/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/eu.yml index e48249976f2..6242dc381f4 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/eu.yml +++ b/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/eu.yml @@ -171,7 +171,7 @@ template: header: one: "Errore batek ezinezkoa egin du {{model}} hau gordetzea" - other: "{{count}} errorek ezinezkoa egiten dute {{model}} hau gordetzea" + other: "%{count} errorek ezinezkoa egiten dute {{model}} hau gordetzea" body: "Arazoak egon dira ondoko eremuekin:" messages: diff --git a/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/sw.yml b/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/sw.yml index e9b33413f3e..3a342c63a64 100644 --- a/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/sw.yml +++ b/sonar-server/src/main/webapp/WEB-INF/config/locales/defaults/sw.yml @@ -157,11 +157,11 @@ sw: wrong_length: 'idadi ya herufi hazilingani (inatakiwa %{count})' not_a_number: 'inaruhusiwa namba tu' not_an_integer: 'inaruhusiwa namba tu' - greater_than: 'z/iwe zaidi ya {{count}}' - greater_than_or_equal_to: 'z/iwe sawa ama zaidi ya {{count}}' - equal_to: 'z/iwe sawa na {{count}}' - less_than: 'z/isizidi {{count}}' - less_than_or_equal_to: 'z/iwe sawa na, ama chini ya {{count}}' + greater_than: 'z/iwe zaidi ya %{count}' + greater_than_or_equal_to: 'z/iwe sawa ama zaidi ya %{count}' + equal_to: 'z/iwe sawa na %{count}' + less_than: 'z/isizidi %{count}' + less_than_or_equal_to: 'z/iwe sawa na, ama chini ya %{count}' odd: 'z/iwe witiri' even: 'z/iwe shufwa' diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/.specification b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/.specification new file mode 100644 index 00000000000..42568afc700 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/.specification @@ -0,0 +1,105 @@ +--- !ruby/object:Gem::Specification +name: i18n +version: !ruby/object:Gem::Version + prerelease: false + segments: + - 0 + - 4 + - 2 + version: 0.4.2 +platform: ruby +authors: + - Sven Fuchs + - Joshua Harvey + - Matt Aimonetti + - Stephan Soller + - Saimon Moore +autorequire: +bindir: bin +cert_chain: [] + +date: 2010-10-26 00:00:00 +02:00 +default_executable: +dependencies: [] + +description: New wave Internationalization support for Ruby. +email: rails-i18n@googlegroups.com +executables: [] + +extensions: [] + +extra_rdoc_files: [] + +files: + - lib/i18n.rb + - lib/i18n/backend.rb + - lib/i18n/backend/active_record.rb + - lib/i18n/backend/active_record/missing.rb + - lib/i18n/backend/active_record/store_procs.rb + - lib/i18n/backend/active_record/translation.rb + - lib/i18n/backend/base.rb + - lib/i18n/backend/cache.rb + - lib/i18n/backend/cascade.rb + - lib/i18n/backend/chain.rb + - lib/i18n/backend/cldr.rb + - lib/i18n/backend/fallbacks.rb + - lib/i18n/backend/flatten.rb + - lib/i18n/backend/gettext.rb + - lib/i18n/backend/interpolation_compiler.rb + - lib/i18n/backend/key_value.rb + - lib/i18n/backend/memoize.rb + - lib/i18n/backend/metadata.rb + - lib/i18n/backend/pluralization.rb + - lib/i18n/backend/simple.rb + - lib/i18n/backend/transliterator.rb + - lib/i18n/config.rb + - lib/i18n/core_ext/hash.rb + - lib/i18n/core_ext/string/interpolate.rb + - lib/i18n/exceptions.rb + - lib/i18n/gettext.rb + - lib/i18n/gettext/helpers.rb + - lib/i18n/gettext/po_parser.rb + - lib/i18n/locale.rb + - lib/i18n/locale/fallbacks.rb + - lib/i18n/locale/tag.rb + - lib/i18n/locale/tag/parents.rb + - lib/i18n/locale/tag/rfc4646.rb + - lib/i18n/locale/tag/simple.rb + - lib/i18n/version.rb + - README.textile + - MIT-LICENSE + - CHANGELOG.textile +has_rdoc: true +homepage: http://github.com/svenfuchs/i18n +licenses: [] + +post_install_message: +rdoc_options: [] + +require_paths: + - lib +required_ruby_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + segments: + - 0 + version: "0" +required_rubygems_version: !ruby/object:Gem::Requirement + requirements: + - - ">=" + - !ruby/object:Gem::Version + segments: + - 1 + - 3 + - 5 + version: 1.3.5 +requirements: [] + +rubyforge_project: "[none]" +rubygems_version: 1.3.6 +signing_key: +specification_version: 3 +summary: New wave Internationalization support for Ruby +test_files: [] + diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/CHANGELOG.textile b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/CHANGELOG.textile new file mode 100644 index 00000000000..31b4fb2e5d9 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/CHANGELOG.textile @@ -0,0 +1,143 @@ +h1. Changelog + +h2. 0.4.2 (2010-10-26) + +* "Improve UTF8 handling":http://github.com/svenfuchs/i18n/commit/e8d5820a3b08eeca28de1a2b9c8a6ad2b9e6476c +* "Expose I18n::VERSION":http://github.com/svenfuchs/i18n/commit/b832037bac94c7144f45f3ff5e3b4e4089781726 +* "Better deprecation output":http://github.com/svenfuchs/i18n/commit/2bee924464b8a9c33d3d7852eb1c8423aa38cc25 + +h2. 0.4.1 (2010-06-05) + +* "Fix interpolation failure on Ruby 1.9":http://github.com/svenfuchs/i18n/commit/8d45bedb11c4136c00e853d104b00a8e67ec4894 + +h2. 0.4.0 (2010-05-27) + +* "The localization proc also receives the object as option":http://github.com/svenfuchs/i18n/commit/4a8cd9fa660daaa3078e24c5851353ca377d9213 + +h2. 0.4.0.beta1 (2010-05-03) + +* "Renamed Fast backend to Memoize backend":http://github.com/svenfuchs/i18n/commit/f7f7dc12c00a19d3876223771e14f8671ff313cd + +* "Deprecate {{}} as interpolation syntax":http://github.com/svenfuchs/i18n/commit/8894ee521ef5788c415b625a6daf522af4c416e0 + +* "Allow nil translation to be stored again":http://github.com/svenfuchs/i18n/commit/f2074f1e82d10c2e9a801c8cc2f2a0c7c30703ba + +h2. 0.4.0.beta (2010-04-30) + +* "Added a KeyValue backend":http://github.com/svenfuchs/i18n/commit/28ca5f53ade7f545f8c0804e93564d4686b416a4 + +* "Added transliteration support":http://github.com/svenfuchs/i18n/commit/928fdb4794959e779e90f360eb01ba043672d8d5 + +* "Create Flatten backend module to aid handling flatten translations":http://github.com/svenfuchs/i18n/commit/2ec9d6998aa8facd7b15a3ef47a96cf2471cd8a1 + +* "Decouple the external separator (used when storing translations) from the internal separator in Fast and ActiveRecord backends":http://github.com/svenfuchs/i18n/commit/274cb4daa0ca5e3b2bd23b45eb7f9fc58f75a79d + +h2. 0.3.7 (2010-04-17) + +* "Speed up I18n.normalize_keys by caching reused normalizations and producing less garbage":http://github.com/svenfuchs/i18n/commit/819dac0fea9c29e6545801aa107e63e355728cd4 + +h2. 0.3.6 (2010-03-23) + +* "Move gettext po parser to lib":http://github.com/svenfuchs/i18n/commit/b2f038663b55727ac2327e6f07a46ba5d69d600c + +* "Move I18n configuration to I18n.config":http://github.com/svenfuchs/i18n/commit/4a7baea86663ead8c681008c3e80a622f0546b07 + +h2. 0.3.5 (2010-02-26) + +* "Delegate I18n.normalize_translation_keys to I18n.normalize_keys and deprecate +the former":http://github.com/svenfuchs/i18n/commit/7284b04d5f5dd9679cb68875515cdd0cdfc96fef + +h2. 0.3.4 (2010-02-25) + +* "Rename I18n.normalize_translation_keys to I18n.normalize_keys and finally make it public":http://github.com/svenfuchs/i18n/commit/20b05fe5802df6c90fb70a4e3760b2b851b791b3 + +* "Added CLDR supoprt":http://github.com/svenfuchs/i18n/commit/860eadf671a231e7f5dffb1bb27fa318ff7a8786 + +h2. 0.3.3 (2009-12-29) + +* "Use lib/i18n/version":http://github.com/svenfuchs/i18n/commit/ff426c8e7a2438b814cb303adadec292dacb752e + +* "Added a benchmark suite":http://github.com/svenfuchs/i18n/commit/f9b5b9b113097724638bdab96862ffa404e67e70 + +* "Ensure links can be handled recursively":http://github.com/svenfuchs/i18n/commit/2c50bd209f3fc24fe9dfa694c81be64340f09b7d + +* "Make sure we can lookup false values as translation data":http://github.com/svenfuchs/i18n/commit/561c82ba4b8921d03bfdf56cb2d0c2f287629001 + +* "Added Fast backend module":http://github.com/svenfuchs/i18n/commit/bd2f09f0a251ca793b0e8ecc7e32177a2f091c23 + +* "Added InterpolationCompiler backend module":http://github.com/svenfuchs/i18n/commit/91810887d1abfb28996a9183bc9004678290d28b + +h2. 0.3.2 (2009-12-12) + +* "Added Cascade backend":http://github.com/svenfuchs/i18n/commit/8009aef293e9ef8564c9005090d8380feabcaf6f + +h2. 0.3.1 (2009-12-11) + +* "Add PoParser to gemspec":http://github.com/svenfuchs/i18n/commit/d6b2763f39c932f66adb039b96882a472f883c51 +* "Enable custom separators for ActiveRecord backend":http://github.com/svenfuchs/i18n/commit/9341d3fcfc951cc31807ba672d2b5d90909ef3e5 +* "Pass interpolation values to interpolation procs":http://github.com/svenfuchs/i18n/commit/39c2ed8fbad645671cd5520ce7ad0aeefe2b0cca +* "Fix that ngettext supports keys with dots":http://github.com/svenfuchs/i18n/commit/7362a43c34364d500de8899cfcca6bf1a5e6d1c8 + +h2. 0.3.0 (2009-11-30) + +* "Gettext backend and helpers":http://github.com/svenfuchs/i18n/commit/35a1740d2f10b808548af352006950da4017e374 +* "Metadata module":http://github.com/svenfuchs/i18n/commit/2677208555179b36fcbe958c0e8bc642cf5bc020 +* "Basic ActiveRecord backend":http://github.com/svenfuchs/i18n/commit/786632d0b42de423ecf0969622efc87f1691e2a2 +* "Set encoding to UTF8 for all files":http://github.com/svenfuchs/i18n/commit/9be3d4a311b5bf583eec5d39986176cc40c112f2 +* "Chain backend":http://github.com/svenfuchs/i18n/commit/08259ffb88b3005403648d77bc1cbca0b92f3cf5 +* "Backend/cache implementation":http://github.com/svenfuchs/i18n/commit/e7bf15351cd2e27f5972eb40e65a5dd6f4a0feed +* "Pluralization module":http://github.com/svenfuchs/i18n/commit/9ca4c9ed52d4706566a6abeb2d78722dcc5d4764 +* "add and adapt Globalize2 fallback implementation":http://github.com/svenfuchs/i18n/commit/1b37a303b27d6222b17162804b06323e5628768f +* "move Simple backend implementation to a Base backend class and extend Simple from Base.":http://github.com/svenfuchs/i18n/commit/32ddc80a04e6aa247f6d6613bde7f78c73396cb4 + +h2. 0.2.0 (2009-07-12) + +* "Allow using Ruby 1.9 syntax for string interpolation (API addition)":http://github.com/svenfuchs/i18n/commit/c6e0b06d512f2af57199a843a1d8a40241b32861 +* "Allow configuring the default scope separator, allow to pass a custom scope separator(API addition)":http://github.com/svenfuchs/i18n/commit/5b75bfbc348061adc11e3790187a187275bfd471 (e.g. I18n.t(:'foo|bar', :separator => '|') +* "Pass :format option to #translate for #localize more useful lambda support":http://github.com/svenfuchs/i18n/commit/e277711b3c844fe7589b8d3f9af0f7d1b969a273 +* "Refactor Simple backend #resolve to #default and #resolve for more consistency. Now allows to pass lambdas as defaults and re-resolve Symbols":http://github.com/svenfuchs/i18n/commit/8c4ce3d923ce5fa73e973fe28217e18165549aba +* "Add lambda support to #translate (API addition)":http://github.com/svenfuchs/i18n/commit/c90e62d8f7d3d5b78f34cfe328d871b58884f115 +* "Add lambda support to #localize (API addition)":http://github.com/svenfuchs/i18n/commit/9d390afcf33f3f469bb95e6888147152f6cc7442 + +h2. 0.1.3 (2009-02-27) + +* "Remove unnecessary string encoding handling in the i18n simple backend which made the backend break on Ruby 1.9":http://github.com/svenfuchs/i18n/commit/4c3a970783861a94f2e89f46714fb3434e4f4f8d + +h2. 0.1.2 (2009-01-09) + +* "added #available_locales (returns an array of locales for which translations are available)":http://github.com/svenfuchs/i18n/commit/411f8fe7c8f3f89e9b6b921fa62ed66cb92f3af4 +* "flatten load_path before using it so that a nested array of paths won't throw up":http://github.com/svenfuchs/i18n/commit/d473a068a2b90aba98135deb225d6eb6d8104d70 + +h2. 0.1.1 (2008-11-20) + +* "Use :'en' as a default locale (in favor of :'en-US')":http://github.com/svenfuchs/i18n/commit/c4b10b246aecf7da78cb2568dd0d2ab7e6b8a230 +* "Add #reload! to Simple backend":http://github.com/svenfuchs/i18n/commit/36dd2bd9973b9e1559728749a9daafa44693e964 + +h2. 0.1.0 (2008-10-25) + +* "Fix Simple backend to distinguish false from nil values":http://github.com/svenfuchs/i18n/commit/39d9a47da14b5f3ba126af48923af8c30e135166 +* "Add #load_path to public api, add initialize to simple backend and remove #load_translations from public api":http://github.com/svenfuchs/i18n/commit/c4c5649e6bc8f020f1aaf5a5470bde048e22c82d +* "Speed up Backend::Simple#interpolate":http://github.com/svenfuchs/i18n/commit/9e1ac6bf8833304e036323ec9932b9f33c468a35 +* "Remove #populate and #store_translations from public API":http://github.com/svenfuchs/i18n/commit/f4e514a80be7feb509f66824ee311905e2940900 +* "Use :other instead of :many as a plural key":http://github.com/svenfuchs/i18n/commit/0f8f20a2552bf6a2aa758d8fdd62a7154e4a1bf6 +* "Use a class instead of a module for Simple backend":http://github.com/svenfuchs/i18n/commit/08f051aa61320c17debde24a83268bc74e33b995 +* "Make Simple backend #interpolate deal with non-ASCII string encodings":http://github.com/svenfuchs/i18n/commit/d84a3f3f55543c084d5dc5d1fed613b8df148789 +* "Fix default arrays of non-existant keys returning the default array":http://github.com/svenfuchs/i18n/commit/6c04ca86c87f97dc78f07c2a4023644e5ba8b839 + +h2. Initial implementation (June/July 2008) + +Initial implementation by "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs based on previous discussion/consensus of the rails-i18n team (alphabetical order) and many others: + +* "Matt Aimonetti":http://railsontherun.com +* "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs +* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey +* "Saimon Moore":http://saimonmoore.net +* "Stephan Soller":http://www.arkanis-development.de + +h2. More information + +* "Homepage":http://rails-i18n.org +* "Wiki":http://rails-i18n.org/wiki +* "Mailinglist":http://groups.google.com/group/rails-i18n +* "About the project/history":http://www.artweb-design.de/2008/7/18/finally-ruby-on-rails-gets-internationalized +* "Initial API Intro":http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/MIT-LICENSE b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/MIT-LICENSE new file mode 100755 index 00000000000..ed8e9ee66db --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 The Ruby I18n team + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/README.textile b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/README.textile new file mode 100644 index 00000000000..7c8ce0f9acb --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/README.textile @@ -0,0 +1,116 @@ +h1. Ruby I18n + +Ruby Internationalization and localization solution. + +Features: + +* translation and localization +* interpolation of values to translations (Ruby 1.9 compatible syntax) +* pluralization (CLDR compatible) +* customizable transliteration to ASCII +* flexible defaults +* bulk lookup +* lambdas as translation data +* custom key/scope separator +* custom exception handlers +* extensible architecture with a swappable backend + +Pluggable features: + +* Cache +* Pluralization: lambda pluralizers stored as translation data +* Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation) +* Gettext support +* Translation metadata + +Alternative backends: + +* Chain +* ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs) +* KeyValue (uses active_support/json and cannot store procs) + +For more information and lots of resources see: "http://ruby-i18n.org/wiki":http://ruby-i18n.org/wiki + +h2. Installation + +gem install i18n + +h4. Rails version warning + +On Rails < 2.3.6 the method I18n.localize will fail with MissingInterpolationArgument (issue "20":http://github.com/svenfuchs/i18n/issues/issue/20). Upgrade to Rails 2.3.6 or higher (2.3.8 preferably) is recommended. + +h3. Installation on Rails < 2.3.5 (deprecated) + +Up to version 2.3.4 Rails will not accept i18n gems > 0.1.3. There is an unpacked +gem inside of active_support/lib/vendor which gets loaded unless gem 'i18n', '~> 0.1.3'. +This requirement is relaxed in "6da03653":http://github.com/rails/rails/commit/6da03653 + +The new i18n gem can be loaded from vendor/plugins like this: + +
+  def reload_i18n!
+    raise "Move to i18n version 0.2.0 or greater" if Rails.version > "2.3.4"
+
+    $:.grep(/i18n/).each { |path| $:.delete(path) }
+    I18n::Backend.send :remove_const, "Simple"
+    $: << Rails.root.join('vendor', 'plugins', 'i18n', 'lib').to_s
+  end
+
+ +Then you can `reload_i18n!` inside an i18n initializer. + +h2. Tests + +You can run tests both with + +* `rake test` or just `rake` +* run any test file directly, e.g. `ruby test/api/simple_test.rb` +* run all tests with `ruby test/all.rb` + +You can parametrize the test suite for using different sets of dependencies by +using: + +.pre `ruby test/all.rb -w DEPENDENCIES` + +... where DEPENDENCIES is a comma-separated list of: + +* r23 or rails-2.3.x +* r3 or rails-3.x +* no-rails +* sqlite +* mysql + +So, e.g. this would run the test suite against Rails 2.3.x using mysql: + +.pre `ruby test/all.rb -w r23,mysql` + +The structure of the test suite is a bit unusual as it uses modules to reuse +particular tests in different test cases. + +The reason for this is that we need to enforce the I18n API across various +combinations of extensions. E.g. the Simple backend alone needs to support +the same API as any combination of feature and/or optimization modules included +to the Simple backend. We test this by reusing the same API defition (implemented +as test methods) in test cases with different setups. + +You can find the test cases that enforce the API in test/api. And you can find +the API definition test methods in test/api/tests. + +All other test cases (e.g. as defined in test/backend, test/core\_ext) etc. +follow the usual test setup and should be easy to grok. + +h2. Authors + +* "Sven Fuchs":http://www.artweb-design.de +* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey +* "Stephan Soller":http://www.arkanis-development.de +* "Saimon Moore":http://saimonmoore.net +* "Matt Aimonetti":http://railsontherun.com + +h2. Contributors + +http://github.com/svenfuchs/i18n/contributors + +h2. License + +MIT License. See the included MIT-LICENSE file. diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n.rb new file mode 100755 index 00000000000..5be3a797284 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n.rb @@ -0,0 +1,331 @@ +# encoding: utf-8 + +# Authors:: Sven Fuchs (http://www.artweb-design.de), +# Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey), +# Stephan Soller (http://www.arkanis-development.de/), +# Saimon Moore (http://saimonmoore.net), +# Matt Aimonetti (http://railsontherun.com/) +# Copyright:: Copyright (c) 2008 The Ruby i18n Team +# License:: MIT +require 'i18n/version' +require 'i18n/exceptions' +require 'i18n/core_ext/string/interpolate' + +module I18n + autoload :Backend, 'i18n/backend' + autoload :Config, 'i18n/config' + autoload :Gettext, 'i18n/gettext' + autoload :Locale, 'i18n/locale' + + class << self + # Gets I18n configuration object. + def config + Thread.current[:i18n_config] ||= I18n::Config.new + end + + # Sets I18n configuration object. + def config=(value) + Thread.current[:i18n_config] = value + end + + # Write methods which delegates to the configuration object + %w(locale backend default_locale available_locales default_separator + exception_handler load_path).each do |method| + module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1 + def #{method} + config.#{method} + end + + def #{method}=(value) + config.#{method} = (value) + end + DELEGATORS + end + + # Tells the backend to reload translations. Used in situations like the + # Rails development environment. Backends can implement whatever strategy + # is useful. + def reload! + config.backend.reload! + end + + # Translates, pluralizes and interpolates a given key using a given locale, + # scope, and default, as well as interpolation values. + # + # *LOOKUP* + # + # Translation data is organized as a nested hash using the upper-level keys + # as namespaces. E.g., ActionView ships with the translation: + # :date => {:formats => {:short => "%b %d"}}. + # + # Translations can be looked up at any level of this hash using the key argument + # and the scope option. E.g., in this example I18n.t :date + # returns the whole translations hash {:formats => {:short => "%b %d"}}. + # + # Key can be either a single key or a dot-separated key (both Strings and Symbols + # work). E.g., the short format can be looked up using both: + # I18n.t 'date.formats.short' + # I18n.t :'date.formats.short' + # + # Scope can be either a single key, a dot-separated key or an array of keys + # or dot-separated keys. Keys and scopes can be combined freely. So these + # examples will all look up the same short date format: + # I18n.t 'date.formats.short' + # I18n.t 'formats.short', :scope => 'date' + # I18n.t 'short', :scope => 'date.formats' + # I18n.t 'short', :scope => %w(date formats) + # + # *INTERPOLATION* + # + # Translations can contain interpolation variables which will be replaced by + # values passed to #translate as part of the options hash, with the keys matching + # the interpolation variable names. + # + # E.g., with a translation :foo => "foo %{bar}" the option + # value for the key +bar+ will be interpolated into the translation: + # I18n.t :foo, :bar => 'baz' # => 'foo baz' + # + # *PLURALIZATION* + # + # Translation data can contain pluralized translations. Pluralized translations + # are arrays of singluar/plural versions of translations like ['Foo', 'Foos']. + # + # Note that I18n::Backend::Simple only supports an algorithm for English + # pluralization rules. Other algorithms can be supported by custom backends. + # + # This returns the singular version of a pluralized translation: + # I18n.t :foo, :count => 1 # => 'Foo' + # + # These both return the plural version of a pluralized translation: + # I18n.t :foo, :count => 0 # => 'Foos' + # I18n.t :foo, :count => 2 # => 'Foos' + # + # The :count option can be used both for pluralization and interpolation. + # E.g., with the translation + # :foo => ['%{count} foo', '%{count} foos'], count will + # be interpolated to the pluralized translation: + # I18n.t :foo, :count => 1 # => '1 foo' + # + # *DEFAULTS* + # + # This returns the translation for :foo or default if no translation was found: + # I18n.t :foo, :default => 'default' + # + # This returns the translation for :foo or the translation for :bar if no + # translation for :foo was found: + # I18n.t :foo, :default => :bar + # + # Returns the translation for :foo or the translation for :bar + # or default if no translations for :foo and :bar were found. + # I18n.t :foo, :default => [:bar, 'default'] + # + # *BULK LOOKUP* + # + # This returns an array with the translations for :foo and :bar. + # I18n.t [:foo, :bar] + # + # Can be used with dot-separated nested keys: + # I18n.t [:'baz.foo', :'baz.bar'] + # + # Which is the same as using a scope option: + # I18n.t [:foo, :bar], :scope => :baz + # + # *LAMBDAS* + # + # Both translations and defaults can be given as Ruby lambdas. Lambdas will be + # called and passed the key and options. + # + # E.g. assuming the key :salutation resolves to: + # lambda { |key, options| options[:gender] == 'm' ? "Mr. %{options[:name]}" : "Mrs. %{options[:name]}" } + # + # Then I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith". + # + # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when + # a cache layer is put in front of I18n.translate it will generate a cache key + # from the argument values passed to #translate. Therefor your lambdas should + # always return the same translations/values per unique combination of argument + # values. + def translate(*args) + options = args.last.is_a?(Hash) ? args.pop : {} + key = args.shift + backend = config.backend + locale = options.delete(:locale) || config.locale + raises = options.delete(:raise) + + raise I18n::ArgumentError if key.is_a?(String) && key.empty? + + if key.is_a?(Array) + key.map { |k| backend.translate(locale, k, options) } + else + backend.translate(locale, key, options) + end + rescue I18n::ArgumentError => exception + raise exception if raises + handle_exception(exception, locale, key, options) + end + alias :t :translate + + def translate!(key, options={}) + translate(key, options.merge(:raise => true)) + end + alias :t! :translate! + + # Transliterates UTF-8 characters to ASCII. By default this method will + # transliterate only Latin strings to an ASCII approximation: + # + # I18n.transliterate("Ærøskøbing") + # # => "AEroskobing" + # + # I18n.transliterate("日本語") + # # => "???" + # + # It's also possible to add support for per-locale transliterations. I18n + # expects transliteration rules to be stored at + # i18n.transliterate.rule. + # + # Transliteration rules can either be a Hash or a Proc. Procs must accept a + # single string argument. Hash rules inherit the default transliteration + # rules, while Procs do not. + # + # *Examples* + # + # Setting a Hash in .yml: + # + # i18n: + # transliterate: + # rule: + # ü: "ue" + # ö: "oe" + # + # Setting a Hash using Ruby: + # + # store_translations(:de, :i18n => { + # :transliterate => { + # :rule => { + # "ü" => "ue", + # "ö" => "oe" + # } + # } + # ) + # + # Setting a Proc: + # + # translit = lambda {|string| MyTransliterator.transliterate(string) } + # store_translations(:xx, :i18n => {:transliterate => {:rule => translit}) + # + # Transliterating strings: + # + # I18n.locale = :en + # I18n.transliterate("Jürgen") # => "Jurgen" + # I18n.locale = :de + # I18n.transliterate("Jürgen") # => "Juergen" + # I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen" + # I18n.transliterate("Jürgen", :locale => :de) # => "Juergen" + def transliterate(*args) + options = args.pop if args.last.is_a?(Hash) + key = args.shift + locale = options && options.delete(:locale) || config.locale + raises = options && options.delete(:raise) + replacement = options && options.delete(:replacement) + config.backend.transliterate(locale, key, replacement) + rescue I18n::ArgumentError => exception + raise exception if raises + handle_exception(exception, locale, key, options) + end + + # Localizes certain objects, such as dates and numbers to local formatting. + def localize(object, options = {}) + locale = options.delete(:locale) || config.locale + format = options.delete(:format) || :default + config.backend.localize(locale, object, format, options) + end + alias :l :localize + + # Executes block with given I18n.locale set. + def with_locale(tmp_locale = nil) + if tmp_locale + current_locale = self.locale + self.locale = tmp_locale + end + yield + ensure + self.locale = current_locale if tmp_locale + end + + + # Merges the given locale, key and scope into a single array of keys. + # Splits keys that contain dots into multiple keys. Makes sure all + # keys are Symbols. + def normalize_keys(locale, key, scope, separator = nil) + separator ||= I18n.default_separator + + keys = [] + keys.concat normalize_key(locale, separator) + keys.concat normalize_key(scope, separator) + keys.concat normalize_key(key, separator) + keys + end + + # making these private until Ruby 1.9.2 can send to protected methods again + # see http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=24280 + private + + # Handles exceptions raised in the backend. All exceptions except for + # MissingTranslationData exceptions are re-raised. When a MissingTranslationData + # was caught and the option :raise is not set the handler returns an error + # message string containing the key/scope. + def default_exception_handler(exception, locale, key, options) + return exception.message if MissingTranslationData === exception + raise exception + end + + # Any exceptions thrown in translate will be sent to the @@exception_handler + # which can be a Symbol, a Proc or any other Object. + # + # If exception_handler is a Symbol then it will simply be sent to I18n as + # a method call. A Proc will simply be called. In any other case the + # method #call will be called on the exception_handler object. + # + # Examples: + # + # I18n.exception_handler = :default_exception_handler # this is the default + # I18n.default_exception_handler(exception, locale, key, options) # will be called like this + # + # I18n.exception_handler = lambda { |*args| ... } # a lambda + # I18n.exception_handler.call(exception, locale, key, options) # will be called like this + # + # I18n.exception_handler = I18nExceptionHandler.new # an object + # I18n.exception_handler.call(exception, locale, key, options) # will be called like this + def handle_exception(exception, locale, key, options) + case config.exception_handler + when Symbol + send(config.exception_handler, exception, locale, key, options) + else + config.exception_handler.call(exception, locale, key, options) + end + end + + # Deprecated. Will raise a warning in future versions and then finally be + # removed. Use I18n.normalize_keys instead. + def normalize_translation_keys(locale, key, scope, separator = nil) + normalize_keys(locale, key, scope, separator) + end + + def normalize_key(key, separator) + normalized_key_cache[separator][key] ||= + case key + when Array + key.map { |k| normalize_key(k, separator) }.flatten + else + keys = key.to_s.split(separator) + keys.delete('') + keys.map!{ |k| k.to_sym } + keys + end + end + + def normalized_key_cache + @normalized_key_cache ||= Hash.new { |h,k| h[k] = {} } + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend.rb new file mode 100644 index 00000000000..fe65fb48418 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend.rb @@ -0,0 +1,20 @@ +module I18n + module Backend + autoload :ActiveRecord, 'i18n/backend/active_record' + autoload :Base, 'i18n/backend/base' + autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler' + autoload :Cache, 'i18n/backend/cache' + autoload :Cascade, 'i18n/backend/cascade' + autoload :Chain, 'i18n/backend/chain' + autoload :Cldr, 'i18n/backend/cldr' + autoload :Fallbacks, 'i18n/backend/fallbacks' + autoload :Flatten, 'i18n/backend/flatten' + autoload :Gettext, 'i18n/backend/gettext' + autoload :KeyValue, 'i18n/backend/key_value' + autoload :Memoize, 'i18n/backend/memoize' + autoload :Metadata, 'i18n/backend/metadata' + autoload :Pluralization, 'i18n/backend/pluralization' + autoload :Simple, 'i18n/backend/simple' + autoload :Transliterator, 'i18n/backend/transliterator' + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record.rb new file mode 100644 index 00000000000..b60f138d11a --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record.rb @@ -0,0 +1,61 @@ +require 'i18n/backend/base' +require 'i18n/backend/active_record/translation' + +module I18n + module Backend + class ActiveRecord + autoload :Missing, 'i18n/backend/active_record/missing' + autoload :StoreProcs, 'i18n/backend/active_record/store_procs' + autoload :Translation, 'i18n/backend/active_record/translation' + + module Implementation + include Base, Flatten + + def available_locales + begin + Translation.available_locales + rescue ::ActiveRecord::StatementInvalid + [] + end + end + + def store_translations(locale, data, options = {}) + escape = options.fetch(:escape, true) + flatten_translations(locale, data, escape, false).each do |key, value| + Translation.locale(locale).lookup(expand_keys(key)).delete_all + Translation.create(:locale => locale.to_s, :key => key.to_s, :value => value) + end + end + + protected + + def lookup(locale, key, scope = [], options = {}) + key = normalize_flat_keys(locale, key, scope, options[:separator]) + result = Translation.locale(locale).lookup(key).all + + if result.empty? + nil + elsif result.first.key == key + result.first.value + else + chop_range = (key.size + FLATTEN_SEPARATOR.size)..-1 + result = result.inject({}) do |hash, r| + hash[r.key.slice(chop_range)] = r.value + hash + end + result.deep_symbolize_keys + end + end + + # For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz'] + def expand_keys(key) + key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, key| + keys << [keys.last, key].compact.join(FLATTEN_SEPARATOR) + end + end + end + + include Implementation + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/missing.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/missing.rb new file mode 100644 index 00000000000..ef34055f602 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/missing.rb @@ -0,0 +1,65 @@ +# This extension stores translation stub records for missing translations to +# the database. +# +# This is useful if you have a web based translation tool. It will populate +# the database with untranslated keys as the application is being used. A +# translator can then go through these and add missing translations. +# +# Example usage: +# +# I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing) +# I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new) +# +# Stub records for pluralizations will also be created for each key defined +# in i18n.plural.keys. +# +# For example: +# +# # en.yml +# en: +# i18n: +# plural: +# keys: [:zero, :one, :other] +# +# # pl.yml +# pl: +# i18n: +# plural: +# keys: [:zero, :one, :few, :other] +# +# It will also persist interpolation keys in Translation#interpolations so +# translators will be able to review and use them. +module I18n + module Backend + class ActiveRecord + module Missing + include Flatten + + def store_default_translations(locale, key, options = {}) + count, scope, default, separator = options.values_at(:count, :scope, :default, :separator) + separator ||= I18n.default_separator + key = normalize_flat_keys(locale, key, scope, separator) + + unless ActiveRecord::Translation.locale(locale).lookup(key).exists? + interpolations = options.keys - Base::RESERVED_KEYS + keys = count ? I18n.t('i18n.plural.keys', :locale => locale).map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key] + keys.each { |key| store_default_translation(locale, key, interpolations) } + end + end + + def store_default_translation(locale, key, interpolations) + translation = ActiveRecord::Translation.new :locale => locale.to_s, :key => key + translation.interpolations = interpolations + translation.save + end + + def translate(locale, key, options = {}) + super + rescue I18n::MissingTranslationData => e + self.store_default_translations(locale, key, options) + raise e + end + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/store_procs.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/store_procs.rb new file mode 100644 index 00000000000..652b1aaa854 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/store_procs.rb @@ -0,0 +1,38 @@ +# This module is intended to be mixed into the ActiveRecord backend to allow +# storing Ruby Procs as translation values in the database. +# +# I18n.backend = I18n::Backend::ActiveRecord.new +# I18n::Backend::ActiveRecord::Translation.send(:include, I18n::Backend::ActiveRecord::StoreProcs) +# +# The StoreProcs module requires the ParseTree and ruby2ruby gems and therefor +# was extracted from the original backend. +# +# ParseTree is not compatible with Ruby 1.9. + +begin + require 'ruby2ruby' + require 'parse_tree' + require 'parse_tree_extensions' +rescue LoadError => e + puts "can't use StoreProcs because: #{e.message}" +end + +module I18n + module Backend + class ActiveRecord + module StoreProcs + def value=(v) + case v + when Proc + write_attribute(:value, v.to_ruby) + write_attribute(:is_proc, true) + else + write_attribute(:value, v) + end + end + + Translation.send(:include, self) if method(:to_s).respond_to?(:to_ruby) + end + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/translation.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/translation.rb new file mode 100644 index 00000000000..f3730432b81 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/active_record/translation.rb @@ -0,0 +1,110 @@ +require 'active_record' + +module I18n + module Backend + # ActiveRecord model used to store actual translations to the database. + # + # This model expects a table like the following to be already set up in + # your the database: + # + # create_table :translations do |t| + # t.string :locale + # t.string :key + # t.text :value + # t.text :interpolations + # t.boolean :is_proc, :default => false + # end + # + # This model supports to named scopes :locale and :lookup. The :locale + # scope simply adds a condition for a given locale: + # + # I18n::Backend::ActiveRecord::Translation.locale(:en).all + # # => all translation records that belong to the :en locale + # + # The :lookup scope adds a condition for looking up all translations + # that either start with the given keys (joined by an optionally given + # separator or I18n.default_separator) or that exactly have this key. + # + # # with translations present for :"foo.bar" and :"foo.baz" + # I18n::Backend::ActiveRecord::Translation.lookup(:foo) + # # => an array with both translation records :"foo.bar" and :"foo.baz" + # + # I18n::Backend::ActiveRecord::Translation.lookup([:foo, :bar]) + # I18n::Backend::ActiveRecord::Translation.lookup(:"foo.bar") + # # => an array with the translation record :"foo.bar" + # + # When the StoreProcs module was mixed into this model then Procs will + # be stored to the database as Ruby code and evaluated when :value is + # called. + # + # Translation = I18n::Backend::ActiveRecord::Translation + # Translation.create \ + # :locale => 'en' + # :key => 'foo' + # :value => lambda { |key, options| 'FOO' } + # Translation.find_by_locale_and_key('en', 'foo').value + # # => 'FOO' + class ActiveRecord + class Translation < ::ActiveRecord::Base + TRUTHY_CHAR = "\001" + FALSY_CHAR = "\002" + + set_table_name 'translations' + attr_protected :is_proc, :interpolations + + serialize :value + serialize :interpolations, Array + + class << self + def locale(locale) + scoped(:conditions => { :locale => locale.to_s }) + end + + def lookup(keys, *separator) + column_name = connection.quote_column_name('key') + keys = Array(keys).map! { |key| key.to_s } + + unless separator.empty? + warn "[DEPRECATION] Giving a separator to Translation.lookup is deprecated. " << + "You can change the internal separator by overwriting FLATTEN_SEPARATOR." + end + + namespace = "#{keys.last}#{I18n::Backend::Flatten::FLATTEN_SEPARATOR}%" + scoped(:conditions => ["#{column_name} IN (?) OR #{column_name} LIKE ?", keys, namespace]) + end + + def available_locales + Translation.find(:all, :select => 'DISTINCT locale').map { |t| t.locale.to_sym } + end + end + + def interpolates?(key) + self.interpolations.include?(key) if self.interpolations + end + + def value + value = read_attribute(:value) + if is_proc + Kernel.eval(value) + elsif value == FALSY_CHAR + false + elsif value == TRUTHY_CHAR + true + else + value + end + end + + def value=(value) + if value === false + value = FALSY_CHAR + elsif value === true + value = TRUTHY_CHAR + end + + write_attribute(:value, value) + end + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/base.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/base.rb new file mode 100644 index 00000000000..f780371dcca --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/base.rb @@ -0,0 +1,215 @@ +# encoding: utf-8 + +require 'yaml' +require 'i18n/core_ext/hash' + +module I18n + module Backend + module Base + include I18n::Backend::Transliterator + + RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback] + RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/ + DEPRECATED_INTERPOLATION_SYNTAX_PATTERN = /(\\)?\{\{([^\}]+)\}\}/ + + # Accepts a list of paths to translation files. Loads translations from + # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml + # for details. + def load_translations(*filenames) + filenames = I18n.load_path.flatten if filenames.empty? + filenames.each { |filename| load_file(filename) } + end + + # This method receives a locale, a data hash and options for storing translations. + # Should be implemented + def store_translations(locale, data, options = {}) + raise NotImplementedError + end + + def translate(locale, key, options = {}) + raise InvalidLocale.new(locale) unless locale + entry = key && lookup(locale, key, options[:scope], options) + + if options.empty? + entry = resolve(locale, key, entry, options) + else + count, default = options.values_at(:count, :default) + values = options.except(*RESERVED_KEYS) + entry = entry.nil? && default ? + default(locale, key, default, options) : resolve(locale, key, entry, options) + end + + raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil? + entry = entry.dup if entry.is_a?(String) + + entry = pluralize(locale, entry, count) if count + entry = interpolate(locale, entry, values) if values + entry + end + + # Acts the same as +strftime+, but uses a localized version of the + # format string. Takes a key from the date/time formats translations as + # a format argument (e.g., :short in :'date.formats'). + def localize(locale, object, format = :default, options = {}) + raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime) + + if Symbol === format + key = format + type = object.respond_to?(:sec) ? 'time' : 'date' + options = options.merge(:raise => true, :object => object, :locale => locale) + format = I18n.t(:"#{type}.formats.#{key}", options) + end + + # format = resolve(locale, object, format, options) + format = format.to_s.gsub(/%[aAbBp]/) do |match| + case match + when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday] + when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday] + when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon] + when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon] + when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format) if object.respond_to? :hour + end + end + + object.strftime(format) + end + + # Returns an array of locales for which translations are available + # ignoring the reserved translation meta data key :i18n. + def available_locales + raise NotImplementedError + end + + def reload! + @skip_syntax_deprecation = false + end + + protected + + # The method which actually looks up for the translation in the store. + def lookup(locale, key, scope = [], options = {}) + raise NotImplementedError + end + + # Evaluates defaults. + # If given subject is an Array, it walks the array and returns the + # first translation that can be resolved. Otherwise it tries to resolve + # the translation directly. + def default(locale, object, subject, options = {}) + options = options.dup.reject { |key, value| key == :default } + case subject + when Array + subject.each do |item| + result = resolve(locale, object, item, options) and return result + end and nil + else + resolve(locale, object, subject, options) + end + end + + # Resolves a translation. + # If the given subject is a Symbol, it will be translated with the + # given options. If it is a Proc then it will be evaluated. All other + # subjects will be returned directly. + def resolve(locale, object, subject, options = {}) + return subject if options[:resolve] == false + case subject + when Symbol + I18n.translate(subject, options.merge(:locale => locale, :raise => true)) + when Proc + date_or_time = options.delete(:object) || object + resolve(locale, object, subject.call(date_or_time, options)) + else + subject + end + rescue MissingTranslationData + nil + end + + # Picks a translation from an array according to English pluralization + # rules. It will pick the first translation if count is not equal to 1 + # and the second translation if it is equal to 1. Other backends can + # implement more flexible or complex pluralization rules. + def pluralize(locale, entry, count) + return entry unless entry.is_a?(Hash) && count + + key = :zero if count == 0 && entry.has_key?(:zero) + key ||= count == 1 ? :one : :other + raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) + entry[key] + end + + # Interpolates values into a given string. + # + # interpolate "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X' + # # => "file test.txt opened by %{user}" + # + # Note that you have to double escape the \\ when you want to escape + # the {{...}} key in a string (once for the string and once for the + # interpolation). + def interpolate(locale, string, values = {}) + return string unless string.is_a?(::String) && !values.empty? + + string = string.gsub(DEPRECATED_INTERPOLATION_SYNTAX_PATTERN) do + escaped, key = $1, $2.to_sym + if escaped + "{{#{key}}}" + else + warn_syntax_deprecation!(locale, string) + "%{#{key}}" + end + end + + values.each do |key, value| + value = value.call(values) if interpolate_lambda?(value, string, key) + value = value.to_s unless value.is_a?(::String) + values[key] = value + end + + string % values + rescue KeyError => e + if string =~ RESERVED_KEYS_PATTERN + raise ReservedInterpolationKey.new($1.to_sym, string) + else + raise MissingInterpolationArgument.new(values, string) + end + end + + # returns true when the given value responds to :call and the key is + # an interpolation placeholder in the given string + def interpolate_lambda?(object, string, key) + object.respond_to?(:call) && string =~ /%\{#{key}\}|%\<#{key}>.*?\d*\.?\d*[bBdiouxXeEfgGcps]\}/ + end + + # Loads a single translations file by delegating to #load_rb or + # #load_yml depending on the file extension and directly merges the + # data to the existing translations. Raises I18n::UnknownFileType + # for all other file extensions. + def load_file(filename) + type = File.extname(filename).tr('.', '').downcase + raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true) + data = send(:"load_#{type}", filename) + raise InvalidLocaleData.new(filename) unless data.is_a?(Hash) + data.each { |locale, d| store_translations(locale, d || {}) } + end + + # Loads a plain Ruby translations file. eval'ing the file must yield + # a Hash containing translation data with locales as toplevel keys. + def load_rb(filename) + eval(IO.read(filename), binding, filename) + end + + # Loads a YAML translations file. The data must have locales as + # toplevel keys. + def load_yml(filename) + YAML.load_file(filename) + end + + def warn_syntax_deprecation!(locale, string) #:nodoc: + return if @skip_syntax_deprecation + warn "The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.\n#{locale} - #{string}\n" + @skip_syntax_deprecation = true + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cache.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cache.rb new file mode 100644 index 00000000000..c0d78e66db5 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cache.rb @@ -0,0 +1,104 @@ +# encoding: utf-8 + +# This module allows you to easily cache all responses from the backend - thus +# speeding up the I18n aspects of your application quite a bit. +# +# To enable caching you can simply include the Cache module to the Simple +# backend - or whatever other backend you are using: +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Cache) +# +# You will also need to set a cache store implementation that you want to use: +# +# I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store) +# +# You can use any cache implementation you want that provides the same API as +# ActiveSupport::Cache (only the methods #fetch and #write are being used). +# +# The cache_key implementation assumes that you only pass values to +# I18n.translate that return a valid key from #hash (see +# http://www.ruby-doc.org/core/classes/Object.html#M000337). +# +# If you use a lambda as a default value in your translation like this: +# +# I18n.t(:"date.order", :default => lambda {[:month, :day, :year]}) +# +# Then you will always have a cache miss, because each time this method +# is called the lambda will have a different hash value. If you know +# the result of the lambda is a constant as in the example above, then +# to cache this you can make the lambda a constant, like this: +# +# DEFAULT_DATE_ORDER = lambda {[:month, :day, :year]} +# ... +# I18n.t(:"date.order", :default => DEFAULT_DATE_ORDER) +# +# If the lambda may result in different values for each call then consider +# also using the Memoize backend. +# +module I18n + class << self + @@cache_store = nil + @@cache_namespace = nil + + def cache_store + @@cache_store + end + + def cache_store=(store) + @@cache_store = store + end + + def cache_namespace + @@cache_namespace + end + + def cache_namespace=(namespace) + @@cache_namespace = namespace + end + + def perform_caching? + !cache_store.nil? + end + end + + module Backend + # TODO Should the cache be cleared if new translations are stored? + module Cache + def translate(locale, key, options = {}) + I18n.perform_caching? ? fetch(cache_key(locale, key, options)) { super } : super + end + + protected + + def fetch(cache_key, &block) + result = fetch_storing_missing_translation_exception(cache_key, &block) + raise result if result.is_a?(Exception) + result = result.dup if result.frozen? rescue result + result + end + + def fetch_storing_missing_translation_exception(cache_key, &block) + fetch_ignoring_procs(cache_key, &block) + rescue MissingTranslationData => exception + I18n.cache_store.write(cache_key, exception) + exception + end + + def fetch_ignoring_procs(cache_key, &block) + I18n.cache_store.read(cache_key) || yield.tap do |result| + I18n.cache_store.write(cache_key, result) unless result.is_a?(Proc) + end + end + + def cache_key(locale, key, options) + # This assumes that only simple, native Ruby values are passed to I18n.translate. + "i18n/#{I18n.cache_namespace}/#{locale}/#{key.hash}/#{USE_INSPECT_HASH ? options.inspect.hash : options.hash}" + end + + private + # In Ruby < 1.9 the following is true: { :foo => 1, :bar => 2 }.hash == { :foo => 2, :bar => 1 }.hash + # Therefore we must use the hash of the inspect string instead to avoid cache key colisions. + USE_INSPECT_HASH = RUBY_VERSION <= "1.9" + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cascade.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cascade.rb new file mode 100644 index 00000000000..370fb481c3c --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cascade.rb @@ -0,0 +1,57 @@ +# encoding: utf-8 + +# EXPERIMENTAL +# +# The Cascade module adds the ability to do cascading lookups to backends that +# are compatible to the Simple backend. +# +# By cascading lookups we mean that for any key that can not be found the +# Cascade module strips one segment off the scope part of the key and then +# tries to look up the key in that scope. +# +# E.g. when a lookup for the key :"foo.bar.baz" does not yield a result then +# the segment :bar will be stripped off the scope part :"foo.bar" and the new +# scope :foo will be used to look up the key :baz. If that does not succeed +# then the remaining scope segment :foo will be omitted, too, and again the +# key :baz will be looked up (now with no scope). +# +# To enable a cascading lookup one passes the :cascade option: +# +# I18n.t(:'foo.bar.baz', :cascade => true) +# +# This will return the first translation found for :"foo.bar.baz", :"foo.baz" +# or :baz in this order. +# +# The cascading lookup takes precedence over resolving any given defaults. +# I.e. defaults will kick in after the cascading lookups haven't succeeded. +# +# This behavior is useful for libraries like ActiveRecord validations where +# the library wants to give users a bunch of more or less fine-grained options +# of scopes for a particular key. +# +# Thanks to Clemens Kofler for the initial idea and implementation! See +# http://github.com/clemens/i18n-cascading-backend + +module I18n + module Backend + module Cascade + def lookup(locale, key, scope = [], options = {}) + return super unless cascade = options[:cascade] + + separator = options[:separator] || I18n.default_separator + skip_root = cascade.has_key?(:skip_root) ? cascade[:skip_root] : true + step = cascade[:step] + + keys = I18n.normalize_keys(nil, key, nil, separator) + offset = options[:cascade][:offset] || keys.length + scope = I18n.normalize_keys(nil, nil, scope, separator) + keys + key = scope.slice!(-offset, offset).join(separator) + + begin + result = super + return result unless result.nil? + end while !scope.empty? && scope.slice!(-step, step) && (!scope.empty? || !skip_root) + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/chain.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/chain.rb new file mode 100644 index 00000000000..9aa3eea3b82 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/chain.rb @@ -0,0 +1,82 @@ +# encoding: utf-8 + +module I18n + module Backend + # Backend that chains multiple other backends and checks each of them when + # a translation needs to be looked up. This is useful when you want to use + # standard translations with a Simple backend but store custom application + # translations in a database or other backends. + # + # To use the Chain backend instantiate it and set it to the I18n module. + # You can add chained backends through the initializer or backends + # accessor: + # + # # preserves the existing Simple backend set to I18n.backend + # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend) + # + # The implementation assumes that all backends added to the Chain implement + # a lookup method with the same API as Simple backend does. + class Chain + module Implementation + include Base + + attr_accessor :backends + + def initialize(*backends) + self.backends = backends + end + + def reload! + backends.each { |backend| backend.reload! } + end + + def store_translations(locale, data, options = {}) + backends.first.store_translations(locale, data, options = {}) + end + + def available_locales + backends.map { |backend| backend.available_locales }.flatten.uniq + end + + def translate(locale, key, default_options = {}) + namespace = nil + options = default_options.except(:default) + + backends.each do |backend| + begin + options = default_options if backend == backends.last + translation = backend.translate(locale, key, options) + if namespace_lookup?(translation, options) + namespace ||= {} + namespace.merge!(translation) + elsif !translation.nil? + return translation + end + rescue MissingTranslationData + end + end + + return namespace if namespace + raise(I18n::MissingTranslationData.new(locale, key, options)) + end + + def localize(locale, object, format = :default, options = {}) + backends.each do |backend| + begin + result = backend.localize(locale, object, format, options) and return result + rescue MissingTranslationData + end + end + raise(I18n::MissingTranslationData.new(locale, format, options)) + end + + protected + def namespace_lookup?(result, options) + result.is_a?(Hash) && !options.has_key?(:count) + end + end + + include Implementation + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cldr.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cldr.rb new file mode 100644 index 00000000000..d702f2249d5 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/cldr.rb @@ -0,0 +1,100 @@ +# encoding: utf-8 +require 'cldr' + +module I18n + module Backend + module Cldr + include ::Cldr::Format + + def localize(locale, object, format = :default, options = {}) + options[:as] ||= detect_type(object, options) + send(:"format_#{options[:as]}", locale, object, format, options) + end + + def format_decimal(locale, object, format = :default, options = {}) + formatter(locale, :decimal, format).apply(object, options) + end + + def format_integer(locale, object, format = :default, options = {}) + format_object(number, options.merge(:precision => 0)) + end + + def format_currency(locale, object, format = :default, options = {}) + options.merge!(:currency => lookup_currency(locale, options[:currency], object)) if options[:currency].is_a?(Symbol) + formatter(locale, :currency, format).apply(object, options) + end + + def format_percent(locale, object, format = :default, options = {}) + formatter(locale, :percent, format).apply(object, options) + end + + def format_date(locale, object, format = :default, options = {}) + formatter(locale, :date, format).apply(object, options) + end + + def format_time(locale, object, format = :default, options = {}) + formatter(locale, :time, format).apply(object, options) + end + + def format_datetime(locale, object, format = :default, options = {}) + key = :"calendars.gregorian.formats.datetime.#{format}.pattern" + date = I18n.l(object, :format => options[:date_format] || format, :locale => locale, :as => :date) + time = I18n.l(object, :format => options[:time_format] || format, :locale => locale, :as => :time) + I18n.t(key, :date => date, :time => time, :locale => locale, :raise => true) + end + + protected + + def detect_type(object, options) + options.has_key?(:currency) ? :currency : case object + when ::Numeric + :decimal + when ::Date, ::DateTime, ::Time + object.class.name.downcase.to_sym + else + raise_unspecified_format_type! + end + end + + def formatter(locale, type, format) + (@formatters ||= {})[:"#{locale}.#{type}.#{format}"] ||= begin + format = lookup_format(locale, type, format) + data = lookup_format_data(locale, type) + ::Cldr::Format.const_get(type.to_s.camelize).new(format, data) + end + end + + def lookup_format(locale, type, format) + key = case type + when :date, :time, :datetime + :"calendars.gregorian.formats.#{type}.#{format}.pattern" + else + :"numbers.formats.#{type}.patterns.#{format || :default}" + end + I18n.t(key, :locale => locale, :raise => true) + end + + def lookup_format_data(locale, type) + key = case type + when :date, :time, :datetime + :'calendars.gregorian' + else + :'numbers.symbols' + end + I18n.t(key, :locale => locale, :raise => true) + end + + def lookup_currency(locale, currency, count) + I18n.t(:"currencies.#{currency}", :locale => locale, :count => count) + end + + def raise_unspecified_format_type! + raise ArgumentError.new("You have to specify a format type, e.g. :as => :number.") + end + + def raise_unspecified_currency! + raise ArgumentError.new("You have to specify a currency, e.g. :currency => 'EUR'.") + end + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/fallbacks.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/fallbacks.rb new file mode 100644 index 00000000000..596d3960cfe --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/fallbacks.rb @@ -0,0 +1,72 @@ +# encoding: utf-8 + +# I18n locale fallbacks are useful when you want your application to use +# translations from other locales when translations for the current locale are +# missing. E.g. you might want to use :en translations when translations in +# your applications main locale :de are missing. +# +# To enable locale fallbacks you can simply include the Fallbacks module to +# the Simple backend - or whatever other backend you are using: +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks) +module I18n + @@fallbacks = nil + + class << self + # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+. + def fallbacks + @@fallbacks ||= I18n::Locale::Fallbacks.new + end + + # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation. + def fallbacks=(fallbacks) + @@fallbacks = fallbacks + end + end + + module Backend + module Fallbacks + # Overwrites the Base backend translate method so that it will try each + # locale given by I18n.fallbacks for the given locale. E.g. for the + # locale :"de-DE" it might try the locales :"de-DE", :de and :en + # (depends on the fallbacks implementation) until it finds a result with + # the given options. If it does not find any result for any of the + # locales it will then raise a MissingTranslationData exception as + # usual. + # + # The default option takes precedence over fallback locales + # only when it's a Symbol. When the default contains a String or a Proc + # it is evaluated last after all the fallback locales have been tried. + def translate(locale, key, options = {}) + return super if options[:fallback] + default = extract_string_or_lambda_default!(options) if options[:default] + + options[:fallback] = true + I18n.fallbacks[locale].each do |fallback| + begin + result = super(fallback, key, options) + return result unless result.nil? + rescue I18n::MissingTranslationData + end + end + options.delete(:fallback) + + return super(locale, nil, options.merge(:default => default)) if default + raise(I18n::MissingTranslationData.new(locale, key, options)) + end + + def extract_string_or_lambda_default!(options) + defaults = Array(options[:default]) + if index = find_first_string_or_lambda_default(defaults) + options[:default] = defaults[0, index] + defaults[index] + end + end + + def find_first_string_or_lambda_default(defaults) + defaults.each_with_index { |default, ix| return ix if String === default || Proc === default } + nil + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/flatten.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/flatten.rb new file mode 100644 index 00000000000..c23f7c13194 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/flatten.rb @@ -0,0 +1,113 @@ +module I18n + module Backend + # This module contains several helpers to assist flattening translations. + # You may want to flatten translations for: + # + # 1) speed up lookups, as in the Memoize backend; + # 2) In case you want to store translations in a data store, as in ActiveRecord backend; + # + # You can check both backends above for some examples. + # This module also keeps all links in a hash so they can be properly resolved when flattened. + module Flatten + SEPARATOR_ESCAPE_CHAR = "\001" + FLATTEN_SEPARATOR = "." + + # normalize_keys the flatten way. This method is significantly faster + # and creates way less objects than the one at I18n.normalize_keys. + # It also handles escaping the translation keys. + def self.normalize_flat_keys(locale, key, scope, separator) + keys = [scope, key].flatten.compact + separator ||= I18n.default_separator + + if separator != FLATTEN_SEPARATOR + keys.map! do |k| + k.to_s.tr("#{FLATTEN_SEPARATOR}#{separator}", + "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}") + end + end + + keys.join(".") + end + + # Receives a string and escape the default separator. + def self.escape_default_separator(key) #:nodoc: + key.to_s.tr(FLATTEN_SEPARATOR, SEPARATOR_ESCAPE_CHAR) + end + + # Shortcut to I18n::Backend::Flatten.normalize_flat_keys + # and then resolve_links. + def normalize_flat_keys(locale, key, scope, separator) + key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, separator) + resolve_link(locale, key) + end + + # Store flattened links. + def links + @links ||= Hash.new { |h,k| h[k] = {} } + end + + # Flatten keys for nested Hashes by chaining up keys: + # + # >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind + # => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" } + # + def flatten_keys(hash, escape, prev_key=nil, &block) + hash.each_pair do |key, value| + key = escape_default_separator(key) if escape + curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym + yield curr_key, value + flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash) + end + end + + # Receives a hash of translations (where the key is a locale and + # the value is another hash) and return a hash with all + # translations flattened. + # + # Nested hashes are included in the flattened hash just if subtree + # is true and Symbols are automatically stored as links. + def flatten_translations(locale, data, escape, subtree) + hash = {} + flatten_keys(data, escape) do |key, value| + if value.is_a?(Hash) + hash[key] = value if subtree + else + store_link(locale, key, value) if value.is_a?(Symbol) + hash[key] = value + end + end + hash + end + + protected + + def store_link(locale, key, link) + links[locale.to_sym][key.to_s] = link.to_s + end + + def resolve_link(locale, key) + key, locale = key.to_s, locale.to_sym + links = self.links[locale] + + if links.key?(key) + links[key] + elsif link = find_link(locale, key) + store_link(locale, key, key.gsub(*link)) + else + key + end + end + + def find_link(locale, key) #:nodoc: + links[locale].each do |from, to| + return [from, to] if key[0, from.length] == from + end && nil + end + + def escape_default_separator(key) #:nodoc: + I18n::Backend::Flatten.escape_default_separator(key) + end + + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/gettext.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/gettext.rb new file mode 100644 index 00000000000..4ff15f9f33d --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/gettext.rb @@ -0,0 +1,73 @@ +# encoding: utf-8 + +require 'i18n/gettext' +require 'i18n/gettext/po_parser' + +# Experimental support for using Gettext po files to store translations. +# +# To use this you can simply include the module to the Simple backend - or +# whatever other backend you are using. +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Gettext) +# +# Now you should be able to include your Gettext translation (*.po) files to +# the I18n.load_path so they're loaded to the backend and you can use them as +# usual: +# +# I18n.load_path += Dir["path/to/locales/*.po"] +# +# Following the Gettext convention this implementation expects that your +# translation files are named by their locales. E.g. the file en.po would +# contain the translations for the English locale. +module I18n + module Backend + module Gettext + class PoData < Hash + def set_comment(msgid_or_sym, comment) + # ignore + end + end + + protected + def load_po(filename) + locale = ::File.basename(filename, '.po').to_sym + data = normalize(locale, parse(filename)) + { locale => data } + end + + def parse(filename) + GetText::PoParser.new.parse(::File.read(filename), PoData.new) + end + + def normalize(locale, data) + data.inject({}) do |result, (key, value)| + unless key.nil? || key.empty? + key, value = normalize_pluralization(locale, key, value) if key.index("\000") + + parts = key.split('|').reverse + normalized = parts.inject({}) do |normalized, part| + normalized = { part => normalized.empty? ? value : normalized } + end + + result.deep_merge!(normalized) + end + result + end + end + + def normalize_pluralization(locale, key, value) + # FIXME po_parser includes \000 chars that can not be turned into Symbols + key = key.gsub("\000", I18n::Gettext::PLURAL_SEPARATOR).split(I18n::Gettext::PLURAL_SEPARATOR).first + + keys = I18n::Gettext.plural_keys(locale) + values = value.split("\000") + raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect}" if values.size != keys.size + + result = {} + values.each_with_index { |value, ix| result[keys[ix]] = value } + [key, result] + end + + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/interpolation_compiler.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/interpolation_compiler.rb new file mode 100644 index 00000000000..8c7c9c91f67 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/interpolation_compiler.rb @@ -0,0 +1,123 @@ +# encoding: utf-8 + +# The InterpolationCompiler module contains optimizations that can tremendously +# speed up the interpolation process on the Simple backend. +# +# It works by defining a pre-compiled method on stored translation Strings that +# already bring all the knowledge about contained interpolation variables etc. +# so that the actual recurring interpolation will be very fast. +# +# To enable pre-compiled interpolations you can simply include the +# InterpolationCompiler module to the Simple backend: +# +# I18n::Backend::Simple.send(:include, I18n::Backend::InterpolationCompiler) +# +# Note that InterpolationCompiler does not yield meaningful results and consequently +# should not be used with Ruby 1.9 (YARV) but improves performance everywhere else +# (jRuby, Rubinius and 1.8.7). +module I18n + module Backend + module InterpolationCompiler + module Compiler + extend self + + TOKENIZER = /(%%\{[^\}]+\}|%\{[^\}]+\})/ + INTERPOLATION_SYNTAX_PATTERN = /(%)?(%\{([^\}]+)\})/ + + def compile_if_an_interpolation(string) + if interpolated_str?(string) + string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + def i18n_interpolate(v = {}) + "#{compiled_interpolation_body(string)}" + end + RUBY_EVAL + end + + string + end + + def interpolated_str?(str) + str.kind_of?(::String) && str =~ INTERPOLATION_SYNTAX_PATTERN + end + + protected + # tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"] + def tokenize(str) + str.split(TOKENIZER) + end + + def compiled_interpolation_body(str) + tokenize(str).map do |token| + (matchdata = token.match(INTERPOLATION_SYNTAX_PATTERN)) ? handle_interpolation_token(token, matchdata) : escape_plain_str(token) + end.join + end + + def handle_interpolation_token(interpolation, matchdata) + escaped, pattern, key = matchdata.values_at(1, 2, 3) + escaped ? pattern : compile_interpolation_token(key.to_sym) + end + + def compile_interpolation_token(key) + "\#{#{interpolate_or_raise_missing(key)}}" + end + + def interpolate_or_raise_missing(key) + escaped_key = escape_key_sym(key) + Base::RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key) + end + + def interpolate_key(key) + [direct_key(key), nil_key(key), missing_key(key)].join('||') + end + + def direct_key(key) + "((t = v[#{key}]) && t.respond_to?(:call) ? t.call : t)" + end + + def nil_key(key) + "(v.has_key?(#{key}) && '')" + end + + def missing_key(key) + "raise(MissingInterpolationArgument.new(#{key}, self))" + end + + def reserved_key(key) + "raise(ReservedInterpolationKey.new(#{key}, self))" + end + + def escape_plain_str(str) + str.gsub(/"|\\|#/) {|x| "\\#{x}"} + end + + def escape_key_sym(key) + # rely on Ruby to do all the hard work :) + key.to_sym.inspect + end + end + + def interpolate(locale, string, values) + if string.respond_to?(:i18n_interpolate) + string.i18n_interpolate(values) + elsif values + super + else + string + end + end + + def store_translations(locale, data, options = {}) + compile_all_strings_in(data) + super + end + + protected + def compile_all_strings_in(data) + data.each_value do |value| + Compiler.compile_if_an_interpolation(value) + compile_all_strings_in(value) if value.kind_of?(Hash) + end + end + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/key_value.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/key_value.rb new file mode 100644 index 00000000000..d0265abfdd5 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/key_value.rb @@ -0,0 +1,102 @@ +# encoding: utf-8 + +require 'i18n/backend/base' +require 'active_support/json' + +module I18n + module Backend + # This is a basic backend for key value stores. It receives on + # initialization the store, which should respond to three methods: + # + # * store#[](key) - Used to get a value + # * store#[]=(key, value) - Used to set a value + # * store#keys - Used to get all keys + # + # Since these stores only supports string, all values are converted + # to JSON before being stored, allowing it to also store booleans, + # hashes and arrays. However, this store does not support Procs. + # + # As the ActiveRecord backend, Symbols are just supported when loading + # translations from the filesystem or through explicit store translations. + # + # Also, avoid calling I18n.available_locales since it's a somehow + # expensive operation in most stores. + # + # == Example + # + # To setup I18n to use TokyoCabinet in memory is quite straightforward: + # + # require 'rufus/tokyo/cabinet' # gem install rufus-tokyo + # I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*')) + # + # == Performance + # + # You may make this backend even faster by including the Memoize module. + # However, notice that you should properly clear the cache if you change + # values directly in the key-store. + # + # == Subtrees + # + # In most backends, you are allowed to retrieve part of a translation tree: + # + # I18n.backend.store_translations :en, :foo => { :bar => :baz } + # I18n.t "foo" #=> { :bar => :baz } + # + # This backend supports this feature by default, but it slows down the storage + # of new data considerably and makes hard to delete entries. That said, you are + # allowed to disable the storage of subtrees on initialization: + # + # I18n::Backend::KeyValue.new(@store, false) + # + # This is useful if you are using a KeyValue backend chained to a Simple backend. + class KeyValue + module Implementation + attr_accessor :store + + include Base, Flatten + + def initialize(store, subtrees=true) + @store, @subtrees = store, subtrees + end + + def store_translations(locale, data, options = {}) + escape = options.fetch(:escape, true) + flatten_translations(locale, data, escape, @subtrees).each do |key, value| + key = "#{locale}.#{key}" + + case value + when Hash + if @subtrees && (old_value = @store[key]) + old_value = ActiveSupport::JSON.decode(old_value) + value = old_value.deep_symbolize_keys.deep_merge!(value) if old_value.is_a?(Hash) + end + when Proc + raise "Key-value stores cannot handle procs" + end + + @store[key] = ActiveSupport::JSON.encode(value) unless value.is_a?(Symbol) + end + end + + def available_locales + locales = @store.keys.map { |k| k =~ /\./; $` } + locales.uniq! + locales.compact! + locales.map! { |k| k.to_sym } + locales + end + + protected + + def lookup(locale, key, scope = [], options = {}) + key = normalize_flat_keys(locale, key, scope, options[:separator]) + value = @store["#{locale}.#{key}"] + value = ActiveSupport::JSON.decode(value) if value + value.is_a?(Hash) ? value.deep_symbolize_keys : value + end + end + + include Implementation + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/memoize.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/memoize.rb new file mode 100644 index 00000000000..6e811d10d10 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/memoize.rb @@ -0,0 +1,48 @@ +# encoding: utf-8 +# +# Memoize module simply memoizes the values returned by lookup using +# a flat hash and can tremendously speed up the lookup process in a backend. +# +# To enable it you can simply include the Memoize module to your backend: +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Memoize) +# +# Notice that it's the responsibility of the backend to define whenever the +# cache should be cleaned. +module I18n + module Backend + module Memoize + def available_locales + @memoized_locales ||= super + end + + def store_translations(locale, data, options = {}) + reset_memoizations!(locale) + super + end + + def reload! + reset_memoizations! + super + end + + protected + + def lookup(locale, key, scope = nil, options = {}) + flat_key = I18n::Backend::Flatten.normalize_flat_keys(locale, + key, scope, options[:separator]).to_sym + flat_hash = memoized_lookup[locale.to_sym] + flat_hash.key?(flat_key) ? flat_hash[flat_key] : (flat_hash[flat_key] = super) + end + + def memoized_lookup + @memoized_lookup ||= Hash.new { |h, k| h[k] = {} } + end + + def reset_memoizations!(locale=nil) + @memoized_locales = nil + (locale ? memoized_lookup[locale.to_sym] : memoized_lookup).clear + end + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/metadata.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/metadata.rb new file mode 100644 index 00000000000..5237b4d9aba --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/metadata.rb @@ -0,0 +1,65 @@ +# I18n translation metadata is useful when you want to access information +# about how a translation was looked up, pluralized or interpolated in +# your application. +# +# msg = I18n.t(:message, :default => 'Hi!', :scope => :foo) +# msg.translation_metadata +# # => { :key => :message, :scope => :foo, :default => 'Hi!' } +# +# If a :count option was passed to #translate it will be set to the metadata. +# Likewise, if any interpolation variables were passed they will also be set. +# +# To enable translation metadata you can simply include the Metadata module +# into the Simple backend class - or whatever other backend you are using: +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Metadata) +# +module I18n + module Backend + module Metadata + class << self + def included(base) + Object.class_eval do + def translation_metadata + @translation_metadata ||= {} + end + + def translation_metadata=(translation_metadata) + @translation_metadata = translation_metadata + end + end unless Object.method_defined?(:translation_metadata) + end + end + + def translate(locale, key, options = {}) + metadata = { + :locale => locale, + :key => key, + :scope => options[:scope], + :default => options[:default], + :separator => options[:separator], + :values => options.reject { |name, value| Base::RESERVED_KEYS.include?(name) } + } + with_metadata(metadata) { super } + end + + def interpolate(locale, entry, values = {}) + metadata = entry.translation_metadata.merge(:original => entry) + with_metadata(metadata) { super } + end + + def pluralize(locale, entry, count) + with_metadata(:count => count) { super } + end + + protected + + def with_metadata(metadata, &block) + result = yield + result.translation_metadata = result.translation_metadata.merge(metadata) if result + result + end + + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/pluralization.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/pluralization.rb new file mode 100644 index 00000000000..33a2aff7f66 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/pluralization.rb @@ -0,0 +1,57 @@ +# encoding: utf-8 + +# I18n locale fallbacks are useful when you want your application to use +# translations from other locales when translations for the current locale are +# missing. E.g. you might want to use :en translations when translations in +# your applications main locale :de are missing. +# +# To enable locale specific pluralizations you can simply include the +# Pluralization module to the Simple backend - or whatever other backend you +# are using. +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization) +# +# You also need to make sure to provide pluralization algorithms to the +# backend, i.e. include them to your I18n.load_path accordingly. +module I18n + module Backend + module Pluralization + # Overwrites the Base backend translate method so that it will check the + # translation meta data space (:i18n) for a locale specific pluralization + # rule and use it to pluralize the given entry. I.e. the library expects + # pluralization rules to be stored at I18n.t(:'i18n.plural.rule') + # + # Pluralization rules are expected to respond to #call(entry, count) and + # return a pluralization key. Valid keys depend on the translation data + # hash (entry) but it is generally recommended to follow CLDR's style, + # i.e., return one of the keys :zero, :one, :few, :many, :other. + # + # The :zero key is always picked directly when count equals 0 AND the + # translation data has the key :zero. This way translators are free to + # either pick a special :zero translation even for languages where the + # pluralizer does not return a :zero key. + def pluralize(locale, entry, count) + return entry unless entry.is_a?(Hash) and count + + pluralizer = pluralizer(locale) + if pluralizer.respond_to?(:call) + key = count == 0 && entry.has_key?(:zero) ? :zero : pluralizer.call(count) + raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) + entry[key] + else + super + end + end + + protected + + def pluralizers + @pluralizers ||= {} + end + + def pluralizer(locale) + pluralizers[locale] ||= I18n.t(:'i18n.plural.rule', :locale => locale, :resolve => false) + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/simple.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/simple.rb new file mode 100644 index 00000000000..25b8c02a018 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/simple.rb @@ -0,0 +1,87 @@ +# encoding: utf-8 + +module I18n + module Backend + # A simple backend that reads translations from YAML files and stores them in + # an in-memory hash. Relies on the Base backend. + # + # The implementation is provided by a Implementation module allowing to easily + # extend Simple backend's behavior by including modules. E.g.: + # + # module I18n::Backend::Pluralization + # def pluralize(*args) + # # extended pluralization logic + # super + # end + # end + # + # I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization) + class Simple + module Implementation + include Base + + def initialized? + @initialized ||= false + end + + # Stores translations for the given locale in memory. + # This uses a deep merge for the translations hash, so existing + # translations will be overwritten by new ones only at the deepest + # level of the hash. + def store_translations(locale, data, options = {}) + locale = locale.to_sym + translations[locale] ||= {} + data = data.deep_symbolize_keys + translations[locale].deep_merge!(data) + end + + # Get available locales from the translations hash + def available_locales + init_translations unless initialized? + translations.inject([]) do |locales, (locale, data)| + locales << locale unless (data.keys - [:i18n]).empty? + locales + end + end + + # Clean up translations hash and set initialized to false on reload! + def reload! + @initialized = false + @translations = nil + super + end + + protected + + def init_translations + load_translations + @initialized = true + end + + def translations + @translations ||= {} + end + + # Looks up a translation from the translations hash. Returns nil if + # eiher key is nil, or locale, scope or key do not exist as a key in the + # nested translations hash. Splits keys or scopes containing dots + # into multiple keys, i.e. currency.format is regarded the same as + # %w(currency format). + def lookup(locale, key, scope = [], options = {}) + init_translations unless initialized? + keys = I18n.normalize_keys(locale, key, scope, options[:separator]) + + keys.inject(translations) do |result, _key| + _key = _key.to_sym + return nil unless result.is_a?(Hash) && result.has_key?(_key) + result = result[_key] + result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol) + result + end + end + end + + include Implementation + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/transliterator.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/transliterator.rb new file mode 100644 index 00000000000..2ce2cc82740 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/backend/transliterator.rb @@ -0,0 +1,98 @@ +# encoding: utf-8 +module I18n + module Backend + module Transliterator + DEFAULT_REPLACEMENT_CHAR = "?" + + # Given a locale and a UTF-8 string, return the locale's ASCII + # approximation for the string. + def transliterate(locale, string, replacement = nil) + @transliterators ||= {} + @transliterators[locale] ||= Transliterator.get I18n.t(:'i18n.transliterate.rule', + :locale => locale, :resolve => false, :default => {}) + @transliterators[locale].transliterate(string, replacement) + end + + # Get a transliterator instance. + def self.get(rule = nil) + if !rule || rule.kind_of?(Hash) + HashTransliterator.new(rule) + elsif rule.kind_of? Proc + ProcTransliterator.new(rule) + else + raise I18n::ArgumentError, "Transliteration rule must be a proc or a hash." + end + end + + # A transliterator which accepts a Proc as its transliteration rule. + class ProcTransliterator + def initialize(rule) + @rule = rule + end + + def transliterate(string, replacement = nil) + @rule.call(string) + end + end + + # A transliterator which accepts a Hash of characters as its translation + # rule. + class HashTransliterator + DEFAULT_APPROXIMATIONS = { + "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"AE", + "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I", + "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O", + "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U", + "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "à"=>"a", "á"=>"a", "â"=>"a", + "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", "è"=>"e", "é"=>"e", + "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", "ï"=>"i", "ð"=>"d", + "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", "ö"=>"o", "ø"=>"o", + "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", "þ"=>"th", "ÿ"=>"y", + "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", "ą"=>"a", "Ć"=>"C", + "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", "Č"=>"C", "č"=>"c", + "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", "ē"=>"e", "Ĕ"=>"E", + "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", "Ě"=>"E", "ě"=>"e", + "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", "ġ"=>"g", "Ģ"=>"G", + "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", "Ĩ"=>"I", "ĩ"=>"i", + "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", "į"=>"i", "İ"=>"I", + "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", "Ķ"=>"K", "ķ"=>"k", + "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", "Ľ"=>"L", "ľ"=>"l", + "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", "ń"=>"n", "Ņ"=>"N", + "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", "ŋ"=>"ng", + "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", "Œ"=>"OE", + "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", "ř"=>"r", + "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", "Š"=>"S", + "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", "ŧ"=>"t", + "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", "Ů"=>"U", + "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", "ŵ"=>"w", + "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", "ż"=>"z", + "Ž"=>"Z", "ž"=>"z" + } + + def initialize(rule = nil) + @rule = rule + add DEFAULT_APPROXIMATIONS + add rule if rule + end + + def transliterate(string, replacement = nil) + string.gsub(/[^\x00-\x7f]/u) do |char| + approximations[char] || replacement || DEFAULT_REPLACEMENT_CHAR + end + end + + private + + def approximations + @approximations ||= {} + end + + # Add transliteration rules to the approximations hash. + def add(hash) + hash.keys.each {|key| hash[key.to_s] = hash.delete(key).to_s} + approximations.merge! hash + end + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/config.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/config.rb new file mode 100644 index 00000000000..e393292493b --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/config.rb @@ -0,0 +1,86 @@ +module I18n + class Config + # The only configuration value that is not global and scoped to thread is :locale. + # It defaults to the default_locale. + def locale + @locale ||= default_locale + end + + # Sets the current locale pseudo-globally, i.e. in the Thread.current hash. + def locale=(locale) + @locale = locale.to_sym rescue nil + end + + # Returns the current backend. Defaults to +Backend::Simple+. + def backend + @@backend ||= Backend::Simple.new + end + + # Sets the current backend. Used to set a custom backend. + def backend=(backend) + @@backend = backend + end + + # Returns the current default locale. Defaults to :'en' + def default_locale + @@default_locale ||= :en + end + + # Sets the current default locale. Used to set a custom default locale. + def default_locale=(locale) + @@default_locale = locale.to_sym rescue nil + end + + # Returns an array of locales for which translations are available. + # Unless you explicitely set these through I18n.available_locales= + # the call will be delegated to the backend. + def available_locales + @@available_locales ||= nil + @@available_locales || backend.available_locales + end + + # Sets the available locales. + def available_locales=(locales) + @@available_locales = Array(locales).map {|locale| locale.to_sym} + @@available_locales = nil if @@available_locales.empty? + end + + # Returns the current default scope separator. Defaults to '.' + def default_separator + @@default_separator ||= '.' + end + + # Sets the current default scope separator. + def default_separator=(separator) + @@default_separator = separator + end + + # Return the current exception handler. Defaults to :default_exception_handler. + def exception_handler + @@exception_handler ||= :default_exception_handler + end + + # Sets the exception handler. + def exception_handler=(exception_handler) + @@exception_handler = exception_handler + end + + # Allow clients to register paths providing translation data sources. The + # backend defines acceptable sources. + # + # E.g. the provided SimpleBackend accepts a list of paths to translation + # files which are either named *.rb and contain plain Ruby Hashes or are + # named *.yml and contain YAML data. So for the SimpleBackend clients may + # register translation files like this: + # I18n.load_path << 'path/to/locale/en.yml' + def load_path + @@load_path ||= [] + end + + # Sets the load path instance. Custom implementations are expected to + # behave like a Ruby Array. + def load_path=(load_path) + @@load_path = load_path + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/core_ext/hash.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/core_ext/hash.rb new file mode 100644 index 00000000000..f2a2422b9b6 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/core_ext/hash.rb @@ -0,0 +1,29 @@ +class Hash + def slice(*keep_keys) + h = {} + keep_keys.each { |key| h[key] = fetch(key) } + h + end unless Hash.method_defined?(:slice) + + def except(*less_keys) + slice(*keys - less_keys) + end unless Hash.method_defined?(:except) + + def deep_symbolize_keys + inject({}) { |result, (key, value)| + value = value.deep_symbolize_keys if value.is_a?(Hash) + result[(key.to_sym rescue key) || key] = value + result + } + end unless Hash.method_defined?(:deep_symbolize_keys) + + # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809 + MERGER = proc do |key, v1, v2| + Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2 + end + + def deep_merge!(data) + merge!(data, &MERGER) + end unless Hash.method_defined?(:deep_merge!) +end + diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/core_ext/string/interpolate.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/core_ext/string/interpolate.rb new file mode 100644 index 00000000000..585af6fb0d2 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/core_ext/string/interpolate.rb @@ -0,0 +1,98 @@ +# encoding: utf-8 + +=begin + heavily based on Masao Mutoh's gettext String interpolation extension + http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb + Copyright (C) 2005-2009 Masao Mutoh + You may redistribute it and/or modify it under the same license terms as Ruby. +=end + +begin + raise ArgumentError if ("a %{x}" % {:x=>'b'}) != 'a b' +rescue ArgumentError + # KeyError is raised by String#% when the string contains a named placeholder + # that is not contained in the given arguments hash. Ruby 1.9 includes and + # raises this exception natively. We define it to mimic Ruby 1.9's behaviour + # in Ruby 1.8.x + class KeyError < IndexError + def initialize(message = nil) + super(message || "key not found") + end + end unless defined?(KeyError) + + # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError. + # + # String#% method which accept "named argument". The translator can know + # the meaning of the msgids using "named argument" instead of %s/%d style. + class String + # For older ruby versions, such as ruby-1.8.5 + alias :bytesize :size unless instance_methods.find {|m| m.to_s == 'bytesize'} + alias :interpolate_without_ruby_19_syntax :% # :nodoc: + + INTERPOLATION_PATTERN = Regexp.union( + /%\{(\w+)\}/, # matches placeholders like "%{foo}" + /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%.d" + ) + + INTERPOLATION_PATTERN_WITH_ESCAPE = Regexp.union( + /%%/, + INTERPOLATION_PATTERN + ) + + # % uses self (i.e. the String) as a format specification and returns the + # result of applying it to the given arguments. In other words it interpolates + # the given arguments to the string according to the formats the string + # defines. + # + # There are three ways to use it: + # + # * Using a single argument or Array of arguments. + # + # This is the default behaviour of the String class. See Kernel#sprintf for + # more details about the format string. + # + # Example: + # + # "%d %s" % [1, "message"] + # # => "1 message" + # + # * Using a Hash as an argument and unformatted, named placeholders. + # + # When you pass a Hash as an argument and specify placeholders with %{foo} + # it will interpret the hash values as named arguments. + # + # Example: + # + # "%{firstname}, %{lastname}" % {:firstname => "Masao", :lastname => "Mutoh"} + # # => "Masao Mutoh" + # + # * Using a Hash as an argument and formatted, named placeholders. + # + # When you pass a Hash as an argument and specify placeholders with %d + # it will interpret the hash values as named arguments and format the value + # according to the formatting instruction appended to the closing >. + # + # Example: + # + # "%d, %.1f" % { :integer => 10, :float => 43.4 } + # # => "10, 43.3" + def %(args) + if args.kind_of?(Hash) + dup.gsub(INTERPOLATION_PATTERN_WITH_ESCAPE) do |match| + if match == '%%' + '%' + else + key = ($1 || $2).to_sym + raise KeyError unless args.has_key?(key) + $3 ? sprintf("%#{$3}", args[key]) : args[key] + end + end + elsif self =~ INTERPOLATION_PATTERN + raise ArgumentError.new('one hash required') + else + result = gsub(/%([{<])/, '%%\1') + result.send :'interpolate_without_ruby_19_syntax', args + end + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/exceptions.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/exceptions.rb new file mode 100644 index 00000000000..98e6a78195f --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/exceptions.rb @@ -0,0 +1,71 @@ +# encoding: utf-8 + +class KeyError < IndexError + def initialize(message = nil) + super(message || "key not found") + end +end unless defined?(KeyError) + +module I18n + class ArgumentError < ::ArgumentError; end + + class InvalidLocale < ArgumentError + attr_reader :locale + def initialize(locale) + @locale = locale + super "#{locale.inspect} is not a valid locale" + end + end + + class InvalidLocaleData < ArgumentError + attr_reader :filename + def initialize(filename) + @filename = filename + super "can not load translations from #{filename}, expected it to return a hash, but does not" + end + end + + class MissingTranslationData < ArgumentError + attr_reader :locale, :key, :options + def initialize(locale, key, opts = nil) + @key, @locale, @options = key, locale, opts.dup || {} + options.each { |k, v| options[k] = v.inspect if v.is_a?(Proc) } + + keys = I18n.normalize_keys(locale, key, options[:scope]) + keys << 'no key' if keys.size < 2 + super "translation missing: #{keys.join(', ')}" + end + end + + class InvalidPluralizationData < ArgumentError + attr_reader :entry, :count + def initialize(entry, count) + @entry, @count = entry, count + super "translation data #{entry.inspect} can not be used with :count => #{count}" + end + end + + class MissingInterpolationArgument < ArgumentError + attr_reader :values, :string + def initialize(values, string) + @values, @string = values, string + super "missing interpolation argument in #{string.inspect} (#{values.inspect} given)" + end + end + + class ReservedInterpolationKey < ArgumentError + attr_reader :key, :string + def initialize(key, string) + @key, @string = key, string + super "reserved key #{key.inspect} used in #{string.inspect}" + end + end + + class UnknownFileType < ArgumentError + attr_reader :type, :filename + def initialize(type, filename) + @type, @filename = type, filename + super "can not load translations from #{filename}, the file type #{type} is not known" + end + end +end \ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext.rb new file mode 100644 index 00000000000..a824aa5a0ca --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext.rb @@ -0,0 +1,27 @@ +# encoding: utf-8 + +module I18n + module Gettext + PLURAL_SEPARATOR = "\001" + CONTEXT_SEPARATOR = "\004" + + autoload :Helpers, 'i18n/gettext/helpers' + + @@plural_keys = { :en => [:one, :other] } + + class << self + # returns an array of plural keys for the given locale so that we can + # convert from gettext's integer-index based style + # TODO move this information to the pluralization module + def plural_keys(locale) + @@plural_keys[locale] || @@plural_keys[:en] + end + + def extract_scope(msgid, separator) + scope = msgid.to_s.split(separator) + msgid = scope.pop + [scope, msgid] + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext/helpers.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext/helpers.rb new file mode 100644 index 00000000000..6a97814b457 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext/helpers.rb @@ -0,0 +1,65 @@ +# encoding: utf-8 +require 'i18n/gettext' + +module I18n + module Gettext + # Implements classical Gettext style accessors. To use this include the + # module to the global namespace or wherever you want to use it. + # + # include I18n::Gettext::Helpers + module Helpers + def gettext(msgid, options = {}) + I18n.t(msgid, { :default => msgid, :separator => '|' }.merge(options)) + end + alias _ gettext + + def sgettext(msgid, separator = '|') + scope, msgid = I18n::Gettext.extract_scope(msgid, separator) + I18n.t(msgid, :scope => scope, :default => msgid, :separator => separator) + end + alias s_ sgettext + + def pgettext(msgctxt, msgid) + separator = I18n::Gettext::CONTEXT_SEPARATOR + sgettext([msgctxt, msgid].join(separator), separator) + end + alias p_ pgettext + + def ngettext(msgid, msgid_plural, n = 1) + nsgettext(msgid, msgid_plural, n) + end + alias n_ ngettext + + # Method signatures: + # nsgettext('Fruits|apple', 'apples', 2) + # nsgettext(['Fruits|apple', 'apples'], 2) + def nsgettext(msgid, msgid_plural, n = 1, separator = '|') + if msgid.is_a?(Array) + msgid, msgid_plural, n, separator = msgid[0], msgid[1], msgid_plural, n + separator = '|' unless separator.is_a?(::String) + end + + scope, msgid = I18n::Gettext.extract_scope(msgid, separator) + default = { :one => msgid, :other => msgid_plural } + I18n.t(msgid, :default => default, :count => n, :scope => scope, :separator => separator) + end + alias ns_ nsgettext + + # Method signatures: + # npgettext('Fruits', 'apple', 'apples', 2) + # npgettext('Fruits', ['apple', 'apples'], 2) + def npgettext(msgctxt, msgid, msgid_plural, n = 1) + separator = I18n::Gettext::CONTEXT_SEPARATOR + + if msgid.is_a?(Array) + msgid_plural, msgid, n = msgid[1], [msgctxt, msgid[0]].join(separator), msgid_plural + else + msgid = [msgctxt, msgid].join(separator) + end + + nsgettext(msgid, msgid_plural, n, separator) + end + alias np_ npgettext + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext/po_parser.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext/po_parser.rb new file mode 100644 index 00000000000..547df6a5931 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/gettext/po_parser.rb @@ -0,0 +1,329 @@ +=begin + poparser.rb - Generate a .mo + + Copyright (C) 2003-2009 Masao Mutoh + + You may redistribute it and/or modify it under the same + license terms as Ruby. +=end + +#MODIFIED +# removed include GetText etc +# added stub translation method _(x) +require 'racc/parser' + +module GetText + + class PoParser < Racc::Parser + + def _(x) + x + end + +module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 108 + def unescape(orig) + ret = orig.gsub(/\\n/, "\n") + ret.gsub!(/\\t/, "\t") + ret.gsub!(/\\r/, "\r") + ret.gsub!(/\\"/, "\"") + ret + end + + def parse(str, data, ignore_fuzzy = true) + @comments = [] + @data = data + @fuzzy = false + @msgctxt = "" + $ignore_fuzzy = ignore_fuzzy + + str.strip! + @q = [] + until str.empty? do + case str + when /\A\s+/ + str = $' + when /\Amsgctxt/ + @q.push [:MSGCTXT, $&] + str = $' + when /\Amsgid_plural/ + @q.push [:MSGID_PLURAL, $&] + str = $' + when /\Amsgid/ + @q.push [:MSGID, $&] + str = $' + when /\Amsgstr/ + @q.push [:MSGSTR, $&] + str = $' + when /\A\[(\d+)\]/ + @q.push [:PLURAL_NUM, $1] + str = $' + when /\A\#~(.*)/ + $stderr.print _("Warning: obsolete msgid exists.\n") + $stderr.print " #{$&}\n" + @q.push [:COMMENT, $&] + str = $' + when /\A\#(.*)/ + @q.push [:COMMENT, $&] + str = $' + when /\A\"(.*)\"/ + @q.push [:STRING, $1] + str = $' + else + #c = str[0,1] + #@q.push [:STRING, c] + str = str[1..-1] + end + end + @q.push [false, '$end'] + if $DEBUG + @q.each do |a,b| + puts "[#{a}, #{b}]" + end + end + @yydebug = true if $DEBUG + do_parse + + if @comments.size > 0 + @data.set_comment(:last, @comments.join("\n")) + end + @data + end + + def next_token + @q.shift + end + + def on_message(msgid, msgstr) + if msgstr.size > 0 + @data[msgid] = msgstr + @data.set_comment(msgid, @comments.join("\n")) + end + @comments.clear + @msgctxt = "" + end + + def on_comment(comment) + @fuzzy = true if (/fuzzy/ =~ comment) + @comments << comment + end + + +..end src/poparser.ry modeval..id7a99570e05 + +##### racc 1.4.5 generates ### + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 12, :_reduce_5, + 1, 13, :_reduce_none, + 1, 13, :_reduce_none, + 4, 15, :_reduce_8, + 5, 16, :_reduce_9, + 2, 17, :_reduce_10, + 1, 17, :_reduce_none, + 3, 18, :_reduce_12, + 1, 11, :_reduce_13, + 2, 14, :_reduce_14, + 1, 14, :_reduce_15 ] + +racc_reduce_n = 16 + +racc_shift_n = 26 + +racc_action_table = [ + 3, 13, 5, 7, 9, 15, 16, 17, 20, 17, + 13, 17, 13, 13, 11, 17, 23, 20, 13, 17 ] + +racc_action_check = [ + 1, 16, 1, 1, 1, 12, 12, 12, 18, 18, + 7, 14, 15, 9, 3, 19, 20, 21, 23, 25 ] + +racc_action_pointer = [ + nil, 0, nil, 14, nil, nil, nil, 3, nil, 6, + nil, nil, 0, nil, 4, 5, -6, nil, 2, 8, + 8, 11, nil, 11, nil, 12 ] + +racc_action_default = [ + -1, -16, -2, -16, -3, -13, -4, -16, -6, -16, + -7, 26, -16, -15, -5, -16, -16, -14, -16, -8, + -16, -9, -11, -16, -10, -12 ] + +racc_goto_table = [ + 12, 22, 14, 4, 24, 6, 2, 8, 18, 19, + 10, 21, 1, nil, nil, nil, 25 ] + +racc_goto_check = [ + 5, 9, 5, 3, 9, 4, 2, 6, 5, 5, + 7, 8, 1, nil, nil, nil, 5 ] + +racc_goto_pointer = [ + nil, 12, 5, 2, 4, -7, 6, 9, -7, -17 ] + +racc_goto_default = [ + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ] + +racc_token_table = { + false => 0, + Object.new => 1, + :COMMENT => 2, + :MSGID => 3, + :MSGCTXT => 4, + :MSGID_PLURAL => 5, + :MSGSTR => 6, + :STRING => 7, + :PLURAL_NUM => 8 } + +racc_use_result_var = true + +racc_nt_base = 9 + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] + +Racc_token_to_s_table = [ +'$end', +'error', +'COMMENT', +'MSGID', +'MSGCTXT', +'MSGID_PLURAL', +'MSGSTR', +'STRING', +'PLURAL_NUM', +'$start', +'msgfmt', +'comment', +'msgctxt', +'message', +'string_list', +'single_message', +'plural_message', +'msgstr_plural', +'msgstr_plural_line'] + +Racc_debug_parser = true + +##### racc system variables end ##### + + # reduce 0 omitted + + # reduce 1 omitted + + # reduce 2 omitted + + # reduce 3 omitted + + # reduce 4 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 25 + def _reduce_5( val, _values, result ) + @msgctxt = unescape(val[1]) + "\004" + result + end +.,., + + # reduce 6 omitted + + # reduce 7 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 48 + def _reduce_8( val, _values, result ) + if @fuzzy and $ignore_fuzzy + if val[1] != "" + $stderr.print _("Warning: fuzzy message was ignored.\n") + $stderr.print " msgid '#{val[1]}'\n" + else + on_message('', unescape(val[3])) + end + @fuzzy = false + else + on_message(@msgctxt + unescape(val[1]), unescape(val[3])) + end + result = "" + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 65 + def _reduce_9( val, _values, result ) + if @fuzzy and $ignore_fuzzy + if val[1] != "" + $stderr.print _("Warning: fuzzy message was ignored.\n") + $stderr.print "msgid = '#{val[1]}\n" + else + on_message('', unescape(val[3])) + end + @fuzzy = false + else + on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4])) + end + result = "" + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 76 + def _reduce_10( val, _values, result ) + if val[0].size > 0 + result = val[0] + "\000" + val[1] + else + result = "" + end + result + end +.,., + + # reduce 11 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 84 + def _reduce_12( val, _values, result ) + result = val[2] + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 91 + def _reduce_13( val, _values, result ) + on_comment(val[0]) + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 99 + def _reduce_14( val, _values, result ) + result = val.delete_if{|item| item == ""}.join + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 103 + def _reduce_15( val, _values, result ) + result = val[0] + result + end +.,., + + def _reduce_none( val, _values, result ) + result + end + + end # class PoParser + +end # module GetText diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale.rb new file mode 100644 index 00000000000..4f9d0266d54 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale.rb @@ -0,0 +1,6 @@ +module I18n + module Locale + autoload :Fallbacks, 'i18n/locale/fallbacks' + autoload :Tag, 'i18n/locale/tag' + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/fallbacks.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/fallbacks.rb new file mode 100644 index 00000000000..11dcf8c2d29 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/fallbacks.rb @@ -0,0 +1,98 @@ +# encoding: utf-8 + +# Locale Fallbacks +# +# Extends the I18n module to hold a fallbacks instance which is set to an +# instance of I18n::Locale::Fallbacks by default but can be swapped with a +# different implementation. +# +# Locale fallbacks will compute a number of fallback locales for a given locale. +# For example: +# +#

+# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] 
+# +# Locale fallbacks always fall back to +# +# * all parent locales of a given locale (e.g. :es for :"es-MX") first, +# * the current default locales and all of their parents second +# +# The default locales are set to [I18n.default_locale] by default but can be +# set to something else. +# +# One can additionally add any number of additional fallback locales manually. +# These will be added before the default locales to the fallback chain. For +# example: +# +# # using the default locale as default fallback locale +# +# I18n.default_locale = :"en-US" +# I18n.fallbacks = I18n::Fallbacks.new(:"de-AT" => :"de-DE") +# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en] +# +# # using a custom locale as default fallback locale +# +# I18n.fallbacks = I18n::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de) +# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en] +# I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en] +# +# # mapping fallbacks to an existing instance +# +# # people speaking Catalan also speak Spanish as spoken in Spain +# fallbacks = I18n.fallbacks +# fallbacks.map(:ca => :"es-ES") +# fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en] +# +# # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel +# fallbacks.map(:"ar-PS" => :"he-IL") +# fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en] +# fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en] +# +# # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland +# fallbacks.map(:sms => [:"se-FI", :"fi-FI"]) +# fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en] + +module I18n + module Locale + class Fallbacks < Hash + def initialize(*mappings) + @map = {} + map(mappings.pop) if mappings.last.is_a?(Hash) + self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings + end + + def defaults=(defaults) + @defaults = defaults.map { |default| compute(default, false) }.flatten + end + attr_reader :defaults + + def [](locale) + raise InvalidLocale.new(locale) if locale.nil? + locale = locale.to_sym + super || store(locale, compute(locale)) + end + + def map(mappings) + mappings.each do |from, to| + from, to = from.to_sym, Array(to) + to.each do |to| + @map[from] ||= [] + @map[from] << to.to_sym + end + end + end + + protected + + def compute(tags, include_defaults = true) + result = Array(tags).collect do |tag| + tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } + tags.each { |tag| tags += compute(@map[tag]) if @map[tag] } + tags + end.flatten + result.push(*defaults) if include_defaults + result.uniq + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag.rb new file mode 100644 index 00000000000..a640b4465f6 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag.rb @@ -0,0 +1,28 @@ +# encoding: utf-8 + +module I18n + module Locale + module Tag + autoload :Parents, 'i18n/locale/tag/parents' + autoload :Rfc4646, 'i18n/locale/tag/rfc4646' + autoload :Simple, 'i18n/locale/tag/simple' + + class << self + # Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+. + def implementation + @@implementation ||= Simple + end + + # Sets the current locale tag implementation. Use this to set a different locale tag implementation. + def implementation=(implementation) + @@implementation = implementation + end + + # Factory method for locale tags. Delegates to the current locale tag implementation. + def tag(tag) + implementation.tag(tag) + end + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/parents.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/parents.rb new file mode 100644 index 00000000000..a0944683844 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/parents.rb @@ -0,0 +1,24 @@ +# encoding: utf-8 + +module I18n + module Locale + module Tag + module Parents + def parent + @parent ||= begin + segs = to_a.compact + segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil + end + end + + def self_and_parents + @self_and_parents ||= [self] + parents + end + + def parents + @parents ||= ([parent] + (parent ? parent.parents : [])).compact + end + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/rfc4646.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/rfc4646.rb new file mode 100644 index 00000000000..c20d35ae727 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/rfc4646.rb @@ -0,0 +1,76 @@ +# encoding: utf-8 + +# RFC 4646/47 compliant Locale tag implementation that parses locale tags to +# subtags such as language, script, region, variant etc. +# +# For more information see by http://en.wikipedia.org/wiki/IETF_language_tag +# +# Rfc4646::Parser does not implement grandfathered tags. + +module I18n + module Locale + module Tag + RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ] + RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase } + + class Rfc4646 < Struct.new(*RFC4646_SUBTAGS) + class << self + # Parses the given tag and returns a Tag instance if it is valid. + # Returns false if the given tag is not valid according to RFC 4646. + def tag(tag) + matches = parser.match(tag) + new(*matches) if matches + end + + def parser + @@parser ||= Rfc4646::Parser + end + + def parser=(parser) + @@parser = parser + end + end + + include Parents + + RFC4646_FORMATS.each do |name, format| + define_method(name) { self[name].send(format) unless self[name].nil? } + end + + def to_sym + to_s.to_sym + end + + def to_s + @tag ||= to_a.compact.join("-") + end + + def to_a + members.collect { |attr| self.send(attr) } + end + + module Parser + PATTERN = %r{\A(?: + ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language + (?:-([a-z]{4}))? # script + (?:-([a-z]{2}|\d{3}))? # region + (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant + (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension + (?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag + (x(?:-[0-9a-z]{1,8})+)| # privateuse tag + /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered + )\z}xi + + class << self + def match(tag) + c = PATTERN.match(tag.to_s).captures + c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here? + rescue + false + end + end + end + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/simple.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/simple.rb new file mode 100644 index 00000000000..0fddb366a60 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/locale/tag/simple.rb @@ -0,0 +1,41 @@ +# encoding: utf-8 + +# Simple Locale tag implementation that computes subtags by simply splitting +# the locale tag at '-' occurences. +module I18n + module Locale + module Tag + class Simple + class << self + def tag(tag) + new(tag) + end + end + + include Parents + + attr_reader :tag + + def initialize(*tag) + @tag = tag.join('-').to_sym + end + + def subtags + @subtags = tag.to_s.split('-').map { |subtag| subtag.to_s } + end + + def to_sym + tag + end + + def to_s + tag.to_s + end + + def to_a + subtags + end + end + end + end +end diff --git a/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/version.rb b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/version.rb new file mode 100644 index 00000000000..33721b9ffe0 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/vendor/gems/i18n-0.4.2/lib/i18n/version.rb @@ -0,0 +1,3 @@ +module I18n + VERSION = "0.4.2" +end