From 13006beb4954e24a4f4899d521068a257240c2a5 Mon Sep 17 00:00:00 2001 From: laura Date: Mon, 25 Sep 2023 15:44:04 +0200 Subject: [PATCH] replac ModelProviderAgent with ArCoTLModelProviderAgent and add HoldBackElementsExtractor --- .../core/api/models/arcotl/HoldBackModel.java | 44 +++++++++++++ .../ArDoCoForInconsistencyDetection.java | 28 ++------ .../core/execution/runner/ArDoCoForLiSSA.java | 25 ++------ ...oCoForSadCodeTraceabilityLinkRecovery.java | 3 +- ...ForSadSamCodeTraceabilityLinkRecovery.java | 16 +---- ...DoCoForSadSamTraceabilityLinkRecovery.java | 27 ++------ .../core/models/ArCoTLModelProviderAgent.java | 23 +++++-- .../core/models/ModelProviderAgent.java | 2 +- .../generators/HoldBackElementsExtractor.java | 64 +++++++++++++++++++ .../ArCoTLModelProviderInformant.java | 3 +- .../ardoco/core/tests/eval/GoldStandard.java | 6 +- .../InconsistencyDetectionEvaluationIT.java | 32 +++++----- .../HoldBackRunResultsProducer.java | 60 +++++++++-------- 13 files changed, 207 insertions(+), 126 deletions(-) create mode 100644 framework/common/src/main/java/edu/kit/kastel/mcse/ardoco/core/api/models/arcotl/HoldBackModel.java create mode 100644 stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/connectors/generators/HoldBackElementsExtractor.java diff --git a/framework/common/src/main/java/edu/kit/kastel/mcse/ardoco/core/api/models/arcotl/HoldBackModel.java b/framework/common/src/main/java/edu/kit/kastel/mcse/ardoco/core/api/models/arcotl/HoldBackModel.java new file mode 100644 index 000000000..160676653 --- /dev/null +++ b/framework/common/src/main/java/edu/kit/kastel/mcse/ardoco/core/api/models/arcotl/HoldBackModel.java @@ -0,0 +1,44 @@ +package edu.kit.kastel.mcse.ardoco.core.api.models.arcotl; + +import edu.kit.kastel.mcse.ardoco.core.api.models.Entity; + +import java.util.List; +import java.util.Objects; + +public class HoldBackModel extends Model { + + private final List content; + private final List endpoints; + + public HoldBackModel(List content, List endpoints) { + this.content = content; + this.endpoints = endpoints; + } + + @Override + public List getContent() { + return this.content; + } + + @Override + public List getEndpoints() { + return this.endpoints; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + if (!super.equals(o)) + return false; + HoldBackModel that = (HoldBackModel) o; + return Objects.equals(content, that.content) && Objects.equals(endpoints, that.endpoints); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), content, endpoints); + } +} diff --git a/pipeline/pipeline-id/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForInconsistencyDetection.java b/pipeline/pipeline-id/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForInconsistencyDetection.java index 9c09a7500..e0a4891d5 100644 --- a/pipeline/pipeline-id/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForInconsistencyDetection.java +++ b/pipeline/pipeline-id/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForInconsistencyDetection.java @@ -2,47 +2,35 @@ package edu.kit.kastel.mcse.ardoco.core.execution.runner; import java.io.File; -import java.io.IOException; import java.util.Map; -import edu.kit.kastel.mcse.ardoco.core.models.ArCoTLModelProviderAgent; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import edu.kit.kastel.mcse.ardoco.core.api.models.ArchitectureModelType; import edu.kit.kastel.mcse.ardoco.core.common.util.CommonUtilities; import edu.kit.kastel.mcse.ardoco.core.common.util.DataRepositoryHelper; import edu.kit.kastel.mcse.ardoco.core.connectiongenerator.ConnectionGenerator; import edu.kit.kastel.mcse.ardoco.core.execution.ArDoCo; import edu.kit.kastel.mcse.ardoco.core.inconsistency.InconsistencyChecker; +import edu.kit.kastel.mcse.ardoco.core.models.ArCoTLModelProviderAgent; import edu.kit.kastel.mcse.ardoco.core.recommendationgenerator.RecommendationGenerator; import edu.kit.kastel.mcse.ardoco.core.text.providers.TextPreprocessingAgent; import edu.kit.kastel.mcse.ardoco.core.textextraction.TextExtraction; public class ArDoCoForInconsistencyDetection extends ArDoCoRunner { - private static final Logger logger = LoggerFactory.getLogger(ArDoCoForInconsistencyDetection.class); public ArDoCoForInconsistencyDetection(String projectName) { super(projectName); } - public void setUp(File inputText, File inputModelArchitecture, ArchitectureModelType inputArchitectureModelType, File inputCode, Map additionalConfigs, + public void setUp(File inputText, File inputModelArchitecture, ArchitectureModelType inputArchitectureModelType, Map additionalConfigs, File outputDir) { - try { - definePipeline(inputText, inputModelArchitecture, inputArchitectureModelType, inputCode, additionalConfigs); - } catch (IOException e) { - logger.error("Problem in initialising pipeline when loading data (IOException)", e.getCause()); - isSetUp = false; - return; - } + definePipeline(inputText, inputModelArchitecture, inputArchitectureModelType, additionalConfigs); setOutputDirectory(outputDir); isSetUp = true; } public void setUp(String inputTextLocation, String inputArchitectureModelLocation, ArchitectureModelType architectureModelType, - String inputCodeLocation, Map additionalConfigs, String outputDirectory) { - setUp(new File(inputTextLocation), new File(inputArchitectureModelLocation), architectureModelType, new File(inputCodeLocation), additionalConfigs, new File(outputDirectory)); + Map additionalConfigs, String outputDirectory) { + setUp(new File(inputTextLocation), new File(inputArchitectureModelLocation), architectureModelType, additionalConfigs, new File(outputDirectory)); } /** @@ -52,10 +40,8 @@ public void setUp(String inputTextLocation, String inputArchitectureModelLocatio * @param inputArchitectureModel the input architecture file * @param architectureModelType the type of the architecture (e.g., PCM, UML) * @param additionalConfigs the additional configs - * @throws IOException When one of the input files cannot be accessed/loaded */ - private void definePipeline(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, File inputCode, Map additionalConfigs) - throws IOException { + private void definePipeline(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, Map additionalConfigs) { ArDoCo arDoCo = getArDoCo(); var dataRepository = arDoCo.getDataRepository(); var text = CommonUtilities.readInputText(inputText); @@ -65,7 +51,7 @@ private void definePipeline(File inputText, File inputArchitectureModel, Archite DataRepositoryHelper.putInputText(dataRepository, text); arDoCo.addPipelineStep(TextPreprocessingAgent.get(additionalConfigs, dataRepository)); - arDoCo.addPipelineStep(ArCoTLModelProviderAgent.get(inputArchitectureModel, architectureModelType, inputCode, additionalConfigs, dataRepository)); + arDoCo.addPipelineStep(ArCoTLModelProviderAgent.get(inputArchitectureModel, architectureModelType, additionalConfigs, dataRepository)); arDoCo.addPipelineStep(TextExtraction.get(additionalConfigs, dataRepository)); arDoCo.addPipelineStep(RecommendationGenerator.get(additionalConfigs, dataRepository)); arDoCo.addPipelineStep(ConnectionGenerator.get(additionalConfigs, dataRepository)); diff --git a/pipeline/pipeline-lissa/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForLiSSA.java b/pipeline/pipeline-lissa/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForLiSSA.java index 4fba84447..2f0c05790 100644 --- a/pipeline/pipeline-lissa/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForLiSSA.java +++ b/pipeline/pipeline-lissa/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/runner/ArDoCoForLiSSA.java @@ -5,17 +5,13 @@ import java.io.IOException; import java.util.Map; -import edu.kit.kastel.mcse.ardoco.core.models.ArCoTLModelProviderAgent; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import edu.kit.kastel.mcse.ardoco.core.api.models.ArchitectureModelType; import edu.kit.kastel.mcse.ardoco.core.common.util.CommonUtilities; import edu.kit.kastel.mcse.ardoco.core.common.util.DataRepositoryHelper; import edu.kit.kastel.mcse.ardoco.core.connectiongenerator.ConnectionGenerator; import edu.kit.kastel.mcse.ardoco.core.execution.ArDoCo; import edu.kit.kastel.mcse.ardoco.core.inconsistency.InconsistencyChecker; +import edu.kit.kastel.mcse.ardoco.core.models.ArCoTLModelProviderAgent; import edu.kit.kastel.mcse.ardoco.core.recommendationgenerator.RecommendationGenerator; import edu.kit.kastel.mcse.ardoco.core.text.providers.TextPreprocessingAgent; import edu.kit.kastel.mcse.ardoco.core.textextraction.TextExtraction; @@ -25,28 +21,21 @@ * The Runner for the Linking Sketches and Software Architecture Approach (LiSSA) */ public class ArDoCoForLiSSA extends ArDoCoRunner { - private static final Logger logger = LoggerFactory.getLogger(ArDoCoForLiSSA.class); public ArDoCoForLiSSA(String projectName) { super(projectName); } public void setUp(File diagramDirectory, File inputText, File inputModelArchitecture, ArchitectureModelType inputArchitectureModelType, - File inputCode, Map additionalConfigs, File outputDir) { - try { - definePipeline(diagramDirectory, inputText, inputModelArchitecture, inputArchitectureModelType, inputCode, additionalConfigs); - } catch (IOException e) { - logger.error("Problem in initialising pipeline when loading data (IOException)", e.getCause()); - isSetUp = false; - return; - } + Map additionalConfigs, File outputDir) { + definePipeline(diagramDirectory, inputText, inputModelArchitecture, inputArchitectureModelType, additionalConfigs); setOutputDirectory(outputDir); isSetUp = true; } public void setUp(String diagramDirectory, String inputTextLocation, String inputArchitectureModelLocation, ArchitectureModelType architectureModelType, - String inputCodeLocation, Map additionalConfigs, String outputDirectory) { - setUp(new File(diagramDirectory), new File(inputTextLocation), new File(inputArchitectureModelLocation), architectureModelType, new File(inputCodeLocation), + Map additionalConfigs, String outputDirectory) { + setUp(new File(diagramDirectory), new File(inputTextLocation), new File(inputArchitectureModelLocation), architectureModelType, additionalConfigs, new File(outputDirectory)); } @@ -61,7 +50,7 @@ public void setUp(String diagramDirectory, String inputTextLocation, String inpu * @throws IOException When one of the input files cannot be accessed/loaded */ private void definePipeline(File diagramDirectory, File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, - File inputCode, Map additionalConfigs) throws IOException { + Map additionalConfigs) { ArDoCo arDoCo = getArDoCo(); var dataRepository = arDoCo.getDataRepository(); var text = CommonUtilities.readInputText(inputText); @@ -73,7 +62,7 @@ private void definePipeline(File diagramDirectory, File inputText, File inputArc arDoCo.addPipelineStep(DiagramRecognition.get(additionalConfigs, dataRepository)); arDoCo.addPipelineStep(TextPreprocessingAgent.get(additionalConfigs, dataRepository)); - arDoCo.addPipelineStep(ArCoTLModelProviderAgent.get(inputArchitectureModel, architectureModelType, inputCode, additionalConfigs, dataRepository)); + arDoCo.addPipelineStep(ArCoTLModelProviderAgent.get(inputArchitectureModel, architectureModelType, additionalConfigs, dataRepository)); arDoCo.addPipelineStep(TextExtraction.get(additionalConfigs, dataRepository)); arDoCo.addPipelineStep(RecommendationGenerator.get(additionalConfigs, dataRepository)); arDoCo.addPipelineStep(ConnectionGenerator.get(additionalConfigs, dataRepository)); diff --git a/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java b/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java index f7c678d2d..da69d47ad 100644 --- a/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java +++ b/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java @@ -11,7 +11,6 @@ import edu.kit.kastel.mcse.ardoco.core.connectiongenerator.ConnectionGenerator; import edu.kit.kastel.mcse.ardoco.core.execution.runner.ArDoCoRunner; import edu.kit.kastel.mcse.ardoco.core.models.ArCoTLModelProviderAgent; -import edu.kit.kastel.mcse.ardoco.core.models.ModelProviderAgent; import edu.kit.kastel.mcse.ardoco.core.recommendationgenerator.RecommendationGenerator; import edu.kit.kastel.mcse.ardoco.core.text.providers.TextPreprocessingAgent; import edu.kit.kastel.mcse.ardoco.core.textextraction.TextExtraction; @@ -43,7 +42,7 @@ private void definePipeline(File inputText, File inputArchitectureModel, Archite ArCoTLModelProviderAgent arCoTLModelProviderAgent = ArCoTLModelProviderAgent.get(inputArchitectureModel, architectureModelType, inputCode, additionalConfigs, dataRepository); arDoCo.addPipelineStep(arCoTLModelProviderAgent); - arDoCo.addPipelineStep(ModelProviderAgent.getCodeProvider(dataRepository)); +// arDoCo.addPipelineStep(ModelProviderAgent.getCodeProvider(dataRepository)); Todo: is this step needed? arDoCo.addPipelineStep(TextPreprocessingAgent.get(additionalConfigs, dataRepository)); diff --git a/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamCodeTraceabilityLinkRecovery.java b/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamCodeTraceabilityLinkRecovery.java index c230a63ea..62c9740c6 100644 --- a/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamCodeTraceabilityLinkRecovery.java +++ b/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamCodeTraceabilityLinkRecovery.java @@ -2,12 +2,8 @@ package edu.kit.kastel.mcse.ardoco.core.execution; import java.io.File; -import java.io.IOException; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import edu.kit.kastel.mcse.ardoco.core.api.models.ArchitectureModelType; import edu.kit.kastel.mcse.ardoco.core.codetraceability.SadSamCodeTraceabilityLinkRecovery; import edu.kit.kastel.mcse.ardoco.core.codetraceability.SamCodeTraceabilityLinkRecovery; @@ -21,7 +17,6 @@ import edu.kit.kastel.mcse.ardoco.core.textextraction.TextExtraction; public class ArDoCoForSadSamCodeTraceabilityLinkRecovery extends ArDoCoRunner { - private static final Logger logger = LoggerFactory.getLogger(ArDoCoForSadSamCodeTraceabilityLinkRecovery.class); public ArDoCoForSadSamCodeTraceabilityLinkRecovery(String projectName) { super(projectName); @@ -29,20 +24,13 @@ public ArDoCoForSadSamCodeTraceabilityLinkRecovery(String projectName) { public void setUp(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, File inputCode, Map additionalConfigs, File outputDir) { - try { - definePipeline(inputText, inputArchitectureModel, architectureModelType, inputCode, additionalConfigs); - } catch (IOException e) { - logger.error("Problem in initialising pipeline when loading data (IOException)", e.getCause()); - isSetUp = false; - return; - } - + definePipeline(inputText, inputArchitectureModel, architectureModelType, inputCode, additionalConfigs); setOutputDirectory(outputDir); isSetUp = true; } private void definePipeline(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, File inputCode, - Map additionalConfigs) throws IOException { + Map additionalConfigs) { ArDoCo arDoCo = this.getArDoCo(); var dataRepository = arDoCo.getDataRepository(); diff --git a/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamTraceabilityLinkRecovery.java b/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamTraceabilityLinkRecovery.java index 56ef0ebd5..4b5c73aa9 100644 --- a/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamTraceabilityLinkRecovery.java +++ b/pipeline/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/core/execution/ArDoCoForSadSamTraceabilityLinkRecovery.java @@ -2,50 +2,37 @@ package edu.kit.kastel.mcse.ardoco.core.execution; import java.io.File; -import java.io.IOException; import java.util.Map; -import edu.kit.kastel.mcse.ardoco.core.models.ArCoTLModelProviderAgent; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import edu.kit.kastel.mcse.ardoco.core.api.models.ArchitectureModelType; import edu.kit.kastel.mcse.ardoco.core.common.util.CommonUtilities; import edu.kit.kastel.mcse.ardoco.core.common.util.DataRepositoryHelper; import edu.kit.kastel.mcse.ardoco.core.connectiongenerator.ConnectionGenerator; import edu.kit.kastel.mcse.ardoco.core.execution.runner.ArDoCoRunner; +import edu.kit.kastel.mcse.ardoco.core.models.ArCoTLModelProviderAgent; import edu.kit.kastel.mcse.ardoco.core.recommendationgenerator.RecommendationGenerator; import edu.kit.kastel.mcse.ardoco.core.text.providers.TextPreprocessingAgent; import edu.kit.kastel.mcse.ardoco.core.textextraction.TextExtraction; public class ArDoCoForSadSamTraceabilityLinkRecovery extends ArDoCoRunner { - private static final Logger logger = LoggerFactory.getLogger(ArDoCoForSadSamTraceabilityLinkRecovery.class); public ArDoCoForSadSamTraceabilityLinkRecovery(String projectName) { super(projectName); } - public void setUp(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, File inputCode, Map additionalConfigs, + public void setUp(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, Map additionalConfigs, File outputDir) { - try { - definePipeline(inputText, inputArchitectureModel, architectureModelType, inputCode, additionalConfigs); - } catch (IOException e) { - logger.error("Problem in initialising pipeline when loading data (IOException)", e.getCause()); - isSetUp = false; - return; - } + definePipeline(inputText, inputArchitectureModel, architectureModelType, additionalConfigs); setOutputDirectory(outputDir); isSetUp = true; } - public void setUp(String inputTextLocation, String inputArchitectureModelLocation, ArchitectureModelType architectureModelType, String inputCodeLocation, + public void setUp(String inputTextLocation, String inputArchitectureModelLocation, ArchitectureModelType architectureModelType, Map additionalConfigs, String outputDirectory) { - setUp(new File(inputTextLocation), new File(inputArchitectureModelLocation), architectureModelType, new File(inputCodeLocation), additionalConfigs, new File(outputDirectory)); + setUp(new File(inputTextLocation), new File(inputArchitectureModelLocation), architectureModelType, additionalConfigs, new File(outputDirectory)); } - private void definePipeline(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, File inputCode, Map additionalConfigs) - throws IOException { + private void definePipeline(File inputText, File inputArchitectureModel, ArchitectureModelType architectureModelType, Map additionalConfigs) { var dataRepository = this.getArDoCo().getDataRepository(); var text = CommonUtilities.readInputText(inputText); if (text.isBlank()) { @@ -54,7 +41,7 @@ private void definePipeline(File inputText, File inputArchitectureModel, Archite DataRepositoryHelper.putInputText(dataRepository, text); this.getArDoCo().addPipelineStep(TextPreprocessingAgent.get(additionalConfigs, dataRepository)); - this.getArDoCo().addPipelineStep(ArCoTLModelProviderAgent.get(inputArchitectureModel, architectureModelType, inputCode, additionalConfigs, dataRepository)); + this.getArDoCo().addPipelineStep(ArCoTLModelProviderAgent.get(inputArchitectureModel, architectureModelType, additionalConfigs, dataRepository)); this.getArDoCo().addPipelineStep(TextExtraction.get(additionalConfigs, dataRepository)); this.getArDoCo().addPipelineStep(RecommendationGenerator.get(additionalConfigs, dataRepository)); diff --git a/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ArCoTLModelProviderAgent.java b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ArCoTLModelProviderAgent.java index 60ba10ff5..3c125762a 100644 --- a/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ArCoTLModelProviderAgent.java +++ b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ArCoTLModelProviderAgent.java @@ -43,17 +43,32 @@ public ArCoTLModelProviderAgent(DataRepository data, List extractors) public static ArCoTLModelProviderAgent get(File inputArchitectureModel, ArchitectureModelType architectureModelType, File inputCode, Map additionalConfigs, DataRepository dataRepository) { - ArchitectureExtractor architectureExtractor = switch (architectureModelType) { - case PCM -> new PcmExtractor(inputArchitectureModel.getAbsolutePath()); - case UML -> new UmlExtractor(inputArchitectureModel.getAbsolutePath()); - }; + ArchitectureExtractor architectureExtractor = getArchitectureExtractor(inputArchitectureModel, architectureModelType); + CodeItemRepository codeItemRepository = new CodeItemRepository(); CodeExtractor codeExtractor = new AllLanguagesExtractor(codeItemRepository, inputCode.getAbsolutePath()); + ArCoTLModelProviderAgent agent = new ArCoTLModelProviderAgent(dataRepository, List.of(architectureExtractor, codeExtractor)); agent.applyConfiguration(additionalConfigs); return agent; } + public static ArCoTLModelProviderAgent get(File inputArchitectureModel, ArchitectureModelType architectureModelType, + Map additionalConfigs, DataRepository dataRepository) { + ArchitectureExtractor architectureExtractor = getArchitectureExtractor(inputArchitectureModel, architectureModelType); + + ArCoTLModelProviderAgent agent = new ArCoTLModelProviderAgent(dataRepository, List.of(architectureExtractor)); + agent.applyConfiguration(additionalConfigs); + return agent; + } + + private static ArchitectureExtractor getArchitectureExtractor(File inputArchitectureModel, ArchitectureModelType architectureModelType) { + return switch (architectureModelType) { + case PCM -> new PcmExtractor(inputArchitectureModel.getAbsolutePath()); + case UML -> new UmlExtractor(inputArchitectureModel.getAbsolutePath()); + }; + } + @Override protected void delegateApplyConfigurationToInternalObjects(Map additionalConfiguration) { // empty diff --git a/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ModelProviderAgent.java b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ModelProviderAgent.java index d6ba818ab..1f08a8a99 100644 --- a/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ModelProviderAgent.java +++ b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/ModelProviderAgent.java @@ -46,7 +46,7 @@ private ModelProviderAgent(DataRepository data, LegacyCodeModelInformant codeMod } /** - * Creates a {@link ModelProviderInformant} for PCM. + * Creates a {@link ModelProviderAgent} for PCM. * * @param inputArchitectureModel the path to the input PCM * @param architectureModelType the architecture model to use diff --git a/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/connectors/generators/HoldBackElementsExtractor.java b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/connectors/generators/HoldBackElementsExtractor.java new file mode 100644 index 000000000..7480eceeb --- /dev/null +++ b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/connectors/generators/HoldBackElementsExtractor.java @@ -0,0 +1,64 @@ +package edu.kit.kastel.mcse.ardoco.core.models.connectors.generators; + +import java.util.List; + +import edu.kit.kastel.mcse.ardoco.core.api.models.Entity; +import edu.kit.kastel.mcse.ardoco.core.api.models.ModelType; +import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.HoldBackModel; +import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.Model; + +public class HoldBackElementsExtractor extends Extractor { + + private final Extractor actualExtractor; + private int currentHoldBackContentIndex = -1; + private int currentHoldBackEndpointIndex = -1; + + public HoldBackElementsExtractor(String path, Extractor actualExtractor) { + super(path); + this.actualExtractor = actualExtractor; + } + + @Override + public Model extractModel() { + List content = actualExtractor.extractModel().getContent(); + content.remove(currentHoldBackContentIndex); + List endpoints = actualExtractor.extractModel().getEndpoints(); + endpoints.remove(currentHoldBackEndpointIndex); + return new HoldBackModel(content, endpoints); + } + + @Override + public ModelType getModelType() { + return actualExtractor.getModelType(); + } + + public void setCurrentHoldBackContentIndex(int currentHoldBackContentIndex) { + this.currentHoldBackContentIndex = currentHoldBackContentIndex; + } + + public void setCurrentHoldBackEndpointIndex(int currentHoldBackEndpointIndex) { + this.currentHoldBackEndpointIndex = currentHoldBackEndpointIndex; + } + + public Entity getCurrentHoldBackEndpoint() { + if (currentHoldBackEndpointIndex < 0) { + return null; + } + return actualExtractor.extractModel().getEndpoints().get(currentHoldBackEndpointIndex); + } + + public Entity getCurrentHoldBackContent() { + if (currentHoldBackContentIndex < 0) { + return null; + } + return actualExtractor.extractModel().getContent().get(currentHoldBackContentIndex); + } + + public int numberOfActualContents() { + return actualExtractor.extractModel().getContent().size(); + } + + public int numberOfActualEndpoints() { + return actualExtractor.extractModel().getEndpoints().size(); + } +} diff --git a/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/informants/ArCoTLModelProviderInformant.java b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/informants/ArCoTLModelProviderInformant.java index fe56477f6..d80b975f0 100644 --- a/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/informants/ArCoTLModelProviderInformant.java +++ b/stages/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/core/models/informants/ArCoTLModelProviderInformant.java @@ -4,7 +4,6 @@ import java.util.Map; import java.util.Optional; -import edu.kit.kastel.mcse.ardoco.core.api.models.ModelConnector; import edu.kit.kastel.mcse.ardoco.core.api.models.ModelStates; import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.Model; import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.code.CodeModel; @@ -29,7 +28,7 @@ private ArCoTLModelProviderInformant() { } /** - * Instantiates a new model provider that uses the provided {@link ModelConnector} to extract information into the {@link DataRepository}. + * Instantiates a new model provider that uses the provided {@link Extractor} to extract information into the {@link DataRepository}. * * @param dataRepository the data repository * @param extractor the model connector diff --git a/tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/GoldStandard.java b/tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/GoldStandard.java index 168518e07..a5664e382 100644 --- a/tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/GoldStandard.java +++ b/tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/GoldStandard.java @@ -6,6 +6,8 @@ import java.nio.charset.StandardCharsets; import java.util.Scanner; +import edu.kit.kastel.mcse.ardoco.core.api.models.Entity; + import org.eclipse.collections.api.factory.Lists; import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.MutableList; @@ -60,11 +62,11 @@ public ImmutableList getModelInstances(int sentenceNo) { return sentence2instance.get(sentenceNo).toImmutable(); } - public ImmutableList getSentencesWithElement(ModelInstance elem) { + public ImmutableList getSentencesWithElement(Entity elem) { MutableList sentences = Lists.mutable.empty(); for (int i = 0; i < sentence2instance.size(); i++) { var instances = sentence2instance.get(i); - if (instances.anySatisfy(e -> e.getUid().equals(elem.getUid()))) { + if (instances.anySatisfy(e -> e.getUid().equals(elem.getId()))) { sentences.add(i); } } diff --git a/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/InconsistencyDetectionEvaluationIT.java b/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/InconsistencyDetectionEvaluationIT.java index 1e5a2e29c..64661d3b8 100644 --- a/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/InconsistencyDetectionEvaluationIT.java +++ b/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/InconsistencyDetectionEvaluationIT.java @@ -13,6 +13,8 @@ import java.util.Objects; import java.util.stream.Collectors; +import edu.kit.kastel.mcse.ardoco.core.api.models.Entity; + import org.eclipse.collections.api.factory.Lists; import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.MutableList; @@ -103,7 +105,7 @@ void missingModelElementInconsistencyHistoricIT(Project project) { private void runMissingModelElementInconsistencyEval(Project project) { logger.info("Start evaluation of MME-inconsistency for {}", project.name()); - Map runs = produceRuns(project); + Map runs = produceRuns(project); var results = calculateEvaluationResults(project, runs); @@ -147,7 +149,7 @@ private void runMissingModelElementInconsistencyBaselineEval(Project project) { ranBaseline = true; HoldBackRunResultsProducer holdBackRunResultsProducer = new HoldBackRunResultsProducer(); - Map runs = holdBackRunResultsProducer.produceHoldBackRunResults(project, true); + Map runs = holdBackRunResultsProducer.produceHoldBackRunResults(project, true); Assertions.assertTrue(runs != null && runs.size() > 0); @@ -202,10 +204,10 @@ private void runMissingTextInconsistencyEval(Project project) { writeOutResults(project, results); } - private static Map produceRuns(Project project) { + private static Map produceRuns(Project project) { HoldBackRunResultsProducer holdBackRunResultsProducer = new HoldBackRunResultsProducer(); - Map runs = holdBackRunResultsProducer.produceHoldBackRunResults(project, false); + Map runs = holdBackRunResultsProducer.produceHoldBackRunResults(project, false); ArDoCoResult baseArDoCoResult = runs.get(null); saveOutput(project, baseArDoCoResult); @@ -260,14 +262,14 @@ void overAllResultsIT() { } } - private MutableList> calculateEvaluationResults(Project project, Map runs) { + private MutableList> calculateEvaluationResults(Project project, Map runs) { MutableList> results = Lists.mutable.empty(); for (var run : runs.entrySet()) { - ModelInstance modelInstance = run.getKey(); + Entity entity = run.getKey(); ArDoCoResult arDoCoResult = run.getValue(); - var runEvalResults = evaluateRun(project, modelInstance, arDoCoResult); + var runEvalResults = evaluateRun(project, entity, arDoCoResult); if (runEvalResults != null) { results.add(runEvalResults); } else { @@ -279,7 +281,7 @@ private MutableList> calculateEvaluationResults(Projec return results; } - private EvaluationResults evaluateRun(Project project, ModelInstance removedElement, ArDoCoResult arDoCoResult) { + private EvaluationResults evaluateRun(Project project, Entity removedElement, ArDoCoResult arDoCoResult) { var modelId = arDoCoResult.getModelIds().get(0); ImmutableList inconsistencies = arDoCoResult.getInconsistenciesOfTypeForModel(modelId, @@ -330,7 +332,7 @@ private void checkResults(EvaluationResults results, ExpectedResults exp .phiCoefficient() + " is below the expected minimum value " + expectedResults.phiCoefficient())); } - private void writeOutResults(Project project, List> results, Map runs) { + private void writeOutResults(Project project, List> results, Map runs) { var outputs = createOutput(project, results, runs); var outputBuilder = outputs.getOne(); var detailedOutputBuilder = outputs.getTwo(); @@ -392,7 +394,7 @@ private static void saveOutput(Project project, ArDoCoResult arDoCoResult) { } private static Pair createOutput(Project project, List> results, - Map runs) { + Map runs) { StringBuilder outputBuilder = createStringBuilderWithHeader(project); var resultCalculatorStringBuilderPair = inspectResults(results, runs, outputBuilder); var resultCalculator = resultCalculatorStringBuilderPair.getOne(); @@ -461,20 +463,20 @@ private static StringBuilder createStringBuilderWithHeader(Project project) { } private static Pair>, StringBuilder> inspectResults(List> results, - Map runs, StringBuilder outputBuilder) { + Map runs, StringBuilder outputBuilder) { var detailedOutputBuilder = new StringBuilder(); MutableList> resultsWithWeight = Lists.mutable.empty(); int counter = 0; for (var run : runs.entrySet()) { ArDoCoResult arDoCoResult = run.getValue(); - ModelInstance instance = run.getKey(); - if (instance == null) { + Entity entity = run.getKey(); + if (entity == null) { inspectBaseCase(outputBuilder, arDoCoResult); } else { outputBuilder.append("###").append(LINE_SEPARATOR); detailedOutputBuilder.append("###").append(LINE_SEPARATOR); - outputBuilder.append("Removed Instance: ").append(instance.getFullName()); - detailedOutputBuilder.append("Removed Instance: ").append(instance.getFullName()); + outputBuilder.append("Removed Instance: ").append(entity.getName()); + detailedOutputBuilder.append("Removed Instance: ").append(entity.getName()); outputBuilder.append(LINE_SEPARATOR); detailedOutputBuilder.append(LINE_SEPARATOR); var result = results.get(counter++); diff --git a/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/inconsistencyhelper/HoldBackRunResultsProducer.java b/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/inconsistencyhelper/HoldBackRunResultsProducer.java index bccdb5834..637a46da2 100644 --- a/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/inconsistencyhelper/HoldBackRunResultsProducer.java +++ b/tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/integration/inconsistencyhelper/HoldBackRunResultsProducer.java @@ -10,7 +10,7 @@ import org.junit.jupiter.api.Assertions; import edu.kit.kastel.mcse.ardoco.core.api.PreprocessingData; -import edu.kit.kastel.mcse.ardoco.core.api.models.ModelInstance; +import edu.kit.kastel.mcse.ardoco.core.api.models.Entity; import edu.kit.kastel.mcse.ardoco.core.api.output.ArDoCoResult; import edu.kit.kastel.mcse.ardoco.core.common.util.CommonUtilities; import edu.kit.kastel.mcse.ardoco.core.common.util.DataRepositoryHelper; @@ -19,8 +19,9 @@ import edu.kit.kastel.mcse.ardoco.core.execution.ArDoCo; import edu.kit.kastel.mcse.ardoco.core.execution.ConfigurationHelper; import edu.kit.kastel.mcse.ardoco.core.inconsistency.InconsistencyChecker; -import edu.kit.kastel.mcse.ardoco.core.models.connectors.PcmXmlModelConnector; -import edu.kit.kastel.mcse.ardoco.core.models.informants.ModelProviderInformant; +import edu.kit.kastel.mcse.ardoco.core.models.connectors.generators.HoldBackElementsExtractor; +import edu.kit.kastel.mcse.ardoco.core.models.connectors.generators.architecture.pcm.PcmExtractor; +import edu.kit.kastel.mcse.ardoco.core.models.informants.ArCoTLModelProviderInformant; import edu.kit.kastel.mcse.ardoco.core.recommendationgenerator.RecommendationGenerator; import edu.kit.kastel.mcse.ardoco.core.tests.eval.Project; import edu.kit.kastel.mcse.ardoco.core.tests.eval.baseline.InconsistencyBaseline; @@ -28,9 +29,9 @@ import edu.kit.kastel.mcse.ardoco.core.textextraction.TextExtraction; public class HoldBackRunResultsProducer { - private File inputText; + private String inputTextPath; private File inputModel; - private PcmXmlModelConnector pcmModel; + private PcmExtractor pcmExtractor; public HoldBackRunResultsProducer() { super(); @@ -46,17 +47,18 @@ public HoldBackRunResultsProducer() { * @return a map containing the mapping from ModelElement that was held back to the DataStructure that was produced * when running ArDoCo without the ModelElement */ - public Map produceHoldBackRunResults(Project project, boolean useBaselineApproach) { - Map runs = new HashMap(); + public Map produceHoldBackRunResults(Project project, boolean useBaselineApproach) { + Map runs = new HashMap(); + File inputText = project.getTextFile(); inputModel = project.getModelFile(); - inputText = project.getTextFile(); + inputTextPath = inputText.getPath(); - var holdElementsBackModelConnector = constructHoldElementsBackModelConnector(); + var holdBackElementsExtractor = constructHoldBackElementsExtractor(); ArDoCo arDoCoBaseRun; try { - arDoCoBaseRun = definePipelineBase(project, inputText, holdElementsBackModelConnector, useBaselineApproach); + arDoCoBaseRun = definePipelineBase(project, inputText, holdBackElementsExtractor, useBaselineApproach); } catch (IOException e) { Assertions.fail(e); return runs; @@ -65,26 +67,30 @@ public Map produceHoldBackRunResults(Project projec var baseRunData = new ArDoCoResult(arDoCoBaseRun.getDataRepository()); runs.put(null, baseRunData); - for (int i = 0; i < holdElementsBackModelConnector.numberOfActualInstances(); i++) { - holdElementsBackModelConnector.setCurrentHoldBackIndex(i); - var currentHoldBack = holdElementsBackModelConnector.getCurrentHoldBack(); - var currentRun = defineArDoCoWithPreComputedData(baseRunData, holdElementsBackModelConnector, useBaselineApproach); + for (int i = 0; i < holdBackElementsExtractor.numberOfActualContents(); i++) { + holdBackElementsExtractor.setCurrentHoldBackContentIndex(i); + var currentHoldBack = holdBackElementsExtractor.getCurrentHoldBackContent(); + var currentRun = defineArDoCoWithPreComputedData(baseRunData, holdBackElementsExtractor, useBaselineApproach); + currentRun.run(); + runs.put(currentHoldBack, new ArDoCoResult(currentRun.getDataRepository())); + } + + for (int i = 0; i < holdBackElementsExtractor.numberOfActualEndpoints(); i++) { + holdBackElementsExtractor.setCurrentHoldBackEndpointIndex(i); + var currentHoldBack = holdBackElementsExtractor.getCurrentHoldBackEndpoint(); + var currentRun = defineArDoCoWithPreComputedData(baseRunData, holdBackElementsExtractor, useBaselineApproach); currentRun.run(); runs.put(currentHoldBack, new ArDoCoResult(currentRun.getDataRepository())); } return runs; } - private HoldElementsBackModelConnector constructHoldElementsBackModelConnector() { - try { - pcmModel = new PcmXmlModelConnector(inputModel); - } catch (IOException e) { - throw new RuntimeException(e); - } - return new HoldElementsBackModelConnector(pcmModel); + private HoldBackElementsExtractor constructHoldBackElementsExtractor() { + pcmExtractor = new PcmExtractor(inputTextPath); + return new HoldBackElementsExtractor(inputTextPath, pcmExtractor); } - private static ArDoCo definePipelineBase(Project project, File inputText, HoldElementsBackModelConnector holdElementsBackModelConnector, + private static ArDoCo definePipelineBase(Project project, File inputText, HoldBackElementsExtractor holdBackElementsExtractor, boolean useInconsistencyBaseline) throws FileNotFoundException { ArDoCo arDoCo = new ArDoCo(project.name().toLowerCase()); var dataRepository = arDoCo.getDataRepository(); @@ -94,7 +100,7 @@ private static ArDoCo definePipelineBase(Project project, File inputText, HoldEl arDoCo.addPipelineStep(TextPreprocessingAgent.get(additionalConfigs, dataRepository)); - addMiddleSteps(holdElementsBackModelConnector, arDoCo, dataRepository, additionalConfigs); + addMiddleSteps(holdBackElementsExtractor, arDoCo, dataRepository, additionalConfigs); if (useInconsistencyBaseline) { arDoCo.addPipelineStep(new InconsistencyBaseline(dataRepository)); @@ -105,7 +111,7 @@ private static ArDoCo definePipelineBase(Project project, File inputText, HoldEl return arDoCo; } - private static ArDoCo defineArDoCoWithPreComputedData(ArDoCoResult precomputedResults, HoldElementsBackModelConnector holdElementsBackModelConnector, + private static ArDoCo defineArDoCoWithPreComputedData(ArDoCoResult precomputedResults, HoldBackElementsExtractor holdBackElementsExtractor, boolean useInconsistencyBaseline) { var projectName = precomputedResults.getProjectName(); ArDoCo arDoCo = new ArDoCo(projectName); @@ -120,7 +126,7 @@ private static ArDoCo defineArDoCoWithPreComputedData(ArDoCoResult precomputedRe var preprocessingData = new PreprocessingData(precomputedResults.getText()); dataRepository.addData(PreprocessingData.ID, preprocessingData); - addMiddleSteps(holdElementsBackModelConnector, arDoCo, dataRepository, additionalConfigs); + addMiddleSteps(holdBackElementsExtractor, arDoCo, dataRepository, additionalConfigs); if (useInconsistencyBaseline) { arDoCo.addPipelineStep(new InconsistencyBaseline(dataRepository)); @@ -130,9 +136,9 @@ private static ArDoCo defineArDoCoWithPreComputedData(ArDoCoResult precomputedRe return arDoCo; } - private static void addMiddleSteps(HoldElementsBackModelConnector holdElementsBackModelConnector, ArDoCo arDoCo, DataRepository dataRepository, + private static void addMiddleSteps(HoldBackElementsExtractor holdBackElementsExtractor, ArDoCo arDoCo, DataRepository dataRepository, Map additionalConfigs) { - arDoCo.addPipelineStep(new ModelProviderInformant(dataRepository, holdElementsBackModelConnector)); + arDoCo.addPipelineStep(new ArCoTLModelProviderInformant(dataRepository, holdBackElementsExtractor)); arDoCo.addPipelineStep(TextExtraction.get(additionalConfigs, dataRepository)); arDoCo.addPipelineStep(RecommendationGenerator.get(additionalConfigs, dataRepository)); arDoCo.addPipelineStep(ConnectionGenerator.get(additionalConfigs, dataRepository));