Class: Archimate::DataModel::ReferenceableCollection
- Inherits:
-
Object
- Object
- Archimate::DataModel::ReferenceableCollection
- Defined in:
- lib/archimate/data_model/referenceable_collection.rb
Overview
This class represents a collection of referenceable objects (i.e. have an ‘id`)
Instance Attribute Summary collapse
Instance Method Summary collapse
- #after(idx) ⇒ Object
- #build_index(hash_index = {}) ⇒ Object
- #clone ⇒ Object
- #compute_item_changes(other, other_enum, _myself, my_item) ⇒ Object
- #diff(other) ⇒ Object
- #dup ⇒ Object
- #find_by_id(an_id) ⇒ Object
- #id ⇒ Object
- #in_model ⇒ Object
- #in_model=(model) ⇒ Object
- #items_are_changed?(other, other_enum, remaining) ⇒ Boolean
- #parent ⇒ Object
- #parent=(par) ⇒ Object
- #patch(diffs) ⇒ Object
- #path(options = {}) ⇒ Object
-
#previous_item_index(ary, node) ⇒ Object
Given a node in self and ary, return the idx of first node p in self that exists in both self and ary and is previous to node in self.
- #primitive? ⇒ Boolean
- #referenced_identified_nodes ⇒ Object
- #smart_find(val = nil) ⇒ Object
- #smart_include?(val) ⇒ Boolean
- #smart_intersection(ary) ⇒ Object
- #to_s ⇒ Object
Instance Attribute Details
#parent_attribute_name ⇒ Object
123 124 125 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 123 def parent_attribute_name @parent_attribute_name if defined?(@parent_attribute_name) end |
Instance Method Details
#after(idx) ⇒ Object
182 183 184 185 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 182 def after(idx) return [] if idx >= size - 1 self[idx + 1..-1] end |
#build_index(hash_index = {}) ⇒ Object
127 128 129 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 127 def build_index(hash_index = {}) reduce(hash_index) { |hi, array_item| array_item.build_index(hi) } end |
#clone ⇒ Object
138 139 140 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 138 def clone map(&:clone) end |
#compute_item_changes(other, other_enum, _myself, my_item) ⇒ Object
103 104 105 106 107 108 109 110 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 103 def compute_item_changes(other, other_enum, _myself, my_item) case my_item when DataModel::ArchimateNode my_item.diff(other_enum.peek[0]) else my_item.diff(other_enum.peek[0], self, other, other_enum.peek[1], find_index(my_item)) end end |
#diff(other) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 24 def diff(other) raise TypeError, "Expected other #{other.class} to be of type #{self.class}" unless other.is_a?(self.class) raise "Well Hell other #{other.path} in_model is nil" if other.in_model.nil? raise "Well Hell my path `#{path}` in_model is nil" if in_model.nil? result = [] remaining_content = Array.new(self) # @todo I want a copy of the array, not a deep clone other_enum = other.each_with_index loop do if other_enum.peek[0] == remaining_content[0] other_enum.next remaining_content.shift elsif items_are_changed?(other, other_enum, remaining_content) result.concat(compute_item_changes(other, other_enum, self, remaining_content[0])) remaining_content.shift other_enum.next elsif !remaining_content.empty? && !other.smart_include?(remaining_content[0]) result << Diff::Delete.new(Diff::ArchimateArrayReference.new(self, smart_find(remaining_content[0]))) remaining_content.shift elsif !smart_include?(other_enum.peek[0]) result << Diff::Insert.new(Diff::ArchimateArrayReference.new(other, other_enum.next[1])) elsif smart_include?(other_enum.peek[0]) result << Diff::Move.new( Diff::ArchimateArrayReference.new(other, other_enum.peek[1]), Diff::ArchimateArrayReference.new(self, smart_find(other_enum.peek[0])) ) remaining_item_idx = remaining_content.smart_find(other_enum.peek[0]) if remaining_item_idx result.concat(compute_item_changes(other, other_enum, self, remaining_content[remaining_item_idx])) remaining_content.delete_at(remaining_item_idx) if remaining_content.smart_include?(other_enum.peek[0]) end other_enum.next else raise "Unhandled diff case for remaining_content: #{remaining_content[0]} and #{other_enum.peek[0]}" end end result.concat( remaining_content .reject { |item| other.include?(item) } .map do |item| Diff::Delete.new(Diff::ArchimateArrayReference.new(self, find_index(item))) end ) end |
#dup ⇒ Object
142 143 144 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 142 def dup map(&:dup) end |
#find_by_id(an_id) ⇒ Object
156 157 158 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 156 def find_by_id(an_id) find { |el| el.id == an_id } end |
#id ⇒ Object
16 17 18 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 16 def id object_id.to_s end |
#in_model ⇒ Object
8 9 10 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 8 def in_model @in_model if defined?(@in_model) end |
#in_model=(model) ⇒ Object
112 113 114 115 116 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 112 def in_model=(model) puts "#{self.inspect} is frozen" if self.frozen? @in_model = model each { |item| item.in_model = model } end |
#items_are_changed?(other, other_enum, remaining) ⇒ Boolean
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 91 def items_are_changed?(other, other_enum, remaining) !remaining.empty? && case remaining[0] when DataModel::Referenceable remaining[0].id == other_enum.peek[0].id when String, DataModel::ArchimateNode !other.include?(remaining[0]) && !include?(other_enum.peek[0]) else raise "Unhandled type for #{remaining[0].class}" end end |
#parent ⇒ Object
12 13 14 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 12 def parent @parent if defined?(@parent) end |
#parent=(par) ⇒ Object
118 119 120 121 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 118 def parent=(par) @parent = par each { |i| i.parent = self } end |
#patch(diffs) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 72 def patch(diffs) # @todo Beware, order of diffs could break patching at the moment. Array(diffs).each do |diff| case diff when Diff::Delete delete_at(smart_find(diff.target.value)) when Diff::Insert insert(diff.target.array_index, diff.target.value) when Diff::Change self[smart_find(diff.changed_from.value)] = diff.target.value when Diff::Move insert(diff.target.array_index, delete_at(smart_find(diff.target.value))) else raise "Unexpected diff type: #{diff.class}" end end self end |
#path(options = {}) ⇒ Object
131 132 133 134 135 136 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 131 def path( = {}) [ parent&.path(), parent_attribute_name ].compact.reject(&:empty?).join("/") end |
#previous_item_index(ary, node) ⇒ Object
Given a node in self and ary, return the idx of first node p in self that exists in both self and ary and is previous to node in self
190 191 192 193 194 195 196 197 198 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 190 def previous_item_index(ary, node) return -1 unless ary.smart_include?(node) initial_idx = smart_find(node) return -1 if initial_idx.nil? (initial_idx - 1).downto(0).find(-> { -1 }) do |idx| ary.smart_include?(at(idx)) end end |
#primitive? ⇒ Boolean
20 21 22 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 20 def primitive? false end |
#referenced_identified_nodes ⇒ Object
150 151 152 153 154 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 150 def referenced_identified_nodes reduce([]) do |a, e| a.concat(e.referenced_identified_nodes) end end |
#smart_find(val = nil) ⇒ Object
160 161 162 163 164 165 166 167 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 160 def smart_find(val = nil) case val when Referenceable lazy.map(&:id).find_index(val.id) else find_index(val) end end |
#smart_include?(val) ⇒ Boolean
169 170 171 172 173 174 175 176 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 169 def smart_include?(val) case val when Referenceable lazy.map(&:id).include?(val.id) else include?(val) end end |
#smart_intersection(ary) ⇒ Object
178 179 180 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 178 def smart_intersection(ary) select { |item| ary.smart_include?(item) } end |
#to_s ⇒ Object
146 147 148 |
# File 'lib/archimate/data_model/referenceable_collection.rb', line 146 def to_s "#{parent}/#{parent_attribute_name}" end |