| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * |
| */ |
| |
| var generators = require('yeoman-generator'); |
| var fs = require('fs'); |
| |
| var polygeneVersion = require(__dirname + '/../package.json').polygene_version; |
| |
| var polygene = {}; |
| |
| module.exports = generators.Base.extend( |
| { |
| constructor: function () { |
| console.log("WARNING!!! This is BETA quality and likely to change drastically over time. "); // + JSON.stringify(arguments)); |
| generators.Base.apply(this, arguments); |
| |
| this.option('import-model', { |
| name: "import", |
| desc: 'Reads a model file and creates the domain model for it.', |
| type: String, |
| default: "./model.json", |
| hide: false |
| }); |
| |
| this.option('export-model', { |
| name: "export", |
| desc: 'Writes the model of the application into a json file.', |
| type: String, |
| default: "exported-model", |
| hide: false |
| }); |
| |
| this.option('noPrompt', { |
| name: "noPrompt", |
| desc: 'If specified, the interactive prompts will be disabled.', |
| type: Boolean, |
| default: false, |
| hide: false |
| }); |
| |
| if (this.options.import) { |
| polygene = importModel(this.options.import); |
| polygene.name = polygene.name ? polygene.name : firstUpper(this.appname); |
| polygene.packageName = polygene.packageName ? polygene.packageName : ("com.acme." + this.appname); |
| polygene.applicationtype = "Rest API"; |
| polygene.features = polygene.features ? polygene.features : []; |
| polygene.modules = polygene.modules ? polygene.modules : {}; |
| polygene.indexing = polygene.indexing ? polygene.indexing : null; |
| polygene.entitystore = polygene.entitystore ? polygene.entitystore : null; |
| polygene.caching = polygene.caching ? polygene.caching : null; |
| polygene.dbpool = polygene.dbpool === undefined ? "DBCP" : answers.dbpool; |
| } |
| }, |
| |
| prompting: function () { |
| if (this.options.noPrompt) { |
| return this.prompt([]); |
| } |
| else { |
| return this.prompt( |
| [ |
| { |
| type: 'input', |
| name: 'name', |
| message: 'Your project name', |
| default: polygene.name ? polygene.name : firstUpper(this.appname) |
| }, |
| { |
| type: 'input', |
| name: 'packageName', |
| message: 'Java package name', |
| default: polygene.packageName ? polygene.packageName : "com.acme" |
| }, |
| { |
| type: 'list', |
| name: 'applicationtype', |
| choices: [ |
| 'Command Line', |
| // 'Web Application', |
| 'Rest API' |
| ], |
| message: 'what type of application do you want to create?', |
| default: polygene.applicationtype ? polygene.applicationtype : "Rest API" |
| }, |
| { |
| type: 'list', |
| name: 'entitystore', |
| choices: [ |
| 'Cassandra', |
| 'File', |
| 'DerbySQL', |
| 'Geode', |
| 'H2SQL', |
| 'Hazelcast', |
| 'JClouds', |
| 'Jdbm', |
| 'LevelDB', |
| 'Memory', |
| 'MongoDB', |
| 'MySQL', |
| 'Preferences', |
| 'Redis', |
| 'Riak', |
| 'PostgreSQL', |
| 'SQLite' |
| ], |
| message: 'Which entity store do you want to use?', |
| default: polygene.entitystore ? polygene.entitystore : "Memory" |
| }, |
| { |
| type: 'list', |
| name: 'dbpool', |
| choices: [ |
| 'BoneCP', |
| 'DBCP' |
| ], |
| message: 'Which connection pool do you want to use?', |
| default: polygene.dbpool ? polygene.dbpool : "DBCP", |
| when: function (answers) { |
| return answers.entitystore.indexOf('SQL') > -1; |
| } |
| }, |
| { |
| type: 'list', |
| name: 'indexing', |
| choices: [ |
| 'Rdf', |
| 'ElasticSearch', |
| 'Solr', |
| 'SQL' |
| ], |
| message: 'Which indexing system do you want to use?', |
| default: polygene.indexing ? polygene.indexing : "Rdf" |
| }, |
| { |
| type: 'list', |
| name: 'caching', |
| choices: [ |
| 'None', |
| 'Memcache', |
| 'EhCache' |
| ], |
| message: 'Which caching system do you want to use?', |
| default: polygene.caching ? polygene.caching : "None" |
| }, |
| { |
| type: 'list', |
| name: 'metrics', |
| choices: [ |
| 'None', |
| 'Codahale' |
| ], |
| message: 'Which metrics capturing system do you want to use?', |
| default: polygene.metrics ? polygene.metrics : "None" |
| }, |
| { |
| type: 'checkbox', |
| name: 'features', |
| choices: [ |
| // 'alarms' |
| // 'circuit breakers' |
| 'envisage', |
| // 'file transactions' |
| // 'logging' |
| 'jmx', |
| // 'spring integration' |
| // 'scheduling' |
| 'mixin scripting', |
| 'security' |
| // ,'version migration' |
| ], |
| message: 'Other features?', |
| default: polygene.features ? polygene.features : [] |
| } |
| ] |
| ).then(function (answers) { |
| this.log('app name', answers.name); |
| this.log('Entity Stores:', answers.entitystore); |
| this.log('Indexing:', answers.indexing); |
| this.log('Caching:', answers.caching); |
| this.log('Metrics:', answers.metrics); |
| this.log('Features:', answers.features); |
| polygene.name = answers.name; |
| polygene.packageName = answers.packageName; |
| polygene.applicationtype = answers.applicationtype; |
| polygene.features = answers.features; |
| polygene.indexing = answers.indexing; |
| polygene.entitystore = answers.entitystore; |
| polygene.dbpool = answers.dbpool === undefined ? "DBCP" : answers.dbpool; |
| polygene.metrics = answers.metrics; |
| polygene.caching = answers.caching; |
| }.bind(this) |
| ); |
| } |
| }, |
| |
| writing: function () { |
| try { |
| polygene.version = polygeneVersion; |
| polygene.entitystoremodule = polygene.entitystore.toLowerCase(); |
| if (polygene.entitystore === "DerbySQL") { |
| polygene.entitystoremodule = "sql"; |
| } |
| if (polygene.entitystore === "H2SQL") { |
| polygene.entitystoremodule = "sql"; |
| } |
| if (polygene.entitystore === "MySQL") { |
| polygene.entitystoremodule = "sql"; |
| } |
| if (polygene.entitystore === "PostgreSQL") { |
| polygene.entitystoremodule = "sql"; |
| } |
| if (polygene.entitystore === "SQLite") { |
| polygene.entitystoremodule = "sql"; |
| } |
| assignFunctions(polygene); |
| polygene.javaPackageDir = polygene.packageName.replace(/[.]/g, '/'); |
| polygene.ctx = this; |
| var app = require(__dirname + '/templates/' + polygene.applicationtype.replace(/ /g, '') + 'Application/app.js'); |
| app.write(polygene); |
| var buildToolChain = require(__dirname + '/templates/buildtool/build.js'); |
| buildToolChain.write(polygene); |
| if (this.options.export) { |
| exportModel(this.options.export); |
| } |
| } catch (exception) { |
| console.log(exception); |
| throw exception; |
| } |
| } |
| } |
| ); |
| |
| function hasFeature(feature) { |
| return polygene.features.indexOf(feature) >= 0; |
| } |
| |
| function firstUpper(text) { |
| return text.charAt(0).toUpperCase() + text.substring(1); |
| } |
| |
| function importModel(filename) { |
| if (typeof filename !== 'string') { |
| filename = "./model.json"; |
| } |
| return JSON.parse(fs.readFileSync(filename, 'utf8')); |
| } |
| |
| function exportModel(filename) { |
| if (typeof filename !== 'string') { |
| filename = "exported-model.json"; |
| } |
| delete polygene.current; |
| return fs.writeFileSync(filename, JSON.stringify(polygene, null, 4) + "\n", 'utf8'); |
| } |
| |
| function assignFunctions(polygene) { |
| |
| polygene.hasFeature = function (feature) { |
| return polygene.features.indexOf(feature) >= 0; |
| }; |
| |
| polygene.copyToConfig = function (ctx, from, toName) { |
| polygene.copyTemplate(ctx, |
| from, |
| 'app/src/dist/config/development/' + toName); |
| polygene.copyTemplate(ctx, |
| from, |
| 'app/src/dist/config/qa/' + toName); |
| polygene.copyTemplate(ctx, |
| from, |
| 'app/src/dist/config/staging/' + toName); |
| polygene.copyTemplate(ctx, |
| from, |
| 'app/src/dist/config/production/' + toName); |
| polygene.copyTemplate(ctx, |
| from, |
| 'app/src/test/resources/' + toName); |
| }; |
| |
| polygene.copyTemplate = function (ctx, from, to) { |
| try { |
| |
| ctx.fs.copyTpl( |
| ctx.templatePath(from), |
| ctx.destinationPath(to), |
| { |
| hasFeature: hasFeature, |
| firstUpper: firstUpper, |
| polygene: polygene |
| } |
| ); |
| } catch (exception) { |
| console.log("Unable to copy template: " + from + "\n", exception); |
| } |
| }; |
| |
| polygene.copyBinary = function (ctx, from, to) { |
| |
| try { |
| ctx.fs.copy( |
| ctx.templatePath(from), |
| ctx.destinationPath(to)); |
| } catch (exception) { |
| console.log("Unable to copy binary: " + from + " to " + to + "\n", exception); |
| } |
| }; |
| |
| polygene.copyPolygeneBootstrap = function (ctx, layer, moduleName, condition) { |
| if (condition) { |
| copyTemplate(ctx, |
| moduleName + '/bootstrap.tmpl', |
| 'bootstrap/src/main/java/' + polygene.javaPackageDir + '/bootstrap/' + layer + '/' + moduleName + '.java'); |
| } |
| }; |
| |
| polygene.copyEntityStore = function (ctx, entityStoreName) { |
| copyTemplate(ctx, |
| 'StorageModule/bootstrap.tmpl', |
| 'bootstrap/src/main/java/' + polygene.javaPackageDir + '/bootstrap/infrastructure/' + entityStoreName + 'StorageModule.java'); |
| }; |
| |
| polygene.copyModules = function (dirname) { |
| fs.readdir(dirname, function (err, files) { |
| if (files !== undefined) { |
| files.forEach(function (directory) { |
| if (directory.endsWith("Module")) { |
| var module = require(dirname + "/" + directory + '/module.js'); |
| module.write(polygene); |
| } |
| }); |
| } |
| }); |
| }; |
| polygene.firstUpper = function (text) { |
| return text.charAt(0).toUpperCase() + text.substring(1); |
| }; |
| polygene.typeNameOnly = function (text) { |
| var lastPos = text.lastIndexOf("."); |
| if (lastPos < 0) { |
| return text; |
| } |
| return text.substring(lastPos + 1); |
| }; |
| |
| polygene.configurationClassName = function (clazzName) { |
| if (clazzName.endsWith("Service")) { |
| clazzName = clazzName.substring(0, clazzName.length - 7); |
| } |
| return clazzName + "Configuration"; |
| }; |
| |
| polygene.prepareClazz = function (current) { |
| var state = []; |
| var imported = {}; |
| var props = current.clazz.properties; |
| var idx; |
| var assoc; |
| if (props) { |
| imported["org.apache.polygene.api.property.Property"] = true; |
| for (idx in props) { |
| if (props.hasOwnProperty(idx)) { |
| var prop = props[idx]; |
| state.push('Property' + '<' + polygene.typeNameOnly(prop.type) + "> " + prop.name + "();"); |
| imported[prop.type] = true; |
| } |
| } |
| } else { |
| imported["org.apache.polygene.api.property.Property"] = true; |
| state.push('Property<String> name(); // TODO: remove sample property') |
| } |
| var assocs = current.clazz.associations; |
| if (assocs) { |
| imported["org.apache.polygene.api.association.Association"] = true; |
| for (idx in assocs) { |
| if (assocs.hasOwnProperty(idx)) { |
| assoc = assocs[idx]; |
| state.push("Association" + '<' + polygene.typeNameOnly(assoc.type) + "> " + assoc.name + "();"); |
| imported[assoc.type] = true; |
| } |
| } |
| } |
| assocs = current.clazz.manyassociations; |
| if (assocs) { |
| imported["org.apache.polygene.api.association.ManyAssociation"] = true; |
| for (idx in assocs) { |
| if (assocs.hasOwnProperty(idx)) { |
| assoc = assocs[idx]; |
| state.push("ManyAssociation<" + polygene.typeNameOnly(assoc.type) + "> " + assoc.name + "();"); |
| imported[assoc.type] = true; |
| } |
| } |
| } |
| assocs = current.clazz.namedassociations; |
| if (assocs) { |
| imported["org.apache.polygene.api.association.NamedAssociation"] = true; |
| for (idx in assocs) { |
| if (assocs.hasOwnProperty(idx)) { |
| assoc = assocs[idx]; |
| state.push("NamedAssociation<" + polygene.typeNameOnly(assoc.type) + "> " + assoc.name + "();"); |
| imported[assoc.type] = true; |
| } |
| } |
| } |
| current.state = state; |
| current.imported = imported; |
| }; |
| |
| polygene.prepareConfigClazz = function (currentModule, composite) { |
| var state = []; |
| var propertyFile = []; |
| var imported = {}; |
| var props = composite.configuration; |
| if (props) { |
| imported["org.apache.polygene.api.property.Property"] = true; |
| for (var idx in props) { |
| if (props.hasOwnProperty(idx)) { |
| var prop = props[idx]; |
| imported[prop.type] = true; |
| var propertyDefault; |
| if (prop.default !== undefined) { |
| propertyDefault = prop.default; |
| } else { |
| if (prop.type === "java.lang.String") { |
| propertyDefault = ''; |
| } |
| else if (prop.type === "java.lang.Boolean") { |
| propertyDefault = 'false'; |
| } |
| else if (prop.type === "java.lang.Long") { |
| propertyDefault = '0'; |
| } |
| else if (prop.type === "java.lang.Integer") { |
| propertyDefault = '0'; |
| } |
| else if (prop.type === "java.lang.Double") { |
| propertyDefault = '0.0'; |
| } |
| else if (prop.type === "java.lang.Float") { |
| propertyDefault = '0.0'; |
| } |
| else { |
| propertyDefault = '\n # TODO: complex configuration type. '; |
| } |
| } |
| state.push("/**"); |
| for (var idxDesc in prop.description) { |
| if (prop.description.hasOwnProperty(idxDesc)) { |
| var desc = prop.description[idxDesc]; |
| propertyFile.push("# " + desc); |
| state.push(" * " + desc) |
| } |
| } |
| state.push(" */"); |
| propertyFile.push(prop.name + "=" + propertyDefault + "\n"); |
| state.push('Property' + '<' + polygene.typeNameOnly(prop.type) + "> " + prop.name + "();\n"); |
| } |
| } |
| } else { |
| imported["org.apache.polygene.api.property.Property"] = true; |
| state.push('/** TODO: remove sample property'); |
| state.push(' */'); |
| state.push('Property<String> name();'); |
| propertyFile.push("# This is just the sample configuration value. "); |
| propertyFile.push("# TODO: Remove this config value "); |
| propertyFile.push('name=sample config value'); |
| } |
| currentModule.state = state; |
| currentModule.propertyLines = propertyFile; |
| currentModule.imported = imported; |
| }; |
| } |