agreement-design-prototype 0.0.4 → 0.0.5
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 +16 -0
- data/Rakefile +2 -2
- data/agreement-design.gemspec +1 -1
- data/data/README.md +17 -0
- data/data/teacher-management-test.csv +39 -0
- data/data/teacher-recruitment-test.csv +5 -0
- data/gen/README.md +7 -0
- data/gen/data/ELETE +4 -0
- data/gen/data/agreements.json +1 -0
- data/gen/data/agreements.jsonlines +6 -0
- data/gen/data/agreements.yaml +238 -0
- data/gen/data/teacher-management-test-offers.jsonlines +160 -0
- data/gen/data/teacher-recruitment-test-offers.jsonlines +240 -0
- data/gen/diagrams/metamodel.dot +20 -14
- data/gen/doc/metamodel.md +43 -11
- data/gen/doc/supply_teachers.md +238 -0
- data/gen/images/metamodel.jpg +0 -0
- data/generate.rb +57 -0
- data/model/README.md +48 -0
- data/model/agreement.rb +6 -6
- data/model/fm.rb +17 -14
- data/model/party.rb +26 -1
- data/model/supply_teachers.rb +287 -0
- data/out/test/doc/doctest.md +14 -8
- data/src/data.rb +31 -46
- data/src/data_model.rb +22 -6
- data/src/doc.rb +12 -6
- data/src/transform.rb +65 -7
- metadata +16 -7
- data/build/build_models.rb +0 -31
- data/gen/data/data.json +0 -1
- data/gen/data/data.yaml +0 -46
- data/gen/data/fm_agreements.jsonlines +0 -2
- data/gen/doc/data.md +0 -44
data/out/test/doc/doctest.md
CHANGED
@@ -1,17 +1,23 @@
|
|
1
|
-
|
1
|
+
# Model: TESTMODEL
|
2
|
+
## complextype
|
3
|
+
### ComplexType - complextype
|
2
4
|
- string ID1
|
3
|
-
#### things
|
5
|
+
#### ArrayParam - things
|
4
6
|
- thingname thing1
|
5
|
-
#### things
|
7
|
+
#### ArrayParam - things
|
6
8
|
- thingname thing2
|
7
|
-
|
9
|
+
## anothertype
|
10
|
+
### AnotherType - anothertype
|
8
11
|
- string Anotherthing
|
9
|
-
|
12
|
+
## table
|
13
|
+
### Table - table
|
10
14
|
- vals 1
|
11
15
|
- vals 2
|
12
|
-
|
16
|
+
## referencingtype
|
17
|
+
### ReferencingType - referencingtype
|
13
18
|
- id owner
|
14
|
-
#### mate
|
19
|
+
#### BasicType - mate
|
15
20
|
- id content
|
16
|
-
|
21
|
+
## kindly
|
22
|
+
### Kindly - kindly
|
17
23
|
- kind Framework
|
data/src/data.rb
CHANGED
@@ -15,64 +15,31 @@ class DataFile < Output
|
|
15
15
|
self.fmt = fmt
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
# @param [object] index - if included, and using :jsonlines, will call index on each item (as a hash) and prepend the line.
|
19
|
+
# @param [string] select - if given this will select out the type, eg agreements, and discard the rest
|
20
|
+
def output *models, index: nil, select: nil
|
21
|
+
|
22
|
+
map = models_to_data(models)
|
19
23
|
|
20
|
-
map = Hash.new
|
21
|
-
stack = [map]
|
22
|
-
transform_datamodel(
|
23
|
-
{
|
24
|
-
:before_group => lambda do |name:, depth:|
|
25
|
-
last = stack.last
|
26
|
-
n = Array.new
|
27
|
-
last[name] = n
|
28
|
-
stack.push(n) # add a new container to the stack to use next
|
29
|
-
end,
|
30
|
-
:before_type => lambda do |type:, depth:, index:, total:|
|
31
|
-
last = stack.last
|
32
|
-
n = Hash.new
|
33
|
-
stack.push(n) # add a new container to the stack to use next
|
34
|
-
if last.class <= Hash
|
35
|
-
last[type.name] = n
|
36
|
-
elsif last.class <= Array
|
37
|
-
last.push(n)
|
38
|
-
end
|
39
|
-
end,
|
40
|
-
:before_array => lambda do |name:, decl:, depth:, total:|
|
41
|
-
last = stack.last
|
42
|
-
n = Array.new
|
43
|
-
last[name] = n
|
44
|
-
stack.push(n) # add a new container to the stack to use next
|
45
|
-
end,
|
46
|
-
:attribute => lambda do |id:, val:, depth:, type:, index:, total:|
|
47
|
-
last = stack.last
|
48
|
-
if last.class <= Hash
|
49
|
-
last[id] = val
|
50
|
-
elsif last.class <= Array
|
51
|
-
last.push val
|
52
|
-
end
|
53
|
-
end,
|
54
|
-
:after_group => lambda do |name:, depth:, before:|
|
55
|
-
stack.pop
|
56
|
-
end,
|
57
|
-
:after_type => lambda do |type:, depth:, before:|
|
58
|
-
stack.pop
|
59
|
-
end,
|
60
|
-
:after_array => lambda do |index:, decl:, depth:, before: nil|
|
61
|
-
stack.pop
|
62
|
-
end,
|
63
|
-
}, *models)
|
64
24
|
|
65
25
|
file do |file|
|
66
26
|
if fmt == :jsonlines
|
67
|
-
|
27
|
+
select ? selection = [select] : selection = map.keys
|
28
|
+
for type in selection
|
68
29
|
for decl in map[type]
|
30
|
+
if (index)
|
31
|
+
file.print (JSON.generate(index.call(decl)))
|
32
|
+
file.print("\n")
|
33
|
+
end
|
69
34
|
file.print(JSON.generate(decl))
|
70
35
|
file.print("\n")
|
71
36
|
end
|
72
37
|
end
|
73
38
|
elsif fmt == :json
|
39
|
+
select ? map = map[select] : map
|
74
40
|
file.print(JSON.generate(map))
|
75
41
|
elsif fmt == :yaml
|
42
|
+
select ? map = map[select] : map
|
76
43
|
file.print(map.to_yaml)
|
77
44
|
else
|
78
45
|
raise "unknown data file format"
|
@@ -82,6 +49,24 @@ class DataFile < Output
|
|
82
49
|
|
83
50
|
end
|
84
51
|
|
52
|
+
# given an offer object return an index object
|
53
|
+
# Maybe: turn this into a datatype map, not an object map, so we can access type metadata
|
54
|
+
|
55
|
+
def index_offering_for_elasticsearch
|
56
|
+
return lambda do |offer|
|
57
|
+
var = offer[:name].gsub(/(\s+)/, '_')
|
58
|
+
return {"index": {"_id": "#{var}"}}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def index_agreement_for_elasticsearch
|
63
|
+
return lambda do |id|
|
64
|
+
var = id[:name].gsub(/(\s+)/, '_')
|
65
|
+
return {"index": {"_id": "#{var}"}}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
85
70
|
private
|
86
71
|
|
87
72
|
def indent(depth)
|
data/src/data_model.rb
CHANGED
@@ -2,6 +2,7 @@ require 'date'
|
|
2
2
|
|
3
3
|
module DataModel
|
4
4
|
|
5
|
+
|
5
6
|
SINGLE = 1..1
|
6
7
|
ZERO_OR_ONE = 0..1
|
7
8
|
ONE_TO_MANY = 1..-1
|
@@ -84,13 +85,25 @@ module DataModel
|
|
84
85
|
end
|
85
86
|
return @attributes[k]
|
86
87
|
end
|
88
|
+
if block
|
89
|
+
value = valueof(k, *args, &block)
|
90
|
+
else
|
91
|
+
value = args[0]
|
92
|
+
end
|
87
93
|
if self.class.attributes[k][:multiplicity].end != 1
|
88
94
|
@attributes[k] = [] unless @attributes[k]
|
89
|
-
@attributes[k] <<
|
95
|
+
@attributes[k] << value
|
90
96
|
else
|
91
|
-
@attributes[k] =
|
97
|
+
@attributes[k] = value
|
92
98
|
end
|
93
|
-
return
|
99
|
+
return value
|
100
|
+
end
|
101
|
+
self.define_singleton_method("#{k}=".to_sym) do |val|
|
102
|
+
@attributes[k] = val
|
103
|
+
val
|
104
|
+
end
|
105
|
+
self.define_singleton_method :include do |&block|
|
106
|
+
self.instance_exec &block
|
94
107
|
end
|
95
108
|
end
|
96
109
|
|
@@ -155,8 +168,8 @@ module DataModel
|
|
155
168
|
end
|
156
169
|
end
|
157
170
|
|
158
|
-
def code(
|
159
|
-
|
171
|
+
def code(*context,
|
172
|
+
description: nil, title: nil, uri: nil)
|
160
173
|
unless instance_variable_defined? :@codes
|
161
174
|
@codes = {}
|
162
175
|
self.define_singleton_method(:codes) {@codes}
|
@@ -207,7 +220,9 @@ module DataModel
|
|
207
220
|
|
208
221
|
def domain(name, &block)
|
209
222
|
dom = Object.const_set name, Class.new(Domain)
|
210
|
-
|
223
|
+
if block_given?
|
224
|
+
dom.instance_exec &block
|
225
|
+
end
|
211
226
|
return dom
|
212
227
|
end
|
213
228
|
|
@@ -226,4 +241,5 @@ module DataModel
|
|
226
241
|
return selclass
|
227
242
|
end
|
228
243
|
|
244
|
+
|
229
245
|
end # DataModel
|
data/src/doc.rb
CHANGED
@@ -4,15 +4,21 @@ include Transform
|
|
4
4
|
class Document < Output
|
5
5
|
|
6
6
|
def initialize dir, name
|
7
|
-
super File.join(
|
7
|
+
super File.join(dir, "doc"), name, "md"
|
8
8
|
end
|
9
9
|
|
10
10
|
def document *models
|
11
11
|
file do |file|
|
12
12
|
transform_datamodel(
|
13
13
|
{
|
14
|
-
:
|
15
|
-
file.print %Q
|
14
|
+
:before_model => lambda do |model: |
|
15
|
+
file.print %Q!# Model: #{model.name} \n!
|
16
|
+
end,
|
17
|
+
:before_group => lambda do |name: |
|
18
|
+
file.print %Q!## #{name}\n!
|
19
|
+
end,
|
20
|
+
:before_type => lambda do |type:, depth: 0, index:, total:|
|
21
|
+
file.print %Q!####{'#' * depth} #{type.class.typename} - #{type.name} \n!
|
16
22
|
end,
|
17
23
|
:attribute => lambda do |id:, val:, depth: 0, type: nil, index:, total:|
|
18
24
|
file.print %Q!#{" " * depth} - #{id} #{val}\n!
|
@@ -29,9 +35,9 @@ class Document < Output
|
|
29
35
|
file.print %Q!\# Data model: #{model}\n!
|
30
36
|
end,
|
31
37
|
before_group: lambda do |group|
|
32
|
-
file.print %Q!\# #{
|
33
|
-
if (
|
34
|
-
file.print %Q! #{
|
38
|
+
file.print %Q!\# #{group.class}: #{group.name}\n!
|
39
|
+
if (group.respond_to?(:description))
|
40
|
+
file.print %Q! #{group.description}\n!
|
35
41
|
end
|
36
42
|
end,
|
37
43
|
before_type: lambda do |type:, depth:, index:, total:|
|
data/src/transform.rb
CHANGED
@@ -38,8 +38,8 @@ module Transform
|
|
38
38
|
return [model: model, code: code]
|
39
39
|
end
|
40
40
|
|
41
|
-
def before_group_lambda name: nil
|
42
|
-
return [name: name
|
41
|
+
def before_group_lambda name: nil
|
42
|
+
return [name: name]
|
43
43
|
end
|
44
44
|
|
45
45
|
def after_group_lambda name: nil, before: nil, depth: 0
|
@@ -77,7 +77,7 @@ module Transform
|
|
77
77
|
t = 0
|
78
78
|
# there will be more than one of each type
|
79
79
|
for type in model.contents[typename]
|
80
|
-
|
80
|
+
transform_entry(lambdas, decl: type, name: typename, depth: 0, index: 0, total: 1)
|
81
81
|
t = t + 1
|
82
82
|
end
|
83
83
|
grp = cond_call(lambdas, :after_group, *after_group_lambda(name: typename, before: grp))
|
@@ -90,7 +90,7 @@ module Transform
|
|
90
90
|
for model in models
|
91
91
|
dom = cond_call(lambdas, :before_model, *before_model_lambda(model: model))
|
92
92
|
for type in model.types.values
|
93
|
-
before = cond_call(lambdas, :before_type, *before_type_lambda(type: type, index:0, total:1))
|
93
|
+
before = cond_call(lambdas, :before_type, *before_type_lambda(type: type, index: 0, total: 1))
|
94
94
|
i = 0
|
95
95
|
for ak in type.attributes.keys
|
96
96
|
av = type.attributes[ak]
|
@@ -116,13 +116,13 @@ module Transform
|
|
116
116
|
return 0
|
117
117
|
end
|
118
118
|
|
119
|
-
def
|
119
|
+
def transform_entry(lambdas, index:, name:, decl:, depth:, total:)
|
120
120
|
|
121
121
|
if decl.class <= Array
|
122
122
|
arrctx = cond_call(lambdas, :before_array, *before_array_lambda(name: name, decl: decl, depth: depth, total: decl.length))
|
123
123
|
j = 0
|
124
124
|
for aa in decl
|
125
|
-
|
125
|
+
transform_entry(lambdas, index: j, decl: aa, name: name, depth: depth, total: decl.length)
|
126
126
|
j = j + 1
|
127
127
|
end
|
128
128
|
cond_call(lambdas, :after_array, *after_array_lambda(index: index, decl: decl, depth: depth, before: arrctx))
|
@@ -131,7 +131,7 @@ module Transform
|
|
131
131
|
i = 0
|
132
132
|
for ak in decl.attributes.keys
|
133
133
|
av = decl.attributes[ak]
|
134
|
-
|
134
|
+
transform_entry(lambdas, name: ak, decl: av, depth: depth + 1, index: i, total: decl.attributes.keys.length)
|
135
135
|
i = i + 1
|
136
136
|
end
|
137
137
|
cond_call(lambdas, :after_type, *after_type_lambda(type: decl, depth: depth, before: before))
|
@@ -141,4 +141,62 @@ module Transform
|
|
141
141
|
self
|
142
142
|
end
|
143
143
|
|
144
|
+
def models_to_data(models)
|
145
|
+
map = Hash.new
|
146
|
+
stack = [map]
|
147
|
+
transform_datamodel(
|
148
|
+
{
|
149
|
+
:before_group => lambda do |name:|
|
150
|
+
# group all instances of the same type name into the same array in the top level map
|
151
|
+
if map[name]
|
152
|
+
stack.push(map[name])
|
153
|
+
else
|
154
|
+
n = Array.new
|
155
|
+
map[name] = n
|
156
|
+
stack.push(map[name]) # add a new container to the stack to use next
|
157
|
+
end
|
158
|
+
end,
|
159
|
+
:before_type => lambda do |type:, depth:, index:, total:|
|
160
|
+
last = stack.last
|
161
|
+
n = Hash.new
|
162
|
+
stack.push(n) # add a new container to the stack to use next
|
163
|
+
if last.class <= Hash
|
164
|
+
last[type.name] = n
|
165
|
+
elsif last.class <= Array
|
166
|
+
last.push(n)
|
167
|
+
end
|
168
|
+
end,
|
169
|
+
:before_array => lambda do |name:, decl:, depth:, total:|
|
170
|
+
last = stack.last
|
171
|
+
n = Array.new
|
172
|
+
if last.class <= Array
|
173
|
+
last << n
|
174
|
+
else
|
175
|
+
last[name] = n
|
176
|
+
end
|
177
|
+
stack.push(n) # add a new container to the stack to use next
|
178
|
+
end,
|
179
|
+
:attribute => lambda do |id:, val:, depth:, type:, index:, total:|
|
180
|
+
last = stack.last
|
181
|
+
if last.class <= Hash
|
182
|
+
last[id] = val
|
183
|
+
elsif last.class <= Array
|
184
|
+
last.push val
|
185
|
+
end
|
186
|
+
end,
|
187
|
+
:after_group => lambda do |name:, depth:, before:|
|
188
|
+
stack.pop
|
189
|
+
end,
|
190
|
+
:after_type => lambda do |type:, depth:, before:|
|
191
|
+
stack.pop
|
192
|
+
end,
|
193
|
+
:after_array => lambda do |index:, decl:, depth:, before: nil|
|
194
|
+
stack.pop
|
195
|
+
end,
|
196
|
+
}, *models)
|
197
|
+
map
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
|
144
202
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: agreement-design-prototype
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- CCS
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -34,19 +34,28 @@ files:
|
|
34
34
|
- "./README.md"
|
35
35
|
- "./Rakefile"
|
36
36
|
- "./agreement-design.gemspec"
|
37
|
-
- "./
|
38
|
-
- "./
|
39
|
-
- "./
|
40
|
-
- "./gen/
|
37
|
+
- "./data/README.md"
|
38
|
+
- "./data/teacher-management-test.csv"
|
39
|
+
- "./data/teacher-recruitment-test.csv"
|
40
|
+
- "./gen/README.md"
|
41
|
+
- "./gen/data/ELETE"
|
42
|
+
- "./gen/data/agreements.json"
|
43
|
+
- "./gen/data/agreements.jsonlines"
|
44
|
+
- "./gen/data/agreements.yaml"
|
41
45
|
- "./gen/data/fm_catalogue.jsonlines"
|
46
|
+
- "./gen/data/teacher-management-test-offers.jsonlines"
|
47
|
+
- "./gen/data/teacher-recruitment-test-offers.jsonlines"
|
42
48
|
- "./gen/diagrams/metamodel.dot"
|
43
|
-
- "./gen/doc/data.md"
|
44
49
|
- "./gen/doc/metamodel.md"
|
50
|
+
- "./gen/doc/supply_teachers.md"
|
45
51
|
- "./gen/images/metamodel.jpg"
|
52
|
+
- "./generate.rb"
|
53
|
+
- "./model/README.md"
|
46
54
|
- "./model/agreement.rb"
|
47
55
|
- "./model/fm.rb"
|
48
56
|
- "./model/geographic.rb"
|
49
57
|
- "./model/party.rb"
|
58
|
+
- "./model/supply_teachers.rb"
|
50
59
|
- "./out/test/data/datatest.json"
|
51
60
|
- "./out/test/diagrams/d.dot"
|
52
61
|
- "./out/test/doc/doctest.md"
|
data/build/build_models.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require_relative "../src/diagram"
|
2
|
-
require_relative "../src/doc"
|
3
|
-
require_relative "../src/data"
|
4
|
-
require_relative "../model/agreement"
|
5
|
-
require_relative "../model/fm"
|
6
|
-
require_relative '../model/geographic'
|
7
|
-
|
8
|
-
path = File.join(File.dirname(__FILE__), '../', "gen")
|
9
|
-
|
10
|
-
metamodels = [Agreements, Parties, Geographic, FM]
|
11
|
-
models = [Agreements::FM_Agreements, FM::FM_Catalogue, Geographic::NUTS]
|
12
|
-
|
13
|
-
diagram = Diagram.new(path, "metamodel")
|
14
|
-
diagram.describe *metamodels
|
15
|
-
|
16
|
-
doc = Document.new(path, "metamodel")
|
17
|
-
doc.document_metamodel *metamodels
|
18
|
-
|
19
|
-
doc = Document.new(path, "data")
|
20
|
-
doc.document *models
|
21
|
-
|
22
|
-
data= DataFile.new( path, "data", fmt: :json)
|
23
|
-
data.output *models
|
24
|
-
data= DataFile.new( path, "data", fmt: :yaml)
|
25
|
-
data.output *models
|
26
|
-
|
27
|
-
data= DataFile.new( path, "fm_agreements", fmt: :jsonlines)
|
28
|
-
data.output Agreements::FM_Agreements
|
29
|
-
|
30
|
-
data= DataFile.new( path, "fm_catalogue", fmt: :jsonlines)
|
31
|
-
data.output FM::FM_Catalogue
|
data/gen/data/data.json
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"agreement":[{"kind":"Framework","id":"FM","fwk_number":"RM8330","version":"0.1.0","description":"This agreement is for the provision of Facilities Management","start_date":"2018-10-01"},{"kind":"Lot","id":"FM lot 1","name":"low-to-mid value Facilities Management Lot","part_of_id":"FM","min_value":0,"max_value":70000000,"version":"0.1.0","item_type":[{"id":"FM.1a-C.3","scheme_id":"CCS","unit":"Currency","code":"CCS-building-area-method","keyword":["cleaning","washing","janitor"]}]}],"fm_offering":[{"supplier_id":"XYZ corp","name":"XYZ's nifty school cleaning service","agreement_id":"FM","location_id":["UK"],"sector":["Education"],"sc_cleared":"TRUE","item":[{"type":"FM.1a-C.3","value":3000}]}],"areacode":[{"name":"UK","subcode":[{"name":"UKC","description":"North East","subcode":[{"name":"UKC1","description":"Tees Valley and County Durham"}]},{"name":"UKL","description":"London"}]}]}
|
data/gen/data/data.yaml
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
---
|
2
|
-
:agreement:
|
3
|
-
- :kind: :Framework
|
4
|
-
:id: FM
|
5
|
-
:fwk_number: RM8330
|
6
|
-
:version: 0.1.0
|
7
|
-
:description: This agreement is for the provision of Facilities Management
|
8
|
-
:start_date: 2018-10-01
|
9
|
-
- :kind: :Lot
|
10
|
-
:id: FM lot 1
|
11
|
-
:name: low-to-mid value Facilities Management Lot
|
12
|
-
:part_of_id: FM
|
13
|
-
:min_value: 0
|
14
|
-
:max_value: 70000000
|
15
|
-
:version: 0.1.0
|
16
|
-
:item_type:
|
17
|
-
- :id: FM.1a-C.3
|
18
|
-
:scheme_id: :CCS
|
19
|
-
:unit: :Currency
|
20
|
-
:code: CCS-building-area-method
|
21
|
-
:keyword:
|
22
|
-
- cleaning
|
23
|
-
- washing
|
24
|
-
- janitor
|
25
|
-
:fm_offering:
|
26
|
-
- :supplier_id: XYZ corp
|
27
|
-
:name: XYZ's nifty school cleaning service
|
28
|
-
:agreement_id: FM
|
29
|
-
:location_id:
|
30
|
-
- :UK
|
31
|
-
:sector:
|
32
|
-
- :Education
|
33
|
-
:sc_cleared: 'TRUE'
|
34
|
-
:item:
|
35
|
-
- :type: FM.1a-C.3
|
36
|
-
:value: 3000
|
37
|
-
:areacode:
|
38
|
-
- :name: :UK
|
39
|
-
:subcode:
|
40
|
-
- :name: :UKC
|
41
|
-
:description: North East
|
42
|
-
:subcode:
|
43
|
-
- :name: :UKC1
|
44
|
-
:description: Tees Valley and County Durham
|
45
|
-
- :name: :UKL
|
46
|
-
:description: London
|