blob: 434e74e8a204df082550962740ab1119d8e4290d [file] [log] [blame]
/*
* 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.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;
};
}