1 |
indexing |
2 |
description: "Objects that is a graph of clusters and classes." |
3 |
legal: "See notice at end of class." |
4 |
status: "See notice at end of class." |
5 |
author: "" |
6 |
date: "$Date$" |
7 |
revision: "$Revision$" |
8 |
|
9 |
class |
10 |
ES_CLUSTER_GRAPH |
11 |
|
12 |
inherit |
13 |
ES_GRAPH |
14 |
redefine |
15 |
default_create, |
16 |
synchronize |
17 |
end |
18 |
|
19 |
EB_CONSTANTS |
20 |
undefine |
21 |
default_create |
22 |
end |
23 |
|
24 |
create |
25 |
make, |
26 |
default_create |
27 |
|
28 |
feature {NONE} -- Initialization |
29 |
|
30 |
default_create is |
31 |
-- Create an ES_CLUSTER_GRAPH. |
32 |
do |
33 |
Precursor {ES_GRAPH} |
34 |
|
35 |
subcluster_depth := 1 |
36 |
supercluster_depth := 1 |
37 |
end |
38 |
|
39 |
|
40 |
make (a_tool: like context_editor) is |
41 |
-- Create a ES_CLUSTER_GRAPH in `a_tool'. |
42 |
require |
43 |
a_tool_not_void: a_tool /= Void |
44 |
do |
45 |
default_create |
46 |
context_editor := a_tool |
47 |
ensure |
48 |
set: context_editor = a_tool |
49 |
end |
50 |
|
51 |
feature -- Access |
52 |
|
53 |
supercluster_depth: INTEGER |
54 |
-- Depth of sub-clusters. |
55 |
|
56 |
subcluster_depth: INTEGER |
57 |
-- Depth of super-clusters. |
58 |
|
59 |
center_cluster: ES_CLUSTER |
60 |
-- Center cluster of `Current'. |
61 |
|
62 |
cluster_of_id (a_id: STRING): ES_CLUSTER is |
63 |
-- Cluster of cluster_id `a_id' |
64 |
require |
65 |
a_id_not_void: a_id /= Void |
66 |
local |
67 |
l_clusters: ARRAYED_LIST [EG_CLUSTER] |
68 |
l_cluster: ES_CLUSTER |
69 |
do |
70 |
l_clusters := clusters |
71 |
from |
72 |
l_clusters.start |
73 |
until |
74 |
l_clusters.after or Result /= Void |
75 |
loop |
76 |
l_cluster ?= l_clusters.item |
77 |
check |
78 |
l_cluster_not_void: l_cluster /= Void |
79 |
end |
80 |
if l_cluster.cluster_id.is_equal (a_id) then |
81 |
Result := l_cluster |
82 |
end |
83 |
l_clusters.forth |
84 |
end |
85 |
end |
86 |
|
87 |
feature -- Element change |
88 |
|
89 |
set_supercluster_depth (a_supercluster_depth: like supercluster_depth) is |
90 |
-- Set `supercluster_depth' to `a_supercluster_depth'. |
91 |
require |
92 |
a_supercluster_depth_non_negative: a_supercluster_depth >= 0 |
93 |
do |
94 |
supercluster_depth := a_supercluster_depth |
95 |
ensure |
96 |
supercluster_depth_assigned: supercluster_depth = a_supercluster_depth |
97 |
end |
98 |
|
99 |
set_subcluster_depth (a_subcluster_depth: like subcluster_depth) is |
100 |
-- Set `subcluster_depth' to `a_subcluster_depth'. |
101 |
require |
102 |
a_subcluster_depth_non_negative: a_subcluster_depth >= 0 |
103 |
do |
104 |
subcluster_depth := a_subcluster_depth |
105 |
ensure |
106 |
subcluster_depth_assigned: subcluster_depth = a_subcluster_depth |
107 |
end |
108 |
|
109 |
set_center_cluster (a_center_cluster: like center_cluster) is |
110 |
-- Set `center_cluster' to `a_center_cluster'. |
111 |
require |
112 |
a_center_cluster_not_void: a_center_cluster /= Void |
113 |
do |
114 |
center_cluster := a_center_cluster |
115 |
ensure |
116 |
set: center_cluster = a_center_cluster |
117 |
end |
118 |
|
119 |
explore_center_cluster is |
120 |
-- Explore relations according to `center_cluster'. |
121 |
require |
122 |
center_cluster_not_void: center_cluster /= Void |
123 |
do |
124 |
wipe_out |
125 |
add_cluster (center_cluster) |
126 |
include_all_classes (center_cluster) |
127 |
explore_relations |
128 |
end |
129 |
|
130 |
include_all_classes (cluster: ES_CLUSTER) is |
131 |
-- Include all classes in `cluster'. |
132 |
require |
133 |
cluster_not_void: cluster /= Void |
134 |
local |
135 |
l_classes: HASH_TABLE [CONF_CLASS, STRING] |
136 |
l_class: CLASS_I |
137 |
do |
138 |
if cluster.group.is_cluster then |
139 |
l_classes := cluster.group.classes |
140 |
if l_classes /= Void then |
141 |
create {ARRAYED_LIST [EG_LINKABLE]} last_included_classes.make (l_classes.count) |
142 |
from |
143 |
l_classes.start |
144 |
until |
145 |
l_classes.after |
146 |
loop |
147 |
l_class ?= l_classes.item_for_iteration |
148 |
check |
149 |
l_class_not_viod: l_class /= Void |
150 |
end |
151 |
add_class (l_class, cluster) |
152 |
if last_added_class /= Void then |
153 |
last_included_classes.extend (last_added_class) |
154 |
end |
155 |
l_classes.forth |
156 |
end |
157 |
else |
158 |
create {ARRAYED_LIST [EG_LINKABLE]} last_included_classes.make (0) |
159 |
end |
160 |
else |
161 |
create {ARRAYED_LIST [EG_LINKABLE]} last_included_classes.make (0) |
162 |
end |
163 |
ensure |
164 |
last_included_classes_not_void: last_included_classes /= Void |
165 |
end |
166 |
|
167 |
last_included_classes: LIST [EG_LINKABLE] |
168 |
-- Last classes added by `include_all_classes'. |
169 |
|
170 |
feature {EB_CONTEXT_EDITOR} -- Synchronization |
171 |
|
172 |
synchronize is |
173 |
-- Contexts need to be updated because of recompilation |
174 |
-- or similar action that needs resynchronization. |
175 |
do |
176 |
Precursor {ES_GRAPH} |
177 |
if not has_cluster (center_cluster) then |
178 |
check |
179 |
not center_cluster.is_needed_on_diagram |
180 |
end |
181 |
add_cluster (center_cluster) |
182 |
end |
183 |
end |
184 |
|
185 |
feature {NONE} -- Implementation |
186 |
|
187 |
explore_relations is |
188 |
-- |
189 |
local |
190 |
nb_of_items: INTEGER |
191 |
do |
192 |
if context_editor /= Void then |
193 |
nb_of_items := number_of_superclusters (center_cluster.group, supercluster_depth) + |
194 |
number_of_subclusters (center_cluster.group, subcluster_depth) |
195 |
|
196 |
context_editor.develop_window.status_bar.reset_progress_bar_with_range (0 |..| nb_of_items) |
197 |
end |
198 |
|
199 |
if context_editor /= Void then |
200 |
context_editor.develop_window.status_bar.display_message ("Exploring superclusters of " + center_cluster.name) |
201 |
end |
202 |
explore_superclusters (center_cluster, supercluster_depth) |
203 |
|
204 |
if context_editor /= Void then |
205 |
context_editor.develop_window.status_bar.display_message ("Exploring subclusters of " + center_cluster.name) |
206 |
end |
207 |
explore_subclusters (center_cluster, subcluster_depth, True, True) |
208 |
end |
209 |
|
210 |
number_of_superclusters (a_group: CONF_GROUP; depth: INTEGER): INTEGER is |
211 |
-- Add superclusters of `a_cluster' until `depth' is reached. |
212 |
require |
213 |
a_group_not_void: a_group /= Void |
214 |
local |
215 |
l_group: CONF_GROUP |
216 |
l_cluster: CONF_CLUSTER |
217 |
l_lib: CONF_LIBRARY |
218 |
l_libs: ARRAYED_LIST [CONF_LIBRARY] |
219 |
do |
220 |
if depth > 0 then |
221 |
l_group := a_group |
222 |
if l_group.is_cluster then |
223 |
l_cluster ?= l_group |
224 |
if l_cluster.parent /= Void then |
225 |
Result := Result + number_of_superclusters (l_cluster.parent, depth - 1) + 1 |
226 |
end |
227 |
elseif l_group.is_library then |
228 |
l_lib ?= l_group |
229 |
if l_lib.target.used_in_libraries /= Void then |
230 |
l_libs := l_lib.target.used_in_libraries.twin |
231 |
end |
232 |
if l_libs /= Void then |
233 |
from |
234 |
l_libs.start |
235 |
until |
236 |
l_libs.after |
237 |
loop |
238 |
Result := Result + number_of_superclusters (l_libs.item, depth - 1) + 1 |
239 |
l_libs.forth |
240 |
end |
241 |
end |
242 |
end |
243 |
end |
244 |
end |
245 |
|
246 |
explore_superclusters (a_group: ES_CLUSTER; depth: INTEGER) is |
247 |
-- Add superclusters of `a_group' until `depth' is reached. |
248 |
require |
249 |
a_group_not_void: a_group /= Void |
250 |
local |
251 |
l_group: CONF_GROUP |
252 |
l_cluster: CONF_CLUSTER |
253 |
l_lib: CONF_LIBRARY |
254 |
l_libs: ARRAYED_LIST [CONF_LIBRARY] |
255 |
es_cluster: ES_CLUSTER |
256 |
l_need_new: BOOLEAN |
257 |
l_cluster_clone: ES_CLUSTER |
258 |
do |
259 |
if depth > 0 then |
260 |
l_group := a_group.group |
261 |
if l_group.is_cluster then |
262 |
l_cluster ?= l_group |
263 |
if l_cluster.parent /= Void then |
264 |
create es_cluster.make (l_cluster.parent) |
265 |
add_cluster (es_cluster) |
266 |
if context_editor /= Void then |
267 |
context_editor.develop_window.status_bar.display_progress_value ( |
268 |
context_editor.develop_window.status_bar.current_progress_value + 1 |
269 |
) |
270 |
end |
271 |
include_all_classes (es_cluster) |
272 |
es_cluster.extend (a_group) |
273 |
explore_superclusters (es_cluster, depth - 1) |
274 |
end |
275 |
elseif l_group.is_library then |
276 |
l_lib ?= l_group |
277 |
if l_lib.target.used_in_libraries /= Void then |
278 |
l_libs := l_lib.target.used_in_libraries.twin |
279 |
end |
280 |
if l_libs /= Void then |
281 |
from |
282 |
l_libs.start |
283 |
until |
284 |
l_libs.after |
285 |
loop |
286 |
create es_cluster.make (l_libs.item) |
287 |
add_cluster (es_cluster) |
288 |
if context_editor /= Void then |
289 |
context_editor.develop_window.status_bar.display_progress_value ( |
290 |
context_editor.develop_window.status_bar.current_progress_value + 1 |
291 |
) |
292 |
end |
293 |
include_all_classes (es_cluster) |
294 |
if not l_need_new then |
295 |
es_cluster.extend (a_group) |
296 |
l_need_new := True |
297 |
else |
298 |
create l_cluster_clone.make (a_group.group) |
299 |
es_cluster.extend (l_cluster_clone) |
300 |
explore_subclusters (l_cluster_clone, subcluster_depth, False, False) |
301 |
end |
302 |
explore_superclusters (es_cluster, depth - 1) |
303 |
l_libs.forth |
304 |
end |
305 |
end |
306 |
end |
307 |
end |
308 |
end |
309 |
|
310 |
number_of_subclusters (a_group: CONF_GROUP; depth: INTEGER): INTEGER is |
311 |
-- Add subgroups of `a_group' until `depth' is reached. |
312 |
require |
313 |
a_group_not_void: a_group /= Void |
314 |
local |
315 |
sub_clusters: ARRAYED_LIST [CONF_CLUSTER] |
316 |
l_cluster: CONF_CLUSTER |
317 |
l_lib: CONF_LIBRARY |
318 |
l_groups: HASH_TABLE [CONF_GROUP, STRING] |
319 |
do |
320 |
if depth > 0 then |
321 |
if a_group.is_cluster then |
322 |
l_cluster ?= a_group |
323 |
sub_clusters := l_cluster.children |
324 |
if sub_clusters /= Void then |
325 |
from |
326 |
sub_clusters.start |
327 |
until |
328 |
sub_clusters.after |
329 |
loop |
330 |
Result := Result + number_of_subclusters (sub_clusters.item, depth - 1) + 1 |
331 |
sub_clusters.forth |
332 |
end |
333 |
end |
334 |
elseif a_group.is_library then |
335 |
l_lib ?= a_group |
336 |
l_groups := l_lib.library_target.groups |
337 |
from |
338 |
l_groups.start |
339 |
until |
340 |
l_groups.after |
341 |
loop |
342 |
if not l_groups.item_for_iteration.is_assembly then |
343 |
Result := Result + number_of_subclusters (l_groups.item_for_iteration, depth - 1) + 1 |
344 |
end |
345 |
l_groups.forth |
346 |
end |
347 |
elseif a_group.is_assembly then |
348 |
check error: false end |
349 |
end |
350 |
end |
351 |
end |
352 |
|
353 |
explore_subclusters (a_group: ES_CLUSTER; depth: INTEGER; include_class: BOOLEAN; status_bar: BOOLEAN) is |
354 |
-- Add subclusters of `a_group' until `depth' is reached. |
355 |
require |
356 |
a_group_not_void: a_group /= Void |
357 |
local |
358 |
sub_clusters: ARRAYED_LIST [CONF_CLUSTER] |
359 |
l_cluster: CONF_CLUSTER |
360 |
l_lib: CONF_LIBRARY |
361 |
l_groups: HASH_TABLE [CONF_GROUP, STRING] |
362 |
l_status_bar: EB_DEVELOPMENT_WINDOW_STATUS_BAR |
363 |
l_group: CONF_GROUP |
364 |
es_cluster: ES_CLUSTER |
365 |
do |
366 |
if depth > 0 then |
367 |
if context_editor /= Void then |
368 |
l_status_bar := context_editor.develop_window.status_bar |
369 |
end |
370 |
l_group := a_group.group |
371 |
if l_group.is_cluster then |
372 |
l_cluster ?= l_group |
373 |
sub_clusters := l_cluster.children |
374 |
if sub_clusters /= Void then |
375 |
from |
376 |
sub_clusters.start |
377 |
until |
378 |
sub_clusters.after |
379 |
loop |
380 |
create es_cluster.make (sub_clusters.item) |
381 |
add_cluster (es_cluster) |
382 |
if l_status_bar /= Void and status_bar then |
383 |
l_status_bar.display_progress_value ( |
384 |
l_status_bar.current_progress_value + 1 |
385 |
) |
386 |
end |
387 |
if include_class then |
388 |
include_all_classes (es_cluster) |
389 |
end |
390 |
a_group.extend (es_cluster) |
391 |
explore_subclusters (es_cluster, depth - 1, include_class, status_bar) |
392 |
sub_clusters.forth |
393 |
end |
394 |
end |
395 |
elseif l_group.is_library then |
396 |
l_lib ?= l_group |
397 |
l_groups := l_lib.library_target.groups |
398 |
from |
399 |
l_groups.start |
400 |
until |
401 |
l_groups.after |
402 |
loop |
403 |
if not l_groups.item_for_iteration.is_assembly then |
404 |
create es_cluster.make (l_groups.item_for_iteration) |
405 |
add_cluster (es_cluster) |
406 |
if l_status_bar /= Void and status_bar then |
407 |
l_status_bar.display_progress_value ( |
408 |
l_status_bar.current_progress_value + 1 |
409 |
) |
410 |
end |
411 |
if include_class then |
412 |
include_all_classes (es_cluster) |
413 |
end |
414 |
a_group.extend (es_cluster) |
415 |
explore_subclusters (es_cluster, depth - 1, include_class, status_bar) |
416 |
end |
417 |
l_groups.forth |
418 |
end |
419 |
elseif l_group.is_assembly then |
420 |
check error: false end |
421 |
end |
422 |
end |
423 |
end |
424 |
|
425 |
add_class (a_class: CLASS_I; cluster: ES_CLUSTER) is |
426 |
-- Include `a_class' in the diagram. |
427 |
-- Add any relations `a_class' may have with |
428 |
-- all items in `class_figures'. |
429 |
require |
430 |
a_class_not_void: a_class /= Void |
431 |
local |
432 |
es_class: ES_CLASS |
433 |
do |
434 |
last_added_class := Void |
435 |
if context_editor = Void or else not context_editor.is_excluded_in_preferences (a_class.name_in_upper) then |
436 |
es_class := cluster.node_of (a_class) |
437 |
if es_class = Void then |
438 |
create es_class.make (a_class) |
439 |
add_node (es_class) |
440 |
cluster.extend (es_class) |
441 |
last_added_class := es_class |
442 |
elseif not es_class.is_needed_on_diagram then |
443 |
es_class.enable_needed_on_diagram |
444 |
if not cluster.has (es_class) then |
445 |
cluster.extend (es_class) |
446 |
end |
447 |
last_added_class := es_class |
448 |
end |
449 |
add_node_relations (es_class) |
450 |
end |
451 |
end |
452 |
|
453 |
last_added_class: ES_CLASS |
454 |
|
455 |
invariant |
456 |
subcluster_depth_positive: subcluster_depth >= 0 |
457 |
supercluster_depth_positive: supercluster_depth >= 0 |
458 |
|
459 |
indexing |
460 |
copyright: "Copyright (c) 1984-2006, Eiffel Software" |
461 |
license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)" |
462 |
licensing_options: "http://www.eiffel.com/licensing" |
463 |
copying: "[ |
464 |
This file is part of Eiffel Software's Eiffel Development Environment. |
465 |
|
466 |
Eiffel Software's Eiffel Development Environment is free |
467 |
software; you can redistribute it and/or modify it under |
468 |
the terms of the GNU General Public License as published |
469 |
by the Free Software Foundation, version 2 of the License |
470 |
(available at the URL listed under "license" above). |
471 |
|
472 |
Eiffel Software's Eiffel Development Environment is |
473 |
distributed in the hope that it will be useful, but |
474 |
WITHOUT ANY WARRANTY; without even the implied warranty |
475 |
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
476 |
See the GNU General Public License for more details. |
477 |
|
478 |
You should have received a copy of the GNU General Public |
479 |
License along with Eiffel Software's Eiffel Development |
480 |
Environment; if not, write to the Free Software Foundation, |
481 |
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
482 |
]" |
483 |
source: "[ |
484 |
Eiffel Software |
485 |
356 Storke Road, Goleta, CA 93117 USA |
486 |
Telephone 805-685-1006, Fax 805-685-6869 |
487 |
Website http://www.eiffel.com |
488 |
Customer support http://support.eiffel.com |
489 |
]" |
490 |
|
491 |
end -- class ES_CLUSTER_GRAPH |