kody 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/kody +41 -0
- data/lib/kody.rb +58 -0
- data/lib/kody/app.rb +73 -0
- data/lib/kody/builder/attribute_builder.rb +88 -0
- data/lib/kody/builder/class_builder.rb +159 -0
- data/lib/kody/builder/project_builder.rb +15 -0
- data/lib/kody/builder/relation_builder.rb +110 -0
- data/lib/kody/engine/demoiselle/datatype.rb +93 -0
- data/lib/kody/engine/demoiselle/demoiselle.rb +320 -0
- data/lib/kody/engine/demoiselle/templates/beans.xml.tpl +4 -0
- data/lib/kody/engine/demoiselle/templates/businnes.tpl +14 -0
- data/lib/kody/engine/demoiselle/templates/entity.tpl +62 -0
- data/lib/kody/engine/demoiselle/templates/enumeration.tpl +28 -0
- data/lib/kody/engine/demoiselle/templates/exemplo.xmi +123 -0
- data/lib/kody/engine/demoiselle/templates/messages.tpl +7 -0
- data/lib/kody/engine/demoiselle/templates/persistence.tpl +13 -0
- data/lib/kody/engine/demoiselle/templates/persistence.xml.tpl +23 -0
- data/lib/kody/engine/demoiselle/templates/pom.xml.tpl +46 -0
- data/lib/kody/engine/demoiselle/templates/view_edit.tpl +42 -0
- data/lib/kody/engine/demoiselle/templates/view_list.tpl +46 -0
- data/lib/kody/engine/demoiselle/templates/view_mb_edit.tpl +48 -0
- data/lib/kody/engine/demoiselle/templates/view_mb_list.tpl +47 -0
- data/lib/kody/engine/generic/generic.rb +151 -0
- data/lib/kody/model.rb +20 -0
- data/lib/kody/modules.rb +19 -0
- data/lib/kody/parser.rb +13 -0
- data/lib/kody/properties.rb +41 -0
- data/lib/kody/string.rb +16 -0
- data/lib/kody/util.rb +17 -0
- metadata +174 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c4d9c78e75e0acaf1da12110ffa89cdc29f5fb90
|
4
|
+
data.tar.gz: 25b3f8971aef19aa69d9e0f2469cb92118f4d373
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4cc6aa9980f2b78f7d202c1286385bda080d42e501bc69b26bb1a43544e91f1cf0d38286bca3fe752bfce088a679beb80145708d22e297f5a2639bbd7b29d2e9
|
7
|
+
data.tar.gz: 467de6ad7bfcac309e5f2cd997b542200b425a85ff9defcb9ff9afbd6793967fc4351e5dca41e7257bbe552d8ea639523713bcb7c3c2f908473e7ce03a3a8ff6
|
data/bin/kody
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'kody'
|
5
|
+
require 'thor'
|
6
|
+
|
7
|
+
#include Thor::Actions
|
8
|
+
|
9
|
+
class KodyRunner < Thor
|
10
|
+
|
11
|
+
desc 'c [OPTIONS]', "Creates a new project."
|
12
|
+
method_option :project_type, :type => :string, :required => true, :default => "demoiselle", :aliases => '-t', :banner => "The type of your project."
|
13
|
+
method_option :framework_version, :type => :string, :required => false, :default => "2.3.4", :aliases => '-v', :banner => "The version of framework."
|
14
|
+
method_option :project_name, :type => :string, :required => true, :aliases => '-n', :banner => "The name of your project."
|
15
|
+
method_option :project_group, :type => :string, :required => true, :aliases => '-g', :banner => "The group name of your project."
|
16
|
+
def c
|
17
|
+
begin
|
18
|
+
@kody = Kody.new
|
19
|
+
@kody.create_project(options)
|
20
|
+
rescue Exception => e
|
21
|
+
App.logger.error e.message
|
22
|
+
puts e.backtrace.join("\n")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'g [MODEL]', "Generates code from the model."
|
27
|
+
method_option :model, :type => :string, :required => true, :aliases => '-m', :banner => "Model path."
|
28
|
+
def g
|
29
|
+
begin
|
30
|
+
kody = Kody.new
|
31
|
+
kody.from_xmi_file(options[:model])
|
32
|
+
kody.generate
|
33
|
+
rescue Exception => e
|
34
|
+
App.logger.error e.message
|
35
|
+
puts e.backtrace.join("\n")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
KodyRunner.start
|
data/lib/kody.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'kody/app.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'kody/model.rb')
|
3
|
+
require File.join(File.dirname(__FILE__), 'kody/parser.rb')
|
4
|
+
require File.join(File.dirname(__FILE__), 'kody/util.rb')
|
5
|
+
require File.join(File.dirname(__FILE__), 'kody/engine/demoiselle/demoiselle.rb')
|
6
|
+
|
7
|
+
class Kody
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@inicio = Time.now
|
11
|
+
App.logger.info "#{App.specification.summary} version #{App.specification.version}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def from_xmi_file(file)
|
15
|
+
init_properties
|
16
|
+
@model = Model.new file
|
17
|
+
end
|
18
|
+
|
19
|
+
def engine(type)
|
20
|
+
|
21
|
+
case type
|
22
|
+
when "demoiselle"
|
23
|
+
@engine = Demoiselle.new(@model, @properties)
|
24
|
+
@engine.output = Dir.pwd
|
25
|
+
else
|
26
|
+
raise "Engine '#{type}' not supported."
|
27
|
+
end
|
28
|
+
App.logger.info "Using the engine '#{@engine.name}' version #{@engine.version}."
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate
|
32
|
+
|
33
|
+
init_properties
|
34
|
+
engine @properties["project.type"]
|
35
|
+
raise "You need define a engine." if @engine.nil?
|
36
|
+
|
37
|
+
parser = Parser.new(@engine)
|
38
|
+
parser.generate
|
39
|
+
|
40
|
+
App.logger.info "Done: #{Util.diff_time(@inicio)}"
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_project(params)
|
45
|
+
|
46
|
+
engine(params[:project_type])
|
47
|
+
@engine.create_project(params)
|
48
|
+
|
49
|
+
App.logger.info "#{Util.diff_time(@inicio)}"
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def init_properties
|
55
|
+
@properties = Properties.load(Dir.pwd) if @properties.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/kody/app.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
class App
|
5
|
+
|
6
|
+
@@log = nil
|
7
|
+
@@spec = nil
|
8
|
+
@@abbreviations = nil
|
9
|
+
|
10
|
+
def self.logger
|
11
|
+
|
12
|
+
return @@log unless @@log.nil?
|
13
|
+
|
14
|
+
@@log = Logger.new($stdout)
|
15
|
+
@@log.level = Logger::DEBUG
|
16
|
+
@@log.formatter = proc do |severity, datetime, progname, msg|
|
17
|
+
"[#{severity}] - #{msg}\n"
|
18
|
+
end
|
19
|
+
@@log
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.specification
|
23
|
+
|
24
|
+
return @@spec unless @@spec.nil?
|
25
|
+
|
26
|
+
@@spec = Gem::Specification.new do |s|
|
27
|
+
s.name = 'kody'
|
28
|
+
s.version = '0.0.2'
|
29
|
+
s.licenses = ['LGPL']
|
30
|
+
s.add_runtime_dependency "thor", '~> 0.18', '>= 0.18.1'
|
31
|
+
s.add_runtime_dependency "rake", '~> 0.9', '>= 0.9.2'
|
32
|
+
s.add_runtime_dependency "nokogiri", '~> 1.6', '>= 1.6.0'
|
33
|
+
s.add_runtime_dependency "liquid", '~> 2.5', '>= 2.5.0'
|
34
|
+
s.add_runtime_dependency "xmimodel", '~> 0.2', '>= 0.2.0'
|
35
|
+
s.date = '2014-06-02'
|
36
|
+
s.summary = "Kody"
|
37
|
+
s.description = "A quick code generator."
|
38
|
+
s.authors = ["Marcus Siqueira"]
|
39
|
+
s.email = 'marvinsiq@gmail.com'
|
40
|
+
s.files = FileList['lib/*.rb', 'lib/**/*.rb', 'lib/**/*'].to_a
|
41
|
+
s.homepage = 'https://github.com/marvinsiq/kody'
|
42
|
+
s.executables << 'kody'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.abbreviations
|
47
|
+
return @@abbreviations unless @@abbreviations.nil?
|
48
|
+
|
49
|
+
properties_filename = "abbreviations.properties"
|
50
|
+
|
51
|
+
return Array.new unless File.exists? properties_filename
|
52
|
+
|
53
|
+
App.logger.info "Loading property file #{properties_filename}..."
|
54
|
+
|
55
|
+
@@abbreviations = {}
|
56
|
+
File.open(properties_filename, 'r') do |properties_file|
|
57
|
+
properties_file.read.each_line do |line|
|
58
|
+
line.strip!.downcase!
|
59
|
+
if (line[0] != ?# and line[0] != ?=)
|
60
|
+
i = line.index('=')
|
61
|
+
if (i)
|
62
|
+
@@abbreviations[line[0..i - 1].strip.downcase] = line[i + 1..-1].strip.downcase
|
63
|
+
else
|
64
|
+
@@abbreviations[line] = ''
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
@@abbreviations
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'kody/string'
|
2
|
+
|
3
|
+
class AttributeBuilder
|
4
|
+
|
5
|
+
attr_reader :type
|
6
|
+
attr_reader :imports
|
7
|
+
|
8
|
+
def initialize(attribute, class_builder, engine)
|
9
|
+
@attribute = attribute
|
10
|
+
@engine = engine
|
11
|
+
|
12
|
+
@imports = Array.new
|
13
|
+
|
14
|
+
@type = engine.convert_type(@attribute.type)
|
15
|
+
|
16
|
+
@visibility = @attribute.visibility
|
17
|
+
|
18
|
+
@multiplicity_range = @attribute.multiplicity_range
|
19
|
+
|
20
|
+
@clazz = class_builder.name
|
21
|
+
|
22
|
+
if @type == "String"
|
23
|
+
@initial_value = "\"#{@attribute.initial_value}\""
|
24
|
+
else
|
25
|
+
@initial_value = "#{@attribute.initial_value}"
|
26
|
+
end
|
27
|
+
|
28
|
+
#@stereotypes = @attribute.stereotypes
|
29
|
+
#@tagged_values = @attribute.tagged_values
|
30
|
+
|
31
|
+
@name = @attribute.name.strip
|
32
|
+
@name.gsub!(/[ -]/, "_")
|
33
|
+
|
34
|
+
column_name = @name.underscore[0, 30]
|
35
|
+
|
36
|
+
@annotations = Array.new
|
37
|
+
|
38
|
+
if @type.eql?("java.util.Date")
|
39
|
+
if @attribute.type.include?("DateTime") || @attribute.type.include?("Timestamp")
|
40
|
+
@annotations << "@Temporal(TemporalType.TIMESTAMP)"
|
41
|
+
elsif @attribute.type.include? "Time"
|
42
|
+
@annotations << "@Temporal(TemporalType.TIME)"
|
43
|
+
else
|
44
|
+
@annotations << "@Temporal(TemporalType.DATE)"
|
45
|
+
end
|
46
|
+
@imports << "javax.persistence.Temporal"
|
47
|
+
@imports << "javax.persistence.TemporalType"
|
48
|
+
end
|
49
|
+
|
50
|
+
if @attribute.is_enum?
|
51
|
+
|
52
|
+
type_enum = "varchar"
|
53
|
+
|
54
|
+
if !@attribute.enum_obj.nil? && @attribute.enum_obj.attributes.size > 0
|
55
|
+
t = engine.convert_type(@attribute.enum_obj.attributes[0].type)
|
56
|
+
if t == "Integer"
|
57
|
+
type_enum = "integer"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
@annotations << "@Column(name=\"#{column_name}\", columnDefinition=\"#{type_enum}\")"
|
62
|
+
@annotations << "@Type(type = \"br.gov.mp.siconv.GenericEnumUserType\", parameters = { @Parameter(name = \"enumClass\", value = \"#{@type}\") })"
|
63
|
+
|
64
|
+
@imports << "org.hibernate.annotations.Parameter"
|
65
|
+
@imports << "org.hibernate.annotations.Type"
|
66
|
+
else
|
67
|
+
@annotations << "@Column(name=\"#{column_name}\")"
|
68
|
+
end
|
69
|
+
|
70
|
+
@attribute.tagged_values.each do |t|
|
71
|
+
@comment = t.value if "@andromda.persistence.comment" == t.name
|
72
|
+
@length = t.value if "@andromda.persistence.column.length" == t.name
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_liquid
|
77
|
+
{
|
78
|
+
'annotations' => @annotations,
|
79
|
+
'name'=> @name,
|
80
|
+
'comment' => @comment,
|
81
|
+
'initial_value' => @initial_value,
|
82
|
+
'length' => @length,
|
83
|
+
'type' => @type,
|
84
|
+
'visibility' => 'public'
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'kody/builder/attribute_builder'
|
4
|
+
require 'kody/string'
|
5
|
+
|
6
|
+
class ClassBuilder
|
7
|
+
|
8
|
+
attr_reader :stereotype
|
9
|
+
attr_reader :name
|
10
|
+
attr_reader :package
|
11
|
+
attr_reader :persistence_package
|
12
|
+
attr_reader :business_package
|
13
|
+
attr_reader :enum_type
|
14
|
+
|
15
|
+
def initialize(clazz, engine)
|
16
|
+
@clazz = clazz
|
17
|
+
@engine = engine
|
18
|
+
|
19
|
+
@name = @clazz.name.strip
|
20
|
+
@package = @clazz.package.full_name
|
21
|
+
@table_name = nil
|
22
|
+
|
23
|
+
@extends = @clazz.parent.full_name if !@clazz.parent.nil?
|
24
|
+
@annotations = Array.new
|
25
|
+
@imports = Array.new
|
26
|
+
|
27
|
+
@persistence_package = engine.properties["project.persistence.package"];
|
28
|
+
raise "Property 'project.persistence.package' does not exists in #{App.specification.name}.properties." if @persistence_package.nil?
|
29
|
+
@business_package = engine.properties["project.business.package"]
|
30
|
+
raise "Property 'project.business.package' does not exists in #{App.specification.name}.properties." if @business_package.nil?
|
31
|
+
|
32
|
+
@enum_type = "String"
|
33
|
+
|
34
|
+
@attributes = Array.new
|
35
|
+
@clazz.attributes.each do |a|
|
36
|
+
att = AttributeBuilder.new(a, self, engine)
|
37
|
+
@attributes << att
|
38
|
+
@imports = @imports + att.imports
|
39
|
+
@enum_type = att.type
|
40
|
+
end
|
41
|
+
|
42
|
+
inheritance = nil
|
43
|
+
|
44
|
+
@clazz.tagged_values.each do |t|
|
45
|
+
if "@andromda.persistence.table" == t.name
|
46
|
+
@table_name = t.value.downcase[0, 30]
|
47
|
+
elsif "@andromda.hibernate.inheritance" == t.name
|
48
|
+
|
49
|
+
# "org.andromda.profile::persistence::HibernateInheritanceStrategy::subclass"
|
50
|
+
inheritance = "JOINED"
|
51
|
+
|
52
|
+
if t.value == "org.andromda.profile::persistence::HibernateInheritanceStrategy::class"
|
53
|
+
inheritance = "SINGLE_TABLE"
|
54
|
+
@annotations << "@DiscriminatorColumn(name=\"class\", discriminatorType=DiscriminatorType.STRING)"
|
55
|
+
@imports << "javax.persistence.DiscriminatorColumn"
|
56
|
+
@imports << "javax.persistence.DiscriminatorType"
|
57
|
+
end
|
58
|
+
|
59
|
+
elsif "@andromda.hibernate.generator.class" == t.name
|
60
|
+
|
61
|
+
else
|
62
|
+
puts "tagged value desconhecida: #{clazz.name} - #{t.name}: #{t.value}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Verifica se esta classe possui filhas.
|
67
|
+
# Caso positipo irá tratar a estratégia de herança "JOINED"
|
68
|
+
if inheritance.nil? && !@clazz.children.nil? && @clazz.children.size > 0
|
69
|
+
inheritance = "JOINED"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Verifica se este classe é filha e se a classe pai possui a tagged value @andromda.persistence.inheritance
|
73
|
+
if inheritance.nil? && !@clazz.parent.nil?
|
74
|
+
puts "Possui heranca #{@name }- #{@clazz.parent}"
|
75
|
+
@clazz.parent.tagged_values.each do |t|
|
76
|
+
puts "Tags '#{t.name}' = '#{t.value}'"
|
77
|
+
if "@andromda.persistence.inheritance".eql?(t.name)
|
78
|
+
puts 'Chegou aqui'
|
79
|
+
if t.value == "org.andromda.profile::persistence::HibernateInheritanceStrategy::class"
|
80
|
+
puts 'Chegou aqui 2'
|
81
|
+
@annotations << "@DiscriminatorValue(\"#{@clazz.parent.name.strip}\")"
|
82
|
+
end
|
83
|
+
break
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
if !inheritance.nil?
|
89
|
+
@annotations << "@Inheritance(strategy=InheritanceType.#{inheritance})"
|
90
|
+
@imports << "javax.persistence.Inheritance"
|
91
|
+
@imports << "javax.persistence.InheritanceType"
|
92
|
+
end
|
93
|
+
|
94
|
+
@clazz.stereotypes.each do |s|
|
95
|
+
case s.name
|
96
|
+
when "org.andromda.profile::persistence::Entity",
|
97
|
+
"UML Standard Profile::entity",
|
98
|
+
"Entity"
|
99
|
+
@stereotype = :entity
|
100
|
+
when "org.andromda.profile::persistence::WebServiceData"
|
101
|
+
@stereotype = :web_service_data
|
102
|
+
when "org.andromda.profile::ApplicationException"
|
103
|
+
@stereotype = :application_exception
|
104
|
+
when "org.andromda.profile::Enumeration"
|
105
|
+
@stereotype = :enumeration
|
106
|
+
when "org.andromda.profile::presentation::FrontEndSessionObject"
|
107
|
+
@stereotype = :front_end_session_object
|
108
|
+
when "org.andromda.profile::ValueObject"
|
109
|
+
@stereotype = :value_object
|
110
|
+
else
|
111
|
+
App.logger.warn "Stereotype desconhecido: '#{s.name}', classe: #{clazz.name}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
@imports = @imports.uniq.sort
|
116
|
+
end
|
117
|
+
|
118
|
+
def to_liquid
|
119
|
+
{
|
120
|
+
'annotations' => @annotations,
|
121
|
+
'attributes' => @attributes,
|
122
|
+
'business_package' => @business_package,
|
123
|
+
'extends' => @extends,
|
124
|
+
'enum_type' => @enum_type,
|
125
|
+
'name'=> @name,
|
126
|
+
'imports' => @imports,
|
127
|
+
'package' => @package,
|
128
|
+
'persistence_package' => @persistence_package,
|
129
|
+
'relations' => relations,
|
130
|
+
'table_name' => table_name,
|
131
|
+
'sequence_name' => sequence_name
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
def relations
|
136
|
+
Array.new
|
137
|
+
end
|
138
|
+
|
139
|
+
def table_name
|
140
|
+
return @table_name unless @table_name.nil?
|
141
|
+
@table_name = @clazz.name.underscore
|
142
|
+
App.abbreviations.each do |k, v|
|
143
|
+
|
144
|
+
@table_name.gsub!(/^#{k}_/, "#{v}_")
|
145
|
+
@table_name.gsub!(/_#{k}_/, "_#{v}_")
|
146
|
+
@table_name.gsub!(/_#{k}$/, "_#{v}")
|
147
|
+
@table_name.gsub!(/^#{k}$/, "#{v}")
|
148
|
+
|
149
|
+
#puts "#{k} -> #{v} = #{@table_name}"
|
150
|
+
end
|
151
|
+
@table_name = @table_name[0, 30]
|
152
|
+
@table_name
|
153
|
+
end
|
154
|
+
|
155
|
+
def sequence_name
|
156
|
+
"#{table_name}_seq"
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|