1
+ /**
2
+ * This program and the accompanying materials
3
+ * are made available under the terms of the License
4
+ * which accompanies this distribution in the file LICENSE.txt
5
+ */
1
6
package com .archimatetool .editor .actions ;
2
7
8
+ import java .util .HashMap ;
3
9
import java .util .HashSet ;
4
- import java .util .Hashtable ;
10
+ import java .util .Map ;
5
11
import java .util .Map .Entry ;
6
12
import java .util .Set ;
7
13
29
35
import com .archimatetool .model .FolderType ;
30
36
import com .archimatetool .model .IArchimateConcept ;
31
37
import com .archimatetool .model .IArchimateElement ;
38
+ import com .archimatetool .model .IArchimateModel ;
32
39
import com .archimatetool .model .IArchimatePackage ;
33
40
import com .archimatetool .model .IArchimateRelationship ;
34
41
import com .archimatetool .model .util .ArchimateModelUtils ;
@@ -51,7 +58,7 @@ public void createContributionItems(IServiceLocator serviceLocator, IContributio
51
58
ISelectionService selectionService = serviceLocator .getService (ISelectionService .class );
52
59
53
60
IStructuredSelection selection = (IStructuredSelection )selectionService .getSelection ();
54
- if (selection == null ) {
61
+ if (selection == null || selection . isEmpty () ) {
55
62
return ;
56
63
}
57
64
@@ -62,17 +69,21 @@ public void createContributionItems(IServiceLocator serviceLocator, IContributio
62
69
63
70
for (Object o : selection ) {
64
71
IArchimateConcept concept = null ;
72
+
65
73
if (o instanceof IArchimateConcept ) {
66
74
concept = (IArchimateConcept )o ;
67
75
}
68
- else if (o instanceof IAdaptable ) {
69
- concept = (( IAdaptable ) o ) .getAdapter (IArchimateConcept .class );
76
+ else if (o instanceof IAdaptable adaptable ) {
77
+ concept = adaptable .getAdapter (IArchimateConcept .class );
70
78
}
71
- if (concept instanceof IArchimateElement && !(concept .eClass () == IArchimatePackage .eINSTANCE .getJunction ())) { // Not Junctions
72
- selectedElements .add ((IArchimateElement )concept );
79
+
80
+ // Element, but not a Junction
81
+ if (concept instanceof IArchimateElement element && element .eClass () != IArchimatePackage .eINSTANCE .getJunction ()) {
82
+ selectedElements .add (element );
73
83
}
74
- else if (concept instanceof IArchimateRelationship ) {
75
- selectedRelations .add ((IArchimateRelationship )concept );
84
+ // Relationship
85
+ else if (concept instanceof IArchimateRelationship relationship ) {
86
+ selectedRelations .add (relationship );
76
87
}
77
88
}
78
89
@@ -153,7 +164,7 @@ public void run() {
153
164
boolean hasInvalidConnections = false ;
154
165
155
166
for (IArchimateElement element : elements ) {
156
- if (!SetConceptTypeCommandFactory .isValidTypeForConcept (eClass , element )) {
167
+ if (!SetConceptTypeCommandFactory .isValidTypeForElement (eClass , element , elements )) {
157
168
hasInvalidConnections = true ;
158
169
}
159
170
}
@@ -170,8 +181,8 @@ public void run() {
170
181
action .setEnabled (false );
171
182
172
183
// Enable menu item if any selected element is different to the target type
173
- for (IArchimateElement e : elements ) {
174
- if (! e .eClass (). equals ( eClass ) ) {
184
+ for (IArchimateElement element : elements ) {
185
+ if (element .eClass () != eClass ) {
175
186
action .setEnabled (true );
176
187
}
177
188
}
@@ -191,8 +202,8 @@ public void run() {
191
202
action .setEnabled (false );
192
203
193
204
// Enable menu item if any selected relation is different to the target type and is valid
194
- for (IArchimateRelationship r : relations ) {
195
- if (! r .eClass (). equals ( eClass ) && ArchimateModelUtils . isValidRelationship ( r . getSource (). eClass (), r . getTarget (). eClass (), eClass )) {
205
+ for (IArchimateRelationship relation : relations ) {
206
+ if (relation .eClass () != eClass && SetConceptTypeCommandFactory . isValidTypeForRelationship ( eClass , relation )) {
196
207
action .setEnabled (true );
197
208
}
198
209
}
@@ -204,62 +215,53 @@ public void run() {
204
215
private void changeElementTypes (EClass eClass , Set <IArchimateElement > elements ) {
205
216
/*
206
217
* If changing types from more than one model we need to use the
207
- * Command Stack allocated to each model. And then allocate one CompoundCommand per Command Stack.
218
+ * Command Stack allocated to each model. And then execute one CompoundCommand per Command Stack.
208
219
*/
209
- Hashtable <CommandStack , CompoundCommand > commandMap = new Hashtable <CommandStack , CompoundCommand >();
210
-
211
- for (IArchimateElement element : elements ) {
212
- CompoundCommand compoundCmd = getCompoundCommand (element , commandMap );
213
- if (compoundCmd != null ) {
214
- compoundCmd .add (SetConceptTypeCommandFactory .createSetElementTypeCommand (eClass , element ,
215
- ArchiPlugin .PREFERENCES .getBoolean (IPreferenceConstants .ADD_DOCUMENTATION_NOTE_ON_RELATION_CHANGE )));
216
- }
217
- }
220
+ Map <IArchimateModel , Set <IArchimateElement >> elementsMap = getConceptMap (elements );
218
221
219
- // Execute the Commands on the CommandStack(s) - there could be more than one if more than one model open in the Tree
220
- for (Entry <CommandStack , CompoundCommand > entry : commandMap .entrySet ()) {
221
- entry .getKey ().execute (entry .getValue ());
222
+ for (Entry <IArchimateModel , Set <IArchimateElement >> entry : elementsMap .entrySet ()) {
223
+ CommandStack stack = (CommandStack )entry .getKey ().getAdapter (CommandStack .class );
224
+ CompoundCommand cmd = SetConceptTypeCommandFactory .createSetElementTypeCommand (eClass , entry .getValue (),
225
+ ArchiPlugin .PREFERENCES .getBoolean (IPreferenceConstants .ADD_DOCUMENTATION_NOTE_ON_RELATION_CHANGE ));
226
+ if (stack != null && cmd != null ) {
227
+ // Wrap the command in a NonNotifyingCompoundCommand to minimise event noise
228
+ stack .execute (new NonNotifyingCompoundCommand (cmd ));
229
+ }
222
230
}
223
231
}
224
232
225
233
private void changeRelationTypes (EClass eClass , Set <IArchimateRelationship > relations ) {
226
234
/*
227
235
* If changing types from more than one model we need to use the
228
- * Command Stack allocated to each model. And then allocate one CompoundCommand per Command Stack.
236
+ * Command Stack allocated to each model. And then execute one CompoundCommand per Command Stack.
229
237
*/
230
- Hashtable <CommandStack , CompoundCommand > commandMap = new Hashtable <CommandStack , CompoundCommand >();
231
-
232
- for (IArchimateRelationship relation : relations ) {
233
- CompoundCommand compoundCmd = getCompoundCommand (relation , commandMap );
234
- if (compoundCmd != null ) {
235
- compoundCmd .add (SetConceptTypeCommandFactory .createSetRelationTypeCommand (eClass , relation ));
236
- }
237
- }
238
+ Map <IArchimateModel , Set <IArchimateRelationship >> relationsMap = getConceptMap (relations );
238
239
239
- // Execute the Commands on the CommandStack(s) - there could be more than one if more than one model open in the Tree
240
- for (Entry <CommandStack , CompoundCommand > entry : commandMap .entrySet ()) {
241
- entry .getKey ().execute (entry .getValue ());
240
+ for (Entry <IArchimateModel , Set <IArchimateRelationship >> entry : relationsMap .entrySet ()) {
241
+ CommandStack stack = (CommandStack )entry .getKey ().getAdapter (CommandStack .class );
242
+ CompoundCommand cmd = SetConceptTypeCommandFactory .createSetRelationTypeCommand (eClass , entry .getValue ());
243
+ if (stack != null && cmd != null ) {
244
+ // Wrap the command in a NonNotifyingCompoundCommand to minimise event noise
245
+ stack .execute (new NonNotifyingCompoundCommand (cmd ));
246
+ }
242
247
}
243
248
}
244
-
249
+
245
250
/**
246
- * Get, and if need be create, a CompoundCommand to which to change the type for each concept in a model
251
+ * Get a mapping of IArchimateModel to a set of IArchimateConcepts
247
252
*/
248
- private CompoundCommand getCompoundCommand (IArchimateConcept concept , Hashtable <CommandStack , CompoundCommand > commandMap ) {
249
- // Get the Command Stack registered to the object
250
- CommandStack stack = (CommandStack )concept .getAdapter (CommandStack .class );
251
- if (stack == null ) {
252
- System .err .println ("CommandStack was null in getCompoundCommand" ); //$NON-NLS-1$
253
- return null ;
254
- }
253
+ private <T extends IArchimateConcept > Map <IArchimateModel , Set <T >> getConceptMap (Set <T > concepts ) {
254
+ Map <IArchimateModel , Set <T >> map = new HashMap <>();
255
255
256
- // Now get or create a Compound Command
257
- CompoundCommand compoundCommand = commandMap .get (stack );
258
- if (compoundCommand == null ) {
259
- compoundCommand = new NonNotifyingCompoundCommand ();
260
- commandMap .put (stack , compoundCommand );
256
+ for (T concept : concepts ) {
257
+ Set <T > elementsSet = map .get (concept .getArchimateModel ());
258
+ if (elementsSet == null ) {
259
+ elementsSet = new HashSet <>();
260
+ map .put (concept .getArchimateModel (), elementsSet );
261
+ }
262
+ elementsSet .add (concept );
261
263
}
262
264
263
- return compoundCommand ;
265
+ return map ;
264
266
}
265
267
}
0 commit comments