diff --git a/lib/functions.js b/lib/functions.js index eae5ed9..fcc480d 100644 --- a/lib/functions.js +++ b/lib/functions.js @@ -322,9 +322,9 @@ const f = { for(var key in from.properties) { var field =from.properties[key] if(!field['x-form-ignore']) { - var fieldType = field['x-form-type'] ? field['x-form-type'] : field.type - var placeholder = field['x-form-placeholder'] ? field['x-form-placeholder'] : key - var label = field['x-form-label'] ? field['x-form-label'] : key + var fieldType = field['x-form-type'] || field.type + var placeholder = field['x-form-placeholder'] || key + var label = field['x-form-label'] || key var visible = field['x-form-visible'] var hint = field['x-form-hint'] var required = field['x-form-required'] diff --git a/lib/generator.js b/lib/generator.js index 58d682e..ffc9026 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -1,4 +1,5 @@ const fs = require('fs') +const path = require('path') /** Class representing the sling model generator */ class Generator { @@ -22,18 +23,57 @@ class Generator { * @return {string} the template */ function makeInitial(srcData, generator) { - var template = srcData.replace(/{{.*?}}/g, function(str, p1, offset, s) { + let definitions = generator.data.definitions[generator.data.modelName] + let properties = definitions.properties + var data = { + imports: genImports(properties), + ...generator.data + } + + var template = srcData.replace(/{{.*?}}/g, function(str, _, _, _) { var key = str.trim().slice(2,str.trim().length-2).trim() - var ret = generator.data[key] - if(!ret) { + var ret = data[key] + if(ret === null || ret === undefined) { console.log('missing property:', key) - ret = '!!!'+key+'!!' + ret = `!!!${key}!!` } + return ret }) + return template } +function genImportsSet(properties, target) { + for(var propName in properties) { + var props = properties[propName] + var annotate = props['x-annotate'] + if (propName !== 'children') { + if(props['x-source'] == 'inject' && annotate) { + forEachSizeAnnotation(annotate, _ => {console.log(`${propName}: ${JSON.stringify(props)}`) + target.add('com.peregrine.model.api.ImageInfo') + target.add('java.awt.Dimension') + }) + } else if(props['x-form-type'] === 'reference') { + genImportsSet(props.properties, target) + } + } + } + + return target +} + +function genImports(properties) { + return Array.from(genImportsSet(properties, new Set())) + .reduce((all, next) => `${all}import ${next};\n`, '') +} + +function forEachSizeAnnotation(crudeValues, callback) { + (typeof crudeValues === 'string' ? [crudeValues] : crudeValues) + .filter(a => a === 'size') + .forEach(callback) +} + /** * Used in the gen function and applies all of the inject properties * @param {string} properties - the properties from the model JSON @@ -41,33 +81,42 @@ function makeInitial(srcData, generator) { */ function genNames(properties) { inject = '' - for(var prop in properties) { - var propName = prop; + for(var propName in properties) { if (propName !== 'children') { var props = properties[propName] - if(props['x-source'] == 'inject') { - inject += '\t/* '+JSON.stringify(props)+' */\n' + if(props['x-source'] === 'inject') { + inject += `\t/* ${JSON.stringify(props)} */\n` inject += '\t@Inject\n' - if(props['x-sourceName']) { - inject += '\t@Named(value ="'+props['x-sourceName']+'")\n' + + var sourceName = props['x-sourceName']; + if(sourceName) { + inject += `\t@Named(value ="${sourceName}")\n` } - if(props['x-default'] === "" || props['x-default']) { - inject += '\t@Default(values ="'+props['x-default']+'")\n' + + var x_default = props['x-default']; + if(x_default === "" || x_default) { + inject += `\t@Default(values ="${x_default}")\n` } - if(props['x-form-type'] === ('collection')) { + if(props['x-form-type'] === 'collection') { if (Object.keys(props['properties']).length > 1 || props['x-form-multifield'] === "true" || props['x-form-multifield'] === true) { - inject += '\tprivate List ' + var collectionType = props['x-collection-type'] + if (collectionType) { + inject += `\tprivate List<${collectionType}Model> ` + } else { + inject += '\tprivate List ' + } } else { inject += '\tprivate String[] ' } } else { inject += '\tprivate String ' } - inject += propName - inject += ';' - inject += '\n' - inject += '\n' - } else if(props['x-form-type'] === ('reference')) { + inject += `${propName};\n\n` + var annotate = props['x-annotate'] + if (annotate) { + inject += genNamesAnnotates(propName, annotate) + } + } else if(props['x-form-type'] === 'reference') { inject += genNames(props.properties) } } @@ -75,6 +124,17 @@ function genNames(properties) { return inject } +function genNamesAnnotates(ownerName, annotate) { + var result = '' + forEachSizeAnnotation(annotate, _ => { + result = '\t@Inject\n' + result += `\t@ImageInfo(name="${ownerName}")\n` + result += `\tprivate Dimension ${ownerName}Size;\n\n` + }) + + return result +} + /** * Used in the gen function and applies all of the getter methods. Has additional functionality to retain any custom getter methods * @param {string} properties - the properties from the model JSON @@ -83,27 +143,33 @@ function genNames(properties) { */ function genGetters(properties, customGetters) { inject = '' - for(var prop in properties) { - var propName = prop; + for(var propName in properties) { var getterName = propName.charAt(0).toUpperCase()+propName.slice(1) - if (propName !== 'children' && (customGetters === null || !customGetters.includes('public String get' + getterName + '()'))) { + if (propName !== 'children' && (customGetters === null || !customGetters.includes(`public String get${getterName}()`))) { var props = properties[propName] if(props['x-source'] == 'inject') { - inject += '\t/* '+JSON.stringify(props)+' */\n' - if(props['x-form-type'] === ('collection')) { + inject += `\t/* ${JSON.stringify(props)} */\n` + if(props['x-form-type'] === 'collection') { if (Object.keys(props['properties']).length > 1 || props['x-form-multifield'] === "true" || props['x-form-multifield'] === true) { - inject += '\tpublic List get' + var collectionType = props['x-collection-type'] + if (collectionType) { + inject += `\tpublic List<${collectionType}Model> get` + } else { + inject += '\tpublic List get' + } } else { inject += '\tpublic String[] get' } } else { inject += '\tpublic String get' } - inject += getterName + '() {\n' - inject += '\t\treturn '+propName+';\n' - inject += '\t}' - inject += '\n' - inject += '\n' + inject += `${getterName}() {\n` + inject += `\t\treturn ${propName};\n` + inject += '\t}\n\n' + var annotate = props['x-annotate'] + if (annotate) { + inject += genGettersAnnotates(propName, annotate) + } } else if(props['x-form-type'] === ('reference')) { inject += genGetters(props.properties, customGetters) } @@ -112,16 +178,56 @@ function genGetters(properties, customGetters) { return inject } +function genGettersAnnotates(ownerName, annotate) { + var result = '' + forEachSizeAnnotation(annotate, _ => { + result += `\tpublic Dimension get${ownerName.charAt(0).toUpperCase()}${ownerName.slice(1)}Size() {\n` + result += `\t\treturn ${ownerName}Size;\n` + result += '\t}\n\n' + }) + + return result +} + +function genTypes(properties, generator) { + for(var propName in properties) { + if (propName !== 'children') { + var props = properties[propName] + if(props['x-source'] === 'inject') { + if(props['x-form-type'] === 'collection') { + if (Object.keys(props['properties']).length > 1 || props['x-form-multifield'] === "true" || props['x-form-multifield'] === true) { + var collectionType = props['x-collection-type'] + if (collectionType) { + var { data } = generator + var { componentPath, package, classNameParent } = data + gen(new Generator(generator.src, path.join(path.dirname(generator.dst), `${collectionType}Model.java`), { + name: collectionType, + modelName: collectionType, + componentPath: `${componentPath}/${propName}`, + package, + classNameParent, + definitions: { + [collectionType]: props + } + })) + } + } + } + } + } + } + +} + /** * Loads in the sling model template and fills in the data, inject, and getters content to make the components model * @param {string} generator - the generator object */ function gen(generator) { - // load the template var srcData = fs.readFileSync(generator.src).toString() - // now substitute all the values we know into the template + // substitute all the values we know into the template srcData = makeInitial(srcData, generator) // if the generated file does not exist yet, create it with the template we just created @@ -147,17 +253,18 @@ function gen(generator) { return str }) + let definitions = generator.data.definitions[generator.data.modelName]; + let properties = definitions.properties; for(key in fragments) { var name = key.split(':')[1] var inject = '' - let data = generator.data.definitions[generator.data.modelName]; if('DATA' === name) { inject = JSON.stringify(generator.data, true, 2) } else if('INJECT' === name) { - inject = genNames(data.properties) + inject = genNames(properties) } else if('GETTERS' === name) { - inject = genGetters(data.properties, customGetters) + inject = genGetters(properties, customGetters) } fragments[key] = fragments[key].replace('//GEN]', inject+'\n//GEN]') @@ -183,6 +290,8 @@ function gen(generator) { } catch(error) { fs.writeFileSync(generator.dst, dstCurrent) } + + genTypes(properties, generator) } module.exports = { diff --git a/lib/htmltovue.js b/lib/htmltovue.js index 1e7f5cc..8928f53 100644 --- a/lib/htmltovue.js +++ b/lib/htmltovue.js @@ -90,7 +90,6 @@ function htmltovue(name, container, compile, deploy, dialog, model, vue, samplee const projectName = settings.appname - let templatePath = templates.getPath() let projectPath = process.cwd() // should check that we are in the root of the project // console.log('template path:',templatePath) diff --git a/templates/model.java.template.java b/templates/model.java.template.java index 6d56b98..32f6724 100644 --- a/templates/model.java.template.java +++ b/templates/model.java.template.java @@ -13,6 +13,8 @@ import javax.inject.Inject; import javax.inject.Named; +{{ imports }} + /* //GEN[:DATA //GEN] @@ -32,7 +34,7 @@ //GEN] public class {{ modelName }}Model extends {{ classNameParent }} { - public {{ modelName }}Model(Resource r) { super(r); } + public {{ modelName }}Model(final Resource r) { super(r); } //GEN[:INJECT //GEN]