metasploit-model 0.27.3 → 0.27.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.rspec +1 -1
- data/app/models/metasploit/model/association/reflection.rb +0 -3
- data/app/models/metasploit/model/module/ancestor/spec/template.rb +0 -3
- data/app/models/metasploit/model/module/class/spec/template.rb +0 -4
- data/app/models/metasploit/model/module/instance/spec/template.rb +0 -4
- data/app/models/metasploit/model/search/group/base.rb +0 -3
- data/app/models/metasploit/model/search/group/intersection.rb +0 -3
- data/app/models/metasploit/model/search/group/union.rb +0 -3
- data/app/models/metasploit/model/search/operation/association.rb +0 -2
- data/app/models/metasploit/model/search/operation/base.rb +0 -3
- data/app/models/metasploit/model/search/operation/boolean.rb +0 -2
- data/app/models/metasploit/model/search/operation/date.rb +0 -2
- data/app/models/metasploit/model/search/operation/group/base.rb +0 -2
- data/app/models/metasploit/model/search/operation/group/intersection.rb +0 -2
- data/app/models/metasploit/model/search/operation/group/union.rb +0 -2
- data/app/models/metasploit/model/search/operation/integer.rb +1 -5
- data/app/models/metasploit/model/search/operation/null.rb +0 -2
- data/app/models/metasploit/model/search/operation/set.rb +5 -2
- data/app/models/metasploit/model/search/operation/set/integer.rb +1 -3
- data/app/models/metasploit/model/search/operation/set/string.rb +1 -3
- data/app/models/metasploit/model/search/operation/string.rb +1 -5
- data/app/models/metasploit/model/search/operator/association.rb +0 -2
- data/app/models/metasploit/model/search/operator/attribute.rb +0 -2
- data/app/models/metasploit/model/search/operator/base.rb +0 -4
- data/app/models/metasploit/model/search/operator/delegation.rb +0 -2
- data/app/models/metasploit/model/search/operator/deprecated/app.rb +0 -2
- data/app/models/metasploit/model/search/operator/deprecated/author.rb +0 -2
- data/app/models/metasploit/model/search/operator/deprecated/authority.rb +0 -2
- data/app/models/metasploit/model/search/operator/deprecated/platform.rb +0 -2
- data/app/models/metasploit/model/search/operator/deprecated/ref.rb +0 -2
- data/app/models/metasploit/model/search/operator/deprecated/text.rb +0 -2
- data/app/models/metasploit/model/search/operator/group/base.rb +0 -2
- data/app/models/metasploit/model/search/operator/group/intersection.rb +0 -2
- data/app/models/metasploit/model/search/operator/group/union.rb +0 -2
- data/app/models/metasploit/model/search/operator/null.rb +0 -2
- data/app/models/metasploit/model/search/operator/single.rb +0 -2
- data/app/models/metasploit/model/search/query.rb +0 -3
- data/app/models/metasploit/model/spec/template.rb +0 -3
- data/app/models/metasploit/model/visitation/visitor.rb +0 -3
- data/lib/metasploit/model.rb +14 -8
- data/lib/metasploit/model/architecture.rb +320 -326
- data/lib/metasploit/model/association.rb +43 -46
- data/lib/metasploit/model/association/error.rb +29 -33
- data/lib/metasploit/model/association/tree.rb +119 -125
- data/lib/metasploit/model/author.rb +45 -51
- data/lib/metasploit/model/authority.rb +139 -146
- data/lib/metasploit/model/authority/bid.rb +0 -2
- data/lib/metasploit/model/authority/cve.rb +0 -2
- data/lib/metasploit/model/authority/msb.rb +0 -2
- data/lib/metasploit/model/authority/osvdb.rb +0 -2
- data/lib/metasploit/model/authority/pmasa.rb +0 -2
- data/lib/metasploit/model/authority/secunia.rb +0 -2
- data/lib/metasploit/model/authority/us_cert_vu.rb +0 -2
- data/lib/metasploit/model/authority/waraxe.rb +0 -2
- data/lib/metasploit/model/authority/zdi.rb +0 -2
- data/lib/metasploit/model/base.rb +0 -2
- data/lib/metasploit/model/derivation.rb +95 -99
- data/lib/metasploit/model/derivation/full_name.rb +16 -22
- data/lib/metasploit/model/email_address.rb +122 -128
- data/lib/metasploit/model/engine.rb +26 -21
- data/lib/metasploit/model/error.rb +3 -7
- data/lib/metasploit/model/file.rb +0 -2
- data/lib/metasploit/model/invalid.rb +11 -17
- data/lib/metasploit/model/login.rb +0 -3
- data/lib/metasploit/model/login/status.rb +0 -2
- data/lib/metasploit/model/module.rb +19 -23
- data/lib/metasploit/model/module/action.rb +50 -58
- data/lib/metasploit/model/module/ancestor.rb +456 -465
- data/lib/metasploit/model/module/ancestor/spec.rb +3 -2
- data/lib/metasploit/model/module/architecture.rb +27 -35
- data/lib/metasploit/model/module/author.rb +38 -47
- data/lib/metasploit/model/module/class.rb +358 -366
- data/lib/metasploit/model/module/class/spec.rb +3 -2
- data/lib/metasploit/model/module/handler.rb +28 -34
- data/lib/metasploit/model/module/instance.rb +586 -596
- data/lib/metasploit/model/module/instance/spec.rb +3 -2
- data/lib/metasploit/model/module/path.rb +157 -166
- data/lib/metasploit/model/module/platform.rb +25 -33
- data/lib/metasploit/model/module/rank.rb +71 -79
- data/lib/metasploit/model/module/reference.rb +25 -33
- data/lib/metasploit/model/module/stance.rb +15 -21
- data/lib/metasploit/model/module/target.rb +76 -84
- data/lib/metasploit/model/module/target/architecture.rb +27 -37
- data/lib/metasploit/model/module/target/platform.rb +27 -37
- data/lib/metasploit/model/module/type.rb +35 -41
- data/lib/metasploit/model/nilify_blanks.rb +39 -43
- data/lib/metasploit/model/platform.rb +231 -237
- data/lib/metasploit/model/real_pathname.rb +12 -16
- data/lib/metasploit/model/realm.rb +0 -2
- data/lib/metasploit/model/realm/key.rb +0 -2
- data/lib/metasploit/model/reference.rb +102 -108
- data/lib/metasploit/model/search.rb +94 -97
- data/lib/metasploit/model/search/association.rb +163 -169
- data/lib/metasploit/model/search/attribute.rb +131 -139
- data/lib/metasploit/model/search/group.rb +5 -2
- data/lib/metasploit/model/search/operation.rb +32 -29
- data/lib/metasploit/model/search/operation/group.rb +5 -2
- data/lib/metasploit/model/search/operation/value.rb +7 -0
- data/lib/metasploit/model/search/operation/{integer/value.rb → value/integer.rb} +1 -1
- data/lib/metasploit/model/search/operation/{string/value.rb → value/string.rb} +1 -1
- data/lib/metasploit/model/search/operator.rb +65 -65
- data/lib/metasploit/model/search/operator/deprecated.rb +8 -2
- data/lib/metasploit/model/search/operator/group.rb +5 -2
- data/lib/metasploit/model/search/operator/help.rb +71 -79
- data/lib/metasploit/model/search/with.rb +72 -78
- data/lib/metasploit/model/spec.rb +133 -136
- data/lib/metasploit/model/spec/error.rb +3 -9
- data/lib/metasploit/model/spec/i18n_exception_handler.rb +0 -2
- data/lib/metasploit/model/spec/pathname_collision.rb +19 -27
- data/lib/metasploit/model/spec/template/write.rb +0 -2
- data/lib/metasploit/model/spec/temporary_pathname.rb +47 -56
- data/lib/metasploit/model/translation.rb +0 -2
- data/lib/metasploit/model/version.rb +1 -1
- data/lib/metasploit/model/visitation.rb +7 -10
- data/lib/metasploit/model/visitation/visit.rb +79 -85
- data/metasploit-model.gemspec +1 -1
- data/spec/app/models/metasploit/model/search/operation/integer_spec.rb +1 -1
- data/spec/app/models/metasploit/model/search/operation/set/integer_spec.rb +1 -1
- data/spec/app/models/metasploit/model/search/operation/set/string_spec.rb +1 -1
- data/spec/app/models/metasploit/model/search/operation/string_spec.rb +1 -1
- data/spec/dummy/config/application.rb +1 -0
- data/spec/lib/metasploit/model/search/operation/{integer/value_spec.rb → value/integer_spec.rb} +2 -2
- data/spec/lib/metasploit/model/search/operation/{string/value_spec.rb → value/string_spec.rb} +2 -2
- data/spec/support/shared/examples/metasploit/model/search/operation/{integer/value.rb → value/integer.rb} +2 -2
- data/spec/support/shared/examples/metasploit/model/search/operation/{string/value.rb → value/string.rb} +2 -2
- metadata +16 -13
@@ -1,53 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
module NilifyBlanks
|
6
|
-
extend ActiveSupport::Concern
|
1
|
+
# Registers before validation callback to convert the given attributes to `nil` if they are blank. This can be used
|
2
|
+
# to normalize empty attributes to NULL in the database so queries don't have to handle both `= ''` and `IS NULL`.
|
3
|
+
module Metasploit::Model::NilifyBlanks
|
4
|
+
extend ActiveSupport::Concern
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
included do
|
7
|
+
include ActiveModel::Validations
|
8
|
+
include ActiveModel::Validations::Callbacks
|
11
9
|
|
12
|
-
|
13
|
-
|
10
|
+
before_validation :nilify_blanks
|
11
|
+
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
13
|
+
# Adds DSL methods once NilifyBlanks is included so that attributes where blanks should be changed to `nil` can be
|
14
|
+
# declared.
|
15
|
+
module ClassMethods
|
16
|
+
# Declares that `attributes` should be changed to `nil` before validation if they are blank.
|
17
|
+
#
|
18
|
+
# @param attributes [Enumerable<Symbol>] one or more attribute names
|
19
|
+
# @return [void]
|
20
|
+
def nilify_blank(*attributes)
|
21
|
+
nilify_blank_attribute_set.merge(attributes)
|
22
|
+
end
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
24
|
+
# Set of all attributes registered with {#nilify_blank}.
|
25
|
+
#
|
26
|
+
# @return [Set<Symbol>]
|
27
|
+
def nilify_blank_attribute_set
|
28
|
+
@nilify_blank_attribute_set ||= Set.new
|
29
|
+
end
|
30
|
+
end
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
#
|
33
|
+
# Instance Methods
|
34
|
+
#
|
37
35
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
# Before validation callback to change any attributes in {ClassMethods#nilify_blank_attribute_set} that are blank to
|
37
|
+
# `nil`.
|
38
|
+
#
|
39
|
+
# @return [void]
|
40
|
+
def nilify_blanks
|
41
|
+
self.class.nilify_blank_attribute_set.each do |attribute|
|
42
|
+
value = send(attribute)
|
45
43
|
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
44
|
+
if value.respond_to? :blank? and value.blank?
|
45
|
+
send("#{attribute}=", nil)
|
50
46
|
end
|
51
47
|
end
|
52
48
|
end
|
53
|
-
end
|
49
|
+
end
|
@@ -1,252 +1,246 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
'
|
37
|
-
'
|
38
|
-
'
|
39
|
-
'
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
1
|
+
# Code shared between `Mdm::Platform` and `Metasploit::Framework::Platform`.
|
2
|
+
module Metasploit::Model::Platform
|
3
|
+
extend ActiveModel::Naming
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
include Metasploit::Model::Translation
|
7
|
+
|
8
|
+
#
|
9
|
+
# CONSTANTS
|
10
|
+
#
|
11
|
+
|
12
|
+
# Platforms are seeded in a hierarchy with deeper levels refining higher levels, so 'Windows 98 SE' is a
|
13
|
+
# refinement of 'Windows 98', which is a refinement of 'Windows'.
|
14
|
+
SEED_RELATIVE_NAME_TREE = {
|
15
|
+
'AIX' => nil,
|
16
|
+
'Android' => nil,
|
17
|
+
'BSD' => nil,
|
18
|
+
'BSDi' => nil,
|
19
|
+
'Cisco' => nil,
|
20
|
+
'Firefox' => nil,
|
21
|
+
'FreeBSD' => nil,
|
22
|
+
'HPUX' => nil,
|
23
|
+
'IRIX' => nil,
|
24
|
+
'Java' => nil,
|
25
|
+
'Javascript' => nil,
|
26
|
+
'Linux' => nil,
|
27
|
+
'NetBSD' => nil,
|
28
|
+
'Netware' => nil,
|
29
|
+
'NodeJS' => nil,
|
30
|
+
'OpenBSD' => nil,
|
31
|
+
'OSX' => nil,
|
32
|
+
'PHP' => nil,
|
33
|
+
'Python' => nil,
|
34
|
+
'Ruby' => nil,
|
35
|
+
'Solaris' => {
|
36
|
+
'4' => nil,
|
37
|
+
'5' => nil,
|
38
|
+
'6' => nil,
|
39
|
+
'7' => nil,
|
40
|
+
'8' => nil,
|
41
|
+
'9' => nil,
|
42
|
+
'10' => nil
|
43
|
+
},
|
44
|
+
'Windows' => {
|
45
|
+
'95' => nil,
|
46
|
+
'98' => {
|
47
|
+
'FE' => nil,
|
48
|
+
'SE' => nil
|
47
49
|
},
|
48
|
-
'
|
49
|
-
|
50
|
-
'
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
'
|
55
|
-
'
|
56
|
-
|
57
|
-
|
58
|
-
'SP2' => nil,
|
59
|
-
'SP3' => nil,
|
60
|
-
'SP4' => nil,
|
61
|
-
'SP5' => nil,
|
62
|
-
'SP6' => nil,
|
63
|
-
'SP6a' => nil
|
64
|
-
},
|
65
|
-
'2000' => {
|
66
|
-
'SP0' => nil,
|
67
|
-
'SP1' => nil,
|
68
|
-
'SP2' => nil,
|
69
|
-
'SP3' => nil,
|
70
|
-
'SP4' => nil
|
71
|
-
},
|
72
|
-
'XP' => {
|
73
|
-
'SP0' => nil,
|
74
|
-
'SP1' => nil,
|
75
|
-
'SP2' => nil,
|
76
|
-
'SP3' => nil
|
77
|
-
},
|
78
|
-
'2003' => {
|
79
|
-
'SP0' => nil,
|
80
|
-
'SP1' => nil
|
81
|
-
},
|
82
|
-
'Vista' => {
|
83
|
-
'SP0' => nil,
|
84
|
-
'SP1' => nil
|
85
|
-
},
|
86
|
-
'7' => nil
|
50
|
+
'ME' => nil,
|
51
|
+
'NT' => {
|
52
|
+
'SP0' => nil,
|
53
|
+
'SP1' => nil,
|
54
|
+
'SP2' => nil,
|
55
|
+
'SP3' => nil,
|
56
|
+
'SP4' => nil,
|
57
|
+
'SP5' => nil,
|
58
|
+
'SP6' => nil,
|
59
|
+
'SP6a' => nil
|
87
60
|
},
|
88
|
-
'
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
61
|
+
'2000' => {
|
62
|
+
'SP0' => nil,
|
63
|
+
'SP1' => nil,
|
64
|
+
'SP2' => nil,
|
65
|
+
'SP3' => nil,
|
66
|
+
'SP4' => nil
|
67
|
+
},
|
68
|
+
'XP' => {
|
69
|
+
'SP0' => nil,
|
70
|
+
'SP1' => nil,
|
71
|
+
'SP2' => nil,
|
72
|
+
'SP3' => nil
|
73
|
+
},
|
74
|
+
'2003' => {
|
75
|
+
'SP0' => nil,
|
76
|
+
'SP1' => nil
|
77
|
+
},
|
78
|
+
'Vista' => {
|
79
|
+
'SP0' => nil,
|
80
|
+
'SP1' => nil
|
81
|
+
},
|
82
|
+
'7' => nil
|
83
|
+
},
|
84
|
+
'UNIX' => nil
|
85
|
+
}
|
86
|
+
|
87
|
+
included do
|
88
|
+
include ActiveModel::MassAssignmentSecurity
|
89
|
+
include ActiveModel::Validations
|
90
|
+
include Metasploit::Model::Derivation
|
91
|
+
include Metasploit::Model::Search
|
92
|
+
|
93
|
+
#
|
94
|
+
# Derivations
|
95
|
+
#
|
96
|
+
|
97
|
+
derives :fully_qualified_name, :validate => true
|
98
|
+
|
99
|
+
#
|
100
|
+
# Mass Assignment Security
|
101
|
+
#
|
102
|
+
|
103
|
+
attr_accessible :relative_name
|
104
|
+
|
105
|
+
#
|
106
|
+
# Search
|
107
|
+
#
|
108
|
+
|
109
|
+
search_attribute :fully_qualified_name,
|
110
|
+
type: {
|
111
|
+
set: :string
|
112
|
+
}
|
113
|
+
|
114
|
+
#
|
115
|
+
# Validation
|
116
|
+
#
|
117
|
+
|
118
|
+
validates :fully_qualified_name,
|
119
|
+
inclusion: {
|
120
|
+
in: Metasploit::Model::Platform.fully_qualified_name_set
|
121
|
+
}
|
122
|
+
validates :relative_name,
|
123
|
+
presence: true
|
124
|
+
end
|
121
125
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
126
|
+
# Adds {#fully_qualified_name_set} to class.
|
127
|
+
module ClassMethods
|
128
|
+
# Set of valid {Metasploit::Model::Platform#fully_qualified_name}.
|
129
|
+
#
|
130
|
+
# @return [Set<String>]
|
131
|
+
def fully_qualified_name_set
|
132
|
+
Metasploit::Model::Platform.fully_qualified_name_set
|
133
|
+
end
|
134
|
+
end
|
129
135
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
136
|
+
#
|
137
|
+
# Attributes
|
138
|
+
#
|
139
|
+
|
140
|
+
# @!attribute [rw] fully_qualified_name
|
141
|
+
# The fully qualified name of this platform, as would be used in the platform list in a metasploit-framework
|
142
|
+
# module.
|
143
|
+
#
|
144
|
+
# @return [String]
|
145
|
+
|
146
|
+
# @!attribute [rw] parent
|
147
|
+
# The parent platform of this platform. For example, Windows is parent of Windows 98, which is the parent of
|
148
|
+
# Windows 98 FE.
|
149
|
+
#
|
150
|
+
# @return [nil] if this is a top-level platform, such as Windows or Linux.
|
151
|
+
# @return [Metasploit::Model::Platform]
|
152
|
+
|
153
|
+
# @!attribute [rw] relative_name
|
154
|
+
# The name of this platform relative to the {#fully_qualified_name} of {#parent}.
|
155
|
+
#
|
156
|
+
# @return [String]
|
157
|
+
|
158
|
+
#
|
159
|
+
# Methods
|
160
|
+
#
|
161
|
+
|
162
|
+
# Derives {#fully_qualified_name} from {#parent}'s {#fully_qualified_name} and this platform's {#relative_name}.
|
163
|
+
#
|
164
|
+
# @return [nil] if {#relative_name} is blank.
|
165
|
+
# @return [String] {#relative_name} if {#parent} is `nil`.
|
166
|
+
# @return [String] '<{#parent} {#relative_name}> <{#relative_name}>' if {#parent} is not `nil`.
|
167
|
+
def derived_fully_qualified_name
|
168
|
+
if relative_name.present?
|
169
|
+
if parent
|
170
|
+
"#{parent.fully_qualified_name} #{relative_name}"
|
171
|
+
else
|
172
|
+
relative_name
|
138
173
|
end
|
174
|
+
end
|
175
|
+
end
|
139
176
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
# @return [String] '<{#parent} {#relative_name}> <{#relative_name}>' if {#parent} is not `nil`.
|
171
|
-
def derived_fully_qualified_name
|
172
|
-
if relative_name.present?
|
173
|
-
if parent
|
174
|
-
"#{parent.fully_qualified_name} #{relative_name}"
|
175
|
-
else
|
176
|
-
relative_name
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
177
|
+
# @note Not defined in `ClassMethods` because consumers should always refer back to {Metasploit::Model::Platform}
|
178
|
+
# when seeding.
|
179
|
+
#
|
180
|
+
# @param options [Hash{Symbol => Object, Hash}]
|
181
|
+
# @option options [Object] :parent (nil) The parent object to which to attach the children.
|
182
|
+
# @option options [Hash{String => nil,Hash}] :grandchildren_by_child_relative_name
|
183
|
+
# ({SEED_RELATIVE_NAME_TREE}) Maps {#relative_name} of children under :parent to their children
|
184
|
+
# (grandchildren of parent). Grandchildren can be `nil` or another recursive `Hash` of names and their
|
185
|
+
# descendants.
|
186
|
+
# @yield [attributes] Block should construct child object using attributes.
|
187
|
+
# @yieldparam attributes [Hash{Symbol => Object,String}] Hash containing attributes for child object, include
|
188
|
+
# :parent for {#parent} and :relative_name for {#relative_name}.
|
189
|
+
# @yieldreturn [Object] child derived from :parent and :relative_name to be used as the parent for
|
190
|
+
# grandchildren.
|
191
|
+
# @return [void]
|
192
|
+
def self.each_seed_attributes(options={}, &block)
|
193
|
+
options.assert_valid_keys(:parent, :grandchildren_by_child_relative_name)
|
194
|
+
|
195
|
+
parent = options[:parent]
|
196
|
+
grandchildren_by_child_relative_name = options.fetch(
|
197
|
+
:grandchildren_by_child_relative_name,
|
198
|
+
SEED_RELATIVE_NAME_TREE
|
199
|
+
)
|
200
|
+
|
201
|
+
grandchildren_by_child_relative_name.each do |child_relative_name, great_grandchildren_by_grandchild_relative_name|
|
202
|
+
attributes = {
|
203
|
+
parent: parent,
|
204
|
+
relative_name: child_relative_name
|
205
|
+
}
|
206
|
+
child = block.call(attributes)
|
180
207
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
# @option options [Hash{String => nil,Hash}] :grandchildren_by_child_relative_name
|
187
|
-
# ({SEED_RELATIVE_NAME_TREE}) Maps {#relative_name} of children under :parent to their children
|
188
|
-
# (grandchildren of parent). Grandchildren can be `nil` or another recursive `Hash` of names and their
|
189
|
-
# descendants.
|
190
|
-
# @yield [attributes] Block should construct child object using attributes.
|
191
|
-
# @yieldparam attributes [Hash{Symbol => Object,String}] Hash containing attributes for child object, include
|
192
|
-
# :parent for {#parent} and :relative_name for {#relative_name}.
|
193
|
-
# @yieldreturn [Object] child derived from :parent and :relative_name to be used as the parent for
|
194
|
-
# grandchildren.
|
195
|
-
# @return [void]
|
196
|
-
def self.each_seed_attributes(options={}, &block)
|
197
|
-
options.assert_valid_keys(:parent, :grandchildren_by_child_relative_name)
|
198
|
-
|
199
|
-
parent = options[:parent]
|
200
|
-
grandchildren_by_child_relative_name = options.fetch(
|
201
|
-
:grandchildren_by_child_relative_name,
|
202
|
-
SEED_RELATIVE_NAME_TREE
|
208
|
+
if great_grandchildren_by_grandchild_relative_name
|
209
|
+
each_seed_attributes(
|
210
|
+
grandchildren_by_child_relative_name: great_grandchildren_by_grandchild_relative_name,
|
211
|
+
parent: child,
|
212
|
+
&block
|
203
213
|
)
|
204
|
-
|
205
|
-
grandchildren_by_child_relative_name.each do |child_relative_name, great_grandchildren_by_grandchild_relative_name|
|
206
|
-
attributes = {
|
207
|
-
parent: parent,
|
208
|
-
relative_name: child_relative_name
|
209
|
-
}
|
210
|
-
child = block.call(attributes)
|
211
|
-
|
212
|
-
if great_grandchildren_by_grandchild_relative_name
|
213
|
-
each_seed_attributes(
|
214
|
-
grandchildren_by_child_relative_name: great_grandchildren_by_grandchild_relative_name,
|
215
|
-
parent: child,
|
216
|
-
&block
|
217
|
-
)
|
218
|
-
end
|
219
|
-
end
|
220
214
|
end
|
215
|
+
end
|
216
|
+
end
|
221
217
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
end
|
238
|
-
|
239
|
-
@fully_qualified_name_set.add fully_qualified_name
|
240
|
-
|
241
|
-
# yieldreturn
|
242
|
-
fully_qualified_name
|
243
|
-
end
|
244
|
-
|
245
|
-
@fully_qualified_name_set.freeze
|
218
|
+
# List of valid {#fully_qualified_name} derived from {SEED_RELATIVE_NAME_TREE}.
|
219
|
+
#
|
220
|
+
# @return [Array<String>]
|
221
|
+
def self.fully_qualified_name_set
|
222
|
+
unless instance_variable_defined? :@fully_qualified_name_set
|
223
|
+
@fully_qualified_name_set = Set.new
|
224
|
+
|
225
|
+
each_seed_attributes do |attributes|
|
226
|
+
parent = attributes.fetch(:parent)
|
227
|
+
relative_name = attributes.fetch(:relative_name)
|
228
|
+
|
229
|
+
if parent
|
230
|
+
fully_qualified_name = "#{parent} #{relative_name}"
|
231
|
+
else
|
232
|
+
fully_qualified_name = relative_name
|
246
233
|
end
|
247
234
|
|
248
|
-
@fully_qualified_name_set
|
235
|
+
@fully_qualified_name_set.add fully_qualified_name
|
236
|
+
|
237
|
+
# yieldreturn
|
238
|
+
fully_qualified_name
|
249
239
|
end
|
240
|
+
|
241
|
+
@fully_qualified_name_set.freeze
|
250
242
|
end
|
243
|
+
|
244
|
+
@fully_qualified_name_set
|
251
245
|
end
|
252
|
-
end
|
246
|
+
end
|