singleton-client 0.7.3 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +27 -28
- data/lib/sgtn-client/api/source.rb +10 -66
- data/lib/sgtn-client/api/t.rb +20 -18
- data/lib/sgtn-client/api/translation.rb +84 -115
- data/lib/sgtn-client/cldr/core_ext.rb +4 -1
- data/lib/sgtn-client/cldr/localized_date.rb +4 -1
- data/lib/sgtn-client/cldr/localized_datetime.rb +4 -1
- data/lib/sgtn-client/cldr/localized_str.rb +4 -1
- data/lib/sgtn-client/cldr/localized_time.rb +4 -1
- data/lib/sgtn-client/common/data.rb +30 -0
- data/lib/sgtn-client/common/single_operation.rb +34 -0
- data/lib/sgtn-client/core/cache.rb +15 -82
- data/lib/sgtn-client/core/config.rb +42 -3
- data/lib/sgtn-client/core/exceptions.rb +3 -0
- data/lib/sgtn-client/core/logging.rb +3 -1
- data/lib/sgtn-client/exceptions.rb +6 -0
- data/lib/sgtn-client/formatters/plurals/plural_formatter.rb +4 -1
- data/lib/sgtn-client/loader/cache.rb +71 -0
- data/lib/sgtn-client/loader/chain_loader.rb +49 -0
- data/lib/sgtn-client/loader/consts.rb +15 -0
- data/lib/sgtn-client/loader/loader_factory.rb +33 -0
- data/lib/sgtn-client/loader/local_translation.rb +49 -0
- data/lib/sgtn-client/loader/server.rb +94 -0
- data/lib/sgtn-client/loader/single_loader.rb +48 -0
- data/lib/sgtn-client/loader/source.rb +56 -0
- data/lib/sgtn-client/loader/source_comparer.rb +58 -0
- data/lib/sgtn-client/sgtn-client.rb +11 -2
- data/lib/sgtn-client/util/cache-util.rb +33 -41
- data/lib/sgtn-client/util/locale-util.rb +67 -28
- data/lib/sgtn-client/util/string-util.rb +12 -0
- data/lib/sgtn-client/util/validate-util.rb +5 -9
- data/lib/singleton-client.rb +15 -0
- data/lib/singleton-ruby.rb +5 -0
- data/lib/version.rb +2 -0
- metadata +43 -147
- data/lib/sgtn-client/core/request.rb +0 -21
- data/lib/sgtn-client/util/file-util.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a587958936d82290e3937f0a96097f4254bb3e8743673a808702a2881d414ff9
|
4
|
+
data.tar.gz: f60706e62d08f058fca8eb1b286800f61f4a79f78cd5aadb4b1c53ed7736f62f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f89add299ebf85604d748fdc5c3d4e0fed05f98810514ca4de8b23eb3305af0568c32d308b59fa2b54f1f3188531de4c07732d6d5c59d4d13cc3a6f6ef0cb21
|
7
|
+
data.tar.gz: c2192d0d69ed16250d55a5f9e255c4ede49b404cc93f90ae3d266aa1663cdfcdce114317b593509a8be64e0f6d3587811eb4f8587b39517c08a5647460a462d1
|
data/README.md
CHANGED
@@ -1,54 +1,53 @@
|
|
1
|
-
#
|
1
|
+
# Singleton Client for Ruby
|
2
2
|
|
3
3
|
## Prerequisites
|
4
4
|
- Ruby version: 3.0.0 or above
|
5
5
|
- Bundler version: 2.2.3 or above
|
6
6
|
|
7
7
|
## Run Unit Test
|
8
|
-
rake spec
|
8
|
+
`rake spec`
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
12
|
Basic Usage:
|
13
13
|
|
14
14
|
```ruby
|
15
|
-
require 'singleton-
|
16
|
-
|
17
|
-
include SgtnClient
|
18
|
-
|
19
|
-
SgtnClient.load(file, mode)
|
20
|
-
|
21
|
-
SgtnClient::Source.loadBundles(locale)
|
22
|
-
|
23
|
-
@Result = SgtnClient::Translation.getString(component, key, locale)
|
15
|
+
require 'singleton-client'
|
24
16
|
|
17
|
+
Sgtn.load_config(file, env)
|
18
|
+
result = Sgtn.translate(key, component, locale)
|
25
19
|
```
|
26
20
|
## API Usage
|
27
21
|
|
28
22
|
### Get a string's translation
|
29
|
-
|
30
|
-
|
31
|
-
### Get a string's translation and format it with placeholders
|
32
|
-
SgtnClient::Translation.getString_f(component, key, args, locale)
|
33
|
-
|
34
|
-
### Get a component's translations
|
35
|
-
SgtnClient::Translation.getStrings(component, locale)
|
36
|
-
|
23
|
+
`result = Sgtn.translate(key, component, locale)`
|
37
24
|
|
38
|
-
|
39
|
-
|
40
|
-
Before call below APIs(without locale and component arguments), it requires to set the locale and component in the initial codes.
|
41
|
-
|
42
|
-
### Get a string's translation
|
43
|
-
SgtnClient::T.s(key)
|
25
|
+
### Get a string's translation with default value when no translation
|
26
|
+
`result = Sgtn.translate(key, component, locale) { 'default value' }`
|
44
27
|
|
45
28
|
### Get a string's translation and format it with placeholders
|
46
|
-
|
29
|
+
`result = Sgtn.translate(key, component, locale, **args)`
|
47
30
|
|
48
|
-
### Get
|
49
|
-
|
31
|
+
### Get pluralized translation
|
32
|
+
`result = Sgtn.translate(key, component, locale, **args)`
|
50
33
|
|
34
|
+
### Get translations of a bundle
|
35
|
+
`result = Sgtn.get_translations(component, locale)`
|
51
36
|
|
37
|
+
### Set locale for a request
|
38
|
+
`Sgtn.locale = 'en'`
|
52
39
|
|
40
|
+
### Get locale of the request
|
41
|
+
`result = Sgtn.locale`
|
53
42
|
|
43
|
+
### Get a string's translation with locale set
|
44
|
+
```ruby
|
45
|
+
Sgtn.locale = 'en'
|
46
|
+
result = Sgtn.translate(key, component)
|
47
|
+
```
|
54
48
|
|
49
|
+
### Get translations of a bundle with locale set
|
50
|
+
```ruby
|
51
|
+
Sgtn.locale = 'en'
|
52
|
+
result = Sgtn.get_translations(component)
|
53
|
+
```
|
@@ -1,71 +1,15 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
4
|
+
require 'sgtn-client/loader/source'
|
1
5
|
|
2
6
|
module SgtnClient
|
3
|
-
|
4
|
-
autoload :CacheUtil, "sgtn-client/util/cache-util"
|
7
|
+
autoload :CacheUtil, 'sgtn-client/util/cache-util'
|
5
8
|
|
6
9
|
class Source
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
if items.nil?
|
12
|
-
items = getBundle(component, locale)
|
13
|
-
SgtnClient.logger.debug "Putting sources items into cache with key: " + cache_key
|
14
|
-
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
15
|
-
else
|
16
|
-
SgtnClient.logger.debug "Getting sources from cache with key: " + cache_key
|
17
|
-
end
|
18
|
-
s = items.nil?? nil : items[locale][key]
|
19
|
-
if items.nil? || s.nil?
|
20
|
-
SgtnClient.logger.debug "Source not found, return key: " + key
|
21
|
-
#return key
|
22
|
-
return nil
|
23
|
-
else
|
24
|
-
return s
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.getSources(component, locale)
|
29
|
-
cache_key = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
30
|
-
expired, items = SgtnClient::CacheUtil.get_cache(cache_key)
|
31
|
-
if items.nil? || expired
|
32
|
-
items = getBundle(component, locale)
|
33
|
-
SgtnClient.logger.debug "Putting sources items into cache with key: " + cache_key
|
34
|
-
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
35
|
-
else
|
36
|
-
SgtnClient.logger.debug "Getting sources from cache with key: " + cache_key
|
37
|
-
end
|
38
|
-
return items
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.loadBundles(locale)
|
42
|
-
env = SgtnClient::Config.default_environment
|
43
|
-
SgtnClient::Config.configurations.default = locale
|
44
|
-
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
45
|
-
SgtnClient.logger.debug "Loading [" + locale + "] source bundles from path: " + source_bundle
|
46
|
-
Dir.foreach(source_bundle) do |component|
|
47
|
-
next if component == '.' || component == '..'
|
48
|
-
yamlfile = File.join(source_bundle, component + "/" + locale + ".yml")
|
49
|
-
bundle = SgtnClient::FileUtil.read_yml(yamlfile)
|
50
|
-
cachekey = SgtnClient::CacheUtil.get_cachekey(component, locale)
|
51
|
-
SgtnClient::CacheUtil.write_cache(cachekey,bundle)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
def self.getBundle(component, locale)
|
57
|
-
env = SgtnClient::Config.default_environment
|
58
|
-
source_bundle = SgtnClient::Config.configurations[env]["source_bundle"]
|
59
|
-
bundlepath = source_bundle + "/" + component + "/" + locale + ".yml"
|
60
|
-
SgtnClient.logger.debug "Getting source from bundle: " + bundlepath
|
61
|
-
begin
|
62
|
-
bundle = SgtnClient::FileUtil.read_yml(bundlepath)
|
63
|
-
rescue => exception
|
64
|
-
SgtnClient.logger.error exception.message
|
65
|
-
end
|
66
|
-
return bundle
|
67
|
-
end
|
68
|
-
|
10
|
+
def self.loadBundles(locale)
|
11
|
+
SgtnClient.logger.debug "[Source][loadBundles]locale=#{locale}"
|
12
|
+
SgtnClient::Config.configurations.default = locale
|
13
|
+
end
|
69
14
|
end
|
70
|
-
|
71
|
-
end
|
15
|
+
end
|
data/lib/sgtn-client/api/t.rb
CHANGED
@@ -1,22 +1,24 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
module SgtnClient
|
5
|
+
class T
|
6
|
+
def self.s(key)
|
7
|
+
locale = RequestStore.store[:locale]
|
8
|
+
component = RequestStore.store[:component]
|
9
|
+
Translation.getString(component, key, locale)
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def self.s_f(key, args)
|
13
|
+
locale = RequestStore.store[:locale]
|
14
|
+
component = RequestStore.store[:component]
|
15
|
+
Translation.getString_f(component, key, args, locale)
|
16
|
+
end
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
18
|
+
def self.c
|
19
|
+
locale = RequestStore.store[:locale]
|
20
|
+
component = RequestStore.store[:component]
|
21
|
+
Translation.getStrings(component, locale)
|
21
22
|
end
|
22
|
-
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,144 +1,113 @@
|
|
1
|
-
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
2
3
|
|
3
|
-
|
4
|
+
require 'request_store'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
class Translation
|
13
|
-
|
14
|
-
def self.getString(component, key, locale)
|
15
|
-
str = getTranslation(component, key, locale)
|
16
|
-
if str.nil?
|
17
|
-
str = SgtnClient::Source.getSource(component, key, SgtnClient::Config.configurations.default)
|
18
|
-
if str.nil?
|
19
|
-
SgtnClient.logger.error "Can't find the key '" + key + "' in source path!"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
str
|
6
|
+
module SgtnClient
|
7
|
+
module Translation
|
8
|
+
module Implementation
|
9
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
10
|
+
def getString(component, key, locale)
|
11
|
+
SgtnClient.logger.debug "[Translation.getString]component: #{component}, key: #{key}, locale: #{locale}"
|
12
|
+
translate(key, component, locale) { nil }
|
23
13
|
end
|
24
14
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
if str.nil?
|
30
|
-
SgtnClient.logger.error "Can't find the key '" + key + "' in source path!"
|
31
|
-
return nil
|
32
|
-
end
|
33
|
-
str.to_plural_s(:en, plural_args)
|
34
|
-
else
|
35
|
-
str.to_plural_s(locale, plural_args)
|
36
|
-
end
|
15
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
16
|
+
def getString_p(component, key, plural_args, locale)
|
17
|
+
SgtnClient.logger.debug "[Translation][getString_p]component=#{component}, key=#{key}, locale=#{locale}"
|
18
|
+
translate(key, component, locale, **plural_args) { nil }
|
37
19
|
end
|
38
20
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
21
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
22
|
+
def getString_f(component, key, args, locale, *_optionals)
|
23
|
+
SgtnClient.logger.debug "[Translation][getString_f]component=#{component}, key=#{key}, locale=#{locale}"
|
24
|
+
s = translate(key, component, locale) { nil }
|
25
|
+
return nil if s.nil?
|
26
|
+
|
27
|
+
if args.is_a?(Hash)
|
45
28
|
args.each do |source, arg|
|
46
29
|
s.gsub! "{#{source}}", arg
|
47
30
|
end
|
48
|
-
|
49
|
-
s =
|
50
|
-
|
51
|
-
|
31
|
+
elsif args.is_a?(Array)
|
32
|
+
s = s % args
|
33
|
+
end
|
34
|
+
s
|
52
35
|
end
|
53
36
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
37
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:get_translations</tt> instead.
|
38
|
+
def getStrings(component, locale)
|
39
|
+
get_translations(component, locale)
|
40
|
+
end
|
41
|
+
|
42
|
+
# raise error when translation is not found
|
43
|
+
def translate(key, component, locale = nil, **kwargs)
|
44
|
+
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] key: #{key}, component: #{component}, locale: #{locale}, args: #{kwargs}"
|
45
|
+
|
46
|
+
locale = locale.nil? ? self.locale : SgtnClient::LocaleUtil.get_best_locale(locale)
|
47
|
+
|
48
|
+
result = get_bundle(component, locale)&.fetch(key, nil)
|
49
|
+
if result.nil? && !LocaleUtil.is_source_locale(locale)
|
50
|
+
locale = LocaleUtil.get_source_locale
|
51
|
+
result = get_bundle(component, locale)&.fetch(key, nil)
|
68
52
|
end
|
69
|
-
return items
|
70
|
-
end
|
71
53
|
|
54
|
+
if result.nil?
|
55
|
+
return key unless block_given?
|
72
56
|
|
73
|
-
|
57
|
+
result = yield
|
58
|
+
return if result.nil?
|
59
|
+
end
|
74
60
|
|
75
|
-
|
76
|
-
|
77
|
-
if items.nil? || items["messages"] == nil
|
78
|
-
nil
|
61
|
+
if kwargs.empty?
|
62
|
+
result
|
79
63
|
else
|
80
|
-
|
64
|
+
locale = result.locale if result.is_a?(SgtnClient::StringUtil)
|
65
|
+
result.localize(locale) % kwargs
|
81
66
|
end
|
82
67
|
end
|
68
|
+
alias t translate
|
83
69
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
SgtnClient::Core::Cache.put(cache_key, items, 60)
|
93
|
-
else
|
94
|
-
SgtnClient::CacheUtil.write_cache(cache_key, items)
|
95
|
-
end
|
96
|
-
else
|
97
|
-
SgtnClient.logger.debug "Getting translations from cache with key: " + cache_key
|
70
|
+
def get_translations(component, locale = nil)
|
71
|
+
SgtnClient.logger.debug "[#{method(__callee__).owner}.#{__callee__}] component: #{component}, locale: #{locale}"
|
72
|
+
|
73
|
+
locale = locale.nil? ? self.locale : SgtnClient::LocaleUtil.get_best_locale(locale)
|
74
|
+
items = get_bundle(component, locale)
|
75
|
+
if items.nil? && !LocaleUtil.is_source_locale(locale)
|
76
|
+
items = get_bundle(component, LocaleUtil.get_source_locale)
|
77
|
+
locale = LocaleUtil.get_source_locale
|
98
78
|
end
|
99
79
|
|
100
|
-
|
101
|
-
|
80
|
+
{ 'component' => component, 'locale' => locale, 'messages' => items || {} } if items
|
81
|
+
end
|
102
82
|
|
103
|
-
def
|
104
|
-
|
105
|
-
mode = SgtnClient::Config.configurations[env]["bundle_mode"]
|
106
|
-
if mode == 'offline'
|
107
|
-
return load_o(component, locale)
|
108
|
-
else
|
109
|
-
return load_s(component, locale)
|
110
|
-
end
|
83
|
+
def locale
|
84
|
+
RequestStore.store[:locale] ||= SgtnClient::LocaleUtil.get_fallback_locale
|
111
85
|
end
|
112
86
|
|
113
|
-
def
|
114
|
-
|
115
|
-
product_name = SgtnClient::Config.configurations[env]["product_name"]
|
116
|
-
version = SgtnClient::Config.configurations[env]["version"].to_s
|
117
|
-
translation_bundle = SgtnClient::Config.configurations[env]["translation_bundle"]
|
118
|
-
bundlepath = translation_bundle + "/" + product_name + "/" + version + "/" + component + "/messages_" + locale + ".json"
|
119
|
-
SgtnClient.logger.debug "Getting translations from offline bundle: " + bundlepath
|
120
|
-
SgtnClient::FileUtil.read_json(bundlepath)
|
87
|
+
def locale=(value)
|
88
|
+
RequestStore.store[:locale] = SgtnClient::LocaleUtil.get_best_locale(value)
|
121
89
|
end
|
122
90
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
begin
|
132
|
-
obj = SgtnClient::Core::Request.get(url)
|
133
|
-
rescue => exception
|
134
|
-
SgtnClient.logger.error exception.message
|
135
|
-
end
|
136
|
-
if obj != nil
|
137
|
-
obj = obj["data"]
|
138
|
-
end
|
139
|
-
return obj
|
91
|
+
private
|
92
|
+
|
93
|
+
def get_bundle(component, locale)
|
94
|
+
get_bundle!(component, locale)
|
95
|
+
rescue StandardError => e
|
96
|
+
SgtnClient.logger.error "[#{method(__callee__).owner}.#{__callee__}] failed to get a bundle. component: #{component}, locale: #{locale}"
|
97
|
+
SgtnClient.logger.error e
|
98
|
+
nil
|
140
99
|
end
|
141
100
|
|
142
|
-
|
101
|
+
def get_bundle!(component, locale)
|
102
|
+
id = SgtnClient::Common::BundleID.new(component, locale)
|
103
|
+
bundles = SgtnClient::Config.available_bundles
|
104
|
+
unless bundles.nil? || bundles.empty? || bundles.include?(id)
|
105
|
+
raise SgtnClient::SingletonError, 'bundle is unavailable.'
|
106
|
+
end
|
143
107
|
|
144
|
-
|
108
|
+
SgtnClient::Config.loader.get_bundle(component, locale)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
extend Implementation
|
112
|
+
end
|
113
|
+
end
|
@@ -1,4 +1,7 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
1
4
|
require 'sgtn-client/cldr/localized_datetime'
|
2
5
|
require 'sgtn-client/cldr/localized_date'
|
3
6
|
require 'sgtn-client/cldr/localized_time'
|
4
|
-
require 'sgtn-client/cldr/localized_str'
|
7
|
+
require 'sgtn-client/cldr/localized_str'
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
1
4
|
require 'date'
|
2
5
|
require 'time'
|
3
6
|
|
@@ -24,4 +27,4 @@ Date.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
|
24
27
|
def l_short_s(locale = TwitterCldr.locale)
|
25
28
|
self.to_datetime().localize(locale).to_date().to_short_s
|
26
29
|
end
|
27
|
-
LOCALIZE
|
30
|
+
LOCALIZE
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
1
4
|
require 'date'
|
2
5
|
require 'time'
|
3
6
|
|
@@ -60,4 +63,4 @@ DateTime.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
|
60
63
|
tz.display_name_for(self, display_name)
|
61
64
|
end
|
62
65
|
end
|
63
|
-
LOCALIZE
|
66
|
+
LOCALIZE
|
@@ -1,5 +1,8 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
1
3
|
|
2
4
|
String.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
5
|
+
# <b>DEPRECATED:</b> Please use <tt>Sgtn:translate</tt> instead.
|
3
6
|
def to_plural_s(locale, arg)
|
4
7
|
num_str = SgtnClient::Formatters::PluralFormatter.new(locale).num_s(self, arg)
|
5
8
|
if num_str.nil? || num_str.empty?
|
@@ -8,4 +11,4 @@ String.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
|
8
11
|
num_str
|
9
12
|
end
|
10
13
|
end
|
11
|
-
LOCALIZE
|
14
|
+
LOCALIZE
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
1
4
|
require 'date'
|
2
5
|
require 'time'
|
3
6
|
|
@@ -24,4 +27,4 @@ Time.class_eval <<-LOCALIZE, __FILE__, __LINE__ + 1
|
|
24
27
|
def l_short_s(locale = TwitterCldr.locale)
|
25
28
|
self.localize(locale).to_short_s
|
26
29
|
end
|
27
|
-
LOCALIZE
|
30
|
+
LOCALIZE
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
module Common
|
6
|
+
class BundleID
|
7
|
+
attr_reader :locale, :component
|
8
|
+
|
9
|
+
def initialize(component, locale)
|
10
|
+
@locale = locale
|
11
|
+
@component = component
|
12
|
+
@key = [@component, @locale].hash
|
13
|
+
end
|
14
|
+
|
15
|
+
def hash
|
16
|
+
@key
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
(other.is_a? self.class) && @locale == other.locale && @component == other.component
|
21
|
+
end
|
22
|
+
|
23
|
+
alias eql? ==
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
"locale=#{@locale}, component=#{@component}}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright 2022 VMware, Inc.
|
2
|
+
# SPDX-License-Identifier: EPL-2.0
|
3
|
+
|
4
|
+
module SgtnClient
|
5
|
+
class SingleOperation
|
6
|
+
def initialize(*conditions, &block)
|
7
|
+
raise 'no way to create a new obj' unless block
|
8
|
+
|
9
|
+
@lock = Mutex.new
|
10
|
+
@hash = {}
|
11
|
+
|
12
|
+
@conditions = conditions
|
13
|
+
@creator = block
|
14
|
+
end
|
15
|
+
|
16
|
+
# return new created object
|
17
|
+
def operate(id, *args)
|
18
|
+
@lock.synchronize do
|
19
|
+
obj = @hash[id]
|
20
|
+
@conditions.each do |con|
|
21
|
+
return obj unless con.call(id, obj, *args)
|
22
|
+
end
|
23
|
+
# TODO: whatif returning nil
|
24
|
+
@hash[id] = @creator.call(id, obj, *args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove_object(id)
|
29
|
+
@lock.synchronize do
|
30
|
+
@hash.delete(id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|