11const fs = require ( 'fs' )
2+ const path = require ( 'path' )
23
34/** Class representing the sling model generator */
45class Generator {
@@ -22,59 +23,118 @@ class Generator {
2223 * @return {string } the template
2324*/
2425function makeInitial ( srcData , generator ) {
25- var template = srcData . replace ( / { { .* ?} } / g, function ( str , p1 , offset , s ) {
26+ let definitions = generator . data . definitions [ generator . data . modelName ]
27+ let properties = definitions . properties
28+ var data = {
29+ imports : genImports ( properties ) ,
30+ ...generator . data
31+ }
32+
33+ var template = srcData . replace ( / { { .* ?} } / g, function ( str , _ , _ , _ ) {
2634 var key = str . trim ( ) . slice ( 2 , str . trim ( ) . length - 2 ) . trim ( )
27- var ret = generator . data [ key ]
28- if ( ! ret ) {
35+ var ret = data [ key ]
36+ if ( ret === null || ret === undefined ) {
2937 console . log ( 'missing property:' , key )
30- ret = ' !!!' + key + '!!'
38+ ret = ` !!!${ key } !!`
3139 }
40+
3241 return ret
3342 } )
43+
3444 return template
3545}
3646
47+ function genImportsSet ( properties , target ) {
48+ for ( var propName in properties ) {
49+ var props = properties [ propName ]
50+ var annotate = props [ 'x-annotate' ]
51+ if ( propName !== 'children' ) {
52+ if ( props [ 'x-source' ] == 'inject' && annotate ) {
53+ forEachSizeAnnotation ( annotate , _ => { console . log ( `${ propName } : ${ JSON . stringify ( props ) } ` )
54+ target . add ( 'com.peregrine.model.api.ImageInfo' )
55+ target . add ( 'java.awt.Dimension' )
56+ } )
57+ } else if ( props [ 'x-form-type' ] === 'reference' ) {
58+ genImportsSet ( props . properties , target )
59+ }
60+ }
61+ }
62+
63+ return target
64+ }
65+
66+ function genImports ( properties ) {
67+ return Array . from ( genImportsSet ( properties , new Set ( ) ) )
68+ . reduce ( ( all , next ) => `${ all } import ${ next } ;\n` , '' )
69+ }
70+
71+ function forEachSizeAnnotation ( crudeValues , callback ) {
72+ ( typeof crudeValues === 'string' ? [ crudeValues ] : crudeValues )
73+ . filter ( a => a === 'size' )
74+ . forEach ( callback )
75+ }
76+
3777/**
3878 * Used in the gen function and applies all of the inject properties
3979 * @param {string } properties - the properties from the model JSON
4080 * @return {string } the inject string block
4181*/
4282function genNames ( properties ) {
4383 inject = ''
44- for ( var prop in properties ) {
45- var propName = prop ;
84+ for ( var propName in properties ) {
4685 if ( propName !== 'children' ) {
4786 var props = properties [ propName ]
48- if ( props [ 'x-source' ] == 'inject' ) {
49- inject += ' \t/* ' + JSON . stringify ( props ) + ' */\n'
87+ if ( props [ 'x-source' ] === 'inject' ) {
88+ inject += ` \t/* ${ JSON . stringify ( props ) } */\n`
5089 inject += '\t@Inject\n'
51- if ( props [ 'x-sourceName' ] ) {
52- inject += '\t@Named(value ="' + props [ 'x-sourceName' ] + '")\n'
90+
91+ var sourceName = props [ 'x-sourceName' ] ;
92+ if ( sourceName ) {
93+ inject += `\t@Named(value ="${ sourceName } ")\n`
5394 }
54- if ( props [ 'x-default' ] === "" || props [ 'x-default' ] ) {
55- inject += '\t@Default(values ="' + props [ 'x-default' ] + '")\n'
95+
96+ var x_default = props [ 'x-default' ] ;
97+ if ( x_default === "" || x_default ) {
98+ inject += `\t@Default(values ="${ x_default } ")\n`
5699 }
57- if ( props [ 'x-form-type' ] === ( 'collection' ) ) {
100+ if ( props [ 'x-form-type' ] === 'collection' ) {
58101 if ( Object . keys ( props [ 'properties' ] ) . length > 1 || props [ 'x-form-multifield' ] === "true" || props [ 'x-form-multifield' ] === true ) {
59- inject += '\tprivate List<IComponent> '
102+ var collectionType = props [ 'x-collection-type' ]
103+ if ( collectionType ) {
104+ inject += `\tprivate List<${ collectionType } Model> `
105+ } else {
106+ inject += '\tprivate List<IComponent> '
107+ }
60108 } else {
61109 inject += '\tprivate String[] '
62110 }
63111 } else {
64112 inject += '\tprivate String '
65113 }
66- inject += propName
67- inject += ';'
68- inject += '\n'
69- inject += '\n'
70- } else if ( props [ 'x-form-type' ] === ( 'reference' ) ) {
114+ inject += `${ propName } ;\n\n`
115+ var annotate = props [ 'x-annotate' ]
116+ if ( annotate ) {
117+ inject += genNamesAnnotates ( propName , annotate )
118+ }
119+ } else if ( props [ 'x-form-type' ] === 'reference' ) {
71120 inject += genNames ( props . properties )
72121 }
73122 }
74123 }
75124 return inject
76125}
77126
127+ function genNamesAnnotates ( ownerName , annotate ) {
128+ var result = ''
129+ forEachSizeAnnotation ( annotate , _ => {
130+ result = '\t@Inject\n'
131+ result += `\t@ImageInfo(name="${ ownerName } ")\n`
132+ result += `\tprivate Dimension ${ ownerName } Size;\n\n`
133+ } )
134+
135+ return result
136+ }
137+
78138/**
79139 * Used in the gen function and applies all of the getter methods. Has additional functionality to retain any custom getter methods
80140 * @param {string } properties - the properties from the model JSON
@@ -83,27 +143,33 @@ function genNames(properties) {
83143*/
84144function genGetters ( properties , customGetters ) {
85145 inject = ''
86- for ( var prop in properties ) {
87- var propName = prop ;
146+ for ( var propName in properties ) {
88147 var getterName = propName . charAt ( 0 ) . toUpperCase ( ) + propName . slice ( 1 )
89- if ( propName !== 'children' && ( customGetters === null || ! customGetters . includes ( ' public String get' + getterName + '()' ) ) ) {
148+ if ( propName !== 'children' && ( customGetters === null || ! customGetters . includes ( ` public String get${ getterName } ()` ) ) ) {
90149 var props = properties [ propName ]
91150 if ( props [ 'x-source' ] == 'inject' ) {
92- inject += ' \t/* ' + JSON . stringify ( props ) + ' */\n'
93- if ( props [ 'x-form-type' ] === ( 'collection' ) ) {
151+ inject += ` \t/* ${ JSON . stringify ( props ) } */\n`
152+ if ( props [ 'x-form-type' ] === 'collection' ) {
94153 if ( Object . keys ( props [ 'properties' ] ) . length > 1 || props [ 'x-form-multifield' ] === "true" || props [ 'x-form-multifield' ] === true ) {
95- inject += '\tpublic List<IComponent> get'
154+ var collectionType = props [ 'x-collection-type' ]
155+ if ( collectionType ) {
156+ inject += `\tpublic List<${ collectionType } Model> get`
157+ } else {
158+ inject += '\tpublic List<IComponent> get'
159+ }
96160 } else {
97161 inject += '\tpublic String[] get'
98162 }
99163 } else {
100164 inject += '\tpublic String get'
101165 }
102- inject += getterName + '() {\n'
103- inject += '\t\treturn ' + propName + ';\n'
104- inject += '\t}'
105- inject += '\n'
106- inject += '\n'
166+ inject += `${ getterName } () {\n`
167+ inject += `\t\treturn ${ propName } ;\n`
168+ inject += '\t}\n\n'
169+ var annotate = props [ 'x-annotate' ]
170+ if ( annotate ) {
171+ inject += genGettersAnnotates ( propName , annotate )
172+ }
107173 } else if ( props [ 'x-form-type' ] === ( 'reference' ) ) {
108174 inject += genGetters ( props . properties , customGetters )
109175 }
@@ -112,16 +178,56 @@ function genGetters(properties, customGetters) {
112178 return inject
113179}
114180
181+ function genGettersAnnotates ( ownerName , annotate ) {
182+ var result = ''
183+ forEachSizeAnnotation ( annotate , _ => {
184+ result += `\tpublic Dimension get${ ownerName . charAt ( 0 ) . toUpperCase ( ) } ${ ownerName . slice ( 1 ) } Size() {\n`
185+ result += `\t\treturn ${ ownerName } Size;\n`
186+ result += '\t}\n\n'
187+ } )
188+
189+ return result
190+ }
191+
192+ function genTypes ( properties , generator ) {
193+ for ( var propName in properties ) {
194+ if ( propName !== 'children' ) {
195+ var props = properties [ propName ]
196+ if ( props [ 'x-source' ] === 'inject' ) {
197+ if ( props [ 'x-form-type' ] === 'collection' ) {
198+ if ( Object . keys ( props [ 'properties' ] ) . length > 1 || props [ 'x-form-multifield' ] === "true" || props [ 'x-form-multifield' ] === true ) {
199+ var collectionType = props [ 'x-collection-type' ]
200+ if ( collectionType ) {
201+ var { data } = generator
202+ var { componentPath, package, classNameParent } = data
203+ gen ( new Generator ( generator . src , path . join ( path . dirname ( generator . dst ) , `${ collectionType } Model.java` ) , {
204+ name : collectionType ,
205+ modelName : collectionType ,
206+ componentPath : `${ componentPath } /${ propName } ` ,
207+ package,
208+ classNameParent,
209+ definitions : {
210+ [ collectionType ] : props
211+ }
212+ } ) )
213+ }
214+ }
215+ }
216+ }
217+ }
218+ }
219+
220+ }
221+
115222/**
116223 * Loads in the sling model template and fills in the data, inject, and getters content to make the components model
117224 * @param {string } generator - the generator object
118225*/
119226function gen ( generator ) {
120-
121227 // load the template
122228 var srcData = fs . readFileSync ( generator . src ) . toString ( )
123229
124- // now substitute all the values we know into the template
230+ // substitute all the values we know into the template
125231 srcData = makeInitial ( srcData , generator )
126232
127233 // if the generated file does not exist yet, create it with the template we just created
@@ -147,17 +253,18 @@ function gen(generator) {
147253 return str
148254 } )
149255
256+ let definitions = generator . data . definitions [ generator . data . modelName ] ;
257+ let properties = definitions . properties ;
150258 for ( key in fragments ) {
151259 var name = key . split ( ':' ) [ 1 ]
152260 var inject = ''
153261
154- let data = generator . data . definitions [ generator . data . modelName ] ;
155262 if ( 'DATA' === name ) {
156263 inject = JSON . stringify ( generator . data , true , 2 )
157264 } else if ( 'INJECT' === name ) {
158- inject = genNames ( data . properties )
265+ inject = genNames ( properties )
159266 } else if ( 'GETTERS' === name ) {
160- inject = genGetters ( data . properties , customGetters )
267+ inject = genGetters ( properties , customGetters )
161268 }
162269
163270 fragments [ key ] = fragments [ key ] . replace ( '//GEN]' , inject + '\n//GEN]' )
@@ -183,6 +290,8 @@ function gen(generator) {
183290 } catch ( error ) {
184291 fs . writeFileSync ( generator . dst , dstCurrent )
185292 }
293+
294+ genTypes ( properties , generator )
186295}
187296
188297module . exports = {
0 commit comments