xmimerge 0.0.1
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/xmimerge +61 -0
- data/lib/xmimerge.rb +53 -0
- data/lib/xmimerge/app.rb +47 -0
- data/lib/xmimerge/commands_file.rb +46 -0
- data/lib/xmimerge/merge.rb +40 -0
- data/lib/xmimerge/merge_action_states.rb +10 -0
- data/lib/xmimerge/merge_activity_graphs.rb +91 -0
- data/lib/xmimerge/merge_associations.rb +116 -0
- data/lib/xmimerge/merge_associations_end.rb +59 -0
- data/lib/xmimerge/merge_attributes.rb +125 -0
- data/lib/xmimerge/merge_call_events.rb +39 -0
- data/lib/xmimerge/merge_classes.rb +122 -0
- data/lib/xmimerge/merge_final_states.rb +9 -0
- data/lib/xmimerge/merge_multiplicity.rb +35 -0
- data/lib/xmimerge/merge_operations.rb +83 -0
- data/lib/xmimerge/merge_packages.rb +81 -0
- data/lib/xmimerge/merge_parameters.rb +89 -0
- data/lib/xmimerge/merge_pseudo_states.rb +9 -0
- data/lib/xmimerge/merge_signal_events.rb +71 -0
- data/lib/xmimerge/merge_states.rb +81 -0
- data/lib/xmimerge/merge_stereotypes.rb +82 -0
- data/lib/xmimerge/merge_tagged_values.rb +75 -0
- data/lib/xmimerge/merge_transitions.rb +98 -0
- data/lib/xmimerge/merge_use_cases.rb +89 -0
- data/lib/xmimerge/util.rb +48 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 27825ef03fad6051aca157d64ef00ff1330d9d7d
|
4
|
+
data.tar.gz: c236b9332c2a3363d8bdcc68563a3793caa93bdc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2c5468288a6dacbab623804f219b075d6a760bfa31ae3d9cfc496009084015ef825064e2f3057f029738a2fa660deefb91646384dcaa750d90a1edddf2eea2bb
|
7
|
+
data.tar.gz: d56443396c3804c93741520618ff1ed2281225cdb81e4a5b1c660e5f88fd52429441d46912aa219f4a46f2bcf32b846079558b967d03a08c59f87caa21a90970
|
data/bin/xmimerge
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require 'xmimerge'
|
5
|
+
require 'thor'
|
6
|
+
require File.join(File.dirname(__FILE__), '../lib/xmimerge/util.rb')
|
7
|
+
|
8
|
+
class XmiMergeRunner < Thor
|
9
|
+
|
10
|
+
desc 'c [OPTIONS]', "check"
|
11
|
+
method_option :from, :type => :string, :required => true, :aliases => '-f', :banner => "Path of the source model."
|
12
|
+
method_option :to, :type => :string, :required => true, :aliases => '-t', :banner => "Path of the target model."
|
13
|
+
def c
|
14
|
+
begin
|
15
|
+
inicio = Time.now
|
16
|
+
@merge = XmiMerge.new(options[:from], options[:to])
|
17
|
+
@merge.check
|
18
|
+
App.logger.info "Total Time: #{diff_time(inicio, Time.now)}"
|
19
|
+
rescue Exception => e
|
20
|
+
App.logger.error e.message
|
21
|
+
puts e.backtrace.join("\n")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'm [OPTIONS]', "merge"
|
26
|
+
method_option :from, :type => :string, :required => true, :aliases => '-f', :banner => "Path of the source model."
|
27
|
+
method_option :to, :type => :string, :required => true, :aliases => '-t', :banner => "Path of the target model."
|
28
|
+
method_option :output, :type => :string, :required => false, :aliases => '-o', :banner => "Output path."
|
29
|
+
def m
|
30
|
+
begin
|
31
|
+
inicio = Time.now
|
32
|
+
@merge = XmiMerge.new(options[:from], options[:to])
|
33
|
+
@merge.merge
|
34
|
+
if options[:output].nil?
|
35
|
+
@merge.save
|
36
|
+
else
|
37
|
+
@merge.save(options[:output])
|
38
|
+
end
|
39
|
+
App.logger.info "Total Time: #{diff_time(inicio, Time.now)}"
|
40
|
+
rescue Exception => e
|
41
|
+
App.logger.error e.message
|
42
|
+
puts e.backtrace.join("\n")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def diff_time(start_time, end_time = Time.now)
|
48
|
+
diff = (end_time - start_time)
|
49
|
+
s = (diff % 60).to_i
|
50
|
+
m = (diff / 60).to_i
|
51
|
+
h = (m / 60).to_i
|
52
|
+
|
53
|
+
if s > 0
|
54
|
+
"#{(h < 10) ? '0' + h.to_s : h}:#{(m < 10) ? '0' + m.to_s : m}:#{(s < 10) ? '0' + s.to_s : s}"
|
55
|
+
else
|
56
|
+
format("%.5f", diff) + " miliseconds."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
App.logger.info App.specification.summary + " " + App.specification.version.to_s
|
61
|
+
XmiMergeRunner.start
|
data/lib/xmimerge.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'xmimodel'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), 'xmimerge/app.rb')
|
5
|
+
require File.join(File.dirname(__FILE__), 'xmimerge/merge_packages.rb')
|
6
|
+
|
7
|
+
class XmiMerge
|
8
|
+
|
9
|
+
def initialize(file_name_from, file_name_to)
|
10
|
+
|
11
|
+
@log = App.logger
|
12
|
+
|
13
|
+
start = Time.now
|
14
|
+
App.logger.info "Loading source model..."
|
15
|
+
@from = XmiModel.new file_name_from
|
16
|
+
App.logger.info "Source model loaded (#{Util.diff_time(start)})."
|
17
|
+
|
18
|
+
start = Time.now
|
19
|
+
App.logger.info "Loading target model..."
|
20
|
+
@to = XmiModel.new file_name_to
|
21
|
+
App.logger.info "Target model loaded (#{Util.diff_time(start)})."
|
22
|
+
|
23
|
+
@commands = App.instance.commands_file
|
24
|
+
|
25
|
+
App.instance.from = @from
|
26
|
+
App.instance.to = @to
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def check
|
31
|
+
@only_check = true
|
32
|
+
verify
|
33
|
+
@log.info("#{@commands.buffer_size} change(s).");
|
34
|
+
@commands.save_buffer
|
35
|
+
end
|
36
|
+
|
37
|
+
def merge
|
38
|
+
@only_check = false
|
39
|
+
@commands.load_commands
|
40
|
+
verify
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify
|
44
|
+
merge = MergePackages.new
|
45
|
+
@only_check ? merge.check : merge.merge
|
46
|
+
end
|
47
|
+
|
48
|
+
def save(path=@to.model_file_name)
|
49
|
+
@to.save(path)
|
50
|
+
App.logger.info "#{path} saved."
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/lib/xmimerge/app.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'commands_file.rb')
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
class App
|
5
|
+
|
6
|
+
attr_accessor :from
|
7
|
+
attr_accessor :to
|
8
|
+
|
9
|
+
@@instance = App.new
|
10
|
+
def self.instance
|
11
|
+
return @@instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def commands_file
|
15
|
+
@commands_file = CommandsFile.new if @commands_file.nil?
|
16
|
+
@commands_file
|
17
|
+
end
|
18
|
+
|
19
|
+
@@log = nil
|
20
|
+
def self.logger
|
21
|
+
return @@log unless @@log.nil?
|
22
|
+
@@log = Logger.new($stdout)
|
23
|
+
@@log.level = Logger::INFO
|
24
|
+
@@log.formatter = proc do |severity, datetime, progname, msg|
|
25
|
+
"[#{severity}] - #{msg}\n"
|
26
|
+
end
|
27
|
+
@@log
|
28
|
+
end
|
29
|
+
|
30
|
+
@@spec = nil
|
31
|
+
def self.specification
|
32
|
+
return @@spec unless @@spec.nil?
|
33
|
+
@@spec = Gem::Specification.new do |s|
|
34
|
+
s.name = 'xmimerge'
|
35
|
+
s.version = '0.0.1'
|
36
|
+
s.date = '2013-08-28'
|
37
|
+
s.summary = "Xmi Merge"
|
38
|
+
s.description = "A helper gem for merge XMI files"
|
39
|
+
s.authors = ["Marcus Siqueira"]
|
40
|
+
s.email = 'marvinsiq@gmail.com'
|
41
|
+
s.files = FileList['lib/*.rb', 'lib/**/*.rb'].to_a
|
42
|
+
s.homepage = 'https://github.com/marvinsiq/xmimerge'
|
43
|
+
s.executables << 'xmimerge'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
class CommandsFile
|
3
|
+
|
4
|
+
COMMAND_FILE_NAME = "commands.merge"
|
5
|
+
|
6
|
+
attr_reader :commands
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@buffer = Array.new
|
10
|
+
@log = App.logger
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_commands
|
14
|
+
@log.info "Loading command file '#{COMMAND_FILE_NAME}'..."
|
15
|
+
@commands = File.readlines(COMMAND_FILE_NAME, :encoding => "UTF-8")
|
16
|
+
@log.info "Command file loaded."
|
17
|
+
#@log.info "#{@commands.size} command(s)."
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_command_to_buffer(command)
|
21
|
+
@log.debug "Command added to the buffer: \"#{command}\"."
|
22
|
+
@buffer << command
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_command?(command)
|
26
|
+
has = @commands.select {|c| c.include? command}
|
27
|
+
!has.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_if_is_last_command(command)
|
31
|
+
@buffer.delete_at(@buffer.size-1) if @buffer.last == command
|
32
|
+
end
|
33
|
+
|
34
|
+
def buffer_size
|
35
|
+
@buffer.size
|
36
|
+
end
|
37
|
+
|
38
|
+
def save_buffer
|
39
|
+
@log.debug "Buffer saved."
|
40
|
+
f = File.new(COMMAND_FILE_NAME, "w")
|
41
|
+
f.write(@buffer.join("\n"))
|
42
|
+
@buffer = Array.new
|
43
|
+
f.close unless f.closed?
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
class Merge
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@app = App.instance
|
6
|
+
@from = @app.from
|
7
|
+
@to = @app.to
|
8
|
+
@log = App.logger
|
9
|
+
@commands = @app.commands_file
|
10
|
+
end
|
11
|
+
|
12
|
+
def check
|
13
|
+
#@log.debug "Check"
|
14
|
+
@only_check = true
|
15
|
+
verify
|
16
|
+
end
|
17
|
+
|
18
|
+
def merge
|
19
|
+
#@log.debug "Merge"
|
20
|
+
@only_check = false
|
21
|
+
verify
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_change_propertie(method, from, to, name)
|
25
|
+
|
26
|
+
changes = Util.check_change_by_method(method, from, to)
|
27
|
+
|
28
|
+
if !changes.nil?
|
29
|
+
command = "\t* #{name} #{from.full_name} {'#{changes[0]}' --> '#{changes[1]}'}"
|
30
|
+
@commands.add_command_to_buffer(command)
|
31
|
+
unless @only_check
|
32
|
+
if @commands.has_command?(command)
|
33
|
+
@log.info "[OK] #{command}"
|
34
|
+
else
|
35
|
+
#@log.info "[NOT] #{command}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'merge.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'merge_states.rb')
|
3
|
+
|
4
|
+
class MergeActionStates < MergeStates
|
5
|
+
|
6
|
+
def initialize(from_activity_graph, to_activity_graph)
|
7
|
+
super("ActionState", "action_states", from_activity_graph, to_activity_graph)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'merge.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'merge_action_states.rb')
|
3
|
+
require File.join(File.dirname(__FILE__), 'merge_final_states.rb')
|
4
|
+
require File.join(File.dirname(__FILE__), 'merge_pseudo_states.rb')
|
5
|
+
require File.join(File.dirname(__FILE__), 'merge_transitions.rb')
|
6
|
+
|
7
|
+
class MergeActivityGraphs < Merge
|
8
|
+
|
9
|
+
def initialize(from_use_case, to_use_case)
|
10
|
+
super()
|
11
|
+
@from_use_case = from_use_case
|
12
|
+
@to_use_case = to_use_case
|
13
|
+
end
|
14
|
+
|
15
|
+
def verify
|
16
|
+
|
17
|
+
@from_use_case.activity_graphs.each do |activity_graphs|
|
18
|
+
check_changes activity_graphs
|
19
|
+
end
|
20
|
+
|
21
|
+
check_removed
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_changes(from_activity_graph)
|
25
|
+
|
26
|
+
@log.info("Checking Activity Graph #{from_activity_graph.full_name}")
|
27
|
+
|
28
|
+
to_activity_graph = @to_use_case.activity_graphs_by_name(from_activity_graph.name)
|
29
|
+
|
30
|
+
if to_activity_graph.nil?
|
31
|
+
new_obj to_activity_graph
|
32
|
+
else
|
33
|
+
check_existing(from_activity_graph, to_activity_graph)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def new_obj(from_activity_graph)
|
38
|
+
command = "+ ActivityGraph #{from_activity_graph.full_name}"
|
39
|
+
@commands.add_command_to_buffer(command)
|
40
|
+
end
|
41
|
+
|
42
|
+
def check_existing(from_activity_graph, to_activity_graph)
|
43
|
+
|
44
|
+
@log.debug("Checking Existing Activity Graph: #{from_activity_graph.full_name}")
|
45
|
+
|
46
|
+
# ActionState
|
47
|
+
merge = MergeActionStates.new(from_activity_graph, to_activity_graph)
|
48
|
+
@only_check ? merge.check : merge.merge
|
49
|
+
|
50
|
+
# FinalState
|
51
|
+
merge = MergeFinalStates.new(from_activity_graph, to_activity_graph)
|
52
|
+
@only_check ? merge.check : merge.merge
|
53
|
+
|
54
|
+
# PseudoState
|
55
|
+
merge = MergePseudoStates.new(from_activity_graph, to_activity_graph)
|
56
|
+
@only_check ? merge.check : merge.merge
|
57
|
+
|
58
|
+
# Transition
|
59
|
+
merge = MergeTransitions.new(from_activity_graph, to_activity_graph)
|
60
|
+
@only_check ? merge.check : merge.merge
|
61
|
+
end
|
62
|
+
|
63
|
+
def check_removed
|
64
|
+
|
65
|
+
@log.debug("Checking removed Activity Graph...")
|
66
|
+
|
67
|
+
@to_use_case.activity_graphs.each do |to_activity_graph|
|
68
|
+
|
69
|
+
ok = false
|
70
|
+
@from_use_case.activity_graphs.each do |from_activity_graph|
|
71
|
+
|
72
|
+
if from_activity_graph.name == to_activity_graph.name
|
73
|
+
ok = true
|
74
|
+
break
|
75
|
+
end
|
76
|
+
end
|
77
|
+
if !ok
|
78
|
+
@log.info("Activity Graph Removed: #{to_activity_graph.full_name}")
|
79
|
+
command = "- ActivityGraph #{to_activity_graph.full_name}"
|
80
|
+
@commands.add_command_to_buffer(command)
|
81
|
+
unless @only_check
|
82
|
+
if @commands.has_command?(command)
|
83
|
+
@log.info "[OK] #{command}"
|
84
|
+
else
|
85
|
+
#@log.info "[NOT] #{command}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'merge.rb')
|
4
|
+
require File.join(File.dirname(__FILE__), 'util.rb')
|
5
|
+
require File.join(File.dirname(__FILE__), 'merge_stereotypes.rb')
|
6
|
+
require File.join(File.dirname(__FILE__), 'merge_tagged_values.rb')
|
7
|
+
require File.join(File.dirname(__FILE__), 'merge_multiplicity.rb')
|
8
|
+
|
9
|
+
class MergeAssociations < Merge
|
10
|
+
|
11
|
+
def initialize(from_class, to_class)
|
12
|
+
super()
|
13
|
+
@from_class = from_class
|
14
|
+
@to_class = to_class
|
15
|
+
end
|
16
|
+
|
17
|
+
def verify
|
18
|
+
|
19
|
+
@from_class.associations.each do |from_association|
|
20
|
+
#check_changes(from_association)
|
21
|
+
end
|
22
|
+
|
23
|
+
#check_removed
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param [Association, #read] from_association.
|
27
|
+
def check_changes(from_association)
|
28
|
+
|
29
|
+
@log.debug("Checking association: #{from_association.full_name}")
|
30
|
+
|
31
|
+
# Localiza a associação no modelo destino
|
32
|
+
to_association = @to_class.xml_root.association_by_id(from_association.id)
|
33
|
+
|
34
|
+
if to_association.nil?
|
35
|
+
# Se não encontrou é poque é um nova associação
|
36
|
+
new_association from_association
|
37
|
+
else
|
38
|
+
# Associação já existe, verifica se houve alterações
|
39
|
+
check_existing_association(from_association, to_association)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def check_removed
|
44
|
+
@to_class.xml_root.associations.each do |to_association|
|
45
|
+
|
46
|
+
ok = false
|
47
|
+
@from_class.xml_root.associations.each do |from_association|
|
48
|
+
|
49
|
+
if from_association == to_association
|
50
|
+
ok = true
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
if !ok
|
55
|
+
command = "\t- Association #{to_association.full_name}"
|
56
|
+
@commands.add_command_to_buffer(command)
|
57
|
+
unless @only_check
|
58
|
+
if @commands.has_command?(command)
|
59
|
+
@log.info "[OK] #{command}"
|
60
|
+
else
|
61
|
+
#@log.info "[NOT] #{command}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# @param [Association, #read] from_association.
|
69
|
+
def new_association(from_association)
|
70
|
+
@log.debug("New Attribute")
|
71
|
+
|
72
|
+
command = "\t+ Association #{from_association.full_name}"
|
73
|
+
@commands.add_command_to_buffer(command)
|
74
|
+
|
75
|
+
unless @only_check
|
76
|
+
if @commands.has_command?(command)
|
77
|
+
@log.info "[OK] #{command}"
|
78
|
+
else
|
79
|
+
@log.info "[NOT] #{command}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_existing_association(from_association, to_association)
|
85
|
+
|
86
|
+
# Visibility
|
87
|
+
check_change_propertie("name", from_association, to_association, "AssociationName")
|
88
|
+
|
89
|
+
# Stereotypes
|
90
|
+
merge = MergeStereotypes.new("Association", from_association, to_association)
|
91
|
+
@only_check ? merge.check : merge.merge
|
92
|
+
|
93
|
+
# TaggedValues
|
94
|
+
t = MergeTaggedValues.new("Association", from_association, to_association)
|
95
|
+
@only_check ? t.check : t.merge
|
96
|
+
|
97
|
+
|
98
|
+
if from_association.end_a != to_association.end_a
|
99
|
+
command = "\t* AssociationEndA #{from_association.end_a.name} {'#{from_association.end_a.participant.full_name}' --> '#{to_association.end_a.participant.full_name}'}"
|
100
|
+
@commands.add_command_to_buffer(command)
|
101
|
+
end
|
102
|
+
|
103
|
+
if from_association.end_b != to_association.end_b
|
104
|
+
command = "\t* AssociationEndB #{from_association.end_b.name} {'#{from_association.end_b.participant.full_name}' --> '#{to_association.end_b.participant.full_name}'}"
|
105
|
+
@commands.add_command_to_buffer(command)
|
106
|
+
end
|
107
|
+
|
108
|
+
# AssociationEnd
|
109
|
+
end_a = MergeAssociationEnd.new("AssociationEndA", from_association.end_a, to_association.end_a)
|
110
|
+
@only_check ? end_a.check : end_a.merge
|
111
|
+
|
112
|
+
end_b = MergeAssociationEnd.new("AssociationEndB", from_association.end_b, to_association.end_b)
|
113
|
+
@only_check ? end_b.check : end_b.merge
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|