dataMetaPii 1.0.1
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 +7 -0
- data/.yardopts +1 -0
- data/History.md +10 -0
- data/PostInstall.txt +2 -0
- data/README.md +77 -0
- data/Rakefile +13 -0
- data/bin/dmPiiGenCode.rb +65 -0
- data/grammar/appLink.treetop +214 -0
- data/grammar/piiCommons.treetop +46 -0
- data/grammar/registry.treetop +66 -0
- data/lib/dataMetaPii.rb +577 -0
- data/test/appLinkFull.dmPii +71 -0
- data/test/appLinkNoReusables.dmPii +35 -0
- data/test/appLinkShowcase.dmPii +73 -0
- data/test/registryShowcase.dmPii +28 -0
- data/test/test_dataMetaPii.rb +42 -0
- data/test/test_grammars.rb +152 -0
- data/test/test_helper.rb +24 -0
- data/tpl/java/master.erb +64 -0
- data/tpl/json/master.erb +7 -0
- data/tpl/python/master.erb +25 -0
- data/tpl/scala/master.erb +31 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6f161338ef8796386b9b83b7fd82251d1554b241
|
4
|
+
data.tar.gz: 20721eb45e7d5090dd4e8922dfd7994e9ac8cd3e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68ba84d15ab2eaef7267a64a1da4f08376a4ff5acbdde3b4af01b17110b8aef6d9f8ea72f7ce1518b06f5218afc03b24d0487ccad1cae4a4dd263e3ac8aedbfd
|
7
|
+
data.tar.gz: 838781277828e11934547bbbb1d2261167af45fa1da34c4b447513d6cf3efe1025d23c4f800b8efc062c5465d8ed003bf83264068f3c95687f12ec8253ff45c2
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--title "DataMeta/PII" -r README.md --charset UTF-8 lib/**/* - README.md
|
data/History.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# `dataMetaPii` Release history:
|
2
|
+
|
3
|
+
## `1.0.1` released `2017-02-16 Thu` by [`mub`](https://github.com/mub)
|
4
|
+
* 1 update:
|
5
|
+
* bug fix: the code generator was wiping out the destination directory which made generating multiple versions
|
6
|
+
impossible.
|
7
|
+
|
8
|
+
## `1.0.0` released `2017-01-15`
|
9
|
+
* 1 major enhancement:
|
10
|
+
* Initial release
|
data/PostInstall.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
## dataMetaPii
|
2
|
+
|
3
|
+
The PII (Personally Identifiable Information) registry support: master data field definition and link to using those to
|
4
|
+
applications/services code.
|
5
|
+
|
6
|
+
References to this gem's:
|
7
|
+
|
8
|
+
* [Source](https://github.com/eBayDataMeta/DataMeta-gems)
|
9
|
+
|
10
|
+
## DESCRIPTION:
|
11
|
+
|
12
|
+
This gem provides:
|
13
|
+
|
14
|
+
* The [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) to describe PII fields definition with properties
|
15
|
+
such as impact level and any other properties you may want to add.
|
16
|
+
* And another [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) to describe how the PII fields are related
|
17
|
+
to the application/services code.
|
18
|
+
such as impact level and any other properties you may want to add.
|
19
|
+
* Parsers for the [DSLs](https://en.wikipedia.org/wiki/Domain-specific_language)↑
|
20
|
+
* Exporters of the PII definition fo Java, Scala, Python and JSON.
|
21
|
+
|
22
|
+
## FEATURES/PROBLEMS:
|
23
|
+
|
24
|
+
The gem features the API and the executable for the code export.
|
25
|
+
|
26
|
+
## SYNOPSIS:
|
27
|
+
|
28
|
+
### Code Export
|
29
|
+
|
30
|
+
The Gem has the executable named `dmPiiGenCode.rb` which is used to export
|
31
|
+
DataMetaPII definitions into different formats.
|
32
|
+
|
33
|
+
The executable's help text you get by running `dmPiiGenCode.rb` without arguments
|
34
|
+
looks like this:
|
35
|
+
|
36
|
+
```
|
37
|
+
Usage: dmPiiGenCode.rb <Scope> <ExportFormat> <OutputRoot> [ Namespace ]
|
38
|
+
|
39
|
+
Exports the PII definition into sources
|
40
|
+
|
41
|
+
Parameters:
|
42
|
+
<Scope> - one of: abstract, app
|
43
|
+
|
44
|
+
<ExportFormat> - one of: java, scala, python, json
|
45
|
+
|
46
|
+
<OutputRoot> - must be a valid directory in the local file system.
|
47
|
+
|
48
|
+
[ Namespace ] - for Java and Scala - package name, for Python - module name, for JSON - does not matter.
|
49
|
+
|
50
|
+
DataMetaPII sources should be piped in.
|
51
|
+
|
52
|
+
```
|
53
|
+
|
54
|
+
Therefore, to export the version `1.0.0` of the Abstract Fields master to
|
55
|
+
JSON into current directory, you would run:
|
56
|
+
|
57
|
+
```
|
58
|
+
cat abstract-1.0.0.dmPii | piiGenCode.rb abstract json .
|
59
|
+
```
|
60
|
+
|
61
|
+
Which would write a file named `PiiAbstractDef_1_0_0.json` in current directory.
|
62
|
+
|
63
|
+
### AppLink API
|
64
|
+
|
65
|
+
The gem provides the AppLink DSL parsing API to obtain the data structure describing the AppLink
|
66
|
+
and use it to generate code.
|
67
|
+
|
68
|
+
Run `DataMetaPii.parseAppLink(source)` to get the AppLink data structures in memory
|
69
|
+
|
70
|
+
## INSTALL:
|
71
|
+
|
72
|
+
gem install dataMetaPii
|
73
|
+
|
74
|
+
## LICENSE:
|
75
|
+
|
76
|
+
[Apache v 2.0](https://github.com/eBayDataMeta/DataMeta/blob/master/LICENSE.md)
|
77
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
%w(yard rake/testtask ./lib/dataMetaPii).each{ |r| require r}
|
2
|
+
|
3
|
+
Rake::TestTask.new do |t|
|
4
|
+
t.libs << 'test'
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Regen Yard docs'
|
8
|
+
task :default => :docs
|
9
|
+
|
10
|
+
YARD::Rake::YardocTask.new('docs') {|r|
|
11
|
+
r.stats_options = ['--list-undoc']
|
12
|
+
}
|
13
|
+
|
data/bin/dmPiiGenCode.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'dataMetaDom'
|
4
|
+
require 'dataMetaDom/record'
|
5
|
+
require 'dataMetaDom/field'
|
6
|
+
require 'dataMetaDom/ver'
|
7
|
+
require 'dataMetaDom/dataType'
|
8
|
+
require 'dataMetaPii'
|
9
|
+
|
10
|
+
L = Logger.new("#{File.basename(__FILE__)[0..-4]}.log", 0, 10_000_000)
|
11
|
+
|
12
|
+
L.datetime_format = '%Y-%m-%d %H:%M:%S'
|
13
|
+
|
14
|
+
=begin
|
15
|
+
For testing, run, for example:
|
16
|
+
|
17
|
+
cat source.dmPii | piiGenCode.rb abstract java .tmp
|
18
|
+
=end
|
19
|
+
def help(errorText = nil)
|
20
|
+
|
21
|
+
puts %Q|
|
22
|
+
Usage: #{File.basename(__FILE__)} <Scope> <ExportFormat> <OutputRoot> [ Namespace ]
|
23
|
+
|
24
|
+
Exports the PII definition into sources
|
25
|
+
|
26
|
+
Parameters:
|
27
|
+
<Scope> - one of: #{DataMetaPii::Scope.constants.map{|c| DataMetaPii::Scope.const_get(c).to_s}.join(', ')}
|
28
|
+
|
29
|
+
<ExportFormat> - one of: #{DataMetaPii::ExportFmts.constants.map{|c| DataMetaPii::ExportFmts.const_get(c).to_s}.join(', ')}
|
30
|
+
|
31
|
+
<OutputRoot> - must be a valid directory in the local file system.
|
32
|
+
|
33
|
+
[ Namespace ] - for Java and Scala - package name, for Python - module name, for JSON - does not matter.
|
34
|
+
|
35
|
+
DataMeta PII sources should be piped in.
|
36
|
+
|
37
|
+
|
|
38
|
+
$stderr.puts(%Q<\nERROR: #{errorText}>) if errorText
|
39
|
+
|
40
|
+
exit errorText ? 2 : 1
|
41
|
+
end
|
42
|
+
|
43
|
+
@scopeDef, @outFmtDef, @outDirName, @namespace = $*
|
44
|
+
help unless @scopeDef && @outFmtDef && @outDirName
|
45
|
+
|
46
|
+
@scope, @outFmt = [@scopeDef, @outFmtDef].map(&:to_sym)
|
47
|
+
|
48
|
+
help %q<Source is not piped in> if $stdin.tty?
|
49
|
+
|
50
|
+
puts %Q|
|
51
|
+
Exporting #{@scope} to #{@outFmt}:
|
52
|
+
|
53
|
+
Generating results to #{@outDirName}...
|
54
|
+
|
55
|
+
|
|
56
|
+
|
57
|
+
begin
|
58
|
+
DataMetaPii.genCode(@scope, @outFmt, @outDirName, $stdin.read, @namespace)
|
59
|
+
puts 'Done.'
|
60
|
+
rescue Exception => x
|
61
|
+
L.error(%<#{x}\n#{DataMetaPii::INDENT}#{x.backtrace.join("\n#{DataMetaPii::INDENT}")}>)
|
62
|
+
help x.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# PII Master Registry to Application Link DSL grammar
|
2
|
+
# to debug, uncomment next line and add this anywhere: &{|s| debugger; true }
|
3
|
+
#require 'ruby-debug'
|
4
|
+
|
5
|
+
grammar PiiAppLink
|
6
|
+
|
7
|
+
# include the PII commons definition, rules shared between PII grammars; it's likely in the same directory
|
8
|
+
# as this file
|
9
|
+
include PiiCommons
|
10
|
+
|
11
|
+
# Top level rule - encompasses the whole definition file
|
12
|
+
rule appLink
|
13
|
+
piiWss? verDef:version piiWss? ad:attrbDiv? piiWss? al:appLinkDiv piiWss?
|
14
|
+
end
|
15
|
+
|
16
|
+
# Rule for the Attributes Division that defines reusable attributes
|
17
|
+
rule attrbDiv
|
18
|
+
'attributes' piiWss? '{' piiWss? a:attrbSectionSet piiWss? '}' {
|
19
|
+
def type; 'attrbDiv' end
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Helper rule: a set of attribute sections
|
24
|
+
rule attrbSectionSet
|
25
|
+
attrbSection+
|
26
|
+
end
|
27
|
+
|
28
|
+
# Attribute Section with the attribute set's ID and the attributes under it.
|
29
|
+
rule attrbSection
|
30
|
+
piiWss? k:symbol piiWss? '{' piiWss? a:attrbList piiWss? '}' piiWss? {
|
31
|
+
def type; 'attrbSect' end
|
32
|
+
def pk; k.text_value end
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Application Link Division:
|
37
|
+
rule appLinkDiv
|
38
|
+
'apps' piiWss? '{' piiWss? a:appLinkSectionSet+ '}' piiWss? {
|
39
|
+
def type; 'appLinkDiv' end
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Set of Application Link definitions for one application/service: App/Service ID and matching attributes under it,
|
44
|
+
# including reusables.
|
45
|
+
rule appLinkSectionSet
|
46
|
+
piiWs? k:symbol piiWss? '{' piiWss? a:appLinkList piiWss? '}' piiWss? {
|
47
|
+
def type
|
48
|
+
'appLinkAapps'
|
49
|
+
end
|
50
|
+
def ak; k.text_value end
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
# An aggregate of Application Link definitions for one Abstract PII ID
|
55
|
+
rule appLinkList
|
56
|
+
appLinkAttrbs+ {
|
57
|
+
def type; 'appLinkList' end
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
# The PII key with attributes (one or more), i.e. key=value, optionally ornamented/separated by comments, whitespaces including newlines
|
62
|
+
rule appLinkAttrbs
|
63
|
+
piiWss? k:piiKey piiWss? '{' piiWss? a:attrbList piiWss? '}' piiWss? {
|
64
|
+
def type
|
65
|
+
'appLinkAttrbs'
|
66
|
+
end
|
67
|
+
def pk; k.text_value end
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
# The aggregate of attributes belonging to a PII ID under Application/Service ID
|
72
|
+
rule attrbList
|
73
|
+
h:attrbDef t:(c:',' w:piiWss? v:attrbDef)* {
|
74
|
+
def type; DataMetaPii::ATTRB_LIST_NODE_TYPE end
|
75
|
+
# seemingly, an alternative to deep digging
|
76
|
+
# def getAll; result = [h]; if t; result << t.v.elements.map{|e| e} end; result.flatten end
|
77
|
+
# but it does not work: the parser does not collect all the v elements under t
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
# One single attribute definition: it can be either constant, or a reference to a reusable or a special
|
82
|
+
# case of the VO (Value Object) class such as Scala Case Class or a Java Storage Class/Java Bean.
|
83
|
+
rule attrbDef
|
84
|
+
ch:(c:constDef / r:refVal / v:voClass) piiWss? {
|
85
|
+
def type; DataMetaPii::ATTRB_DEF_NODE_TYPE end
|
86
|
+
def val
|
87
|
+
case nodeType
|
88
|
+
when DataMetaPii::REF_KEY
|
89
|
+
ch.r.sym
|
90
|
+
when DataMetaPii::CONST_KEY
|
91
|
+
ch.c.val
|
92
|
+
when DataMetaPii::VO_CLASS_KEY
|
93
|
+
ch.v.klass
|
94
|
+
else # neither -- raise an error
|
95
|
+
raise ArgumentError, %<Unsupported attribute definition type in "#{self.text_value}">
|
96
|
+
end
|
97
|
+
end
|
98
|
+
def node
|
99
|
+
case nodeType
|
100
|
+
when DataMetaPii::REF_KEY
|
101
|
+
ch.r
|
102
|
+
when DataMetaPii::CONST_KEY
|
103
|
+
ch.c
|
104
|
+
when DataMetaPii::VO_CLASS_KEY
|
105
|
+
ch.v
|
106
|
+
else # neither -- raise an error
|
107
|
+
raise ArgumentError, %<Unsupported attribute definition type in "#{self.text_value}">
|
108
|
+
end
|
109
|
+
end
|
110
|
+
def nodeType # figure out the type of this definition
|
111
|
+
if ch.respond_to?(:r)
|
112
|
+
DataMetaPii::REF_KEY
|
113
|
+
elsif ch.respond_to?(:c)
|
114
|
+
DataMetaPii::CONST_KEY
|
115
|
+
elsif ch.respond_to?(:v)
|
116
|
+
DataMetaPii::VO_CLASS_KEY
|
117
|
+
else # neither -- raise an error
|
118
|
+
raise ArgumentError, %<Unsupported attribute definition type in "#{self.text_value}">
|
119
|
+
end
|
120
|
+
end
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
# Value Object (such as Java Bean or Scala Case class)
|
125
|
+
rule voClass
|
126
|
+
w 'voClass' w ':' w c:properCaseSym piiWss? {
|
127
|
+
def type; DataMetaPii::VO_CLASS_KEY end
|
128
|
+
def klass; c.text_value end
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
# Reference to a reusable definition
|
133
|
+
rule refVal
|
134
|
+
'@' symElem:symbol piiWss? {
|
135
|
+
def type; DataMetaPii::REF_KEY end
|
136
|
+
def sym; symElem.text_value end
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
# Constant definition
|
141
|
+
rule constDef
|
142
|
+
k:symbol w ':' w v:constValue {
|
143
|
+
def type; DataMetaPii::CONST_KEY end
|
144
|
+
def key; k.text_value end
|
145
|
+
def val; v.text_value end
|
146
|
+
def valNode; v end
|
147
|
+
def keyNode; k end
|
148
|
+
# has to be defined here because the definition on constValue does not work
|
149
|
+
def dataType # report the type of this constant
|
150
|
+
if v.respond_to?(:s)
|
151
|
+
DataMetaPii::STR_CONST_DT # it's a string
|
152
|
+
elsif v.respond_to?(:d)
|
153
|
+
DataMetaPii::DECIMAL_CONST_DT # it's a decimal number with a fraction
|
154
|
+
elsif v.respond_to?(:i)
|
155
|
+
DataMetaPii::INT_CONST_DT # it's an integer number without a fraction
|
156
|
+
else
|
157
|
+
raise ArgumentError, %<Unsupported constant type in "#{self.text_value}">
|
158
|
+
end
|
159
|
+
end
|
160
|
+
# has to be defined here because the definition on constValue does not work
|
161
|
+
def nodeVal
|
162
|
+
case dataType
|
163
|
+
when DataMetaPii::STR_CONST_DT # it's a string
|
164
|
+
eval(val)
|
165
|
+
when DataMetaPii::DECIMAL_CONST_DT # it's a decimal number with a fraction
|
166
|
+
BigDecimal.new(val)
|
167
|
+
when DataMetaPii::INT_CONST_DT # it's an integer number without a fraction
|
168
|
+
val.to_i
|
169
|
+
else
|
170
|
+
raise ArgumentError, %<Unsupported constant type in "#{self.text_value}">
|
171
|
+
end
|
172
|
+
end
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
176
|
+
# constant value: either an optionally signed integer or optionally signed decimal with fraction
|
177
|
+
rule constValue
|
178
|
+
d:fixedDecimal / i:decIntSignable / s:string {
|
179
|
+
def type
|
180
|
+
'constValue'
|
181
|
+
end
|
182
|
+
# This does not work, probably because of the "OR" condition. The one on constDef does.
|
183
|
+
# Keeping it with the comment to avoid the temptation to move it back here in future, unless
|
184
|
+
# the treetop team fixes the bug
|
185
|
+
def nodeVal
|
186
|
+
case dataType
|
187
|
+
when DataMetaPii::STR_CONST_DT # it's a string
|
188
|
+
eval(eval(text_value))
|
189
|
+
when DataMetaPii::DECIMAL_CONST_DT # it's a decimal number with a fraction
|
190
|
+
BigDecimal.new(text_value)
|
191
|
+
when DataMetaPii::INT_CONST_DT # it's an integer number without a fraction
|
192
|
+
text_value.to_i
|
193
|
+
else
|
194
|
+
raise ArgumentError, %<Unsupported constant type in "#{self.text_value}">
|
195
|
+
end
|
196
|
+
end
|
197
|
+
# This does not work, probably because of the "OR" condition. The one on constDef does.
|
198
|
+
# Keeping it with the comment to avoid the temptation to move it back here in future, unless
|
199
|
+
# the treetop team fixes the bug
|
200
|
+
def dataType # report the type of this constant
|
201
|
+
if self.respond_to?(:s)
|
202
|
+
DataMetaPii::STR_CONST_DT # it's a string
|
203
|
+
elsif self.respond_to?(:d)
|
204
|
+
DataMetaPii::DECIMAL_CONST_DT # it's a decimal number with a fraction
|
205
|
+
elsif self.respond_to?(:i)
|
206
|
+
DataMetaPii::INT_CONST_DT # it's an integer number without a fraction
|
207
|
+
else
|
208
|
+
raise ArgumentError, %<Unsupported constant type in "#{self.text_value}">
|
209
|
+
end
|
210
|
+
end
|
211
|
+
}
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# PII rules common between the concrete grammers, to be reused.
|
2
|
+
grammar PiiCommons
|
3
|
+
|
4
|
+
# Load the commons from the DataMetaParse which lives in:
|
5
|
+
# binary: http://FIXME
|
6
|
+
# documentation: http://FIXME
|
7
|
+
# source: https://FIXME
|
8
|
+
include DataMetaCommonsRoot
|
9
|
+
|
10
|
+
# PII field key - a sequence of symChar, one or more
|
11
|
+
rule piiKey
|
12
|
+
symChar+
|
13
|
+
end
|
14
|
+
|
15
|
+
# One or more PII Whitespaces
|
16
|
+
rule piiWss
|
17
|
+
piiWs+
|
18
|
+
end
|
19
|
+
|
20
|
+
# PII Whitespace: a comment with endline or a plain whitespace as defined in DataMeta Parsing Commons
|
21
|
+
rule piiWs
|
22
|
+
sEol / W
|
23
|
+
end
|
24
|
+
|
25
|
+
# Symbol with the first letter lowercase - suitable for a variable name.
|
26
|
+
rule symbol
|
27
|
+
[a-z] symChar*
|
28
|
+
end
|
29
|
+
|
30
|
+
# Symbol with the first letter uppercase - suitable for a class name.
|
31
|
+
rule properCaseSym
|
32
|
+
[A-Z] symChar*
|
33
|
+
end
|
34
|
+
|
35
|
+
# Symbol character: letter, number, underscore
|
36
|
+
rule symChar
|
37
|
+
[a-zA-Z0-9_]
|
38
|
+
end
|
39
|
+
|
40
|
+
rule version
|
41
|
+
'ver' W v:string {
|
42
|
+
def type; 'version' end
|
43
|
+
def ver; eval(v.text_value) end
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|