1 # $Id: relationship.rb,v 1.21 2012/01/25 10:06:01 machan Exp $
2
3 require 'tmdoc/tmstd'
4 require 'tmdoc/tmstd/treeable'
5 require 'tmdoc/constant'
6 require 'tmdoc/model/object/logical/node'
7
8
9 module TmDoc
10
11 module Model::Object::Logical::Node
12
13 module Relationship
14
15 module Abstraction
16
17 class ModuleMapOfOneToMany < TmStd::Lsm::Collection::Map::Abstract
18 LSM_DOMAIN_CLASS = MOLA::GenericModule
19 LSM_RANGE_CLASS = MOLA::SetOfGenericModule
20
21
22 def print(indent)
23 is = "\t" * indent
24 is1 = "\t" * (indent + 1)
25
26 for dom in self.domains.sort
27 elems = self.at dom
28 unless elems.empty?
29 LOG::Debug.log "%s%s ==>", is, dom.to_s
30 for elem in elems.sort
31 LOG::Debug.log "%s%s", is1, elem.to_s
32 end
33 else
34 LOG::Debug.log "%s%s ==> empty", is, dom.to_s
35 end
36 end
37 end
38 end
39
40
41 class ClassMapOfOneToMany < ModuleMapOfOneToMany
42 LSM_DOMAIN_CLASS = MOLA::GenericClass
43 LSM_RANGE_CLASS = MOLA::SetOfGenericClass
44 end
45
46 end
47
48
49
50 class MapOfAboveToBelows < Abstraction::ModuleMapOfOneToMany; end
51 EMPTY_MAP_OF_ABOVE_TO_BELOWS = MapOfAboveToBelows.new
52
53 class MapOfExtenderToExtendees < Abstraction::ModuleMapOfOneToMany; end
54 EMPTY_MAP_OF_EXTENDER_TO_EXTENDEES = MapOfExtenderToExtendees.new
55
56 class MapOfExtendeeToExtenders < Abstraction::ModuleMapOfOneToMany; end
57 EMPTY_MAP_OF_EXTENDEE_TO_EXTENDERS = MapOfExtendeeToExtenders.new
58
59 class MapOfIncluderToIncludees < Abstraction::ModuleMapOfOneToMany; end
60 EMPTY_MAP_OF_INCLUDER_TO_INCLUDEES = MapOfIncluderToIncludees.new
61
62 class MapOfIncludeeToIncluders < Abstraction::ModuleMapOfOneToMany; end
63 EMPTY_MAP_OF_INCLUDEE_TO_INCLUDERS = MapOfIncludeeToIncluders.new
64
65 class MapOfSuperclassToSubclass < Abstraction::ClassMapOfOneToMany; end
66 EMPTY_MAP_OF_SUPERCLASS_TO_SUBCLASS = MapOfSuperclassToSubclass.new
67
68
69
70 class RelationshipBetweenSubjects < TmStd::Lsm::Product::Abstract
71 attr_reader :map_of_above_to_belows,
72 :map_of_extender_to_extendees,
73 :map_of_extendee_to_extenders,
74 :map_of_includer_to_includees,
75 :map_of_includee_to_includers,
76 :map_of_super_to_subs
77
78
79 def initialize(
80 map_of_above_to_belows,
81 map_of_extender_to_extendees,
82 map_of_extendee_to_extenders,
83 map_of_includer_to_includees,
84 map_of_includee_to_includers,
85 map_of_super_to_subs
86 )
87 ASSERT.kind_of(
88 map_of_above_to_belows, MapOfAboveToBelows
89 )
90 ASSERT.kind_of(
91 map_of_extender_to_extendees, MapOfExtenderToExtendees
92 )
93 ASSERT.kind_of(
94 map_of_extendee_to_extenders, MapOfExtendeeToExtenders
95 )
96 ASSERT.kind_of(
97 map_of_includer_to_includees, MapOfIncluderToIncludees
98 )
99 ASSERT.kind_of(
100 map_of_includee_to_includers, MapOfIncludeeToIncluders
101 )
102 ASSERT.kind_of(
103 map_of_super_to_subs, MapOfSuperclassToSubclass
104 )
105
106 @map_of_above_to_belows = map_of_above_to_belows
107 @map_of_extender_to_extendees = map_of_extender_to_extendees
108 @map_of_extendee_to_extenders = map_of_extendee_to_extenders
109 @map_of_includer_to_includees = map_of_includer_to_includees
110 @map_of_includee_to_includers = map_of_includee_to_includers
111 @map_of_super_to_subs = map_of_super_to_subs
112 end
113 end
114
115
116
117 module_function
118
119 def make_it_between_subjects(
120 all_modules, map_of_path_to_module
121 )
122 ASSERT.kind_of all_modules, MOLA::SeqOfGenericModule
123 ASSERT.kind_of map_of_path_to_module, MOLA::MapOfPathToModule
124
125 relationships = all_modules.inject(
126 RelationshipBetweenSubjects.new(
127 EMPTY_MAP_OF_ABOVE_TO_BELOWS,
128 EMPTY_MAP_OF_EXTENDER_TO_EXTENDEES,
129 EMPTY_MAP_OF_EXTENDEE_TO_EXTENDERS,
130 EMPTY_MAP_OF_INCLUDER_TO_INCLUDEES,
131 EMPTY_MAP_OF_INCLUDEE_TO_INCLUDERS,
132 MapOfSuperclassToSubclass.new
133 )
134 ) { |relationship, mo_module|
135
136 new_map_of_above_to_belows =
137 update_map_of_above_to_belows(
138 relationship.map_of_above_to_belows,
139 mo_module,
140 map_of_path_to_module
141 )
142
143 new_map_of_extender_to_extendees,
144 new_map_of_extendee_to_extenders =
145 update_maps_of_extending(
146 relationship.map_of_extender_to_extendees,
147 relationship.map_of_extendee_to_extenders,
148 mo_module,
149 map_of_path_to_module
150 )
151
152 new_map_of_includer_to_includees,
153 new_map_of_includee_to_includers =
154 update_maps_of_including(
155 relationship.map_of_includer_to_includees,
156 relationship.map_of_includee_to_includers,
157 mo_module,
158 map_of_path_to_module
159 )
160
161 new_map_of_super_to_subs =
162 if mo_module.kind_of?(MOLA::ChildClass)
163 update_map_of_superclass_to_subclasses(
164 relationship.map_of_super_to_subs,
165 mo_module,
166 map_of_path_to_module
167 )
168 else
169 relationship.map_of_super_to_subs
170 end
171
172 RelationshipBetweenSubjects.new(
173 new_map_of_above_to_belows,
174 new_map_of_extender_to_extendees,
175 new_map_of_extendee_to_extenders,
176 new_map_of_includer_to_includees,
177 new_map_of_includee_to_includers,
178 new_map_of_super_to_subs
179 )
180 }
181
182 ASSERT.kind_of relationships, RelationshipBetweenSubjects
183 end
184
185
186 def update_map_of_above_to_belows(
187 old_map_of_above_to_belows,
188 above_module,
189 map_of_path_to_module
190 )
191 ASSERT.kind_of(
192 old_map_of_above_to_belows, MapOfAboveToBelows
193 )
194 ASSERT.kind_of above_module, MOLA::GenericModule
195 ASSERT.kind_of map_of_path_to_module, MOLA::MapOfPathToModule
196
197 array_of_below_module = above_module.below_module_paths.map {
198 |below_module_path|
199
200 below_module = map_of_path_to_module.at below_module_path
201 ASSERT.kind_of(below_module, MOLA::GenericModule,
202 "above_module: %s", above_module.to_s
203 )
204
205 below_module
206 }
207
208 new_map = unless array_of_below_module.empty?
209 old_map_of_above_to_belows.update(
210 above_module,
211 MOLA::SetOfGenericModule.new(
212 array_of_below_module
213 )
214 )
215 else
216 old_map_of_above_to_belows
217 end
218
219 ASSERT.kind_of new_map, MapOfAboveToBelows
220 end
221
222
223 def update_maps_of_extending(
224 old_map_of_extender_to_extendees,
225 old_map_of_extendee_to_extenders,
226 mo_extender,
227 map_of_path_to_module
228 )
229 ASSERT.kind_of(
230 old_map_of_extender_to_extendees, MapOfExtenderToExtendees
231 )
232 ASSERT.kind_of(
233 old_map_of_extendee_to_extenders, MapOfExtendeeToExtenders
234 )
235 ASSERT.kind_of mo_extender, MOLA::GenericModule
236 ASSERT.kind_of map_of_path_to_module, MOLA::MapOfPathToModule
237
238 new_map_of_extender_to_extendees, mo_extendees =
239 update_map_of_director_to_directees(
240 old_map_of_extender_to_extendees,
241 mo_extender,
242 mo_extender.extendee_module_paths,
243 map_of_path_to_module
244 )
245
246 new_map_of_extendee_to_extenders =
247 update_map_of_directee_to_directors(
248 old_map_of_extendee_to_extenders,
249 mo_extender,
250 map_of_path_to_module,
251 mo_extendees,
252 EMPTY_MAP_OF_EXTENDEE_TO_EXTENDERS,
253 MapOfExtendeeToExtenders
254 )
255
256 ASSERT.tuple_of(
257 [
258 new_map_of_extender_to_extendees,
259 new_map_of_extendee_to_extenders
260 ], [
261 MapOfExtenderToExtendees,
262 MapOfExtendeeToExtenders
263 ]
264 )
265 end
266
267
268 def update_maps_of_including(
269 old_map_of_includer_to_includees,
270 old_map_of_includee_to_includers,
271 mo_includer,
272 map_of_path_to_module
273 )
274 ASSERT.kind_of(
275 old_map_of_includer_to_includees, MapOfIncluderToIncludees
276 )
277 ASSERT.kind_of(
278 old_map_of_includee_to_includers, MapOfIncludeeToIncluders
279 )
280 ASSERT.kind_of mo_includer, MOLA::GenericModule
281 ASSERT.kind_of map_of_path_to_module, MOLA::MapOfPathToModule
282
283 new_map_of_includer_to_includees, mo_includees =
284 update_map_of_director_to_directees(
285 old_map_of_includer_to_includees,
286 mo_includer,
287 mo_includer.includee_module_paths,
288 map_of_path_to_module
289 )
290
291 new_map_of_includee_to_includers =
292 update_map_of_directee_to_directors(
293 old_map_of_includee_to_includers,
294 mo_includer,
295 map_of_path_to_module,
296 mo_includees,
297 EMPTY_MAP_OF_INCLUDEE_TO_INCLUDERS,
298 MapOfIncludeeToIncluders
299 )
300
301 ASSERT.tuple_of(
302 [
303 new_map_of_includer_to_includees,
304 new_map_of_includee_to_includers
305 ], [
306 MapOfIncluderToIncludees,
307 MapOfIncludeeToIncluders
308 ]
309 )
310 end
311
312
313 def update_map_of_director_to_directees(
314 old_map_of_director_to_directees,
315 mo_director,
316 directee_paths,
317 map_of_path_to_module
318 )
319 ASSERT.kind_of(
320 old_map_of_director_to_directees,
321 Abstraction::ModuleMapOfOneToMany
322 )
323 ASSERT.kind_of mo_director, MOLA::GenericModule
324 ASSERT.kind_of directee_paths, MOL::SetOfPath
325 ASSERT.kind_of map_of_path_to_module, MOLA::MapOfPathToModule
326
327 array_of_directee = directee_paths.map { |directee_path|
328 mo_directee = map_of_path_to_module.at directee_path
329 ASSERT.kind_of(mo_directee, MOLA::GenericModule,
330 "mo_director: %s", mo_director.to_s
331 )
332 ASSERT.assert(
333 ! mo_directee.kind_of?(MOLA::GenericClass),
334 "director: %s, directee: %s",
335 mo_director.to_s, mo_directee.to_s
336 )
337
338 if mo_directee != self
339 mo_directee
340 else
341 nil
342 end
343 }.compact
344 set_of_directee =
345 unless array_of_directee.empty?
346 MOLA::SetOfGenericModule.new array_of_directee
347 else
348 MOLA::EMPTY_SET_OF_GENERIC_MODULE
349 end
350
351 new_map = unless set_of_directee.empty?
352 old_map_of_director_to_directees.update(
353 mo_director, set_of_directee
354 )
355 else
356 old_map_of_director_to_directees
357 end
358
359 ASSERT.tuple_of(
360 [new_map, set_of_directee],
361 [Abstraction::ModuleMapOfOneToMany, MOLA::SetOfGenericModule]
362 )
363 end
364
365
366 def update_map_of_directee_to_directors(
367 old_map_of_directee_to_directors,
368 mo_director,
369 map_of_path_to_module,
370 mo_directees,
371 init_map_of_directee_to_directors,
372 map_class_of_directee_to_directors
373 )
374 ASSERT.kind_of(
375 old_map_of_directee_to_directors,
376 Abstraction::ModuleMapOfOneToMany
377 )
378 ASSERT.kind_of mo_director, MOLA::GenericModule
379 ASSERT.kind_of map_of_path_to_module, MOLA::MapOfPathToModule
380 ASSERT.kind_of mo_directees, MOLA::SetOfGenericModule
381 ASSERT.kind_of(
382 init_map_of_directee_to_directors,
383 Abstraction::ModuleMapOfOneToMany
384 )
385 ASSERT.subclass_of(
386 map_class_of_directee_to_directors,
387 Abstraction::ModuleMapOfOneToMany
388 )
389
390 merge_map =
391 unless mo_directees.empty?
392 mo_directees.inject(init_map_of_directee_to_directors) {
393 |map, mo_directee|
394
395 map.merge(
396 map_class_of_directee_to_directors.new(
397 mo_directee =>
398 MOLA::SetOfGenericModule.new([mo_director])
399 )
400 ) { |_, self_directors, other_directors|
401 self_directors + other_directors
402 }
403 }
404 else
405 nil
406 end
407
408 new_map = if merge_map
409 old_map_of_directee_to_directors.merge(merge_map) {
410 |_, self_directors, other_directors|
411
412 self_directors + other_directors
413 }
414 else
415 old_map_of_directee_to_directors
416 end
417
418 ASSERT.kind_of new_map, Abstraction::ModuleMapOfOneToMany
419 end
420
421
422 def update_map_of_superclass_to_subclasses(
423 old_map_of_super_to_subs,
424 mo_module,
425 map_of_path_to_module
426 )
427 ASSERT.kind_of(
428 old_map_of_super_to_subs,
429 MapOfSuperclassToSubclass
430 )
431 ASSERT.kind_of mo_module, MOLA::GenericModule
432 ASSERT.kind_of map_of_path_to_module, MOLA::MapOfPathToModule
433
434 mo_subclass = mo_module
435 superclass_path = mo_subclass.superclass_path
436 mo_superclass = map_of_path_to_module.at superclass_path
437 ASSERT.kind_of(
438 mo_superclass, MOLA::GenericClass,
439 "mo_subclass: %s", mo_subclass.to_s
440 )
441
442 new_map = old_map_of_super_to_subs.merge(
443 MapOfSuperclassToSubclass.new(
444 mo_superclass => MOLA::SetOfGenericClass.new([mo_subclass])
445 )
446 ) { |_superclass, self_subclasses, other_subclasses|
447 self_subclasses + other_subclasses
448 }
449
450 ASSERT.kind_of new_map, MapOfSuperclassToSubclass
451 end
452 end
453
454 end # TmDoc::Model::Object::Logical::Node
455
456 end # TmDoc