dataMetaPii 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|