LittleWeasel 3.0.3 → 5.0.0
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 +5 -5
- data/.gitignore +3 -0
- data/.reek.yml +17 -0
- data/.rspec +4 -2
- data/.rubocop.yml +187 -0
- data/.ruby-version +1 -1
- data/.yardopts +2 -0
- data/CHANGELOG.md +22 -1
- data/Gemfile +3 -1
- data/Jenkinsfile +20 -0
- data/LittleWeasel.gemspec +31 -18
- data/README.md +408 -42
- data/Rakefile +296 -3
- data/lib/LittleWeasel/block_results.rb +81 -0
- data/lib/LittleWeasel/configure.rb +98 -0
- data/lib/LittleWeasel/dictionary.rb +125 -0
- data/lib/LittleWeasel/dictionary_key.rb +48 -0
- data/lib/LittleWeasel/dictionary_manager.rb +91 -0
- data/lib/LittleWeasel/errors/dictionary_file_already_loaded_error.rb +9 -0
- data/lib/LittleWeasel/errors/dictionary_file_empty_error.rb +8 -0
- data/lib/LittleWeasel/errors/dictionary_file_not_found_error.rb +8 -0
- data/lib/LittleWeasel/errors/dictionary_file_too_large_error.rb +16 -0
- data/lib/LittleWeasel/errors/language_required_error.rb +8 -0
- data/lib/LittleWeasel/errors/must_override_error.rb +8 -0
- data/lib/LittleWeasel/filters/en_us/currency_filter.rb +19 -0
- data/lib/LittleWeasel/filters/en_us/numeric_filter.rb +19 -0
- data/lib/LittleWeasel/filters/en_us/single_character_word_filter.rb +21 -0
- data/lib/LittleWeasel/filters/word_filter.rb +59 -0
- data/lib/LittleWeasel/filters/word_filter_managable.rb +80 -0
- data/lib/LittleWeasel/filters/word_filter_validatable.rb +31 -0
- data/lib/LittleWeasel/filters/word_filterable.rb +19 -0
- data/lib/LittleWeasel/filters/word_filters_validatable.rb +29 -0
- data/lib/LittleWeasel/metadata/dictionary_metadata.rb +145 -0
- data/lib/LittleWeasel/metadata/invalid_words_metadata.rb +134 -0
- data/lib/LittleWeasel/metadata/invalid_words_service_results.rb +45 -0
- data/lib/LittleWeasel/metadata/metadata_observable_validatable.rb +22 -0
- data/lib/LittleWeasel/metadata/metadata_observerable.rb +90 -0
- data/lib/LittleWeasel/metadata/metadatable.rb +134 -0
- data/lib/LittleWeasel/modules/class_name_to_symbol.rb +26 -0
- data/lib/LittleWeasel/modules/configurable.rb +26 -0
- data/lib/LittleWeasel/modules/deep_dup.rb +11 -0
- data/lib/LittleWeasel/modules/dictionary_cache_keys.rb +34 -0
- data/lib/LittleWeasel/modules/dictionary_cache_servicable.rb +26 -0
- data/lib/LittleWeasel/modules/dictionary_cache_validatable.rb +18 -0
- data/lib/LittleWeasel/modules/dictionary_creator_servicable.rb +27 -0
- data/lib/LittleWeasel/modules/dictionary_file_loader.rb +67 -0
- data/lib/LittleWeasel/modules/dictionary_key_validatable.rb +17 -0
- data/lib/LittleWeasel/modules/dictionary_keyable.rb +24 -0
- data/lib/LittleWeasel/modules/dictionary_metadata_servicable.rb +29 -0
- data/lib/LittleWeasel/modules/dictionary_metadata_validatable.rb +15 -0
- data/lib/LittleWeasel/modules/dictionary_source_validatable.rb +15 -0
- data/lib/LittleWeasel/modules/dictionary_sourceable.rb +86 -0
- data/lib/LittleWeasel/modules/dictionary_validatable.rb +18 -0
- data/lib/LittleWeasel/modules/language.rb +24 -0
- data/lib/LittleWeasel/modules/language_validatable.rb +14 -0
- data/lib/LittleWeasel/modules/locale.rb +23 -0
- data/lib/LittleWeasel/modules/order_validatable.rb +16 -0
- data/lib/LittleWeasel/modules/orderable.rb +17 -0
- data/lib/LittleWeasel/modules/region.rb +24 -0
- data/lib/LittleWeasel/modules/region_validatable.rb +14 -0
- data/lib/LittleWeasel/modules/tag_validatable.rb +14 -0
- data/lib/LittleWeasel/modules/taggable.rb +31 -0
- data/lib/LittleWeasel/modules/word_results_validatable.rb +28 -0
- data/lib/LittleWeasel/preprocessors/en_us/capitalize_preprocessor.rb +22 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_word.rb +29 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_word_validatable.rb +56 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_words.rb +59 -0
- data/lib/LittleWeasel/preprocessors/preprocessed_words_validatable.rb +28 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessable.rb +19 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessor.rb +123 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessor_managable.rb +114 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessor_validatable.rb +40 -0
- data/lib/LittleWeasel/preprocessors/word_preprocessors_validatable.rb +24 -0
- data/lib/LittleWeasel/services/dictionary_cache_service.rb +211 -0
- data/lib/LittleWeasel/services/dictionary_creator_service.rb +94 -0
- data/lib/LittleWeasel/services/dictionary_file_loader_service.rb +37 -0
- data/lib/LittleWeasel/services/dictionary_killer_service.rb +35 -0
- data/lib/LittleWeasel/services/dictionary_metadata_service.rb +116 -0
- data/lib/LittleWeasel/services/invalid_words_service.rb +59 -0
- data/lib/LittleWeasel/version.rb +3 -1
- data/lib/LittleWeasel/word_results.rb +146 -0
- data/lib/LittleWeasel.rb +5 -184
- data/spec/factories/dictionary.rb +43 -0
- data/spec/factories/dictionary_cache_service.rb +95 -0
- data/spec/factories/dictionary_creator_service.rb +16 -0
- data/spec/factories/dictionary_file_loader_service.rb +13 -0
- data/spec/factories/dictionary_hash.rb +39 -0
- data/spec/factories/dictionary_key.rb +14 -0
- data/spec/factories/dictionary_killer_service.rb +14 -0
- data/spec/factories/dictionary_manager.rb +10 -0
- data/spec/factories/dictionary_metadata.rb +16 -0
- data/spec/factories/dictionary_metadata_service.rb +16 -0
- data/spec/factories/numeric_filter.rb +12 -0
- data/spec/factories/preprocessed_word.rb +16 -0
- data/spec/factories/preprocessed_words.rb +41 -0
- data/spec/factories/single_character_word_filter.rb +12 -0
- data/spec/factories/word_results.rb +16 -0
- data/spec/lib/LittleWeasel/block_results_spec.rb +248 -0
- data/spec/lib/LittleWeasel/configure_spec.rb +74 -0
- data/spec/lib/LittleWeasel/dictionary_key_spec.rb +118 -0
- data/spec/lib/LittleWeasel/dictionary_manager_spec.rb +166 -0
- data/spec/lib/LittleWeasel/dictionary_spec.rb +289 -0
- data/spec/lib/LittleWeasel/filters/en_us/currency_filter_spec.rb +80 -0
- data/spec/lib/LittleWeasel/filters/en_us/numeric_filter_spec.rb +66 -0
- data/spec/lib/LittleWeasel/filters/en_us/single_character_word_filter_spec.rb +58 -0
- data/spec/lib/LittleWeasel/filters/word_filter_managable_spec.rb +180 -0
- data/spec/lib/LittleWeasel/filters/word_filter_spec.rb +151 -0
- data/spec/lib/LittleWeasel/filters/word_filter_validatable_spec.rb +94 -0
- data/spec/lib/LittleWeasel/filters/word_filters_validatable_spec.rb +48 -0
- data/spec/lib/LittleWeasel/integraton_tests/dictionary_integration_spec.rb +201 -0
- data/spec/lib/LittleWeasel/metadata/dictionary_creator_servicable_spec.rb +54 -0
- data/spec/lib/LittleWeasel/metadata/dictionary_metadata_spec.rb +209 -0
- data/spec/lib/LittleWeasel/metadata/invalid_words_metadata_spec.rb +155 -0
- data/spec/lib/LittleWeasel/metadata/metadata_observerable_spec.rb +31 -0
- data/spec/lib/LittleWeasel/metadata/metadatable_spec.rb +35 -0
- data/spec/lib/LittleWeasel/modules/class_name_to_symbol_spec.rb +21 -0
- data/spec/lib/LittleWeasel/modules/dictionary_file_loader_spec.rb +125 -0
- data/spec/lib/LittleWeasel/modules/dictionary_sourceable_spec.rb +81 -0
- data/spec/lib/LittleWeasel/modules/language_spec.rb +112 -0
- data/spec/lib/LittleWeasel/modules/locale_spec.rb +95 -0
- data/spec/lib/LittleWeasel/modules/region_spec.rb +112 -0
- data/spec/lib/LittleWeasel/preprocessors/en_us/capitalize_preprocessor_spec.rb +34 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_word_spec.rb +105 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_word_validatable_spec.rb +143 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_words_spec.rb +77 -0
- data/spec/lib/LittleWeasel/preprocessors/preprocessed_words_validatable_spec.rb +58 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_managable_spec.rb +242 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_spec.rb +218 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessor_validatable_spec.rb +109 -0
- data/spec/lib/LittleWeasel/preprocessors/word_preprocessors_validatable_spec.rb +49 -0
- data/spec/lib/LittleWeasel/services/dictionary_cache_service_spec.rb +444 -0
- data/spec/lib/LittleWeasel/services/dictionary_creator_service_spec.rb +119 -0
- data/spec/lib/LittleWeasel/services/dictionary_file_loader_service_spec.rb +71 -0
- data/spec/lib/LittleWeasel/services/dictionary_metadata_service_spec.rb +279 -0
- data/spec/lib/LittleWeasel/word_results_spec.rb +275 -0
- data/spec/lib/LittleWeasel/workflow/workflow_spec.rb +20 -0
- data/spec/spec_helper.rb +117 -6
- data/spec/support/factory_bot.rb +15 -0
- data/spec/support/file_helpers.rb +46 -0
- data/spec/support/files/empty-dictionary.txt +0 -0
- data/{lib/dictionary → spec/support/files/en-US-big.txt} +262156 -31488
- data/spec/support/files/en-US-tagged.txt +26 -0
- data/spec/support/files/en-US.txt +26 -0
- data/spec/support/files/en.txt +26 -0
- data/spec/support/files/es-ES.txt +27 -0
- data/spec/support/files/es.txt +27 -0
- data/spec/support/general_helpers.rb +68 -0
- data/spec/support/shared_contexts.rb +107 -0
- data/spec/support/shared_examples.rb +105 -0
- metadata +378 -38
- data/spec/checker/checker_spec.rb +0 -286
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../errors/must_override_error'
|
|
4
|
+
require_relative '../modules/class_name_to_symbol'
|
|
5
|
+
require_relative '../modules/orderable'
|
|
6
|
+
require_relative 'preprocessed_word'
|
|
7
|
+
|
|
8
|
+
module LittleWeasel
|
|
9
|
+
module Preprocessors
|
|
10
|
+
# This is a base class that provides methods and functionality for
|
|
11
|
+
# word preprocessors. A "word preprocessor" is an object that manipulates a
|
|
12
|
+
# word before it is passed to any word filters and before it is compared
|
|
13
|
+
# against the dictionary for validity.
|
|
14
|
+
# :reek:MissingSafeMethod, ignored - safe methods for preprocessor_on!/off! make no sense in this case
|
|
15
|
+
class WordPreprocessor
|
|
16
|
+
include Modules::ClassNameToSymbol
|
|
17
|
+
include Modules::Orderable
|
|
18
|
+
|
|
19
|
+
attr_reader :preprocessor_on
|
|
20
|
+
|
|
21
|
+
# order:Integer, the order in which this preprocessor should
|
|
22
|
+
# be applied.
|
|
23
|
+
# preprocessor_on:Boolean, whether or not this preprocessor
|
|
24
|
+
# should be applied to any words.
|
|
25
|
+
def initialize(order:)
|
|
26
|
+
validate_order order: order
|
|
27
|
+
self.order = order
|
|
28
|
+
preprocessor_on!
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
# Should return true if word matches the preprocess criteria;
|
|
33
|
+
# false, otherwise. If this preprocessor has no preprocess criteria,
|
|
34
|
+
# simply return true. This class method is unlike the instance method in
|
|
35
|
+
# that it does not consider whether or not this preprocessor is "on"
|
|
36
|
+
# or "off"; it simply returns true or false based on whether or not the
|
|
37
|
+
# word matches the preprocess criteria.
|
|
38
|
+
def preprocess?(_word)
|
|
39
|
+
true
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# This method should UNconditionally apply preprocessing to word ONLY if
|
|
43
|
+
# word meets the criteria for preprocessing (.preprocess?).
|
|
44
|
+
#
|
|
45
|
+
# This method should return the following Array:
|
|
46
|
+
#
|
|
47
|
+
# [<preprocessed?>, <preprocessed word | nil>]
|
|
48
|
+
#
|
|
49
|
+
# Where:
|
|
50
|
+
#
|
|
51
|
+
# <preprocessed?> == whether or not the word was preprocessed
|
|
52
|
+
# based on whether or not the word meets the preprocessing
|
|
53
|
+
# criteria (.preprocess?).
|
|
54
|
+
#
|
|
55
|
+
# <preprocessed word | nil> == the preprocessed word (if word
|
|
56
|
+
# met the preprocessing criteria (.preprocessed?)) or nil if
|
|
57
|
+
# word was NOT preprocessed (word did NOT meet the preprocessing
|
|
58
|
+
# criteria).
|
|
59
|
+
def preprocess(_word)
|
|
60
|
+
raise Errors::MustOverrideError
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def preprocessor_on=(value)
|
|
65
|
+
raise ArgumentError, "Argument value is not true or false: #{value}" \
|
|
66
|
+
unless [true, false].include? value
|
|
67
|
+
|
|
68
|
+
@preprocessor_on = value
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns true if word meets the criteria for preprocessing. false
|
|
72
|
+
# is returned if word does not meet the criteria for preprocessing, or,
|
|
73
|
+
# if the preprocessor is "off".
|
|
74
|
+
def preprocess?(word)
|
|
75
|
+
return false if preprocessor_off?
|
|
76
|
+
|
|
77
|
+
self.class.preprocess? word
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Applies preprocessing to word if this preprocessor is "on" AND if word
|
|
81
|
+
# meets the criteria for preprocessing; no preprocessing is applied to
|
|
82
|
+
# word otherwise.
|
|
83
|
+
#
|
|
84
|
+
# This method should return a Preprocessors::PreprocessedWord object.
|
|
85
|
+
def preprocess(word)
|
|
86
|
+
preprocessed, preprocessed_word = if preprocessor_on?
|
|
87
|
+
self.class.preprocess word
|
|
88
|
+
else
|
|
89
|
+
[false, nil]
|
|
90
|
+
end
|
|
91
|
+
preprocessed_word(original_word: word, preprocessed_word: preprocessed_word, preprocessed: preprocessed)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Returns true if this preprocessor is "on"; false, otherwise. If this
|
|
95
|
+
# preprocessor is "on", preprocessing should be applied to a word if word
|
|
96
|
+
# meets the criteria for preprocessing.
|
|
97
|
+
def preprocessor_on?
|
|
98
|
+
preprocessor_on
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def preprocessor_on!
|
|
102
|
+
@preprocessor_on = true
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Returns true if this preprocessor is "off". Preprocessing should not
|
|
106
|
+
# be applied to a word if this preprocessor is "off".
|
|
107
|
+
def preprocessor_off?
|
|
108
|
+
!preprocessor_on?
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def preprocessor_off!
|
|
112
|
+
@preprocessor_on = false
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def preprocessed_word(original_word:, preprocessed:, preprocessed_word:)
|
|
118
|
+
PreprocessedWord.new(original_word: original_word, preprocessed: preprocessed,
|
|
119
|
+
preprocessed_word: preprocessed_word, preprocessor: to_sym, preprocessor_order: order)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'word_preprocessable'
|
|
4
|
+
require_relative 'word_preprocessor_validatable'
|
|
5
|
+
|
|
6
|
+
module LittleWeasel
|
|
7
|
+
module Preprocessors
|
|
8
|
+
# This module provides methods and functionality to manage word
|
|
9
|
+
# preprocessors. A "word preprocessor" is an object that manipulates a word
|
|
10
|
+
# before it is passed to any word filters and before it is compared against
|
|
11
|
+
# the dictionary for validity.
|
|
12
|
+
#
|
|
13
|
+
# When creating your own word preprocessors, here are some things you
|
|
14
|
+
# need to consider:
|
|
15
|
+
#
|
|
16
|
+
# Multiple word preprocessors can be applied to a given word. Word
|
|
17
|
+
# processors will be applied to a word in
|
|
18
|
+
# Preprocessors::WordPreprocessor#order order (ascending). Even though this
|
|
19
|
+
# is the case, it doesn't mean you should seek to apply more than one word
|
|
20
|
+
# preprocessor at a time. However, if you do, write and order your word
|
|
21
|
+
# preprocessors in such a way that each preprocessor manipulates the word
|
|
22
|
+
# in a complimentary rather than contridictionary way. For example,
|
|
23
|
+
# applying one word preprocessor that convert a word to uppercase and a
|
|
24
|
+
# second that converts the word to lowercase, contradict each other.
|
|
25
|
+
#
|
|
26
|
+
# Another thing you need to consider, is whether or not metadata observers
|
|
27
|
+
# should be notified of the preprocessed word (now that it has been
|
|
28
|
+
# potentially manipulated) or if they should be notified of the original
|
|
29
|
+
# word; this is because, the original word may not be found as a valid word
|
|
30
|
+
# in the dictionary, while the preprocessed word might and vise versa.
|
|
31
|
+
module WordPreprocessorManagable
|
|
32
|
+
include WordPreprocessable
|
|
33
|
+
include WordPreprocessorsValidatable
|
|
34
|
+
|
|
35
|
+
# Override attr_reader word_preprocessor found in WordPreprocessable
|
|
36
|
+
# so that we don't raise nil errors when using word_preprocessors.
|
|
37
|
+
def word_preprocessors
|
|
38
|
+
@word_preprocessors ||= []
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def clear_preprocessors
|
|
42
|
+
self.word_preprocessors = []
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Appends word preprocessors to the #word_preprocessors Array.
|
|
46
|
+
#
|
|
47
|
+
# If Argument word_preprocessor is nil, a block must be passed to populate
|
|
48
|
+
# the word_preprocessors with an Array of valid word preprocessor objects.
|
|
49
|
+
#
|
|
50
|
+
# This method is used for adding/appending word preprocessors to the
|
|
51
|
+
# word_preprocessors Array. To replace word preprocessors, use #replace_preprocessors;
|
|
52
|
+
# to perform any other manipulation of the word_preprocessors Array,
|
|
53
|
+
# use #word_preprocessors directly.
|
|
54
|
+
def add_preprocessors(word_preprocessors: nil)
|
|
55
|
+
return if word_preprocessors.is_a?(Array) && word_preprocessors.blank?
|
|
56
|
+
|
|
57
|
+
unless word_preprocessors.present? || block_given?
|
|
58
|
+
raise 'A block is required if argument word_preprocessors is nil'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
word_preprocessors ||= []
|
|
62
|
+
yield word_preprocessors if block_given?
|
|
63
|
+
|
|
64
|
+
concat_and_sort_word_preprocessors! word_preprocessors
|
|
65
|
+
end
|
|
66
|
+
alias append_preprocessors add_preprocessors
|
|
67
|
+
|
|
68
|
+
def replace_preprocessors(word_preprocessors:)
|
|
69
|
+
clear_preprocessors
|
|
70
|
+
add_preprocessors word_preprocessors: word_preprocessors
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def preprocessors_on=(on)
|
|
74
|
+
raise ArgumentError, "Argument on is not true or false: #{on.class}" unless [true, false].include?(on)
|
|
75
|
+
|
|
76
|
+
word_preprocessors.each { |word_preprocessor| word_preprocessor.preprocessor_on = on }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns a Preprocessors::PreprocessedWords object.
|
|
80
|
+
def preprocess(word:)
|
|
81
|
+
preprocessed_words = preprocessed_words word: word
|
|
82
|
+
PreprocessedWords.new(original_word: word, preprocessed_words: preprocessed_words)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def preprocessed_words(word:)
|
|
86
|
+
word_preprocessors.map do |word_preprocessor|
|
|
87
|
+
word_preprocessor.preprocess(word).tap do |processed_word|
|
|
88
|
+
word = processed_word.preprocessed_word
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Returns the final (or last) preprocessed word in the Array of
|
|
94
|
+
# preprocessed words. The final preprocessed word is the word that has
|
|
95
|
+
# passed through all the word preprocessors.
|
|
96
|
+
def preprocessed_word(word:)
|
|
97
|
+
preprocessed_words = self.preprocessed_words word: word
|
|
98
|
+
preprocessed_words.max_by(&:preprocessor_order).preprocessed_word unless preprocessed_words.blank?
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
# This method concatinates preprocessors to #word_preprocessors,
|
|
104
|
+
# sorts #word_preprocessors by WordPreprocessor#order and
|
|
105
|
+
# returns the results.
|
|
106
|
+
def concat_and_sort_word_preprocessors!(preprocessors)
|
|
107
|
+
validate_word_preprocessors word_preprocessors: preprocessors
|
|
108
|
+
|
|
109
|
+
word_preprocessors.concat preprocessors
|
|
110
|
+
word_preprocessors.sort_by!(&:order)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LittleWeasel
|
|
4
|
+
module Preprocessors
|
|
5
|
+
# This module validates word preprocessor types.
|
|
6
|
+
# rubocop: disable Layout/LineLength
|
|
7
|
+
module WordPreprocessorValidatable
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
# :reek:ManualDispatch - ignored, this is duck-typing not 'simulated polymorphism'
|
|
11
|
+
# :reek:TooManyStatements - ignored, "too many statements" is easier to understand than arbitrarily breaking all this down into individual methods
|
|
12
|
+
def validate_word_preprocessor(word_preprocessor:)
|
|
13
|
+
# You can use your own word preprocessor types as long as they quack
|
|
14
|
+
# correctly; however, you are responsible for the behavior of these
|
|
15
|
+
# required methods/ attributes. It's probably better to follow the
|
|
16
|
+
# pattern of existing word preprocessor objects and inherit from
|
|
17
|
+
# Preprocessors::WordPreprocessor.
|
|
18
|
+
|
|
19
|
+
word_preprocessor_class = word_preprocessor.class
|
|
20
|
+
|
|
21
|
+
# class methods
|
|
22
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '.preprocess') unless word_preprocessor_class.respond_to?(:preprocess)
|
|
23
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '.preprocess?') unless word_preprocessor_class.respond_to?(:preprocess?)
|
|
24
|
+
|
|
25
|
+
# instance methods
|
|
26
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '#preprocess') unless word_preprocessor.respond_to?(:preprocess)
|
|
27
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '#preprocess?') unless word_preprocessor.respond_to?(:preprocess?)
|
|
28
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '#preprocessor_off?') unless word_preprocessor.respond_to?(:preprocessor_off?)
|
|
29
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '#preprocessor_on') unless word_preprocessor.respond_to?(:preprocessor_on)
|
|
30
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '#preprocessor_on=') unless word_preprocessor.respond_to?(:preprocessor_on=)
|
|
31
|
+
raise validation_error_message(object: word_preprocessor_class, respond_to: '#preprocessor_on?') unless word_preprocessor.respond_to?(:preprocessor_on?)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def validation_error_message(object:, respond_to:)
|
|
35
|
+
"Argument word_preprocessor: does not respond to: #{object}#{respond_to}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
# rubocop: enable Layout/LineLength
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'word_preprocessor_validatable'
|
|
4
|
+
|
|
5
|
+
module LittleWeasel
|
|
6
|
+
module Preprocessors
|
|
7
|
+
# This module provides methods to validate an Array of word preprocessor
|
|
8
|
+
# objects.
|
|
9
|
+
module WordPreprocessorsValidatable
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def validate_word_preprocessors(word_preprocessors:)
|
|
13
|
+
return if word_preprocessors.blank?
|
|
14
|
+
|
|
15
|
+
raise ArgumentError, "Argument word_preprocessors is not an Array: #{word_preprocessors.class}" \
|
|
16
|
+
unless word_preprocessors.is_a? Array
|
|
17
|
+
|
|
18
|
+
word_preprocessors.each do |word_preprocessor|
|
|
19
|
+
WordPreprocessorValidatable.validate_word_preprocessor word_preprocessor: word_preprocessor
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../modules/dictionary_cache_keys'
|
|
4
|
+
require_relative '../modules/dictionary_cache_validatable'
|
|
5
|
+
require_relative '../modules/dictionary_keyable'
|
|
6
|
+
require_relative '../modules/dictionary_sourceable'
|
|
7
|
+
|
|
8
|
+
module LittleWeasel
|
|
9
|
+
module Services
|
|
10
|
+
# This class provides methods and attributes that can be used to manage the
|
|
11
|
+
# dictionary cache. The "dictionary cache" is a simple Hash that provides
|
|
12
|
+
# access to informaiton related to dictionaries through a dictionary "key".
|
|
13
|
+
# A dictionary "key" is a unique key comprised of a locale and
|
|
14
|
+
# optional "tag" (see Modules::Taggable and DictionaryKey for more
|
|
15
|
+
# information). The dictionary cache also provides a way for dictionary
|
|
16
|
+
# objects to share dictionary information, in particular, the dictionary
|
|
17
|
+
# file and dictionary metadata.
|
|
18
|
+
class DictionaryCacheService
|
|
19
|
+
include Modules::DictionaryCacheKeys
|
|
20
|
+
include Modules::DictionaryCacheValidatable
|
|
21
|
+
include Modules::DictionaryKeyable
|
|
22
|
+
include Modules::DictionarySourceable
|
|
23
|
+
|
|
24
|
+
attr_reader :dictionary_cache
|
|
25
|
+
|
|
26
|
+
# This class produces the following (example) Hash that represents the
|
|
27
|
+
# dictionary cache structure:
|
|
28
|
+
#
|
|
29
|
+
# @example This is an example:
|
|
30
|
+
#
|
|
31
|
+
# {
|
|
32
|
+
# 'dictionary_cache' =>
|
|
33
|
+
# {
|
|
34
|
+
# 'dictionary_references' =>
|
|
35
|
+
# {
|
|
36
|
+
# 'en' =>
|
|
37
|
+
# {
|
|
38
|
+
# 'dictionary_id' => 19ec7845
|
|
39
|
+
# },
|
|
40
|
+
# 'en-US' =>
|
|
41
|
+
# {
|
|
42
|
+
# 'dictionary_id' => 0987a3f2
|
|
43
|
+
# },
|
|
44
|
+
# 'en-US-temp' =>
|
|
45
|
+
# {
|
|
46
|
+
# 'dictionary_id' => 9273eac6
|
|
47
|
+
# }
|
|
48
|
+
# },
|
|
49
|
+
# 'dictionaries' =>
|
|
50
|
+
# {
|
|
51
|
+
# 19ec7845 =>
|
|
52
|
+
# {
|
|
53
|
+
# 'source' => '/en.txt',
|
|
54
|
+
# 'dictionary_object' => {}
|
|
55
|
+
# },
|
|
56
|
+
# 0987a3f2 =>
|
|
57
|
+
# {
|
|
58
|
+
# 'source' => '/en-US.txt',
|
|
59
|
+
# 'dictionary_object' => {}
|
|
60
|
+
# },
|
|
61
|
+
# 9273eac6 =>
|
|
62
|
+
# {
|
|
63
|
+
# 'source' => '*736ed423',
|
|
64
|
+
# 'dictionary_object' => {}
|
|
65
|
+
# }
|
|
66
|
+
# }
|
|
67
|
+
# }
|
|
68
|
+
# }
|
|
69
|
+
def initialize(dictionary_key:, dictionary_cache:)
|
|
70
|
+
validate_dictionary_key dictionary_key: dictionary_key
|
|
71
|
+
self.dictionary_key = dictionary_key
|
|
72
|
+
|
|
73
|
+
validate_dictionary_cache dictionary_cache: dictionary_cache
|
|
74
|
+
self.dictionary_cache = dictionary_cache
|
|
75
|
+
|
|
76
|
+
self.class.init(dictionary_cache: dictionary_cache) unless dictionary_cache[DICTIONARY_CACHE]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
class << self
|
|
80
|
+
# This method resets dictionary_cache to its initialized state.
|
|
81
|
+
# This class method is different from the #init instance method
|
|
82
|
+
# in that ALL dictionary references and ALL dictionaries are
|
|
83
|
+
# initialized.
|
|
84
|
+
def init(dictionary_cache:)
|
|
85
|
+
Modules::DictionaryCacheKeys.initialize_dictionary_cache dictionary_cache: dictionary_cache
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Returns true if the dictionary cache is initialized; that
|
|
89
|
+
# is, if the given dictionary_cache is in the same state the
|
|
90
|
+
# dictionary cache would be in after .init were called.
|
|
91
|
+
def init?(dictionary_cache:)
|
|
92
|
+
initialized_dictionary_cache = init(dictionary_cache: {})
|
|
93
|
+
dictionary_cache.eql?(initialized_dictionary_cache)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Returns the number of dictionaries currently in the cache.
|
|
97
|
+
def count(dictionary_cache:)
|
|
98
|
+
dictionary_cache.dig(self::DICTIONARY_CACHE, self::DICTIONARIES)&.keys&.count || 0
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# This method resets the dictionary cache for the given key. This method
|
|
103
|
+
# is different from the .init class method in that ONLY the dictionary
|
|
104
|
+
# reference and dictionary specific to the given key is initialized.
|
|
105
|
+
def init
|
|
106
|
+
# TODO: Do not delete the dictionary if it is being pointed to by
|
|
107
|
+
# another dictionary reference.
|
|
108
|
+
dictionary_cache_hash = dictionary_cache[DICTIONARY_CACHE]
|
|
109
|
+
dictionary_cache_hash[DICTIONARIES]&.delete(dictionary_id)
|
|
110
|
+
dictionary_cache_hash[DICTIONARY_REFERENCES]&.delete(key)
|
|
111
|
+
self
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Returns true if the dictionary reference exists for the given key; false
|
|
115
|
+
# otherwise. This method is only concerned with the dictionary reference
|
|
116
|
+
# and has nothing to do with whether or not the associated dictionary
|
|
117
|
+
# is actually loaded into the dictionary cache.
|
|
118
|
+
def dictionary_reference?
|
|
119
|
+
dictionary_reference&.present? || false
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Returns true if a dictionaries Hash key exists for the given dictionary_id
|
|
123
|
+
# in the dictionary cache. This method is only concerned with the existance of
|
|
124
|
+
# the key and has nothing to do with whether or not file/memory sources are
|
|
125
|
+
# present or the presence of a dictionary object.
|
|
126
|
+
def dictionary?
|
|
127
|
+
dictionary_cache[DICTIONARY_CACHE][DICTIONARIES].key? dictionary_id
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Returns the dictionary id if there is a dictionary id in the dictionary
|
|
131
|
+
# cache associated with the given key; nil otherwise.
|
|
132
|
+
def dictionary_id
|
|
133
|
+
dictionary_cache.dig(DICTIONARY_CACHE, DICTIONARY_REFERENCES, key, DICTIONARY_ID)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Returns the dictionary id if there is a dictionary id in the dictionary
|
|
137
|
+
# cache associated with the given key. This method raises an error if the
|
|
138
|
+
# dictionary id cannot be found.
|
|
139
|
+
def dictionary_id!
|
|
140
|
+
return dictionary_id if dictionary_id?
|
|
141
|
+
|
|
142
|
+
raise ArgumentError, "A dictionary id could not be found for key '#{key}'."
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# This method returns true if the dictionary associated with the
|
|
146
|
+
# given dictionary key is loaded/cached. If this is the case,
|
|
147
|
+
# a dictionary object is available in the dictionary cache.
|
|
148
|
+
def dictionary_object?
|
|
149
|
+
dictionary_object.present?
|
|
150
|
+
end
|
|
151
|
+
alias dictionary_exist? dictionary_object?
|
|
152
|
+
|
|
153
|
+
# <b>DEPRECATED:</b> Use <tt>dictionary_exist?</tt> instead.
|
|
154
|
+
def dictionary_exists?
|
|
155
|
+
warn "[DEPRECATION] 'dictionary_exists?' is deprecated. Please use 'dictionary_exist?' instead."
|
|
156
|
+
dictionary_object?
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Returns the dictionary object from the dictionary cache for the given
|
|
160
|
+
# key. This method raises an error if the dictionary is not in the cache;
|
|
161
|
+
# that is, if the dictionary was not previously loaded from disk or memory.
|
|
162
|
+
def dictionary_object!
|
|
163
|
+
unless dictionary_object?
|
|
164
|
+
raise ArgumentError,
|
|
165
|
+
"The dictionary object associated with argument key '#{key}' is not in the cache."
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
dictionary_object
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def dictionary_object
|
|
172
|
+
dictionary_cache.dig(DICTIONARY_CACHE, DICTIONARIES, dictionary_id, DICTIONARY_OBJECT)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def dictionary_object=(object)
|
|
176
|
+
raise ArgumentError, 'Argument object is not a Dictionary object' unless object.is_a? Dictionary
|
|
177
|
+
|
|
178
|
+
unless dictionary_reference?
|
|
179
|
+
raise ArgumentError,
|
|
180
|
+
"The dictionary reference associated with key '#{key}' could not be found."
|
|
181
|
+
end
|
|
182
|
+
return if object.equal? dictionary_object
|
|
183
|
+
|
|
184
|
+
if dictionary_exist?
|
|
185
|
+
raise ArgumentError,
|
|
186
|
+
"The dictionary is already loaded/cached for key '#{key}'; use #unload or #kill first."
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
dictionary_cache[DICTIONARY_CACHE][DICTIONARIES][dictionary_id!][DICTIONARY_OBJECT] = object
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
private
|
|
193
|
+
|
|
194
|
+
attr_writer :dictionary_cache
|
|
195
|
+
|
|
196
|
+
def dictionary_reference
|
|
197
|
+
dictionary_cache.dig(DICTIONARY_CACHE, DICTIONARY_REFERENCES, key)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def set_dictionary_reference(dictionary_id:)
|
|
201
|
+
dictionary_cache[DICTIONARY_CACHE][DICTIONARY_REFERENCES][key] = {
|
|
202
|
+
DICTIONARY_ID => dictionary_id
|
|
203
|
+
}
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def dictionary_id?
|
|
207
|
+
dictionary_id.present?
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../dictionary'
|
|
4
|
+
require_relative '../filters/word_filterable'
|
|
5
|
+
require_relative '../filters/word_filters_validatable'
|
|
6
|
+
require_relative '../metadata/dictionary_metadata'
|
|
7
|
+
require_relative '../modules/dictionary_cache_servicable'
|
|
8
|
+
require_relative '../modules/dictionary_creator_servicable'
|
|
9
|
+
require_relative '../modules/dictionary_keyable'
|
|
10
|
+
require_relative '../modules/dictionary_metadata_servicable'
|
|
11
|
+
require_relative '../modules/dictionary_sourceable'
|
|
12
|
+
require_relative '../preprocessors/word_preprocessor_managable'
|
|
13
|
+
require_relative 'dictionary_file_loader_service'
|
|
14
|
+
|
|
15
|
+
module LittleWeasel
|
|
16
|
+
module Services
|
|
17
|
+
# This class provides a service to load dictionaries from disk, create
|
|
18
|
+
# and return a Dictionary object.
|
|
19
|
+
class DictionaryCreatorService
|
|
20
|
+
include Filters::WordFilterable
|
|
21
|
+
include Filters::WordFiltersValidatable
|
|
22
|
+
include Modules::DictionaryCacheServicable
|
|
23
|
+
include Modules::DictionaryKeyable
|
|
24
|
+
include Modules::DictionaryMetadataServicable
|
|
25
|
+
include Modules::DictionarySourceable
|
|
26
|
+
include Preprocessors::WordPreprocessorManagable
|
|
27
|
+
|
|
28
|
+
def initialize(dictionary_key:, dictionary_cache:, dictionary_metadata:,
|
|
29
|
+
word_filters: nil, word_preprocessors: nil)
|
|
30
|
+
validate_dictionary_key dictionary_key: dictionary_key
|
|
31
|
+
self.dictionary_key = dictionary_key
|
|
32
|
+
|
|
33
|
+
validate_dictionary_cache dictionary_cache: dictionary_cache
|
|
34
|
+
self.dictionary_cache = dictionary_cache
|
|
35
|
+
|
|
36
|
+
validate_dictionary_metadata dictionary_metadata: dictionary_metadata
|
|
37
|
+
self.dictionary_metadata = dictionary_metadata
|
|
38
|
+
|
|
39
|
+
validate_word_filters word_filters: word_filters unless word_filters.blank?
|
|
40
|
+
self.word_filters = word_filters
|
|
41
|
+
|
|
42
|
+
validate_word_preprocessors word_preprocessors: word_preprocessors unless word_preprocessors.blank?
|
|
43
|
+
self.word_preprocessors = word_preprocessors
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def from_file_source(file:)
|
|
47
|
+
add_dictionary_file_source file: file
|
|
48
|
+
dictionary_words = dictionary_file_loader_service.execute
|
|
49
|
+
create_dictionary dictionary_words: dictionary_words
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def from_memory_source(dictionary_words:)
|
|
53
|
+
add_dictionary_memory_source
|
|
54
|
+
create_dictionary dictionary_words: dictionary_words
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def dictionary_file_loader_service
|
|
60
|
+
Services::DictionaryFileLoaderService.new dictionary_key: dictionary_key, dictionary_cache: dictionary_cache
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def create_dictionary(dictionary_words:)
|
|
64
|
+
Dictionary.new(dictionary_key: dictionary_key, dictionary_cache: dictionary_cache,
|
|
65
|
+
dictionary_metadata: dictionary_metadata, dictionary_words: dictionary_words, word_filters: word_filters,
|
|
66
|
+
word_preprocessors: word_preprocessors).tap do |dictionary|
|
|
67
|
+
dictionary_cache_service.dictionary_object = dictionary
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Adds a dictionary file source. A "file source" is a file path that
|
|
72
|
+
# indicates that the dictionary words associated with this dictionary are
|
|
73
|
+
# located on disk. This file path is used to locate and load the
|
|
74
|
+
# dictionary words into the dictionary cache for use.
|
|
75
|
+
#
|
|
76
|
+
# @param file [String] a file path pointing to the dictionary file to load and use.
|
|
77
|
+
#
|
|
78
|
+
# @return returns a reference to self.
|
|
79
|
+
def add_dictionary_file_source(file:)
|
|
80
|
+
dictionary_cache_service.add_dictionary_source(dictionary_source: file)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Adds a dictionary memory source. A "memory source" indicates that the
|
|
84
|
+
# dictionary words associated with this dictionary were created
|
|
85
|
+
# dynamically and will be located in memory, as opposed to loaded from
|
|
86
|
+
# a file on disk.
|
|
87
|
+
#
|
|
88
|
+
# @return returns a reference to self.
|
|
89
|
+
def add_dictionary_memory_source
|
|
90
|
+
dictionary_cache_service.add_dictionary_source(dictionary_source: memory_source)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../modules/configurable'
|
|
4
|
+
require_relative '../modules/dictionary_cache_servicable'
|
|
5
|
+
require_relative '../modules/dictionary_file_loader'
|
|
6
|
+
require_relative '../modules/dictionary_keyable'
|
|
7
|
+
|
|
8
|
+
module LittleWeasel
|
|
9
|
+
module Services
|
|
10
|
+
# This class provides a service for loading dictionaries from disk and
|
|
11
|
+
# returning a Hash of dictionary words that can be used to instantiate
|
|
12
|
+
# a Dictionary object or otherwise.
|
|
13
|
+
class DictionaryFileLoaderService
|
|
14
|
+
include Modules::Configurable
|
|
15
|
+
include Modules::DictionaryCacheServicable
|
|
16
|
+
include Modules::DictionaryFileLoader
|
|
17
|
+
include Modules::DictionaryKeyable
|
|
18
|
+
|
|
19
|
+
def initialize(dictionary_key:, dictionary_cache:)
|
|
20
|
+
validate_dictionary_key dictionary_key: dictionary_key
|
|
21
|
+
self.dictionary_key = dictionary_key
|
|
22
|
+
|
|
23
|
+
validate_dictionary_cache dictionary_cache: dictionary_cache
|
|
24
|
+
self.dictionary_cache = dictionary_cache
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def execute
|
|
28
|
+
if dictionary_cache_service.dictionary_exist?
|
|
29
|
+
raise ArgumentError,
|
|
30
|
+
"The dictionary associated with key '#{key}' already exists."
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
load dictionary_cache_service.dictionary_file!
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../modules/dictionary_cache_servicable'
|
|
4
|
+
require_relative '../modules/dictionary_metadata_servicable'
|
|
5
|
+
require_relative '../modules/dictionary_keyable'
|
|
6
|
+
|
|
7
|
+
module LittleWeasel
|
|
8
|
+
module Services
|
|
9
|
+
# This service removes a dictionary (Dictionary object) associated with
|
|
10
|
+
# the dictionary key from the dictionary cache along with the dictionary
|
|
11
|
+
# file reference and any metadata associated with the dictionary from the
|
|
12
|
+
# dictionary cache.
|
|
13
|
+
class DictionaryKillerService
|
|
14
|
+
include Modules::DictionaryCacheServicable
|
|
15
|
+
include Modules::DictionaryMetadataServicable
|
|
16
|
+
include Modules::DictionaryKeyable
|
|
17
|
+
|
|
18
|
+
def initialize(dictionary_key:, dictionary_cache:, dictionary_metadata:)
|
|
19
|
+
validate_dictionary_key dictionary_key: dictionary_key
|
|
20
|
+
self.dictionary_key = dictionary_key
|
|
21
|
+
|
|
22
|
+
validate_dictionary_cache dictionary_cache: dictionary_cache
|
|
23
|
+
self.dictionary_cache = dictionary_cache
|
|
24
|
+
|
|
25
|
+
validate_dictionary_metadata dictionary_metadata: dictionary_metadata
|
|
26
|
+
self.dictionary_metadata = dictionary_metadata
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def execute
|
|
30
|
+
dictionary_cache_service.init
|
|
31
|
+
dictionary_metadata_service.class.init dictionary_metadata: dictionary_metadata
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|