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
@@ -0,0 +1,71 @@
|
|
1
|
+
# DSL describing Connection between the PII abstract definition and application concretics
|
2
|
+
# This is full definition that can be parsed and structured.
|
3
|
+
|
4
|
+
ver "12.489.2.alpha"
|
5
|
+
|
6
|
+
# Reusable Attributes Division
|
7
|
+
attributes {
|
8
|
+
universalConstants {
|
9
|
+
piPositive: 3.14, # numers and decimal point: Float
|
10
|
+
piNegative: -3.14, # check the negative case
|
11
|
+
universe: "Forty-two",
|
12
|
+
@sam# reference to the reusable, see further down
|
13
|
+
}
|
14
|
+
ints {
|
15
|
+
maxInstanceCount: 0012, # numbers only, no decimal point: perceived/rendered as an Integer
|
16
|
+
foo: -019 # check the negative case; note that octal conversion does not apply like with literals in Ruby code
|
17
|
+
}
|
18
|
+
sam { # Can the parser handle strings with C-like backslash escapes?
|
19
|
+
says: "Sam \t says, \"You kidding me, right?\"",
|
20
|
+
@donald # should be able to handle cycles in the inclusion tree
|
21
|
+
}
|
22
|
+
donald {
|
23
|
+
quacks: "Quack!",
|
24
|
+
@sam # should be able to handle cycles in the inclusion tree
|
25
|
+
}
|
26
|
+
# see if the parser can handle a one-liner
|
27
|
+
noise { @donald, spectrum: "white", @sam, @ints }
|
28
|
+
}
|
29
|
+
|
30
|
+
# Application Division
|
31
|
+
apps {
|
32
|
+
pollingServices { # Unique application ID; should be unique throughout the config, each app responsible for its own def
|
33
|
+
# or make it centralized, standard??
|
34
|
+
Name_Full { # the PII key from the abstract definition
|
35
|
+
# Application-specific attributes for this field (need to standardize them?):
|
36
|
+
|
37
|
+
# DataMeta DOM record's name, without the version let alone the package: the application
|
38
|
+
# should be aware of those details and be flexible. From this, can infer the InOutable and migration calls
|
39
|
+
voClass: Name,
|
40
|
+
# list of database fields that store this value
|
41
|
+
bigTableFields: "users:name, clients:fullName",
|
42
|
+
@ints # reference to the reusables
|
43
|
+
}
|
44
|
+
|
45
|
+
TwoFA_Token_Serial_Number {
|
46
|
+
voClass: TwoFaSerialNumber,
|
47
|
+
bigTableFields: "security:twoFa",
|
48
|
+
@universalConstants,@ints
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
bcastingServices {
|
53
|
+
Name_First {
|
54
|
+
voClass: Name,
|
55
|
+
oracleFields: "USERS:FIRST_NAME",
|
56
|
+
lapseCount: 0123,
|
57
|
+
median: -123.4567,
|
58
|
+
weight: 987.65432
|
59
|
+
}
|
60
|
+
Name_Last {
|
61
|
+
voClass: Name,
|
62
|
+
oracleFields: "USERS:LAST_NAME"
|
63
|
+
}
|
64
|
+
Date_Of_Birth {
|
65
|
+
voClass: BirthDate, # plain symbol, no enclosure: perceived/rendered as a string
|
66
|
+
logFormat: "yyyy-MM-dd HH:mm:SS", # enclosured in a string: perceived/rendered as a string
|
67
|
+
@universalConstants,
|
68
|
+
bigTableFields: "users:dob,clients:birthDate" # enclosured in a string: perceived/rendered as a string
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# DSL describing Connection between the PII abstract definition and application concretics
|
2
|
+
# This is full definition that can be parsed and structured.
|
3
|
+
# For testing/structuring purposes, the attributes division is missing and
|
4
|
+
# no reusables are referred to.
|
5
|
+
|
6
|
+
ver "3.423.11.19"
|
7
|
+
|
8
|
+
# Application Division
|
9
|
+
apps {
|
10
|
+
pollingServices { # Unique application ID; should be unique throughout the config, each app responsible for its own def
|
11
|
+
# or make it centralized, standard??
|
12
|
+
Name_Full { # the PII key from the abstract definition
|
13
|
+
# Application-specific attributes for this field (need to standardize them?):
|
14
|
+
|
15
|
+
# DataMeta DOM record's name, without the version let alone the package: the application
|
16
|
+
# should be aware of those details and be flexible. From this, can infer the InOutable and migration calls
|
17
|
+
voClass: Name,
|
18
|
+
# list of database fields that store this value
|
19
|
+
oracleFields: "users:name, clients:fullName"
|
20
|
+
}
|
21
|
+
|
22
|
+
TwoFA_Token_Serial_Number {
|
23
|
+
voClass: TwoFaSerialNumber,
|
24
|
+
oracleFields: "security:twoFa"
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
bcastingServices {
|
29
|
+
Date_Of_Birth {
|
30
|
+
voClass: BirthDate, # plain symbol, no enclosure: perceived/rendered as a string
|
31
|
+
logFormat: "yyyy-MM-dd HH:mm:SS", # enclosured in a string: perceived/rendered as a string
|
32
|
+
oracleFields: "users:dob,clients:birthDate" # enclosured in a string: perceived/rendered as a string
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# This definition is for grammar testing/debugging only.
|
2
|
+
# An attempt to pass it through structuring should fail because there are intentional violations
|
3
|
+
# of a exogrammatical structure: for example, multiple VO definitions are allowed by the grammar
|
4
|
+
# but the CST builder rejects those with an error.
|
5
|
+
|
6
|
+
ver "1.2.3.4.beta" # Full version presented here
|
7
|
+
|
8
|
+
# Reusable Attributes Division
|
9
|
+
attributes {
|
10
|
+
universalConstants {
|
11
|
+
piPositive: 3.14, # numers and decimal point: Float
|
12
|
+
piNegative: -3.14, # check the negative case
|
13
|
+
universe: "Forty-two",
|
14
|
+
@sam, # reference to the reusable, see further down
|
15
|
+
@symbolSoloOnLine,
|
16
|
+
boo: 1.23, foo:-35.36,
|
17
|
+
@symbolLeadinWsAndTrailingComment, # endline comment for this
|
18
|
+
@symbolWithTrailingComment, # endline comment
|
19
|
+
@symbolWithLeadingWhitespace, str:"Some \n string"
|
20
|
+
}
|
21
|
+
ints {
|
22
|
+
maxInstanceCount: 4, # numbers only, no decimal point: perceived/rendered as an Integer
|
23
|
+
foo: -4 # check the negative case
|
24
|
+
}
|
25
|
+
sam { # Can the parser handle strings with C-like backslash escapes?
|
26
|
+
says: "Sam \t says, \"You kidding me, right?\""
|
27
|
+
}
|
28
|
+
donald {
|
29
|
+
quacks: "Quack!"
|
30
|
+
}
|
31
|
+
# see if the parser can handle a one-liner
|
32
|
+
noise { @donald, spectrum: "white", @sam }
|
33
|
+
}
|
34
|
+
|
35
|
+
# Application Division
|
36
|
+
apps {
|
37
|
+
pollingServices { # Unique application ID; should be unique throughout the config, each app responsible for its own def
|
38
|
+
# or make it centralized, standard??
|
39
|
+
Name_Full { # the PII key from the abstract definition
|
40
|
+
# Application-specific attributes for this field (need to standardize them?):
|
41
|
+
|
42
|
+
# DataMeta DOM record's name, without the version let alone the package: the application
|
43
|
+
# should be aware of those details and be flexible. From this, can infer the InOutable and migration calls
|
44
|
+
voClass: Name,
|
45
|
+
# list of database fields that store this value
|
46
|
+
mySqlFields: "users:name, clients:fullName",
|
47
|
+
@ints # reference to the reusables
|
48
|
+
}
|
49
|
+
|
50
|
+
TwoFA_Token_Serial_Number {
|
51
|
+
voClass: TwoFaSerialNumber,
|
52
|
+
db2Fields: "security:twoFa",
|
53
|
+
@universalConstants,@ints
|
54
|
+
}
|
55
|
+
} # try this
|
56
|
+
bcastingServices {
|
57
|
+
Date_Of_Birth {
|
58
|
+
voClass:FirstClass,
|
59
|
+
voClass: SecondClass,
|
60
|
+
voClass : ThirdClass,
|
61
|
+
voClass :FourthClass,
|
62
|
+
# Leading space
|
63
|
+
voClass: FifthClass,
|
64
|
+
voClass: SixthClass, # tail comment
|
65
|
+
voClass :SeventhClass # tail with no leading whitespace
|
66
|
+
}
|
67
|
+
TwoFA_Token_Serial_Number {
|
68
|
+
voClass: TwoFaSerialNumber,
|
69
|
+
bigTableFields: "security:twoFa",
|
70
|
+
@universalConstants,@ints
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Master Definition Of the PII fields
|
2
|
+
# the "taboo" level means that under no circumstances the value should be stored.
|
3
|
+
|
4
|
+
# PII field definition format:
|
5
|
+
# PII-Field-UniqueKey {PROFILE-KEY {level=IMPACT_LEVEL}}
|
6
|
+
|
7
|
+
# These impact levels are picked at random for testing, check with your company's policies
|
8
|
+
# for real impact levels.
|
9
|
+
|
10
|
+
ver "1.0.0"
|
11
|
+
|
12
|
+
Corp_User_Name { # PII field unique key
|
13
|
+
level=taboo # "taboo" : in this profile, under no circumstances this field can be stored or rendered in the logs
|
14
|
+
}
|
15
|
+
|
16
|
+
Date_Of_Birth { level=restricted }
|
17
|
+
|
18
|
+
TwoFA_Token {level=confidential, dataType=access}
|
19
|
+
|
20
|
+
Home_City {level=confidential, dataType=location}
|
21
|
+
Home_Country {level=confidential}
|
22
|
+
Home_State {level=confidential} # State or Province
|
23
|
+
Home_Zip {level=confidential} # U.S. ZIP code
|
24
|
+
Name_First {level=confidential}
|
25
|
+
Name_Last {level=internal}
|
26
|
+
Name_Middle {level=public}
|
27
|
+
Name_Full {level=confidential,enabled=true, owner=nameKeeper}
|
28
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# keep this underscore naming in the test subdir, it's easier to append files names to test
|
2
|
+
require './test/test_helper.rb'
|
3
|
+
|
4
|
+
=begin rdoc
|
5
|
+
Unit test cases for the DataMetaPii
|
6
|
+
=end
|
7
|
+
class TestNewGem < Test::Unit::TestCase
|
8
|
+
include DataMetaPiiTests
|
9
|
+
|
10
|
+
# an empty stub for now
|
11
|
+
def setup;
|
12
|
+
@impactConstVals = DataMetaPii::Impact.constants.map{|c| ":#{DataMetaPii::Impact.const_get(c)}"}
|
13
|
+
end
|
14
|
+
|
15
|
+
=begin rdoc
|
16
|
+
Test obtaining a constant list from a module
|
17
|
+
=end
|
18
|
+
def test_constantList
|
19
|
+
v = DataMetaPii::RegKeyVo.new('A_PII_field',
|
20
|
+
{DataMetaPii::RegKeyVo::LEVEL => DataMetaPii::Impact::CONFIDENTIAL, "foo" => "bar", "val" => 123.456})
|
21
|
+
|
22
|
+
L.info(%<Impact constants: #{DataMetaPii::Impact.constants.map{|c| "#{c}=#{DataMetaPii::Impact.const_get(c)}"}.join('; ')}
|
23
|
+
first PII VO created: #{v.to_tree_image(DataMetaPii::INDENT)}
|
24
|
+
>)
|
25
|
+
xcp = assert_raise(ArgumentError) { DataMetaPii::RegKeyVo.new('A_PII_field', {DataMetaPii::RegKeyVo::LEVEL => ''}) }
|
26
|
+
assert(xcp.message.start_with?('Impact level missing or empty in'))
|
27
|
+
|
28
|
+
xcp = assert_raise(ArgumentError) { DataMetaPii::RegKeyVo.new('A_PII_field', {'foo' => 'bar'}) }
|
29
|
+
assert(xcp.message.start_with?('Impact level missing or empty in'))
|
30
|
+
|
31
|
+
xcp = assert_raise(ArgumentError) { DataMetaPii::RegKeyVo.new('A PII field',
|
32
|
+
{DataMetaPii::RegKeyVo::LEVEL => DataMetaPii::Impact::CONFIDENTIAL}) }
|
33
|
+
|
34
|
+
assert(xcp.message.start_with?('Invalid PII key: '))
|
35
|
+
|
36
|
+
xcp = assert_raise(ArgumentError) { DataMetaPii::RegKeyVo.new('A_PII_field',
|
37
|
+
{DataMetaPii::RegKeyVo::LEVEL => :bad_impact_level}) }
|
38
|
+
|
39
|
+
L.info(%<Testing #{:bad_impact_level}: #{xcp.message}\n#{xcp.backtrace.join("\n\t")}\n>)
|
40
|
+
assert(xcp.message.start_with?('Unsupported Impact Level '))
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require './test/test_helper.rb'
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
Test for the DataMetaPii grammars and parsing.
|
5
|
+
|
6
|
+
Assertions: http://ruby-doc.org/stdlib-1.9.3/libdoc/test/unit/rdoc/Test/Unit/Assertions.html
|
7
|
+
=end
|
8
|
+
class TestPiiFmts < Test::Unit::TestCase
|
9
|
+
|
10
|
+
include DataMetaPiiTests
|
11
|
+
|
12
|
+
# loads the fmt grammar and creates the parser instance
|
13
|
+
def setup
|
14
|
+
|
15
|
+
@registryParser = PiiRegistryParser.new
|
16
|
+
@piiAppLinkParser = PiiAppLinkParser.new
|
17
|
+
L.info %<DataMeta PII Registry parser: #{@registryParser.inspect}
|
18
|
+
DataMeta PII App Link parser: #{@piiAppLinkParser.inspect}
|
19
|
+
>
|
20
|
+
end
|
21
|
+
|
22
|
+
=begin rdoc
|
23
|
+
Test Pii Registry DML parsing
|
24
|
+
=end
|
25
|
+
def test_registry_parse
|
26
|
+
ast = DataMetaParse.parse(@registryParser, IO.read('./test/registryShowcase.dmPii'))
|
27
|
+
L.info 'Registry parse start'
|
28
|
+
raise 'Registry File Format parse unsuccessful' unless ast
|
29
|
+
raise ast if ast.is_a?(DataMetaParse::Err)
|
30
|
+
#L.info "AST:\n#{ast.fields.inspect}"
|
31
|
+
#L.info "----------AST:\n#{ast.inspect}"
|
32
|
+
#elems = [ast.items.elements]
|
33
|
+
#elems = [ast.fields]
|
34
|
+
#L.info "===========AST Fields:\n#{elems.inspect}\n==================="
|
35
|
+
ast.fields.elements.each { |f|
|
36
|
+
L.info("PII Key: #{f.pk}: #{f.attrbLst.attrbs.map{|e| "#{e.k}::#{e.v}"}.join('; ')}")
|
37
|
+
}
|
38
|
+
L.info(%<PII Registry:
|
39
|
+
#{DataMetaPii.buildRegCst(ast).to_tree_image(DataMetaPii::INDENT)}>)
|
40
|
+
end
|
41
|
+
|
42
|
+
=begin rdoc
|
43
|
+
Test Pii Registry DML parsing and structuring - full version
|
44
|
+
=end
|
45
|
+
def test_app_link_parse_full
|
46
|
+
L.info 'Full applink parse start'
|
47
|
+
ast = DataMetaParse.parse(@piiAppLinkParser, IO.read('./test/appLinkFull.dmPii'))
|
48
|
+
raise 'Full AppLink parse unsuccessful' unless ast
|
49
|
+
if ast.is_a?(DataMetaParse::Err)
|
50
|
+
raise %<#{ast.parser.failure_line}
|
51
|
+
#{ast.parser.failure_reason}>
|
52
|
+
end
|
53
|
+
#L.info "AST:\n#{ast.fields.inspect}"
|
54
|
+
#L.info "----------AST:\n#{ast.inspect}"
|
55
|
+
#elems = [ast.items.elements]
|
56
|
+
#elems = [ast.fields]
|
57
|
+
#L.info "===========AST Fields:\n#{elems.inspect}\n==================="
|
58
|
+
ast.elements[1].elements.each { |f|
|
59
|
+
if f.respond_to?(:type) && f.type == 'refVal'
|
60
|
+
L.info(%<refVal: #{f.sym}>)
|
61
|
+
else
|
62
|
+
L.info(%<AppLink Elem: #{f.inspect}>)
|
63
|
+
end
|
64
|
+
}
|
65
|
+
ast.elements[3].elements.each { |f|
|
66
|
+
if f.respond_to?(:type) && f.type == 'refVal'
|
67
|
+
L.info(%<refVal: #{f.sym}>)
|
68
|
+
else
|
69
|
+
L.info(%<AppLink Elem: #{f.inspect}>)
|
70
|
+
end
|
71
|
+
}
|
72
|
+
log = ''
|
73
|
+
appLinkObj = DataMetaPii.buildAlCst(ast, log)
|
74
|
+
|
75
|
+
L.info(%<AppLink Full:
|
76
|
+
#{appLinkObj}
|
77
|
+
Building log:
|
78
|
+
#{log}
|
79
|
+
>)#.to_tree_image(DataMetaPii::INDENT_STEP)}>)
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_app_link_parse_method
|
84
|
+
appLinkModel = DataMetaPii.parseAppLink(IO.read('./test/appLinkFull.dmPii'))
|
85
|
+
L.info(%<AppLink Model - full:
|
86
|
+
#{appLinkModel.inspect}>)
|
87
|
+
end
|
88
|
+
|
89
|
+
=begin rdoc
|
90
|
+
Test Pii Registry DML parsing - showcase version, do not run this tree through CST builder!
|
91
|
+
=end
|
92
|
+
def test_app_link_parse_showcase
|
93
|
+
L.info 'Showcase applink parse start'
|
94
|
+
ast = DataMetaParse.parse(@piiAppLinkParser, IO.read('./test/appLinkShowcase.dmPii'))
|
95
|
+
raise 'Showcase File Format parse unsuccessful' unless ast
|
96
|
+
if ast.is_a?(DataMetaParse::Err)
|
97
|
+
raise %<#{ast.parser.failure_line}
|
98
|
+
#{ast.parser.failure_reason}>
|
99
|
+
end
|
100
|
+
#L.info "AST:\n#{ast.fields.inspect}"
|
101
|
+
#L.info "----------AST:\n#{ast.inspect}"
|
102
|
+
#elems = [ast.items.elements]
|
103
|
+
#elems = [ast.fields]
|
104
|
+
#L.info "===========AST Fields:\n#{elems.inspect}\n==================="
|
105
|
+
ast.elements[1].elements.each { |f|
|
106
|
+
if f.respond_to?(:type) && f.type == 'refVal'
|
107
|
+
L.info(%<refVal: #{f.sym}>)
|
108
|
+
else
|
109
|
+
L.info(%<AppLink Elem: #{f.inspect}>)
|
110
|
+
end
|
111
|
+
}
|
112
|
+
ast.elements[3].elements.each { |f|
|
113
|
+
if f.respond_to?(:type) && f.type == 'refVal'
|
114
|
+
L.info(%<refVal: #{f.sym}>)
|
115
|
+
else
|
116
|
+
L.info(%<AppLink Elem: #{f.inspect}>)
|
117
|
+
end
|
118
|
+
}
|
119
|
+
end
|
120
|
+
|
121
|
+
=begin rdoc
|
122
|
+
Test Pii Registry DML parsing - version with no reusables, must be successfully processed by the CST builder
|
123
|
+
=end
|
124
|
+
def test_app_link_parse_no_reusables
|
125
|
+
L.info 'No-reusables applink parse start'
|
126
|
+
ast = DataMetaParse.parse(@piiAppLinkParser, IO.read('./test/appLinkNoReusables.dmPii'))
|
127
|
+
raise 'No-reusables File Format parse unsuccessful' unless ast
|
128
|
+
if ast.is_a?(DataMetaParse::Err)
|
129
|
+
raise %<#{ast.parser.failure_line}
|
130
|
+
#{ast.parser.failure_reason}>
|
131
|
+
end
|
132
|
+
#L.info "AST:\n#{ast.fields.inspect}"
|
133
|
+
#L.info "----------AST:\n#{ast.inspect}"
|
134
|
+
#elems = [ast.items.elements]
|
135
|
+
#elems = [ast.fields]
|
136
|
+
#L.info "===========AST Fields:\n#{elems.inspect}\n==================="
|
137
|
+
ast.elements[0].elements.each { |f|
|
138
|
+
if f.respond_to?(:type) && f.type == 'refVal'
|
139
|
+
L.info(%<refVal: #{f.sym}>)
|
140
|
+
else
|
141
|
+
L.info(%<AppLink Elem: #{f.inspect}>)
|
142
|
+
end
|
143
|
+
}
|
144
|
+
log = ''
|
145
|
+
applinkObj = DataMetaPii.buildAlCst(ast, log)
|
146
|
+
L.info(%<AppLink No Reusables:
|
147
|
+
#{applinkObj.inspect}
|
148
|
+
Building log:
|
149
|
+
#{log}
|
150
|
+
>)#.to_tree_image(DataMetaPii::INDENT_STEP)}>)
|
151
|
+
end
|
152
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## keep this underscore naming in the test subdir, it's easier to append files names to test
|
2
|
+
%w(stringio test/unit).each { |r| require r }
|
3
|
+
# this is expected to run from the project root, normally by the rake file
|
4
|
+
|
5
|
+
$VERBOSE = false # turn off noisy for the 1st release
|
6
|
+
|
7
|
+
require './lib/dataMetaPii'
|
8
|
+
require 'logger'
|
9
|
+
require 'dataMetaParse'
|
10
|
+
|
11
|
+
module DataMetaPiiTests
|
12
|
+
|
13
|
+
L = Logger.new('piiTests.log', 0, 10_000_000)
|
14
|
+
L.level = Logger::DEBUG
|
15
|
+
L.datetime_format = '%Y-%m-%d %H:%M:%S'
|
16
|
+
|
17
|
+
# By the way, inspecting a parser does not make any difference compared to just to_s:
|
18
|
+
L.info(%<Loaded base rules: #{DataMetaPii::BASE_RULES}
|
19
|
+
|
20
|
+
Loaded PII Commons Rules: #{DataMetaPii::PII_COMMONS.inspect}
|
21
|
+
Loaded Regstry Rules: #{DataMetaPii::REGISTRY}
|
22
|
+
Loaded AppLink Rules: #{DataMetaPii::APP_LINK}
|
23
|
+
>)
|
24
|
+
end
|
data/tpl/java/master.erb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
package <%= namespace %>;
|
2
|
+
|
3
|
+
/*
|
4
|
+
**************** This file is generated by DataMeta; do not edit manually!!
|
5
|
+
*/
|
6
|
+
|
7
|
+
import java.util.HashMap;
|
8
|
+
import java.util.Map;
|
9
|
+
|
10
|
+
import static java.util.Collections.unmodifiableMap;
|
11
|
+
|
12
|
+
/**
|
13
|
+
* The encapsulation of the version <%= reg.ver %> of the Abstract PII definition.
|
14
|
+
*/
|
15
|
+
public class <%= className %> {
|
16
|
+
<% reg.keyVos.keys.sort.each { |k| fldName = k.to_s.inspect; %>
|
17
|
+
public final static String <%= k.to_s %> = <%=fldName%>;
|
18
|
+
<%}%>
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Impact Levels:
|
22
|
+
*/
|
23
|
+
public static enum Level {
|
24
|
+
<%= (codeIndent * 3)[0..-2] %><%= ALL_IMPACTS.map{|i| i.to_s.upcase}.join(",\n#{(codeIndent * 3)[0..-2]}") %>
|
25
|
+
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* One abstract key definition encapsulation.
|
30
|
+
*/
|
31
|
+
public static class Def {
|
32
|
+
private final String key;
|
33
|
+
private final Level level;
|
34
|
+
private final Map<String, String> props;
|
35
|
+
|
36
|
+
public Def(String key, final Level level, final Map<String, String> props) {
|
37
|
+
this.key = key;
|
38
|
+
this.level = level;
|
39
|
+
this.props = props;
|
40
|
+
}
|
41
|
+
|
42
|
+
public Level getLevel() { return level; }
|
43
|
+
|
44
|
+
public Map<String, String> getProps() { return props; }
|
45
|
+
|
46
|
+
public String getKey() { return key; }
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* The map keyed by field name pointing to the matching instance of the {@link Def} class.
|
51
|
+
*/
|
52
|
+
public static final Map<String, Def> DEFS = unmodifiableMap(new HashMap<String, Def>() {
|
53
|
+
{
|
54
|
+
<% reg.keyVos.keys.sort.each { |k| fldName = k.to_s; fldDef = reg.keyVos[k] %>
|
55
|
+
put(<%= fldName %>, new Def(<%= fldName %>, Level.<%= fldDef.level.to_s.upcase %>, unmodifiableMap(new HashMap<String, String>() {
|
56
|
+
{<% fldDef.attrs.keys.sort.each {|k| keyStr = k.to_s.inspect; valStr = fldDef.attrs[k].inspect %>
|
57
|
+
put(<%=keyStr%>, <%=valStr%>); <% } %>
|
58
|
+
}
|
59
|
+
})));
|
60
|
+
<% } %>
|
61
|
+
}
|
62
|
+
});
|
63
|
+
}
|
64
|
+
|