diff --git a/DEHCapellaAdapter/META-INF/MANIFEST.MF b/DEHCapellaAdapter/META-INF/MANIFEST.MF index 268335c..3b37677 100644 --- a/DEHCapellaAdapter/META-INF/MANIFEST.MF +++ b/DEHCapellaAdapter/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: DEH-CapellaAdapter Bundle-SymbolicName: com.rheagroup.dehcapellaadapter;singleton:=true -Bundle-Version: 1.5.1 +Bundle-Version: 1.5.2 Bundle-Vendor: RHEAGROUP Require-Bundle: org.eclipse.ui, org.polarsys.capella.core.model.handler;bundle-version="5.1.0";visibility:=reexport, diff --git a/DEHCapellaAdapter/src/Commands/OpenLocalExchangeHistoryCommand.java b/DEHCapellaAdapter/src/Commands/OpenLocalExchangeHistoryCommand.java index 27f6a00..4367cf8 100644 --- a/DEHCapellaAdapter/src/Commands/OpenLocalExchangeHistoryCommand.java +++ b/DEHCapellaAdapter/src/Commands/OpenLocalExchangeHistoryCommand.java @@ -42,6 +42,7 @@ /** * The {@linkplain OpenLocalExchangeHistoryCommand} is the command {@linkplain AbstractHandler} to handle the local exchange history dialog */ +@Annotations.ExludeFromCodeCoverageGeneratedReport public class OpenLocalExchangeHistoryCommand extends AbstractHandler { /** diff --git a/DEHCapellaAdapter/src/DstController/DstController.java b/DEHCapellaAdapter/src/DstController/DstController.java index b31877d..c7e666d 100644 --- a/DEHCapellaAdapter/src/DstController/DstController.java +++ b/DEHCapellaAdapter/src/DstController/DstController.java @@ -36,6 +36,7 @@ import java.util.stream.Stream; import org.apache.commons.lang3.time.StopWatch; +import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; @@ -371,6 +372,8 @@ public DstController(IMappingEngineService mappingEngine, IHubController hubCont { this.hubMapResult.clear(); this.dstMapResult.clear(); + this.mappedTracesToBinaryRelationships.clear(); + this.mappedBinaryRelationshipsToTraces.clear(); this.selectedDstMapResultForTransfer.clear(); this.selectedHubMapResultForTransfer.clear(); } @@ -457,6 +460,8 @@ public void LoadMapping() { StopWatch timer = StopWatch.createStarted(); + this.transactionService.Reset(); + var mappedElements = this.mappingConfigurationService.LoadMapping(); var allMappedCapellaComponents = new CapellaComponentCollection(); @@ -474,6 +479,8 @@ public void LoadMapping() this.dstMapResult.clear(); this.hubMapResult.clear(); + this.selectedHubMapResultForTransfer.clear(); + this.selectedDstMapResultForTransfer.clear(); var result = this.Map(allMappedCapellaComponents, MappingDirection.FromDstToHub) & this.Map(allMappedCapellaRequirements, MappingDirection.FromDstToHub) @@ -626,7 +633,7 @@ else if (mappingDirection == MappingDirection.FromHubToDst * Tries to map the provided {@linkplain IMappableThingCollection} * * @param input the {@linkplain IMappableThingCollection} - * @param output the {@linkplain ArrayList} output of whatever mapping rule returns + * @param output the {@linkplain ArrayList} output of whatever mapping rule returns * @param result the result to return {@linkplain #Map(IMappableThingCollection, MappingDirection)} from in case the mapping fails * @return a value that is true when the {@linkplain IMappableThingCollection} mapping succeed */ @@ -654,26 +661,71 @@ private boolean TryMap(IMappableThingCollection input, Ref> output, */ @Override public boolean Transfer() - { - boolean result; + { + MutablePair result = MutablePair.of(true, true); - switch(this.CurrentMappingDirection()) + try { - case FromDstToHub: - result = this.TransferToHub(); - break; - case FromHubToDst: - result = this.TransferToDst(); - break; - default: - result = false; - break; + this.isHubSessionRefreshSilent = true; + + switch(this.CurrentMappingDirection()) + { + case FromDstToHub: + result = this.TransferToHub(); + break; + case FromHubToDst: + result.left &= this.TransferToDst(); + break; + default: + result = MutablePair.of(false, false); + break; + } + + if(result.getRight().booleanValue()) + { + this.SaveMappingConfiguration(); + result.left &= this.hubController.Refresh(); + } + } + catch (TransactionException exception) + { + this.logger.catching(exception); + } + finally + { + (this.CurrentMappingDirection() == MappingDirection.FromHubToDst ? this.selectedHubMapResultForTransfer : this.selectedDstMapResultForTransfer).clear(); + this.isHubSessionRefreshSilent = false; + this.logService.Append("Reloading the mapping configuration in progress..."); + this.LoadMapping(); } - this.LoadMapping(); - return result; + return result.getLeft(); } + /** + * Saves the mapping configuration + * + * @throws TransactionException + */ + private void SaveMappingConfiguration() throws TransactionException + { + if(!this.mappingConfigurationService.IsTheCurrentIdentifierMapTemporary()) + { + this.logService.Append("Saving the mapping configuration in progress..."); + + Pair iterationTransaction = this.hubController.GetIterationTransaction(); + + Iteration iterationClone = iterationTransaction.getLeft(); + ThingTransaction transaction = iterationTransaction.getRight(); + this.mappingConfigurationService.PersistExternalIdentifierMap(transaction, iterationClone); + transaction.createOrUpdate(iterationClone); + + this.hubController.Write(transaction); + this.hubController.Refresh(); + this.mappingConfigurationService.RefreshExternalIdentifierMap(); + } + } + /** * Transfers all the {@linkplain CapellaElement} contained in the {@linkplain hubMapResult} to the DST * @@ -686,38 +738,14 @@ public boolean TransferToDst() var result = this.transactionService.Commit(() -> PrepareElementsForTransferToCapella()); this.logService.Append(String.format("Transfered %s elements to Capella", this.selectedHubMapResultForTransfer.size()), result); - if(!this.mappingConfigurationService.IsTheCurrentIdentifierMapTemporary()) - { - this.logService.Append("Saving the mapping configuration in progress..."); - - this.isHubSessionRefreshSilent = true; - Pair iterationTransaction = this.hubController.GetIterationTransaction(); - - Iteration iterationClone = iterationTransaction.getLeft(); - ThingTransaction transaction = iterationTransaction.getRight(); - this.mappingConfigurationService.PersistExternalIdentifierMap(transaction, iterationClone); - transaction.createOrUpdate(iterationClone); - - this.hubController.Write(transaction); - result &= this.hubController.Refresh(); - this.mappingConfigurationService.RefreshExternalIdentifierMap(); - } - - this.selectedHubMapResultForTransfer.clear(); - this.logService.Append("Reloading the mapping configuration in progress..."); - return result & this.hubController.Refresh(); + return result; } catch (Exception exception) { - this.logService.Append(exception.toString(), exception); + this.logService.Append(String.format("The transfer to Capella failed because %s : %s", exception.getClass().getSimpleName(), exception.toString()), exception); this.logger.catching(exception); return false; } - finally - { - this.selectedHubMapResultForTransfer.clear(); - this.isHubSessionRefreshSilent = false; - } } /** @@ -1035,14 +1063,14 @@ private void UpdateInterfaces(EList clonedInterfaces, EList TransferToHub() { try { - this.isHubSessionRefreshSilent = true; Pair iterationTransaction = this.hubController.GetIterationTransaction(); Iteration iterationClone = iterationTransaction.getLeft(); ThingTransaction transaction = iterationTransaction.getRight(); @@ -1050,36 +1078,26 @@ public boolean TransferToHub() if(!this.hubController.TrySupplyAndCreateLogEntry(transaction)) { this.logService.Append("Transfer to the HUB aborted!"); - return true; + return MutablePair.of(true, false); } this.PrepareThingsForTransfer(iterationClone, transaction); - - this.mappingConfigurationService.PersistExternalIdentifierMap(transaction, iterationClone); - transaction.createOrUpdate(iterationClone); - this.hubController.Write(transaction); + boolean result = this.hubController.Refresh(); - this.mappingConfigurationService.RefreshExternalIdentifierMap(); this.PrepareParameterOverrides(); result &= this.hubController.Refresh(); this.UpdateParameterValueSets(); - this.isHubSessionRefreshSilent = true; - return result && this.hubController.Refresh(); + return MutablePair.of(result, true); } catch (Exception exception) { - this.logService.Append(exception.toString(), exception); - return false; - } - finally - { - this.selectedDstMapResultForTransfer.clear(); - this.isHubSessionRefreshSilent = true; + this.logService.Append(String.format("The transfer to the HUB failed because %s : %s", exception.getClass().getSimpleName(), exception.toString()), exception); + return MutablePair.of(false, true); } } - /** + /** * Prepares all the {@linkplain ParameterOverrides}s that are to be updated or created * * @throws TransactionException can throw {@linkplain TransactionException} diff --git a/DEHCapellaAdapter/src/DstController/IDstController.java b/DEHCapellaAdapter/src/DstController/IDstController.java index 7e4d6a7..8f9b8ea 100644 --- a/DEHCapellaAdapter/src/DstController/IDstController.java +++ b/DEHCapellaAdapter/src/DstController/IDstController.java @@ -26,6 +26,7 @@ import java.util.Collection; import java.util.function.Predicate; +import org.apache.commons.lang3.tuple.Pair; import org.polarsys.capella.core.data.capellacore.CapellaElement; import org.polarsys.capella.core.data.capellacore.NamedElement; import org.polarsys.capella.core.data.capellacore.Trace; @@ -66,9 +67,10 @@ public interface IDstController extends IDstControllerBase /** * Transfers all the {@linkplain Thing} contained in the {@linkplain dstMapResult} to the Hub * - * @return a value indicating that all transfer could be completed + * @return a pair of value where one indicates that all transfer could be completed and + * the other one indicates whether the mapping configuration should be persisted */ - boolean TransferToHub(); + Pair TransferToHub(); /** * Transfers the selected things to be transfered depending on the current {@linkplain MappingDirection} diff --git a/DEHCapellaAdapter/src/MappingRules/ComponentToElementMappingRule.java b/DEHCapellaAdapter/src/MappingRules/ComponentToElementMappingRule.java index 94b5e89..aa7a473 100644 --- a/DEHCapellaAdapter/src/MappingRules/ComponentToElementMappingRule.java +++ b/DEHCapellaAdapter/src/MappingRules/ComponentToElementMappingRule.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.List; import java.util.UUID; +import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -437,14 +438,16 @@ private ElementDefinition GetOrCreateElementDefinition(String name) { var shortName = GetShortName(name); + Predicate matcher = x -> AreTheseEquals(x.getShortName(), shortName, true) || AreTheseEquals(x.getName(), name); ElementDefinition elementDefinition = this.elements.stream() - .filter(x -> x.GetHubElement() != null && AreTheseEquals(x.GetHubElement().getShortName(), shortName, true)) + .filter(x -> x.GetHubElement() != null) .map(x -> x.GetHubElement()) + .filter(matcher) .findFirst() .orElse(this.hubController.GetOpenIteration() .getElement() .stream() - .filter(x -> AreTheseEquals(x.getShortName(), shortName)) + .filter(matcher) .findFirst() .map(x -> x.clone(false)) .orElse(null)); @@ -971,5 +974,6 @@ private newValue = new ValueArray<>(Arrays.asList(refValue.Get()), String.class); valueSet.setManual(newValue); + valueSet.setValueSwitch(ParameterSwitchKind.MANUAL); } } diff --git a/DEHCapellaAdapter/src/MappingRules/ElementToComponentMappingRule.java b/DEHCapellaAdapter/src/MappingRules/ElementToComponentMappingRule.java index b271128..51c8bc8 100644 --- a/DEHCapellaAdapter/src/MappingRules/ElementToComponentMappingRule.java +++ b/DEHCapellaAdapter/src/MappingRules/ElementToComponentMappingRule.java @@ -739,7 +739,9 @@ private void MapContainedElement(MappedElementDefinitionRowViewModel mappedEleme .filter(x -> x.getInterfaceEnd() == InterfaceEndKind.NONE).collect(Collectors.toList())) { MappedElementDefinitionRowViewModel usageDefinitionMappedElement = this.elements.stream() - .filter(x -> x.GetDstElement() != null && AreTheseEquals(x.GetDstElement().getName(), containedUsage.getName(), true)) + .filter(x -> ((x.GetDstElement() != null && AreTheseEquals(x.GetDstElement().getName(), containedUsage.getName(), true)) + || AreTheseEquals(containedUsage.getElementDefinition().getIid(), x.GetHubElement().getIid())) + && x.GetTargetArchitecture() == targetArchitecture) .findFirst() .orElseGet(() -> { @@ -751,11 +753,19 @@ private void MapContainedElement(MappedElementDefinitionRowViewModel mappedEleme return newMappedElement; }); + if(usageDefinitionMappedElement.GetDstElement() == null) + { + usageDefinitionMappedElement.SetDstElement(this.GetOrCreateComponent(containedUsage, targetArchitecture)); + } + this.MapProperties(containedUsage, usageDefinitionMappedElement.GetDstElement()); this.UpdateContainement(mappedElement.GetDstElement(), usageDefinitionMappedElement.GetDstElement()); this.MapPort(usageDefinitionMappedElement); - this.MapContainedElement(usageDefinitionMappedElement, targetArchitecture); + if(!AreTheseEquals(mappedElement.GetHubElement().getIid(), usageDefinitionMappedElement.GetHubElement().getIid())) + { + this.MapContainedElement(usageDefinitionMappedElement, targetArchitecture); + } } } diff --git a/DEHCapellaAdapter/src/Services/CapellaTransaction/CapellaTransactionService.java b/DEHCapellaAdapter/src/Services/CapellaTransaction/CapellaTransactionService.java index a8a1053..e19e095 100644 --- a/DEHCapellaAdapter/src/Services/CapellaTransaction/CapellaTransactionService.java +++ b/DEHCapellaAdapter/src/Services/CapellaTransaction/CapellaTransactionService.java @@ -228,6 +228,19 @@ public boolean IsNew(TElement element) && this.newReferences.get(((CapellaElement)element).getId()) == element; } + /** + * Gets the original reference from the {@linkplain ClonedReferenceElement} where the element id == the provided {@linkplain #TElement} id. + * In the case the provided element is not a clone, it is returned. + * + * @param the type of the element + * @param element the element + * @return a {@linkplain #TElement} + */ + public TElement GetOriginal(TElement element) + { + return this.IsCloned(element) ? this.GetClone(element).GetOriginal() : element; + } + /** * Initializes a new {@linkplain CapellaElement} from the specified {@linkplain #Class}, and registers the target {@linkplain CapellaArchitecture} * @@ -313,10 +326,10 @@ public void RegisterTargetArchitecture(CapellaElement capellaElement, CapellaArc } /** - * Reset the clones references, by means of finalizing the transaction + * Reset the clones references, the new ones and the registered target architecture */ @Override - public void Finalize() + public void Reset() { this.cloneReferences.clear(); this.newReferences.clear(); @@ -382,7 +395,7 @@ public boolean Commit(Runnable transactionMethod) var project = this.sessionService.GetProject(); var result = new Ref<>(Boolean.class, false); TransactionHelper.getExecutionManager(project).execute(new CapellaTransaction(transactionMethod, result)); - this.Finalize(); + this.Reset(); this.Logger.info("End commiting transaction to Capella"); return result.Get(); } diff --git a/DEHCapellaAdapter/src/Services/CapellaTransaction/ICapellaTransactionService.java b/DEHCapellaAdapter/src/Services/CapellaTransaction/ICapellaTransactionService.java index f3817f8..cb88c6f 100644 --- a/DEHCapellaAdapter/src/Services/CapellaTransaction/ICapellaTransactionService.java +++ b/DEHCapellaAdapter/src/Services/CapellaTransaction/ICapellaTransactionService.java @@ -29,6 +29,7 @@ import org.eclipse.emf.ecore.EObject; import org.polarsys.capella.core.data.capellacore.CapellaElement; import org.polarsys.capella.core.data.capellacore.NamedElement; +import org.polarsys.capella.core.data.cs.BlockArchitecture; import org.polarsys.capella.core.data.cs.Component; import org.polarsys.capella.core.data.information.Unit; import org.polarsys.capella.core.data.information.datatype.DataType; @@ -79,9 +80,9 @@ public interface ICapellaTransactionService Map> GetClones(); /** - * Reset the clones references, by means of finalizing the transaction + * Reset the clones references, the new ones and the registered target architecture */ - void Finalize(); + void Reset(); /** * Adds the provided {@linkplain Unit} to the {@linkplain DataPackage} of the current project @@ -187,4 +188,14 @@ public interface ICapellaTransactionService * @return an assert */ boolean IsNew(TElement element); + + /** + * Gets the original reference from the {@linkplain ClonedReferenceElement} where the element id == the provided {@linkplain #TElement} id. + * In the case the provided element is not a clone, it is returned. + * + * @param the type of the element + * @param element the element + * @return a {@linkplain #TElement} + */ + TElement GetOriginal(TElement element); } diff --git a/DEHCapellaAdapter/src/Services/Mapping/MapCommandService.java b/DEHCapellaAdapter/src/Services/Mapping/MapCommandService.java index ccce830..c7953ca 100644 --- a/DEHCapellaAdapter/src/Services/Mapping/MapCommandService.java +++ b/DEHCapellaAdapter/src/Services/Mapping/MapCommandService.java @@ -424,7 +424,7 @@ void WhenDialogHasBeenClosed(Ref dialogResult, MappingDirection mapping this.logger.catching(t.GetException()); } - this.logService.Append(String.format("Mapping action is done in %s ms", timer.getTime(TimeUnit.MILLISECONDS)), t.GetResult() == true); + this.logService.Append(String.format("Mapping action is done in %s ms", timer.getTime(TimeUnit.MILLISECONDS)), t.GetResult() == null ? false : t.GetResult().booleanValue()); }, t -> this.logger.catching(t)); } diff --git a/DEHCapellaAdapter/src/Services/MappingConfiguration/CapellaMappingConfigurationService.java b/DEHCapellaAdapter/src/Services/MappingConfiguration/CapellaMappingConfigurationService.java index 85c8d38..e34d68d 100644 --- a/DEHCapellaAdapter/src/Services/MappingConfiguration/CapellaMappingConfigurationService.java +++ b/DEHCapellaAdapter/src/Services/MappingConfiguration/CapellaMappingConfigurationService.java @@ -26,13 +26,15 @@ import static Utils.Operators.Operators.AreTheseEquals; import static Utils.Stereotypes.StereotypeUtils.GetChildren; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.Optional; import java.util.UUID; +import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.ImmutableTriple; - +import org.apache.commons.lang3.tuple.MutableTriple; import org.polarsys.capella.core.data.capellacore.CapellaElement; import org.polarsys.capella.core.data.cs.Component; import org.polarsys.capella.core.data.requirement.Requirement; @@ -43,8 +45,11 @@ import Services.CapellaSession.ICapellaSessionService; import Services.CapellaTransaction.ICapellaTransactionService; import Utils.Ref; +import Utils.StreamExtensions; +import ViewModels.Interfaces.IHaveTargetArchitecture; import ViewModels.Interfaces.IMappedElementRowViewModel; import ViewModels.Rows.MappedElementDefinitionRowViewModel; +import ViewModels.Rows.MappedElementRowViewModel; import ViewModels.Rows.MappedHubRequirementRowViewModel; import ViewModels.Rows.MappedRequirementBaseRowViewModel; import ViewModels.Rows.MappedDstRequirementRowViewModel; @@ -109,9 +114,88 @@ public Collection LoadMapping() mappedElements.addAll(this.LoadMapping(sessionsAndElementsMap.get(sessionUri))); } + this.LoadMappingForMissingCapellaElement(mappedElements); + return mappedElements; } - + + /** + * Loading all mapped HubElement that misses their target on the currently loaded Capella Model + * + * @param mappedElements the {@linkplain Collection} of currently {@linkplain IMappedElementRowViewModel} + */ + private void LoadMappingForMissingCapellaElement(ArrayList mappedElements) + { + var mappedElementRowViewModels = StreamExtensions.OfType(mappedElements, MappedElementRowViewModel.class); + + var correspondencesNotLoaded = this.correspondences.stream() + .filter(x -> x.middle.MappingDirection == MappingDirection.FromHubToDst && mappedElementRowViewModels.stream() + .noneMatch(p -> AreTheseEquals(x.right, p.GetHubElement().getIid()))) + .collect(Collectors.toList()); + + for (MutableTriple correspondence : correspondencesNotLoaded) + { + var refMappedElement = new Ref(IMappedElementRowViewModel.class); + + try + { + if(this.TryGetMappedElement(correspondence, MappedHubRequirementRowViewModel.class, cdp4common.engineeringmodeldata.Requirement.class, refMappedElement) + || this.TryGetMappedElement(correspondence, MappedElementDefinitionRowViewModel.class, ElementDefinition.class, refMappedElement)) + { + mappedElements.add((IMappedElementRowViewModel) refMappedElement.Get()); + } + else + { + this.logger.warn(String.format("Could not initialize the IMappedElementRowViewModel for the internalIid [%s] and externalId [%s]", + correspondence.getRight(), correspondence.getMiddle().Identifier)); + } + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException exception) + { + this.logger.catching(exception); + } + } + } + + /** + * Tries to get the {@linkplain IMappedElementRowViewModel} based on the provided correspondence represented by a + * {@linkplain Triple} of {@linkplain UUID}, {@linkplain CapellaExternalIdentifier}, {@linkplain UUID} + * + * if the represented thing is of the provided {@linkplain Class} thingType, a rowViewModelType is initialized and + * sets as the value carried by the provided {@linkplain Ref} of {@linkplain IMappedElementRowViewModel} + * + * @param the type of {@linkplain Thing} the internalId of the correspondence could represent + * @param the type of {@linkplain IMappedElementRowViewModel} & {@linkplain IHaveTargetArchitecture} that should be initialized if the Thing is found + * @param correspondence a {@linkplain Triple} of {@linkplain UUID}, {@linkplain CapellaExternalIdentifier}, {@linkplain UUID} representing an id correspondence + * @param rowViewModelType the {@linkplain Class} of {@linkplain #TRowViewModel} + * @param thingType the {@linkplain Class} of {@linkplain #TThing} + * @param refMappedElement the {@linkplain Ref} of {@linkplain IMappedElementRowViewModel} + * @return a value indicating whether the {@linkplain IMappedElementRowViewModel} could be initialized + * @throws InstantiationException + * @throws IllegalAccessException + * @throws IllegalArgumentException + * @throws InvocationTargetException + * @throws NoSuchMethodException + * @throws SecurityException + */ + private boolean TryGetMappedElement( + MutableTriple correspondence, Class rowViewModelType, Class thingType, Ref refMappedElement) + throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException + { + var refHubElement = new Ref(thingType); + + if(this.hubController.TryGetThingById(correspondence.getRight(), refHubElement)) + { + TRowViewModel newMappedElement = rowViewModelType.getDeclaredConstructor(thingType, MappingDirection.class).newInstance(refHubElement.Get(), MappingDirection.FromHubToDst); + + newMappedElement.SetTargetArchitecture(correspondence.getMiddle().TargetArchitecture); + refMappedElement.Set(newMappedElement); + } + + return refMappedElement.HasValue(); + } + /** * Loads the mapping configuration and generates the map result respectively * @@ -130,13 +214,6 @@ public Collection LoadMapping(Collection LoadMapping(Collection refMappedElementRowViewModel) { - Optional> optionalCorrespondence = this.correspondences.stream() + Optional> optionalCorrespondence = this.correspondences.stream() .filter(x -> AreTheseEquals(x.middle.Identifier, element.getId())) .findFirst(); @@ -263,6 +340,8 @@ public void AddToExternalIdentifierMap(UUID internalId, String externalId, Capel externalIdentifier.Identifier = externalId; externalIdentifier.TargetArchitecture = targetArchitecture; - this.AddToExternalIdentifierMap(internalId, externalIdentifier, x -> x.getMiddle().TargetArchitecture == targetArchitecture); + this.AddToExternalIdentifierMap(internalId, externalIdentifier, + x -> x.getMiddle().TargetArchitecture == targetArchitecture + && AreTheseEquals(x.getRight(), internalId)); } } diff --git a/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewPanelViewModel.java b/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewPanelViewModel.java index d959108..2ae2824 100644 --- a/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewPanelViewModel.java +++ b/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewPanelViewModel.java @@ -280,10 +280,13 @@ public boolean OnSaveLoadMappingConfiguration(String configurationName) return false; } - this.mappingConfigurationService.SetExternalIdentifierMap(this.hubController.GetAvailableExternalIdentifierMap(DstController.THISTOOLNAME) - .stream().filter(x -> AreTheseEquals(x.getName(), configurationName)) - .findFirst() - .orElse(this.CreateNewMappingConfiguration(configurationName))); + if(isNew) + { + this.mappingConfigurationService.SetExternalIdentifierMap(this.hubController.GetAvailableExternalIdentifierMap(DstController.THISTOOLNAME) + .stream().filter(x -> AreTheseEquals(x.getName(), configurationName)) + .findFirst() + .orElse(this.CreateNewMappingConfiguration(configurationName))); + } Task.Run(() -> this.dstController.LoadMapping()); diff --git a/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewViewModel.java b/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewViewModel.java index 0048614..f47eae0 100644 --- a/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewViewModel.java +++ b/DEHCapellaAdapter/src/ViewModels/CapellaImpactViewViewModel.java @@ -308,7 +308,9 @@ private boolean VerifyArchitecture(MappedElementRowViewModel rowViewMod { if(rowViewModel.SwitchIsSelectedValue()) { - this.AddOrRemoveSelectedRowToTransfer(rowViewModel, - row -> + this.AddOrRemoveSelectedRowToTransfer(rowViewModel, row -> { if(this.dstController.GetSelectedHubMapResultForTransfer().stream().noneMatch(x -> x == row.GetElement())) { diff --git a/DEHCapellaAdapter/src/ViewModels/Rows/MappedElementDefinitionRowViewModel.java b/DEHCapellaAdapter/src/ViewModels/Rows/MappedElementDefinitionRowViewModel.java index b8103a2..5f5680c 100644 --- a/DEHCapellaAdapter/src/ViewModels/Rows/MappedElementDefinitionRowViewModel.java +++ b/DEHCapellaAdapter/src/ViewModels/Rows/MappedElementDefinitionRowViewModel.java @@ -88,7 +88,18 @@ public Observable GetTargetArchitectureObservable() public MappedElementDefinitionRowViewModel(ElementDefinition thing, Component dstElement, MappingDirection mappingDirection) { super(thing, ElementDefinition.class, dstElement, mappingDirection); - } + } + + /** + * Initializes a new {@linkplain MappedElementDefinitionRowViewModel} + * + * @param thing the {@linkplain TThing} that is at one end of the mapping + * @param mappingDirection the {@linkplain MappingDirection} to which this mapping applies to + */ + public MappedElementDefinitionRowViewModel(ElementDefinition thing, MappingDirection mappingDirection) + { + super(thing, ElementDefinition.class, null, mappingDirection); + } /** * Initializes a new {@linkplain MappedElementDefinitionRowViewModel} with {@linkplain MappingDirection}.{@code FromDstToHub} diff --git a/DEHCapellaAdapter/tests/DstController/DstControllerTestFixture.java b/DEHCapellaAdapter/tests/DstController/DstControllerTestFixture.java index f9a4f4e..c1674f6 100644 --- a/DEHCapellaAdapter/tests/DstController/DstControllerTestFixture.java +++ b/DEHCapellaAdapter/tests/DstController/DstControllerTestFixture.java @@ -293,7 +293,7 @@ else if(ElementDefinition.class.isAssignableFrom(refParameter.GetType())) this.controller.GetSelectedDstMapResultForTransfer().add(requirement); this.controller.GetSelectedDstMapResultForTransfer().add(elementDefinition); assertTrue(this.controller.Transfer()); - verify(this.hubController, times(8)).Refresh(); + verify(this.hubController, times(10)).Refresh(); } @Test diff --git a/DEHCapellaAdapter/tests/MappingRules/ElementToComponentMappingRuleTestFixture.java b/DEHCapellaAdapter/tests/MappingRules/ElementToComponentMappingRuleTestFixture.java index 61b0c3f..b018885 100644 --- a/DEHCapellaAdapter/tests/MappingRules/ElementToComponentMappingRuleTestFixture.java +++ b/DEHCapellaAdapter/tests/MappingRules/ElementToComponentMappingRuleTestFixture.java @@ -112,6 +112,7 @@ class ElementToComponentMappingRuleTestFixture private TextParameterType stringParameterType; private EnumerationParameterType enumParameterType; private BasicEList literals; + private ElementDefinition elementDefinition3; @BeforeEach public void Setup() @@ -186,7 +187,7 @@ void VerifyTransform() { assertDoesNotThrow(() -> this.mappingRule.Transform(null)); assertDoesNotThrow(() -> this.mappingRule.Transform(mock(List.class))); - assertEquals(3, this.mappingRule.Transform(this.elements).size()); + assertEquals(2, this.mappingRule.Transform(this.elements).size()); when(this.dstController.TryGetElementBy(any(), any(Ref.class))).thenAnswer(x -> { @@ -197,14 +198,14 @@ void VerifyTransform() when(this.transactionService.Clone(any())).thenAnswer(x -> x.getArgument(0)); - assertEquals(3, this.mappingRule.Transform(this.elements).size()); + assertEquals(2, this.mappingRule.Transform(this.elements).size()); this.elements.clear(); this.elements.add(new MappedElementDefinitionRowViewModel(elementDefinition2, null, MappingDirection.FromHubToDst)); assertEquals(1, this.mappingRule.Transform(this.elements).size()); - verify(this.transactionService, times(48)).Create(any(Class.class)); + verify(this.transactionService, times(39)).Create(any(Class.class)); verify(this.transactionService, times(2)).AddReferenceDataToDataPackage(any(PhysicalQuantity.class)); verify(this.transactionService, times(2)).AddReferenceDataToDataPackage(any(Unit.class)); } @@ -307,6 +308,10 @@ private void SetupElements() this.elementDefinition1 = new ElementDefinition(); this.elementDefinition1.setName("elementDefinition1"); this.elementDefinition1.setShortName("elementDefinition1"); + + this.elementDefinition3 = new ElementDefinition(); + this.elementDefinition3.setName("elementDefinition3"); + this.elementDefinition3.setShortName("elementDefinition3"); this.elementUsage0 = new ElementUsage(); this.elementUsage0.setName("elementUsage0"); this.elementUsage0.setShortName("elementUsage0"); @@ -330,7 +335,7 @@ private void SetupElements() this.iteration.getElement().add(this.elementDefinition1); var mappedElement0 = new MappedElementDefinitionRowViewModel(this.elementDefinition0, null, MappingDirection.FromHubToDst); - mappedElement0.SetTargetArchitecture(CapellaArchitecture.LogicalArchitecture); + mappedElement0.SetTargetArchitecture(CapellaArchitecture.PhysicalArchitecture); var mappedElement1 = new MappedElementDefinitionRowViewModel(elementDefinition1, null, MappingDirection.FromHubToDst); mappedElement1.SetTargetArchitecture(CapellaArchitecture.PhysicalArchitecture); diff --git a/DEHCapellaAdapter/tests/Services/MappingConfiguration/CapellaMappingConfigurationServiceTestFixture.java b/DEHCapellaAdapter/tests/Services/MappingConfiguration/CapellaMappingConfigurationServiceTestFixture.java index efb0e3c..7951842 100644 --- a/DEHCapellaAdapter/tests/Services/MappingConfiguration/CapellaMappingConfigurationServiceTestFixture.java +++ b/DEHCapellaAdapter/tests/Services/MappingConfiguration/CapellaMappingConfigurationServiceTestFixture.java @@ -37,6 +37,7 @@ import static org.junit.jupiter.api.Assertions.*; import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.MutableTriple; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.util.URI; import org.junit.jupiter.api.BeforeEach; @@ -63,7 +64,7 @@ public class CapellaMappingConfigurationServiceTestFixture extends CapellaSessio private CapellaMappingConfigurationService service; private ICapellaSessionService sessionService; private URI sessionUri; - private ElementDefinition elementDefinition; + private ElementDefinition elementDefinition0; private cdp4common.engineeringmodeldata.Requirement requirement; private ICapellaTransactionService transactionService; @@ -75,7 +76,7 @@ public void setUp() throws Exception { this.hubController = mock(IHubController.class); when(this.hubController.GetIsSessionOpenObservable()).thenReturn(Observable.fromArray(true, false)); - this.elementDefinition = new ElementDefinition(UUID.randomUUID(), null, null); + this.elementDefinition0 = new ElementDefinition(UUID.randomUUID(), null, null); this.requirement = new cdp4common.engineeringmodeldata.Requirement(UUID.randomUUID(), null, null); var requirementsSpecification = new RequirementsSpecification(); requirementsSpecification.getRequirement().add(this.requirement); @@ -105,16 +106,20 @@ public void VerifyLoadMapping() assertDoesNotThrow(() -> result.Set(this.service.LoadMapping())); assertTrue(result.Get().isEmpty()); - var componentExternalId = new CapellaExternalIdentifier(); - componentExternalId.Identifier = this.LogicalComponentId; - componentExternalId.MappingDirection = MappingDirection.FromDstToHub; + var componentExternalId0 = new CapellaExternalIdentifier(); + componentExternalId0.Identifier = this.LogicalComponentId; + componentExternalId0.MappingDirection = MappingDirection.FromDstToHub; + var componentExternalId1 = new CapellaExternalIdentifier(); + componentExternalId1.Identifier = UUID.randomUUID().toString(); + componentExternalId1.MappingDirection = MappingDirection.FromHubToDst; + var requirementExternalId = new CapellaExternalIdentifier(); requirementExternalId.Identifier = this.UserRequirementId; requirementExternalId.MappingDirection = MappingDirection.FromDstToHub; - this.service.correspondences.add(ImmutableTriple.of(UUID.randomUUID(), componentExternalId, this.elementDefinition.getIid())); - this.service.correspondences.add(ImmutableTriple.of(UUID.randomUUID(), requirementExternalId, this.requirement.getIid())); + this.service.correspondences.add(MutableTriple.of(UUID.randomUUID(), requirementExternalId, this.requirement.getIid())); + this.service.correspondences.add(MutableTriple.of(UUID.randomUUID(), componentExternalId1, this.elementDefinition0.getIid())); when(this.hubController.TryGetThingById(any(UUID.class), any(Ref.class))).thenAnswer(new Answer() { @@ -122,11 +127,15 @@ public void VerifyLoadMapping() public Boolean answer(InvocationOnMock invocation) throws Throwable { var arguments = invocation.getArguments(); - var thing = (Thing)(((UUID)arguments[0]).equals(elementDefinition.getIid()) ? elementDefinition : requirement); + var thing = (Thing)(((UUID)arguments[0]).equals(elementDefinition0.getIid()) ? elementDefinition0 : requirement); ((Ref)arguments[1]).Set(thing); return true; }}); + assertDoesNotThrow(() -> result.Set(this.service.LoadMapping())); + assertFalse(result.Get().isEmpty()); + assertEquals(1, result.Get().size()); + this.service.correspondences.add(MutableTriple.of(UUID.randomUUID(), componentExternalId0, this.elementDefinition0.getIid())); assertDoesNotThrow(() -> result.Set(this.service.LoadMapping())); assertFalse(result.Get().isEmpty()); assertEquals(2, result.Get().size()); diff --git a/DEHCapellaAdapterFeature/feature.xml b/DEHCapellaAdapterFeature/feature.xml index d7711bd..0682de5 100644 --- a/DEHCapellaAdapterFeature/feature.xml +++ b/DEHCapellaAdapterFeature/feature.xml @@ -2,7 +2,7 @@