From 89a1cf0f0e71fb1e82458c8de99d9abc8a59351a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Fuch=C3=9F?= Date: Thu, 22 Aug 2024 16:12:11 +0200 Subject: [PATCH 1/3] Loading of ACM files is possible for code now. --- ...oCoForSadCodeTraceabilityLinkRecovery.java | 10 ++- ...ForSadSamCodeTraceabilityLinkRecovery.java | 14 ++-- ...DoCoForSadSamTraceabilityLinkRecovery.java | 7 +- ...oCoForSamCodeTraceabilityLinkRecovery.java | 10 ++- .../agents/ArCoTLModelProviderAgent.java | 80 +++++++++++-------- .../agents/ArchitectureConfiguration.java | 27 +++++++ .../tlr/models/agents/CodeConfiguration.java | 44 ++++++++++ .../generators/code/CodeExtractor.java | 5 -- .../ArCoTLModelProviderInformant.java | 44 ++++++---- .../ardoco/core/tests/eval/CodeProject.java | 49 +++--------- .../ardoco/core/tests/eval/ProjectHelper.java | 5 -- .../core/tests/eval/CodeProjectTest.java | 3 +- .../HoldBackArCoTLModelProvider.java | 13 ++- ...odeTraceabilityLinkRecoveryEvaluation.java | 9 ++- ...odeTraceabilityLinkRecoveryEvaluation.java | 8 +- ...odeTraceabilityLinkRecoveryEvaluation.java | 9 ++- .../integration/TraceLinkEvaluationIT.java | 30 ++----- .../TraceLinkEvaluationSadCodeDirectIT.java | 5 +- .../TraceabilityLinkRecoveryEvaluation.java | 12 +-- 19 files changed, 234 insertions(+), 150 deletions(-) create mode 100644 stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArchitectureConfiguration.java create mode 100644 stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/CodeConfiguration.java diff --git a/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java b/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java index 07900bf..1385163 100644 --- a/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java +++ b/pipeline-tlr/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/execution/ArDoCoForSadCodeTraceabilityLinkRecovery.java @@ -4,12 +4,12 @@ import java.io.File; import java.util.SortedMap; -import edu.kit.kastel.mcse.ardoco.core.execution.ArDoCo; -import edu.kit.kastel.mcse.ardoco.tlr.codetraceability.SadCodeTraceabilityLinkRecovery; 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.tlr.connectiongenerator.ConnectionGenerator; +import edu.kit.kastel.mcse.ardoco.core.execution.ArDoCo; import edu.kit.kastel.mcse.ardoco.core.execution.runner.ArDoCoRunner; +import edu.kit.kastel.mcse.ardoco.tlr.codetraceability.SadCodeTraceabilityLinkRecovery; +import edu.kit.kastel.mcse.ardoco.tlr.connectiongenerator.ConnectionGenerator; import edu.kit.kastel.mcse.ardoco.tlr.models.agents.ArCoTLModelProviderAgent; import edu.kit.kastel.mcse.ardoco.tlr.recommendationgenerator.RecommendationGenerator; import edu.kit.kastel.mcse.ardoco.tlr.text.providers.TextPreprocessingAgent; @@ -36,7 +36,9 @@ private void definePipeline(File inputText, File inputCode, SortedMap extractors) { - super(informants(data, extractors), ArCoTLModelProviderAgent.class.getSimpleName(), data); + public ArCoTLModelProviderAgent(DataRepository data, ArchitectureConfiguration architectureConfiguration, CodeConfiguration codeConfiguration) { + super(informants(data, architectureConfiguration, codeConfiguration), ArCoTLModelProviderAgent.class.getSimpleName(), data); } - private static List informants(DataRepository data, List extractors) { - return extractors.stream().map(e -> new ArCoTLModelProviderInformant(data, e)).toList(); - } - - public static ArCoTLModelProviderAgent get(File inputArchitectureModel, ArchitectureModelType architectureModelType, File inputCode, - SortedMap additionalConfigs, DataRepository dataRepository) { - - List extractors = new ArrayList<>(); + private static List informants(DataRepository data, ArchitectureConfiguration architectureConfiguration, + CodeConfiguration codeConfiguration) { + List informants = new ArrayList<>(); + if (architectureConfiguration != null) { + informants.add(new ArCoTLModelProviderInformant(data, architectureConfiguration.extractor())); + } - if (inputArchitectureModel != null && architectureModelType != null) { - ArchitectureExtractor architectureExtractor = switch (architectureModelType) { - case PCM -> new PcmExtractor(inputArchitectureModel.getAbsolutePath()); - case UML -> new UmlExtractor(inputArchitectureModel.getAbsolutePath()); - }; - extractors.add(architectureExtractor); + if (codeConfiguration != null && codeConfiguration.type() == CodeConfiguration.CodeConfigurationType.ACM_FILE) { + informants.add(new ArCoTLModelProviderInformant(data, codeConfiguration.code())); } - if (inputCode != null) { - CodeItemRepository codeItemRepository = new CodeItemRepository(); - CodeExtractor codeExtractor = new AllLanguagesExtractor(codeItemRepository, inputCode.getAbsolutePath()); - extractors.add(codeExtractor); + if (codeConfiguration != null && codeConfiguration.type() == CodeConfiguration.CodeConfigurationType.DIRECTORY) { + for (Extractor e : codeConfiguration.extractors()) { + informants.add(new ArCoTLModelProviderInformant(data, e)); + } } - if (extractors.isEmpty()) { - throw new IllegalArgumentException("No model extractor was provided."); + return informants; + } + + public static ArCoTLModelProviderAgent getArCoTLModelProviderAgent(DataRepository dataRepository, SortedMap additionalConfigs, + ArchitectureConfiguration architectureConfiguration, CodeConfiguration codeConfiguration) { + if (architectureConfiguration == null && codeConfiguration == null) { + throw new IllegalArgumentException("At least one configuration must be provided"); } - ArCoTLModelProviderAgent agent = new ArCoTLModelProviderAgent(dataRepository, extractors); + var agent = new ArCoTLModelProviderAgent(dataRepository, architectureConfiguration, codeConfiguration); agent.applyConfiguration(additionalConfigs); return agent; } @@ -71,4 +65,22 @@ public static ArCoTLModelProviderAgent get(File inputArchitectureModel, Architec protected void delegateApplyConfigurationToInternalObjects(SortedMap additionalConfiguration) { // empty } + + public static CodeConfiguration getCodeConfiguration(File inputCode) { + if (inputCode == null) { + throw new IllegalArgumentException("Code file must not be null"); + } + + if (inputCode.isFile()) { + return new CodeConfiguration(inputCode, CodeConfiguration.CodeConfigurationType.ACM_FILE); + } + + // Legacy Support for only ACM_FILE in a directory + // TODO: Maybe delete in the future + if (inputCode.isDirectory() && new File(inputCode, "codeModel.acm").exists()) { + return new CodeConfiguration(new File(inputCode, "codeModel.acm"), CodeConfiguration.CodeConfigurationType.ACM_FILE); + } + + return new CodeConfiguration(inputCode, CodeConfiguration.CodeConfigurationType.DIRECTORY); + } } diff --git a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArchitectureConfiguration.java b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArchitectureConfiguration.java new file mode 100644 index 0000000..da4e599 --- /dev/null +++ b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArchitectureConfiguration.java @@ -0,0 +1,27 @@ +/* Licensed under MIT 2024. */ +package edu.kit.kastel.mcse.ardoco.tlr.models.agents; + +import java.io.File; + +import edu.kit.kastel.mcse.ardoco.core.api.models.ArchitectureModelType; +import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.Extractor; +import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.architecture.pcm.PcmExtractor; +import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.architecture.uml.UmlExtractor; + +public record ArchitectureConfiguration(File architectureFile, ArchitectureModelType type) { + public ArchitectureConfiguration { + if (architectureFile == null || type == null) { + throw new IllegalArgumentException("Architecture file and type must not be null"); + } + if (!architectureFile.exists() || !architectureFile.isFile()) { + throw new IllegalArgumentException("Architecture file must exist and be a file"); + } + } + + public Extractor extractor() { + return switch (type) { + case PCM -> new PcmExtractor(architectureFile.getAbsolutePath()); + case UML -> new UmlExtractor(architectureFile.getAbsolutePath()); + }; + } +} diff --git a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/CodeConfiguration.java b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/CodeConfiguration.java new file mode 100644 index 0000000..27bc05a --- /dev/null +++ b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/CodeConfiguration.java @@ -0,0 +1,44 @@ +/* Licensed under MIT 2024. */ +package edu.kit.kastel.mcse.ardoco.tlr.models.agents; + +import java.io.File; +import java.util.List; + +import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.code.CodeItemRepository; +import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.Extractor; +import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.code.AllLanguagesExtractor; +import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.code.CodeExtractor; + +public record CodeConfiguration(File code, CodeConfigurationType type) { + + public CodeConfiguration { + if (code == null || type == null) { + throw new IllegalArgumentException("Code file and type must not be null"); + } + + if (!code.exists()) { + throw new IllegalArgumentException("Code file must exist"); + } + + if (type == CodeConfigurationType.DIRECTORY && code.isFile()) { + throw new IllegalArgumentException("Code file must be a directory in DIRECTORY mode"); + } + + if (type == CodeConfigurationType.ACM_FILE && !code.isFile()) { + throw new IllegalArgumentException("Code file must be a file in ACM_FILE mode"); + } + } + + public List extractors() { + if (type == CodeConfigurationType.DIRECTORY) { + CodeItemRepository codeItemRepository = new CodeItemRepository(); + CodeExtractor codeExtractor = new AllLanguagesExtractor(codeItemRepository, code.getAbsolutePath()); + return List.of(codeExtractor); + } + throw new IllegalStateException("CodeConfigurationType not supported"); + } + + public enum CodeConfigurationType { + DIRECTORY, ACM_FILE + } +} diff --git a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/connectors/generators/code/CodeExtractor.java b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/connectors/generators/code/CodeExtractor.java index 76eae39..141ec02 100644 --- a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/connectors/generators/code/CodeExtractor.java +++ b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/connectors/generators/code/CodeExtractor.java @@ -57,11 +57,6 @@ public void writeOutCodeModel(CodeModel codeModel) { writeOutCodeModel(codeModel, file); } - public CodeModel readInCodeModel() { - File codeModelFile = new File(this.getCodeModelFileString()); - return readInCodeModel(codeModelFile); - } - public static CodeModel readInCodeModel(File codeModelFile) { if (codeModelFile != null && codeModelFile.isFile()) { logger.info("Reading in existing code model."); diff --git a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/informants/ArCoTLModelProviderInformant.java b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/informants/ArCoTLModelProviderInformant.java index 3c6f221..ed64778 100644 --- a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/informants/ArCoTLModelProviderInformant.java +++ b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/informants/ArCoTLModelProviderInformant.java @@ -1,17 +1,19 @@ /* Licensed under MIT 2021-2024. */ package edu.kit.kastel.mcse.ardoco.tlr.models.informants; +import java.io.File; import java.util.Optional; import java.util.SortedMap; +import edu.kit.kastel.mcse.ardoco.core.api.models.CodeModelType; import edu.kit.kastel.mcse.ardoco.core.api.models.ModelStates; import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.CodeModel; import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.Model; import edu.kit.kastel.mcse.ardoco.core.common.IdentifierProvider; import edu.kit.kastel.mcse.ardoco.core.data.DataRepository; +import edu.kit.kastel.mcse.ardoco.core.pipeline.agent.Informant; import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.Extractor; import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.code.CodeExtractor; -import edu.kit.kastel.mcse.ardoco.core.pipeline.agent.Informant; /** * The model extractor extracts the instances and relations via a connector. The extracted items are stored in a model extraction state. @@ -19,12 +21,26 @@ public final class ArCoTLModelProviderInformant extends Informant { private static final String MODEL_STATES_DATA = "ModelStatesData"; private final Extractor extractor; + private final File fromFile; // Needed for Configuration Generation @SuppressWarnings("unused") private ArCoTLModelProviderInformant() { super(null, null); this.extractor = null; + this.fromFile = null; + } + + /** + * Instantiates a new model provider to extract information into the {@link DataRepository}. + * + * @param dataRepository the data repository + * @param fromFile whether the model should be read from a file + */ + public ArCoTLModelProviderInformant(DataRepository dataRepository, File fromFile) { + super("Extractor File", dataRepository); + this.fromFile = fromFile; + this.extractor = null; } /** @@ -34,29 +50,27 @@ private ArCoTLModelProviderInformant() { * @param extractor the model connector */ public ArCoTLModelProviderInformant(DataRepository dataRepository, Extractor extractor) { - super("Extractor " + extractor.getClass().getSimpleName(), dataRepository); + super("Extractor " + (extractor == null ? "File" : extractor.getClass().getSimpleName()), dataRepository); this.extractor = extractor; + this.fromFile = null; } @Override public void process() { - if (extractor == null) { + Model extractedModel; + + if (fromFile != null) { + extractedModel = CodeExtractor.readInCodeModel(this.fromFile); + addModelStateToDataRepository(CodeModelType.CODE_MODEL.getModelId(), extractedModel); return; } IdentifierProvider.reset(); - - Model extractedModel = null; - if (extractor instanceof CodeExtractor codeExtractor) { - extractedModel = codeExtractor.readInCodeModel(); - } - - if (extractedModel == null) { - logger.info("Extracting code model."); - extractedModel = extractor.extractModel(); - if (extractor instanceof CodeExtractor codeExtractor && extractedModel instanceof CodeModel codeModel) { - codeExtractor.writeOutCodeModel(codeModel); - } + logger.info("Extracting code model."); + extractedModel = extractor.extractModel(); + if (extractor instanceof CodeExtractor codeExtractor && extractedModel instanceof CodeModel codeModel) { + logger.info("Writing out code model to file in directory."); + codeExtractor.writeOutCodeModel(codeModel); } addModelStateToDataRepository(extractor.getModelId(), extractedModel); } diff --git a/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java b/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java index bab51bb..9fdfab9 100644 --- a/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java +++ b/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java @@ -1,11 +1,10 @@ /* Licensed under MIT 2023-2024. */ package edu.kit.kastel.mcse.ardoco.core.tests.eval; +import static edu.kit.kastel.mcse.ardoco.core.tests.eval.ProjectHelper.loadFileFromResources; + import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; @@ -146,40 +145,18 @@ public String getCommitHash() { } /** - * {@return path of the code directory} - */ - public String getCodeLocation() { - return getTemporaryCodeLocation().getAbsolutePath(); - } - - /** - * {@return the directory of the code model} - */ - public String getCodeModelDirectory() { - try { - loadCodeModelFromResourcesIfNeeded(); - return getTemporaryCodeLocation().getAbsolutePath(); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - /** - * Loads the code from resources or from the code directoy cache + * Get Code Location (ACM File or Temporary Directory) + * + * @param acmFile If true, the ACM file is loaded from resources * - * @throws IOException Can occur during file operations */ - public void loadCodeModelFromResourcesIfNeeded() throws IOException { - if (ProjectHelper.ANALYZE_CODE_DIRECTLY.get()) - return; - - File temporaryCodeLocation = getTemporaryCodeLocation(); - File codeModelFile = new File(temporaryCodeLocation + "/codeModel.acm"); - try (InputStream is = getClass().getResourceAsStream(this.codeModelLocationInResources)) { - try (FileOutputStream fos = new FileOutputStream(codeModelFile)) { - is.transferTo(fos); - } + public File getCodeLocation(boolean acmFile) { + if (acmFile) { + // If ACM load file from resources + return loadFileFromResources(this.codeModelLocationInResources); } + + return getTemporaryCodeLocation(); } /** @@ -202,7 +179,7 @@ public ExpectedResults getExpectedResultsForSadSamCode() { * @see TraceLinkUtilities#createTraceLinkString(String, String) */ public ImmutableList getSamCodeGoldStandard() { - File samCodeGoldStandardFile = ProjectHelper.loadFileFromResources(samCodeGoldStandardLocation); + File samCodeGoldStandardFile = loadFileFromResources(samCodeGoldStandardLocation); List lines = getLinesFromGoldStandardFile(samCodeGoldStandardFile); MutableList goldStandard = Lists.mutable.empty(); @@ -222,7 +199,7 @@ public ImmutableList getSamCodeGoldStandard() { * {@return all lines from the gold standard in csv format} */ public ImmutableList getSadCodeGoldStandard() { - File sadCodeGoldStandardFile = ProjectHelper.loadFileFromResources(sadCodeGoldStandardLocation); + File sadCodeGoldStandardFile = loadFileFromResources(sadCodeGoldStandardLocation); List lines = getLinesFromGoldStandardFile(sadCodeGoldStandardFile); return Lists.immutable.ofAll(lines); } diff --git a/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/ProjectHelper.java b/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/ProjectHelper.java index 45a5465..009099a 100644 --- a/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/ProjectHelper.java +++ b/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/ProjectHelper.java @@ -6,16 +6,11 @@ import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; -import java.util.concurrent.atomic.AtomicBoolean; /** * Helper class for {@link GoldStandardProject} implementations. */ public class ProjectHelper { - /** - * If set to false. The CodeProject will place the codeModel.acm file from the benchmark to the project directory. - */ - public static final AtomicBoolean ANALYZE_CODE_DIRECTLY = new AtomicBoolean(false); private ProjectHelper() { throw new IllegalAccessError(); diff --git a/tests/integration-tests/tests-base/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProjectTest.java b/tests/integration-tests/tests-base/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProjectTest.java index fff77ce..dbe3c76 100644 --- a/tests/integration-tests/tests-base/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProjectTest.java +++ b/tests/integration-tests/tests-base/src/test/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProjectTest.java @@ -12,8 +12,7 @@ void testFiles(CodeProject project) { Assertions.assertNotNull(project); Assertions.assertNotNull(project.getCodeRepository()); Assertions.assertNotNull(project.getCommitHash()); - Assertions.assertNotNull(project.getCodeLocation()); - Assertions.assertNotNull(project.getCodeModelDirectory()); + Assertions.assertNotNull(project.getCodeLocation(true)); Assertions.assertNotNull(project.getExpectedResultsForSamCode()); Assertions.assertNotNull(project.getExpectedResultsForSadSamCode()); Assertions.assertNotNull(project.getSamCodeGoldStandard()); diff --git a/tests/integration-tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/id/tests/integration/inconsistencyhelper/HoldBackArCoTLModelProvider.java b/tests/integration-tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/id/tests/integration/inconsistencyhelper/HoldBackArCoTLModelProvider.java index de6f019..9d64926 100644 --- a/tests/integration-tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/id/tests/integration/inconsistencyhelper/HoldBackArCoTLModelProvider.java +++ b/tests/integration-tests/tests-inconsistency/src/test/java/edu/kit/kastel/mcse/ardoco/id/tests/integration/inconsistencyhelper/HoldBackArCoTLModelProvider.java @@ -16,9 +16,11 @@ import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.Model; import edu.kit.kastel.mcse.ardoco.core.api.models.arcotl.architecture.ArchitectureComponent; import edu.kit.kastel.mcse.ardoco.core.data.DataRepository; +import edu.kit.kastel.mcse.ardoco.core.pipeline.agent.PipelineAgent; import edu.kit.kastel.mcse.ardoco.tlr.models.agents.ArCoTLModelProviderAgent; import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.Extractor; import edu.kit.kastel.mcse.ardoco.tlr.models.connectors.generators.architecture.pcm.PcmExtractor; +import edu.kit.kastel.mcse.ardoco.tlr.models.informants.ArCoTLModelProviderInformant; public class HoldBackArCoTLModelProvider { @@ -72,8 +74,8 @@ public ModelElement getCurrentHoldBack() { return components.get(currentHoldBackIndex); } - public ArCoTLModelProviderAgent get(SortedMap additionalConfigs, DataRepository dataRepository) { - ArCoTLModelProviderAgent agent = new ArCoTLModelProviderAgent(dataRepository, List.of(new Extractor("") { + public PipelineAgent get(SortedMap additionalConfigs, DataRepository dataRepository) { + PipelineAgent agent = new PipelineAgent(List.of(new ArCoTLModelProviderInformant(dataRepository, new Extractor("") { @Override public Model extractModel() { var elements = new ArrayList<>(initialModel.getContent()); @@ -86,7 +88,12 @@ public Model extractModel() { public ModelType getModelType() { return ArchitectureModelType.PCM; } - })); + })), ArCoTLModelProviderAgent.class.getSimpleName(), dataRepository) { + @Override + protected void delegateApplyConfigurationToInternalObjects(SortedMap additionalConfiguration) { + // empty + } + }; agent.applyConfiguration(additionalConfigs); return agent; } diff --git a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadCodeTraceabilityLinkRecoveryEvaluation.java b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadCodeTraceabilityLinkRecoveryEvaluation.java index fc5b62d..dbc44cd 100644 --- a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadCodeTraceabilityLinkRecoveryEvaluation.java +++ b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadCodeTraceabilityLinkRecoveryEvaluation.java @@ -26,6 +26,13 @@ class SadCodeTraceabilityLinkRecoveryEvaluation extends TraceabilityLinkRecoveryEvaluation { + private final boolean acmFile; + + public SadCodeTraceabilityLinkRecoveryEvaluation(boolean acmFile) { + super(); + this.acmFile = acmFile; + } + @Override protected boolean resultHasRequiredData(ArDoCoResult arDoCoResult) { var traceLinks = arDoCoResult.getSadCodeTraceLinks(); @@ -36,7 +43,7 @@ protected boolean resultHasRequiredData(ArDoCoResult arDoCoResult) { protected ArDoCoRunner getAndSetupRunner(CodeProject codeProject) { String name = codeProject.name().toLowerCase(); File textInput = codeProject.getTextFile(); - File inputCode = getInputCode(codeProject); + File inputCode = getInputCode(codeProject, acmFile); SortedMap additionalConfigsMap = new TreeMap<>(); File outputDir = new File(OUTPUT); diff --git a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadSamCodeTraceabilityLinkRecoveryEvaluation.java b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadSamCodeTraceabilityLinkRecoveryEvaluation.java index 4c71193..d8a50b2 100644 --- a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadSamCodeTraceabilityLinkRecoveryEvaluation.java +++ b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SadSamCodeTraceabilityLinkRecoveryEvaluation.java @@ -25,6 +25,12 @@ import edu.kit.kastel.mcse.ardoco.tlr.execution.ArDoCoForSadSamCodeTraceabilityLinkRecovery; class SadSamCodeTraceabilityLinkRecoveryEvaluation extends TraceabilityLinkRecoveryEvaluation { + private final boolean acmFile; + + public SadSamCodeTraceabilityLinkRecoveryEvaluation(boolean acmFile) { + super(); + this.acmFile = acmFile; + } @Override protected boolean resultHasRequiredData(ArDoCoResult arDoCoResult) { @@ -37,7 +43,7 @@ protected ArDoCoRunner getAndSetupRunner(CodeProject codeProject) { String name = codeProject.name().toLowerCase(); File textInput = codeProject.getTextFile(); File inputArchitectureModel = codeProject.getModelFile(); - File inputCode = getInputCode(codeProject); + File inputCode = getInputCode(codeProject, acmFile); SortedMap additionalConfigsMap = new TreeMap<>(); File outputDir = new File(OUTPUT); diff --git a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SamCodeTraceabilityLinkRecoveryEvaluation.java b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SamCodeTraceabilityLinkRecoveryEvaluation.java index ae136f1..8316364 100644 --- a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SamCodeTraceabilityLinkRecoveryEvaluation.java +++ b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/SamCodeTraceabilityLinkRecoveryEvaluation.java @@ -23,6 +23,13 @@ class SamCodeTraceabilityLinkRecoveryEvaluation extends TraceabilityLinkRecoveryEvaluation { + private final boolean acmFile; + + public SamCodeTraceabilityLinkRecoveryEvaluation(boolean acmFile) { + super(); + this.acmFile = acmFile; + } + @Override protected boolean resultHasRequiredData(ArDoCoResult arDoCoResult) { var traceLinks = arDoCoResult.getSamCodeTraceLinks(); @@ -32,7 +39,7 @@ protected boolean resultHasRequiredData(ArDoCoResult arDoCoResult) { @Override protected ArDoCoForSamCodeTraceabilityLinkRecovery getAndSetupRunner(CodeProject codeProject) { String name = codeProject.name().toLowerCase(); - File inputCode = getInputCode(codeProject); + File inputCode = getInputCode(codeProject, acmFile); File inputArchitectureModel = codeProject.getModelFile(); SortedMap additionalConfigsMap = new TreeMap<>(); File outputDir = new File(OUTPUT); diff --git a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationIT.java b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationIT.java index 25c165b..9cecb01 100644 --- a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationIT.java +++ b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationIT.java @@ -1,11 +1,8 @@ /* Licensed under MIT 2023-2024. */ package edu.kit.kastel.mcse.ardoco.tlr.tests.integration; -import static edu.kit.kastel.mcse.ardoco.core.tests.eval.ProjectHelper.ANALYZE_CODE_DIRECTLY; - import java.util.Arrays; import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.*; import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; @@ -25,7 +22,6 @@ class TraceLinkEvaluationIT { protected static final String OUTPUT = "target/testout-tlr-it"; protected static final String LOGGING_ARDOCO_CORE = "org.slf4j.simpleLogger.log.edu.kit.kastel.mcse.ardoco.core"; - protected static AtomicBoolean analyzeCodeDirectly = ANALYZE_CODE_DIRECTLY; @BeforeAll static void beforeAll() { @@ -38,7 +34,7 @@ static void afterAll() { } private static void cleanUpCodeRepository(CodeProject codeProject) { - RepositoryHandler.removeRepository(codeProject.getCodeLocation()); + RepositoryHandler.removeRepository(codeProject.getCodeLocation(false).getAbsolutePath()); } @EnabledIfEnvironmentVariable(named = "testCodeFull", matches = ".*") @@ -47,11 +43,9 @@ private static void cleanUpCodeRepository(CodeProject codeProject) { @EnumSource(CodeProject.class) @Order(1) void evaluateSadSamCodeTlrFullIT(CodeProject project) { - analyzeCodeDirectly.set(true); - if (analyzeCodeDirectly.get()) - cleanUpCodeRepository(project); + cleanUpCodeRepository(project); - var evaluation = new SadSamCodeTraceabilityLinkRecoveryEvaluation(); + var evaluation = new SadSamCodeTraceabilityLinkRecoveryEvaluation(false); ArDoCoResult results = evaluation.runTraceLinkEvaluation(project); Assertions.assertNotNull(results); } @@ -62,11 +56,9 @@ void evaluateSadSamCodeTlrFullIT(CodeProject project) { @EnumSource(value = CodeProject.class) @Order(2) void evaluateSamCodeTlrFullIT(CodeProject project) { - analyzeCodeDirectly.set(true); - if (analyzeCodeDirectly.get()) - cleanUpCodeRepository(project); + cleanUpCodeRepository(project); - var evaluation = new SamCodeTraceabilityLinkRecoveryEvaluation(); + var evaluation = new SamCodeTraceabilityLinkRecoveryEvaluation(false); var results = evaluation.runTraceLinkEvaluation(project); Assertions.assertNotNull(results); } @@ -76,11 +68,7 @@ void evaluateSamCodeTlrFullIT(CodeProject project) { @EnumSource(CodeProject.class) @Order(9) void evaluateSadSamCodeTlrIT(CodeProject codeProject) { - analyzeCodeDirectly.set(false); - if (analyzeCodeDirectly.get()) - cleanUpCodeRepository(codeProject); - - var evaluation = new SadSamCodeTraceabilityLinkRecoveryEvaluation(); + var evaluation = new SadSamCodeTraceabilityLinkRecoveryEvaluation(true); var results = evaluation.runTraceLinkEvaluation(codeProject); Assertions.assertNotNull(results); @@ -92,11 +80,7 @@ void evaluateSadSamCodeTlrIT(CodeProject codeProject) { @EnumSource(CodeProject.class) @Order(10) void evaluateSamCodeTlrIT(CodeProject project) { - analyzeCodeDirectly.set(false); - if (analyzeCodeDirectly.get()) - cleanUpCodeRepository(project); - - var evaluation = new SamCodeTraceabilityLinkRecoveryEvaluation(); + var evaluation = new SamCodeTraceabilityLinkRecoveryEvaluation(true); ArDoCoResult results = evaluation.runTraceLinkEvaluation(project); Assertions.assertNotNull(results); } diff --git a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationSadCodeDirectIT.java b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationSadCodeDirectIT.java index 522c963..1300ce7 100644 --- a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationSadCodeDirectIT.java +++ b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceLinkEvaluationSadCodeDirectIT.java @@ -1,8 +1,6 @@ /* Licensed under MIT 2023-2024. */ package edu.kit.kastel.mcse.ardoco.tlr.tests.integration; -import static edu.kit.kastel.mcse.ardoco.core.tests.eval.ProjectHelper.ANALYZE_CODE_DIRECTLY; - import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -42,8 +40,7 @@ static void afterAll() { @ParameterizedTest(name = "{0}") @EnumSource(CodeProject.class) void evaluateSadCodeTlrIT(CodeProject project) { - ANALYZE_CODE_DIRECTLY.set(false); - var evaluation = new SadCodeTraceabilityLinkRecoveryEvaluation(); + var evaluation = new SadCodeTraceabilityLinkRecoveryEvaluation(true); ArDoCoResult results = evaluation.runTraceLinkEvaluation(project); Assertions.assertNotNull(results); } diff --git a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceabilityLinkRecoveryEvaluation.java b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceabilityLinkRecoveryEvaluation.java index 81658a0..aafee0d 100644 --- a/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceabilityLinkRecoveryEvaluation.java +++ b/tests/integration-tests/tests-tlr/src/test/java/edu/kit/kastel/mcse/ardoco/tlr/tests/integration/TraceabilityLinkRecoveryEvaluation.java @@ -63,13 +63,13 @@ protected final ArDoCoResult runTraceLinkEvaluation(T project) { protected abstract boolean resultHasRequiredData(ArDoCoResult potentialResults); - protected File getInputCode(CodeProject codeProject) { + protected File getInputCode(CodeProject codeProject, boolean acmFile) { File inputCode; - if (TraceLinkEvaluationIT.analyzeCodeDirectly.get()) { + if (!acmFile) { prepareCode(codeProject); - inputCode = new File(codeProject.getCodeLocation()); + inputCode = codeProject.getCodeLocation(false); } else { - inputCode = new File(codeProject.getCodeModelDirectory()); + inputCode = codeProject.getCodeLocation(true); } return inputCode; } @@ -77,10 +77,10 @@ protected File getInputCode(CodeProject codeProject) { protected abstract ArDoCoRunner getAndSetupRunner(T project); private void prepareCode(CodeProject codeProject) { - File codeLocation = new File(codeProject.getCodeLocation()); + File codeLocation = codeProject.getCodeLocation(false); if (!codeLocation.exists() || Objects.requireNonNull(codeLocation.listFiles()).length == 0) { - RepositoryHandler.shallowCloneRepository(codeProject.getCodeRepository(), codeProject.getCodeLocation(), codeProject.getCommitHash()); + RepositoryHandler.shallowCloneRepository(codeProject.getCodeRepository(), codeLocation.getAbsolutePath(), codeProject.getCommitHash()); } } From dcbb6bf20a9554f0b373de3069fcdd500bd4f48f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Fuch=C3=9F?= Date: Fri, 23 Aug 2024 09:40:51 +0200 Subject: [PATCH 2/3] Logging for ACM Legacy Support --- .../ardoco/tlr/models/agents/ArCoTLModelProviderAgent.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArCoTLModelProviderAgent.java b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArCoTLModelProviderAgent.java index 3a16d84..df3e64d 100644 --- a/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArCoTLModelProviderAgent.java +++ b/stages-tlr/model-provider/src/main/java/edu/kit/kastel/mcse/ardoco/tlr/models/agents/ArCoTLModelProviderAgent.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.SortedMap; +import org.slf4j.LoggerFactory; + import edu.kit.kastel.mcse.ardoco.core.data.DataRepository; import edu.kit.kastel.mcse.ardoco.core.pipeline.agent.Informant; import edu.kit.kastel.mcse.ardoco.core.pipeline.agent.PipelineAgent; @@ -78,6 +80,8 @@ public static CodeConfiguration getCodeConfiguration(File inputCode) { // Legacy Support for only ACM_FILE in a directory // TODO: Maybe delete in the future if (inputCode.isDirectory() && new File(inputCode, "codeModel.acm").exists()) { + var logger = LoggerFactory.getLogger(ArCoTLModelProviderAgent.class); + logger.error("Legacy support for only ACM_FILE in a directory. Please use the ACM_FILE directly."); return new CodeConfiguration(new File(inputCode, "codeModel.acm"), CodeConfiguration.CodeConfigurationType.ACM_FILE); } From a79d79f70eddc77516e539eb0f98d69f710cd8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Fuch=C3=9F?= Date: Mon, 16 Sep 2024 16:36:15 +0200 Subject: [PATCH 3/3] Review comments --- .../mcse/ardoco/core/tests/eval/CodeProject.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java b/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java index 9fdfab9..30fe509 100644 --- a/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java +++ b/tests/integration-tests/tests-base/src/main/java/edu/kit/kastel/mcse/ardoco/core/tests/eval/CodeProject.java @@ -1,8 +1,6 @@ /* Licensed under MIT 2023-2024. */ package edu.kit.kastel.mcse.ardoco.core.tests.eval; -import static edu.kit.kastel.mcse.ardoco.core.tests.eval.ProjectHelper.loadFileFromResources; - import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -152,8 +150,7 @@ public String getCommitHash() { */ public File getCodeLocation(boolean acmFile) { if (acmFile) { - // If ACM load file from resources - return loadFileFromResources(this.codeModelLocationInResources); + return ProjectHelper.loadFileFromResources(this.codeModelLocationInResources); } return getTemporaryCodeLocation(); @@ -179,7 +176,7 @@ public ExpectedResults getExpectedResultsForSadSamCode() { * @see TraceLinkUtilities#createTraceLinkString(String, String) */ public ImmutableList getSamCodeGoldStandard() { - File samCodeGoldStandardFile = loadFileFromResources(samCodeGoldStandardLocation); + File samCodeGoldStandardFile = ProjectHelper.loadFileFromResources(samCodeGoldStandardLocation); List lines = getLinesFromGoldStandardFile(samCodeGoldStandardFile); MutableList goldStandard = Lists.mutable.empty(); @@ -199,7 +196,7 @@ public ImmutableList getSamCodeGoldStandard() { * {@return all lines from the gold standard in csv format} */ public ImmutableList getSadCodeGoldStandard() { - File sadCodeGoldStandardFile = loadFileFromResources(sadCodeGoldStandardLocation); + File sadCodeGoldStandardFile = ProjectHelper.loadFileFromResources(sadCodeGoldStandardLocation); List lines = getLinesFromGoldStandardFile(sadCodeGoldStandardFile); return Lists.immutable.ofAll(lines); } @@ -212,7 +209,7 @@ private static List getLinesFromGoldStandardFile(File samCodeGoldStandar } catch (IOException e) { logger.error(e.getMessage(), e); } - lines.remove(0); + lines.removeFirst(); lines = lines.stream().filter(Predicate.not(String::isBlank)).toList(); return lines; }