agreement-design-prototype 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|