Class: Archimate::Diff::Cli::Merger
- Inherits:
-
Object
- Object
- Archimate::Diff::Cli::Merger
- Defined in:
- lib/archimate/diff/cli/merger.rb
Overview
Merger is a class that is a decorator on Archimate::DataModel::Model to provide the capability to merge another model into itself
TODO: provide for a conflict resolver instance TODO: provide an option to determine if potential matches are merged
or if the conflict resolver should be asked.
Instance Method Summary collapse
- #conflicting_ids(doc1, doc2) ⇒ Object
- #e_to_s(e) ⇒ Object
-
#hash_to_attr(h) ⇒ Object
TODO: handle inner text of elements TODO: handle merging by element type.
- #id_hash_for(doc) ⇒ Object
-
#merge(doc1, doc2) ⇒ Object
Merge node1, node2 For node For each child If has a matching child.
- #merge_files(file1, file2) ⇒ Object
Instance Method Details
#conflicting_ids(doc1, doc2) ⇒ Object
92 93 94 95 96 97 98 99 |
# File 'lib/archimate/diff/cli/merger.rb', line 92 def conflicting_ids(doc1, doc2) doc_id_hash1 = id_hash_for(doc1) doc_id_hash2 = id_hash_for(doc2) cids = Set.new(doc_id_hash1.keys) & doc_id_hash2.keys # puts "ID Conflicts:" # puts cids.to_a.join(",") cids end |
#e_to_s(e) ⇒ Object
49 50 51 |
# File 'lib/archimate/diff/cli/merger.rb', line 49 def e_to_s(e) "#{e.name} #{hash_to_attr(e.attributes)}" end |
#hash_to_attr(h) ⇒ Object
TODO: handle inner text of elements TODO: handle merging by element type
45 46 47 |
# File 'lib/archimate/diff/cli/merger.rb', line 45 def hash_to_attr(h) h.map { |k, v| "#{k}=\"#{v}\"" }.join(" ") end |
#id_hash_for(doc) ⇒ Object
85 86 87 88 89 90 |
# File 'lib/archimate/diff/cli/merger.rb', line 85 def id_hash_for(doc) doc.css("[id]").each_with_object({}) do |obj, memo| memo[obj["id"]] = obj memo end end |
#merge(doc1, doc2) ⇒ Object
Merge node1, node2 For node
For each child
If has a matching child
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/archimate/diff/cli/merger.rb', line 57 def merge(doc1, doc2) doc2.children.each do |e| next if e.name == "text" && e.text.strip.empty? # p = e.path # if p =~ /\[\d+\]$/ # p = p.gsub(/\[\d+\]$/, "[@name=\"#{e.attr("name")}\"]") # end # puts "Looking for #{p}"`` # matches = doc1.xpath(p) css = ">#{e.name}" # puts css css += "[name=\"#{e.attr('name')}\"]" if e.attributes.include?("name") css += "[xsi|type=\"#{e.attr('xsi:type')}\"]" if e.attributes.include?("xsi:type") matches = doc1.css(css) if !matches.empty? # We have a potential match # puts "Match?" # puts " Doc2: #{e_to_s(e)}" # matches.each do |e1| # puts " Doc1: #{e_to_s(e1)}" # end merge(matches[0], e) unless matches.size > 1 else # No match insert the node into the tree TODO: handle id conflicts doc1.add_child(e) end end doc1 end |
#merge_files(file1, file2) ⇒ Object
101 102 103 104 105 106 107 |
# File 'lib/archimate/diff/cli/merger.rb', line 101 def merge_files(file1, file2) doc1 = Nokogiri::XML(File.open(file1)) doc2 = Nokogiri::XML(File.open(file2)) # cids = conflicting_ids(doc1, doc2) merge(doc1.root, doc2.root).document end |