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+ */
16package com .archimatetool .editor .actions ;
27
8+ import java .util .HashMap ;
39import java .util .HashSet ;
4- import java .util .Hashtable ;
10+ import java .util .Map ;
511import java .util .Map .Entry ;
612import java .util .Set ;
713
2935import com .archimatetool .model .FolderType ;
3036import com .archimatetool .model .IArchimateConcept ;
3137import com .archimatetool .model .IArchimateElement ;
38+ import com .archimatetool .model .IArchimateModel ;
3239import com .archimatetool .model .IArchimatePackage ;
3340import com .archimatetool .model .IArchimateRelationship ;
3441import com .archimatetool .model .util .ArchimateModelUtils ;
@@ -51,7 +58,7 @@ public void createContributionItems(IServiceLocator serviceLocator, IContributio
5158 ISelectionService selectionService = serviceLocator .getService (ISelectionService .class );
5259
5360 IStructuredSelection selection = (IStructuredSelection )selectionService .getSelection ();
54- if (selection == null ) {
61+ if (selection == null || selection . isEmpty () ) {
5562 return ;
5663 }
5764
@@ -62,17 +69,21 @@ public void createContributionItems(IServiceLocator serviceLocator, IContributio
6269
6370 for (Object o : selection ) {
6471 IArchimateConcept concept = null ;
72+
6573 if (o instanceof IArchimateConcept ) {
6674 concept = (IArchimateConcept )o ;
6775 }
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 );
7078 }
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 );
7383 }
74- else if (concept instanceof IArchimateRelationship ) {
75- selectedRelations .add ((IArchimateRelationship )concept );
84+ // Relationship
85+ else if (concept instanceof IArchimateRelationship relationship ) {
86+ selectedRelations .add (relationship );
7687 }
7788 }
7889
@@ -153,7 +164,7 @@ public void run() {
153164 boolean hasInvalidConnections = false ;
154165
155166 for (IArchimateElement element : elements ) {
156- if (!SetConceptTypeCommandFactory .isValidTypeForConcept (eClass , element )) {
167+ if (!SetConceptTypeCommandFactory .isValidTypeForElement (eClass , element , elements )) {
157168 hasInvalidConnections = true ;
158169 }
159170 }
@@ -191,8 +202,8 @@ public void run() {
191202 action .setEnabled (false );
192203
193204 // 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 ().equals (eClass ) && SetConceptTypeCommandFactory . isValidTypeForRelationship ( eClass , relation )) {
196207 action .setEnabled (true );
197208 }
198209 }
@@ -204,62 +215,53 @@ public void run() {
204215 private void changeElementTypes (EClass eClass , Set <IArchimateElement > elements ) {
205216 /*
206217 * 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.
208219 */
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 );
218221
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+ }
222230 }
223231 }
224232
225233 private void changeRelationTypes (EClass eClass , Set <IArchimateRelationship > relations ) {
226234 /*
227235 * 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.
229237 */
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 );
238239
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+ }
242247 }
243248 }
244-
249+
245250 /**
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
247252 */
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 <>();
255255
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 );
261263 }
262264
263- return compoundCommand ;
265+ return map ;
264266 }
265267}
0 commit comments