diff --git a/assemble-tools.sh b/assemble-tools.sh new file mode 100755 index 0000000000000000000000000000000000000000..1d27050ac69b68e73bcb9e94bfaa059d31e3d347 --- /dev/null +++ b/assemble-tools.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +BASE_DIR=$(cd "$(dirname "$0")"; pwd) + +rm -rf $BASE_DIR/build/oceandsl-tools + +mkdir -p $BASE_DIR/build/oceandsl-tools +cd $BASE_DIR/build/oceandsl-tools + +mkdir bin +mkdir lib + +for I in cmi dar mop mvis sar relabel ; do + unzip $BASE_DIR/tools/$I/build/distributions/$I.zip + mv $I/lib/* lib/ + mv $I/bin/* bin/ + rm -rf $I +done + +cd .. +tar -cvzpf oceandsl-tools.tgz oceandsl-tools + +# end + diff --git a/build.gradle b/build.gradle index 529317d47529a60237fef91842c40ed2e497c276..7681be74b0c4a5fe341787cbe9819063beb2009e 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,6 @@ plugins { repositories { jcenter() mavenCentral() - maven { url 'https://jitpack.io' } } subprojects { @@ -20,20 +19,19 @@ subprojects { repositories { jcenter() + mavenLocal() mavenCentral() maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } maven { url "https://oss.sonatype.org/content/repositories/releases/" } - maven { url 'https://jitpack.io' } } dependencies { - implementation 'net.kieker-monitoring:kieker:1.16-SNAPSHOT' - implementation 'net.sourceforge.teetime:teetime:3.0' - implementation 'com.beust:jcommander:1.78' - implementation 'ch.qos.logback:logback-classic:1.1.7' - implementation 'org.slf4j:slf4j-api:1.7.30' + implementation 'net.kieker-monitoring:kieker:1.16-SNAPSHOT' + implementation 'net.sourceforge.teetime:teetime:3.1-SNAPSHOT' + implementation 'com.beust:jcommander:1.78' + implementation 'ch.qos.logback:logback-classic:1.1.7' + implementation 'org.slf4j:slf4j-api:1.7.30' implementation 'org.codehaus.groovy:groovy-all:3.0.2' - implementation 'com.github.MoSimEngine.RefactorLizar:architecture-evaluation:6214cbdfb6' // Use JUnit test framework testImplementation 'junit:junit:4.13' diff --git a/common/build.gradle b/common/build.gradle index 3f64f91a8eeacdb84f5c98d943f5767e0b39f5c7..602a910fce49dd9f6d3cc9e8f2f481889aa33364 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -81,8 +81,8 @@ signing { } -javadoc { - if(JavaVersion.current().isJava9Compatible()) { - options.addBooleanOption('html5', true) - } -} +//javadoc { +// if(JavaVersion.current().isJava9Compatible()) { +// options.addBooleanOption('html5', true) +// } +//} diff --git a/settings.gradle b/settings.gradle index a8c582445e359c175f980b8397d7d3ad5f29e303..9034a46d36f259531cd5e54b7d9d5fe885c7ed47 100644 --- a/settings.gradle +++ b/settings.gradle @@ -19,5 +19,6 @@ include 'tools:dar' include 'tools:mop' include 'tools:mvis' include 'tools:cmi' +include 'tools:relabel' diff --git a/tools/cmi/src/main/java/org/oceandsl/tools/cmi/CheckModelIntegrityMain.java b/tools/cmi/src/main/java/org/oceandsl/tools/cmi/CheckModelIntegrityMain.java index e625995faea3e67eedb30d34d9a6d5648b9b26af..8a9b1885b8a26221beb346b99953ceec9681a22d 100644 --- a/tools/cmi/src/main/java/org/oceandsl/tools/cmi/CheckModelIntegrityMain.java +++ b/tools/cmi/src/main/java/org/oceandsl/tools/cmi/CheckModelIntegrityMain.java @@ -75,7 +75,8 @@ public class CheckModelIntegrityMain { errors = 0; for (final Entry<Class<? extends EObject>, List<Class<? extends EObject>>> modelConfig : CheckModelIntegrityMain .configureModels().entrySet()) { - errors += CheckModelIntegrityMain.checkReferences(repository.getModel(modelConfig.getKey()).eAllContents()); + errors += CheckModelIntegrityMain.checkReferences(modelConfig.getKey(), + repository.getModel(modelConfig.getKey()).eAllContents()); } System.out.printf("Missing references %s\n", errors); @@ -88,9 +89,60 @@ public class CheckModelIntegrityMain { } System.out.printf("Missing signature %s\n", errors); + // CheckModelIntegrityMain.checkForDuplicateDeployedOperations(repository.getModel(DeploymentModel.class)); + CheckModelIntegrityMain.checkExecutionInvocationIntegrity(repository.getModel(ExecutionModel.class), repository.getModel(DeploymentModel.class)); CheckModelIntegrityMain.checkExecutionStorageAccessIntegrity(repository.getModel(ExecutionModel.class)); + CheckModelIntegrityMain.checkForDuplicateInvocations(repository.getModel(ExecutionModel.class)); + } + +// private static void checkForDuplicateDeployedOperations(final DeploymentModel model) { +// for (final DeploymentContext context : model.getDeploymentContexts().values()) { +// for (final DeployedComponent component : context.getComponents().values()) { +// component.getContainedOperations().keySet() +// } +// } +// } + + private static void checkForDuplicateInvocations(final ExecutionModel model) { + System.out.println("Check for duplicate invocations based on DeployedOperation"); + final Map<DeployedOperation, Map<DeployedOperation, AggregatedInvocation>> map = new HashMap<>(); + for (final AggregatedInvocation invocation : model.getAggregatedInvocations().values()) { + Map<DeployedOperation, AggregatedInvocation> targetMap = map.get(invocation.getSource()); + if (targetMap == null) { + targetMap = new HashMap<>(); + targetMap.put(invocation.getTarget(), invocation); + } else { + if (targetMap.get(invocation.getTarget()) != null) { + System.out.printf("Found duplicate %s -> %s\n", + invocation.getSource().getAssemblyOperation().getOperationType().getName(), + invocation.getTarget().getAssemblyOperation().getOperationType().getName()); + } + } + } + + System.out.println("Check for duplicate invocations based on DeployedOperation names"); + final List<String> l = new ArrayList<>(); + for (final AggregatedInvocation invocation : model.getAggregatedInvocations().values()) { + final String m = String.format("%s:%s:%s -> %s:%s:%s", + invocation.getSource().getComponent().getDeploymentContext().getName(), + invocation.getSource().getComponent().getAssemblyComponent().getSignature(), + invocation.getSource().getAssemblyOperation().getOperationType().getSignature(), + invocation.getTarget().getComponent().getDeploymentContext().getName(), + invocation.getTarget().getComponent().getAssemblyComponent().getSignature(), + invocation.getTarget().getAssemblyOperation().getOperationType().getSignature()); + boolean g = false; + for (final String x : l) { + if (x.equals(m)) { + System.out.printf("Found duplicate %s\n", m); + g = true; + } + } + if (!g) { + l.add(m); + } + } } private static void checkExecutionInvocationIntegrity(final ExecutionModel model, @@ -222,7 +274,9 @@ public class CheckModelIntegrityMain { return result; } - private static long checkReferences(final TreeIterator<EObject> iterator) { + private static long checkReferences(final Class<? extends EObject> modelClass, + final TreeIterator<EObject> iterator) { + System.out.printf("Model %s\n", modelClass.getName()); long errorCount = 0; while (iterator.hasNext()) { final EObject object = iterator.next(); @@ -230,7 +284,8 @@ public class CheckModelIntegrityMain { for (final EReference reference : clazz.getEAllReferences()) { final Object referencedObject = object.eGet(reference, true); if (referencedObject == null) { - System.out.printf("Missing referenced object: %s -> %s\n", RepositoryUtils.getName(object),reference.getName()); + System.out.printf("Missing referenced object: %s:%s -> %s:%s\n", object.getClass().getSimpleName(), + RepositoryUtils.getName(object), reference.getEType().getName(), reference.getName()); errorCount++; } diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/CountEventsStage.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/CountEventsStage.java index ac3306527ae1013974513fac7e4d3fbe4a64c5a4..ae4f7334de0fd389fec15bc52b2e5974e35b0753 100644 --- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/CountEventsStage.java +++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/CountEventsStage.java @@ -15,12 +15,12 @@ ***************************************************************************/ package org.oceandsl.architecture.model.stages; -import teetime.stage.basic.AbstractTransformation; +import teetime.stage.basic.AbstractFilter; /** * Counts all events and hands them to the next filter unchanged. The stage outputs the number of - * events for every <code>interval</code> event occurrence and on termination. Output is written to - * info log channel. + * events for every <code>numberOfOccurance</code> event occurrence and on termination. Output is + * written to info log channel. * * @param <T> * event type @@ -28,19 +28,19 @@ import teetime.stage.basic.AbstractTransformation; * @author Reiner Jung * @since 1.0 */ -public class CountEventsStage<T> extends AbstractTransformation<T, T> { +public class CountEventsStage<T> extends AbstractFilter<T> { private long counter; - private final long interval; + private final long numberOfOccurance; - public CountEventsStage(final long interval) { - this.interval = interval; + public CountEventsStage(final long numberOfOccurance) { + this.numberOfOccurance = numberOfOccurance; } @Override protected void execute(final T element) throws Exception { this.counter++; - if ((this.counter % this.interval) == 0) { + if (this.counter % this.numberOfOccurance == 0) { this.logger.info("Received {} events.", this.counter); } this.outputPort.send(element); diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/ModelRepositoryProducerStage.java b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/ModelRepositoryProducerStage.java similarity index 96% rename from tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/ModelRepositoryProducerStage.java rename to tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/ModelRepositoryProducerStage.java index cc047b2bd42943a85521e337d4970078230940c3..8af6c8a8c943de9a34574c8a74ec2d7720bc6ab6 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/ModelRepositoryProducerStage.java +++ b/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/ModelRepositoryProducerStage.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mvis.stages; +package org.oceandsl.architecture.model.stages; import java.nio.file.Path; diff --git a/tools/dar/src/main/java/org/oceandsl/tools/dar/DynamicArchitectureRecoveryMain.java b/tools/dar/src/main/java/org/oceandsl/tools/dar/DynamicArchitectureRecoveryMain.java index 18932360cf51580c574d3fa24654bbc9da057b93..adac2925e74a380037daacb9f52f8a75caeffe81 100644 --- a/tools/dar/src/main/java/org/oceandsl/tools/dar/DynamicArchitectureRecoveryMain.java +++ b/tools/dar/src/main/java/org/oceandsl/tools/dar/DynamicArchitectureRecoveryMain.java @@ -57,7 +57,7 @@ public class DynamicArchitectureRecoveryMain extends AbstractService<TeetimeConf try { this.repository = ArchitectureModelManagementFactory.createModelRepository( this.parameterConfiguration.getExperimentName(), - this.parameterConfiguration.getComponentMapFile() != null); + this.parameterConfiguration.getComponentMapFiles() != null); return new TeetimeConfiguration(this.logger, this.parameterConfiguration, this.repository); } catch (final IOException | ValueConversionErrorException e) { diff --git a/tools/dar/src/main/java/org/oceandsl/tools/dar/MapBasedSignatureCleaner.java b/tools/dar/src/main/java/org/oceandsl/tools/dar/MapBasedSignatureCleaner.java index 00a3389b2f9135bfd4377bb8ee9b74355c00c6ed..69ae508e48fd7a23b1c4f4e0f15f19b542898b6b 100644 --- a/tools/dar/src/main/java/org/oceandsl/tools/dar/MapBasedSignatureCleaner.java +++ b/tools/dar/src/main/java/org/oceandsl/tools/dar/MapBasedSignatureCleaner.java @@ -21,6 +21,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.slf4j.Logger; @@ -38,24 +39,27 @@ public class MapBasedSignatureCleaner extends AbstractSignatureCleaner { private final Map<String, String> componentMap = new HashMap<>(); - public MapBasedSignatureCleaner(final Path componentMapFile, final boolean caseInsensitive) throws IOException { + public MapBasedSignatureCleaner(final List<Path> componentMapFiles, final boolean caseInsensitive) + throws IOException { super(caseInsensitive); - this.logger.info("Reading map file {}", componentMapFile.toString()); - final BufferedReader reader = Files.newBufferedReader(componentMapFile); - String line; - while ((line = reader.readLine()) != null) { - final String[] values = line.split(","); - if (values.length == 3) { - // 0 = component name - // 1 = file name - // 2 = function name - this.componentMap.put(this.convertToLowerCase(this.removeTrailingUnderscore(values[1].trim())), - this.convertToLowerCase(this.removeTrailingUnderscore(values[0].trim()))); - } else { - this.logger.error("Entry incomplete '{}'", line.trim()); + for (final Path componentMapFile : componentMapFiles) { + this.logger.info("Reading map file {}", componentMapFile.toString()); + final BufferedReader reader = Files.newBufferedReader(componentMapFile); + String line; + while ((line = reader.readLine()) != null) { + final String[] values = line.split(";"); + if (values.length == 2) { + // 0 = component name + // 1 = file name + // 2 = function name + this.componentMap.put(this.convertToLowerCase(this.removeTrailingUnderscore(values[1].trim())), + this.convertToLowerCase(this.removeTrailingUnderscore(values[0].trim()))); + } else { + this.logger.error("Entry incomplete '{}'", line.trim()); + } } + reader.close(); } - reader.close(); } @Override diff --git a/tools/dar/src/main/java/org/oceandsl/tools/dar/Settings.java b/tools/dar/src/main/java/org/oceandsl/tools/dar/Settings.java index e22afaba81ea0e8ad9468ee46efe1be210bd2a2e..c73a0d10d7af183c80ab7c18d59baa84478a12e6 100644 --- a/tools/dar/src/main/java/org/oceandsl/tools/dar/Settings.java +++ b/tools/dar/src/main/java/org/oceandsl/tools/dar/Settings.java @@ -17,6 +17,7 @@ package org.oceandsl.tools.dar; import java.io.File; import java.nio.file.Path; +import java.util.List; import com.beust.jcommander.Parameter; import com.beust.jcommander.converters.FileConverter; @@ -39,8 +40,8 @@ public class Settings { private Path outputDirectory; @Parameter(names = { "-M", - "--component-map" }, required = false, converter = PathConverter.class, description = "Component, file and function map file") - private Path componentMapFile; + "--component-map" }, required = false, variableArity = true, converter = PathConverter.class, description = "Component, file and function map file") + private List<Path> componentMapFiles; @Parameter(names = { "-a", "--addrline" }, required = false, converter = FileConverter.class, description = "Location of the addrline tool") @@ -84,8 +85,8 @@ public class Settings { return this.caseInsensitive; } - public Path getComponentMapFile() { - return this.componentMapFile; + public List<Path> getComponentMapFiles() { + return this.componentMapFiles; } public String getExperimentName() { diff --git a/tools/dar/src/main/java/org/oceandsl/tools/dar/TeetimeConfiguration.java b/tools/dar/src/main/java/org/oceandsl/tools/dar/TeetimeConfiguration.java index 3885abf8c225eef8d29e1995a124183c827f0a65..0528abacdb54eecd2379ac4dfa6937aaafe43099 100644 --- a/tools/dar/src/main/java/org/oceandsl/tools/dar/TeetimeConfiguration.java +++ b/tools/dar/src/main/java/org/oceandsl/tools/dar/TeetimeConfiguration.java @@ -85,9 +85,9 @@ public class TeetimeConfiguration extends Configuration { final AbstractSignatureCleaner componentSignatureCleaner; final AbstractSignatureCleaner operationSignatureCleaner; - if (parameterConfiguration.getComponentMapFile() != null) { + if (parameterConfiguration.getComponentMapFiles() != null) { logger.info("Map based component definition"); - componentSignatureCleaner = new MapBasedSignatureCleaner(parameterConfiguration.getComponentMapFile(), + componentSignatureCleaner = new MapBasedSignatureCleaner(parameterConfiguration.getComponentMapFiles(), parameterConfiguration.getCaseInsensitive()); operationSignatureCleaner = new MapBasedOperationSignatureCleaner( parameterConfiguration.getCaseInsensitive()); diff --git a/tools/mop/build.gradle b/tools/mop/build.gradle index 766d37ddd392f5c4e33400d8cacd40c54b9d5af7..be36e854d34b3b6cb93dfe6285164cce436e1017 100644 --- a/tools/mop/build.gradle +++ b/tools/mop/build.gradle @@ -31,5 +31,5 @@ dependencies { } application { - mainClassName = 'org.oceandsl.tools.ModelOperationMain' + mainClassName = 'org.oceandsl.tools.mop.ModelOperationMain' } diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/AssemblyModelCloneUtils.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/AssemblyModelCloneUtils.java similarity index 90% rename from tools/mop/src/main/java/org/oceandsl/tools/mop/operations/AssemblyModelCloneUtils.java rename to tools/mop/src/main/java/org/oceandsl/tools/mop/merge/AssemblyModelCloneUtils.java index 6075d787c7db6e923232d938ef40b8d3b2b60354..00319302e9e65397d376485adad9a3d66e17bc9b 100644 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/AssemblyModelCloneUtils.java +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/AssemblyModelCloneUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mop.operations; +package org.oceandsl.tools.mop.merge; import java.util.Map.Entry; @@ -36,6 +36,11 @@ public final class AssemblyModelCloneUtils { final AssemblyComponent newComponent = AssemblyFactory.eINSTANCE.createAssemblyComponent(); newComponent.setSignature(component.getSignature()); + if (component.getComponentType().eIsProxy()) { + throw new InternalError( + "Unresolved component type for " + component.getSignature() + " probably broken reference URI"); + } + // TODO the following fails. newComponent.setComponentType( AssemblyModelCloneUtils.findComponentType(typeModel, component.getComponentType().getSignature())); @@ -77,6 +82,9 @@ public final class AssemblyModelCloneUtils { } private static ComponentType findComponentType(final TypeModel typeModel, final String signature) { + if (signature == null) { + throw new InternalError("Try to find signature, bit signature is null"); + } return typeModel.getComponentTypes().get(signature); } } diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/AssemblyModelMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/AssemblyModelMerger.java new file mode 100644 index 0000000000000000000000000000000000000000..4af05e4753d8df41857091d0e1190585183e59b4 --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/AssemblyModelMerger.java @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mop.merge; + +import org.eclipse.emf.common.util.EMap; + +import kieker.model.analysismodel.assembly.AssemblyComponent; +import kieker.model.analysismodel.assembly.AssemblyModel; +import kieker.model.analysismodel.assembly.AssemblyOperation; +import kieker.model.analysismodel.assembly.AssemblyStorage; +import kieker.model.analysismodel.type.TypeModel; + +/** + * @author Reiner Jung + * @since 1.1 + */ +public final class AssemblyModelMerger { + + private AssemblyModelMerger() { + } + + static void mergeAssemblyModel(final TypeModel typeModel, final AssemblyModel model, + final AssemblyModel mergeModel) { + // add additional component types if necessary + for (final AssemblyComponent mergeComponent : mergeModel.getAssemblyComponents().values()) { + if (!model.getAssemblyComponents().containsKey(mergeComponent.getSignature())) { + model.getAssemblyComponents().put(mergeComponent.getSignature(), + AssemblyModelCloneUtils.duplicate(typeModel, mergeComponent)); + } + } + // now merge operations + for (final AssemblyComponent component : model.getAssemblyComponents().values()) { + final AssemblyComponent mergeComponent = mergeModel.getAssemblyComponents().get(component.getSignature()); + if (mergeComponent != null) { + AssemblyModelMerger.mergeAssemblyOperations(component, mergeComponent.getAssemblyOperations()); + AssemblyModelMerger.mergeAssemblyStorages(component, mergeComponent.getAssemblyStorages()); + } + } + } + + private static void mergeAssemblyOperations(final AssemblyComponent component, + final EMap<String, AssemblyOperation> assemblyOperations) { + for (final AssemblyOperation mergeOperation : assemblyOperations.values()) { + if (!component.getAssemblyOperations().containsKey(mergeOperation.getOperationType().getSignature())) { + component.getAssemblyOperations().put(mergeOperation.getOperationType().getSignature(), + AssemblyModelCloneUtils.duplicate(component.getComponentType(), mergeOperation)); + } + } + } + + private static void mergeAssemblyStorages(final AssemblyComponent component, + final EMap<String, AssemblyStorage> mergeAssemblyStorages) { + for (final AssemblyStorage mergeStorage : mergeAssemblyStorages.values()) { + if (!component.getAssemblyStorages().containsKey(mergeStorage.getStorageType().getName())) { + component.getAssemblyStorages().put(mergeStorage.getStorageType().getName(), + AssemblyModelCloneUtils.duplicate(component.getComponentType(), mergeStorage)); + } + } + } +} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/DeploymentModelCloneUtils.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/DeploymentModelCloneUtils.java similarity index 99% rename from tools/mop/src/main/java/org/oceandsl/tools/mop/operations/DeploymentModelCloneUtils.java rename to tools/mop/src/main/java/org/oceandsl/tools/mop/merge/DeploymentModelCloneUtils.java index 793d7c04e2cbb9fbff4eeba3ecbe035c2089b0ba..32450dab6f0ac8bc95a635241ecf645b1cccb572 100644 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/DeploymentModelCloneUtils.java +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/DeploymentModelCloneUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mop.operations; +package org.oceandsl.tools.mop.merge; import java.util.Map.Entry; diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/DeploymentModelMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/DeploymentModelMerger.java new file mode 100644 index 0000000000000000000000000000000000000000..55f9074ff33dca71caafadb6d3e9c7d961b96951 --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/DeploymentModelMerger.java @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mop.merge; + +import java.util.Map.Entry; + +import org.eclipse.emf.common.util.EMap; + +import kieker.model.analysismodel.assembly.AssemblyComponent; +import kieker.model.analysismodel.assembly.AssemblyModel; +import kieker.model.analysismodel.deployment.DeployedComponent; +import kieker.model.analysismodel.deployment.DeployedOperation; +import kieker.model.analysismodel.deployment.DeployedStorage; +import kieker.model.analysismodel.deployment.DeploymentContext; +import kieker.model.analysismodel.deployment.DeploymentModel; + +/** + * @author Reiner Jung + * @since 1.1 + */ +public class DeploymentModelMerger { + + private DeploymentModelMerger() { + } + + static void mergeDeploymentModel(final AssemblyModel assemblyModel, final DeploymentModel model, + final DeploymentModel mergeModel) { + // add additional contexts if necessary + for (final DeploymentContext mergeDeploymentContext : mergeModel.getDeploymentContexts().values()) { + if (!model.getDeploymentContexts().containsKey(mergeDeploymentContext.getName())) { + model.getDeploymentContexts().put(mergeDeploymentContext.getName(), + DeploymentModelCloneUtils.duplicate(assemblyModel, mergeDeploymentContext)); + } + } + // now merge operations + for (final DeploymentContext deploymentContext : model.getDeploymentContexts().values()) { + final DeploymentContext mergeDeploymentContext = mergeModel.getDeploymentContexts() + .get(deploymentContext.getName()); + if (mergeDeploymentContext != null) { + DeploymentModelMerger.mergeDepolymentComponents(assemblyModel, deploymentContext, + mergeDeploymentContext.getComponents()); + } + } + + } + + private static void mergeDepolymentComponents(final AssemblyModel assemblyModel, + final DeploymentContext deploymentContext, final EMap<String, DeployedComponent> components) { + for (final DeployedComponent mergeComponent : components.values()) { + if (!deploymentContext.getComponents().containsKey(mergeComponent.getSignature())) { + deploymentContext.getComponents().put(mergeComponent.getSignature(), + DeploymentModelCloneUtils.duplicate(assemblyModel, mergeComponent)); + } else { + final DeployedComponent component = deploymentContext.getComponents() + .get(mergeComponent.getSignature()); + DeploymentModelMerger.mergeDeploymentOperations(component.getAssemblyComponent(), component, + mergeComponent.getContainedOperations()); + DeploymentModelMerger.mergeDeploymentStorages(component.getAssemblyComponent(), component, + mergeComponent.getContainedStorages()); + } + } + } + + private static void mergeDeploymentOperations(final AssemblyComponent assemblyComponent, + final DeployedComponent component, final EMap<String, DeployedOperation> containedOperations) { + for (final Entry<String, DeployedOperation> mergeOperation : containedOperations) { + if (!component.getContainedOperations().containsKey(mergeOperation.getKey())) { + component.getContainedOperations().put(mergeOperation.getKey(), + DeploymentModelCloneUtils.duplicate(assemblyComponent, mergeOperation.getValue())); + } + } + } + + private static void mergeDeploymentStorages(final AssemblyComponent assemblyComponent, + final DeployedComponent component, final EMap<String, DeployedStorage> containedStorages) { + for (final Entry<String, DeployedStorage> mergeStorage : containedStorages) { + if (!component.getContainedStorages().containsKey(mergeStorage.getKey())) { + component.getContainedStorages().put(mergeStorage.getKey(), + DeploymentModelCloneUtils.duplicate(assemblyComponent, mergeStorage.getValue())); + } + } + } +} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ExecutionModelCloneUtils.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ExecutionModelCloneUtils.java similarity index 92% rename from tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ExecutionModelCloneUtils.java rename to tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ExecutionModelCloneUtils.java index b0abf34c9f0eb3996ee81124f98edc4d869ff177..24ae7d3155a6dfe45908a34e572fd793875095fc 100644 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ExecutionModelCloneUtils.java +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ExecutionModelCloneUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mop.operations; +package org.oceandsl.tools.mop.merge; import kieker.model.analysismodel.deployment.DeployedComponent; import kieker.model.analysismodel.deployment.DeployedOperation; @@ -55,7 +55,7 @@ public final class ExecutionModelCloneUtils { return newAccess; } - private static DeployedOperation findDeployedOperation(final DeploymentModel newModel, + private static DeployedOperation findDeployedOperation(final DeploymentModel targetModel, final DeployedOperation operation) { final EStringToDeployedOperationMapEntryImpl mapOperationEntry = (EStringToDeployedOperationMapEntryImpl) operation .eContainer(); @@ -65,13 +65,14 @@ public final class ExecutionModelCloneUtils { .eContainer(); final DeploymentContext context = (DeploymentContext) mapComponentEntry.eContainer(); - final DeploymentContext newContext = newModel.getDeploymentContexts().get(context.getName()); + final DeploymentContext newContext = targetModel.getDeploymentContexts().get(context.getName()); final DeployedComponent newComponent = newContext.getComponents().get(component.getSignature()); + return newComponent.getContainedOperations() .get(operation.getAssemblyOperation().getOperationType().getSignature()); } - private static DeployedStorage findDeployedStorage(final DeploymentModel newModel, final DeployedStorage storage) { + private static DeployedStorage findDeployedStorage(final DeploymentModel targetModel, final DeployedStorage storage) { final EStringToDeployedStorageMapEntryImpl mapStorageEntry = (EStringToDeployedStorageMapEntryImpl) storage .eContainer(); final DeployedComponent component = (DeployedComponent) mapStorageEntry.eContainer(); @@ -80,7 +81,7 @@ public final class ExecutionModelCloneUtils { .eContainer(); final DeploymentContext context = (DeploymentContext) mapComponentEntry.eContainer(); - final DeploymentContext newContext = newModel.getDeploymentContexts().get(context.getName()); + final DeploymentContext newContext = targetModel.getDeploymentContexts().get(context.getName()); final DeployedComponent newComponent = newContext.getComponents().get(component.getSignature()); return newComponent.getContainedStorages().get(storage.getAssemblyStorage().getStorageType().getName()); } diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ExecutionModelMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ExecutionModelMerger.java new file mode 100644 index 0000000000000000000000000000000000000000..ebb4c257e2308930600bf07aca16dac307459085 --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ExecutionModelMerger.java @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mop.merge; + +import java.util.Map.Entry; + +import org.eclipse.emf.common.util.EMap; + +import kieker.model.analysismodel.deployment.DeployedOperation; +import kieker.model.analysismodel.deployment.DeployedStorage; +import kieker.model.analysismodel.deployment.DeploymentModel; +import kieker.model.analysismodel.execution.AggregatedInvocation; +import kieker.model.analysismodel.execution.AggregatedStorageAccess; +import kieker.model.analysismodel.execution.EDirection; +import kieker.model.analysismodel.execution.ExecutionFactory; +import kieker.model.analysismodel.execution.ExecutionModel; +import kieker.model.analysismodel.execution.Tuple; + +/** + * @author Reiner Jung + * @since + */ +public final class ExecutionModelMerger { + + private ExecutionModelMerger() { + } + + static void mergeExecutionModel(final DeploymentModel deploymentModel, final ExecutionModel targetModel, + final ExecutionModel mergeModel) { + for (final Entry<Tuple<DeployedOperation, DeployedOperation>, AggregatedInvocation> entry : mergeModel + .getAggregatedInvocations()) { + if (!ExecutionModelMerger.compareTupleOperationKeys(targetModel.getAggregatedInvocations(), + entry.getKey())) { + final AggregatedInvocation value = ExecutionModelCloneUtils.duplicate(deploymentModel, + entry.getValue()); + final Tuple<DeployedOperation, DeployedOperation> key = ExecutionFactory.eINSTANCE.createTuple(); + key.setFirst(value.getSource()); + key.setSecond(value.getTarget()); + targetModel.getAggregatedInvocations().put(key, value); + } + } + for (final Entry<Tuple<DeployedOperation, DeployedStorage>, AggregatedStorageAccess> entry : mergeModel + .getAggregatedStorageAccesses()) { + final Tuple<DeployedOperation, DeployedStorage> targetModelKey = ExecutionModelMerger + .findTupleStorageKeys(targetModel.getAggregatedStorageAccesses(), entry.getKey()); + if (targetModelKey == null) { + final AggregatedStorageAccess value = ExecutionModelCloneUtils.duplicate(deploymentModel, + entry.getValue()); + final Tuple<DeployedOperation, DeployedStorage> key = ExecutionFactory.eINSTANCE.createTuple(); + key.setFirst(value.getCode()); + key.setSecond(value.getStorage()); + targetModel.getAggregatedStorageAccesses().put(key, value); + } else { + final AggregatedStorageAccess targetStorageAccess = targetModel.getAggregatedStorageAccesses() + .get(targetModelKey); + final AggregatedStorageAccess sourceStorageAccess = entry.getValue(); + switch (sourceStorageAccess.getDirection()) { + case READ: + if (targetStorageAccess.getDirection() == EDirection.WRITE) { + targetStorageAccess.setDirection(EDirection.BOTH); + } + break; + case WRITE: + if (targetStorageAccess.getDirection() == EDirection.READ) { + targetStorageAccess.setDirection(EDirection.BOTH); + } + break; + case BOTH: + targetStorageAccess.setDirection(EDirection.BOTH); + break; + default: + throw new InternalError( + "Found unsupported direction type " + sourceStorageAccess.getDirection().getName()); + } + targetModel.getAggregatedStorageAccesses().put(targetModelKey, targetStorageAccess); + } + } + + } + + private static boolean compareTupleOperationKeys( + final EMap<Tuple<DeployedOperation, DeployedOperation>, AggregatedInvocation> aggregatedInvocations, + final Tuple<DeployedOperation, DeployedOperation> key) { + for (final Tuple<DeployedOperation, DeployedOperation> invocationKey : aggregatedInvocations.keySet()) { + if (ModelUtils.isEqual(invocationKey.getFirst(), key.getFirst()) + && ModelUtils.isEqual(invocationKey.getSecond(), key.getSecond())) { + return true; + } + } + return false; + } + + private static Tuple<DeployedOperation, DeployedStorage> findTupleStorageKeys( + final EMap<Tuple<DeployedOperation, DeployedStorage>, AggregatedStorageAccess> aggregatedStorageAccesses, + final Tuple<DeployedOperation, DeployedStorage> key) { + for (final Tuple<DeployedOperation, DeployedStorage> invocationKey : aggregatedStorageAccesses.keySet()) { + if (ModelUtils.isEqual(invocationKey.getFirst(), key.getFirst()) + && ModelUtils.isEqual(invocationKey.getSecond(), key.getSecond())) { + return invocationKey; + } + } + return null; + } +} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ModelRepositoryMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ModelRepositoryMerger.java new file mode 100644 index 0000000000000000000000000000000000000000..eb44b02f0ee51dde9a9443b40974d3ce9001ea1e --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ModelRepositoryMerger.java @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mop.merge; + +import kieker.analysis.stage.model.ModelRepository; +import kieker.model.analysismodel.assembly.AssemblyModel; +import kieker.model.analysismodel.deployment.DeploymentModel; +import kieker.model.analysismodel.execution.ExecutionModel; +import kieker.model.analysismodel.sources.SourceModel; +import kieker.model.analysismodel.statistics.StatisticsModel; +import kieker.model.analysismodel.type.TypeModel; + +/** + * Merge two different model repositories + * + * @author Reiner Jung + * @since 1.1 + */ +public class ModelRepositoryMerger { + + public static void perform(final ModelRepository lastModelRepository, final ModelRepository mergeModelRepository) { + TypeModelMerger.mergeTypeModel(lastModelRepository.getModel(TypeModel.class), + mergeModelRepository.getModel(TypeModel.class)); + AssemblyModelMerger.mergeAssemblyModel(lastModelRepository.getModel(TypeModel.class), + lastModelRepository.getModel(AssemblyModel.class), mergeModelRepository.getModel(AssemblyModel.class)); + DeploymentModelMerger.mergeDeploymentModel(lastModelRepository.getModel(AssemblyModel.class), + lastModelRepository.getModel(DeploymentModel.class), + mergeModelRepository.getModel(DeploymentModel.class)); + ExecutionModelMerger.mergeExecutionModel(lastModelRepository.getModel(DeploymentModel.class), + lastModelRepository.getModel(ExecutionModel.class), + mergeModelRepository.getModel(ExecutionModel.class)); + StatisticsModelMerger.mergeStatisticsModel(lastModelRepository.getModel(ExecutionModel.class), + lastModelRepository.getModel(StatisticsModel.class), + mergeModelRepository.getModel(StatisticsModel.class)); + SourceModelMerger.mergeSourceModel(lastModelRepository.getModel(TypeModel.class), + lastModelRepository.getModel(AssemblyModel.class), lastModelRepository.getModel(DeploymentModel.class), + lastModelRepository.getModel(ExecutionModel.class), lastModelRepository.getModel(SourceModel.class), + mergeModelRepository.getModel(SourceModel.class)); + } + +} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ModelUtils.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ModelUtils.java similarity index 65% rename from tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ModelUtils.java rename to tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ModelUtils.java index deb8dd1c29db95bfd08c7edacbff17eab9d74717..ad813f5085fa1830b7efdbb3dc5fd72de7d4c68e 100644 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ModelUtils.java +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/ModelUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mop.operations; +package org.oceandsl.tools.mop.merge; import java.util.Map.Entry; @@ -32,6 +32,7 @@ import kieker.model.analysismodel.deployment.DeployedStorage; import kieker.model.analysismodel.deployment.DeploymentContext; import kieker.model.analysismodel.execution.AggregatedInvocation; import kieker.model.analysismodel.execution.AggregatedStorageAccess; +import kieker.model.analysismodel.execution.EDirection; import kieker.model.analysismodel.execution.Tuple; import kieker.model.analysismodel.type.ComponentType; import kieker.model.analysismodel.type.OperationType; @@ -45,36 +46,36 @@ public class ModelUtils { public static boolean areObjectsEqual(final EObject left, final EObject right) { if (left.getClass().equals(right.getClass())) { - if (right instanceof DeployedOperation) { - return ModelUtils.isEqual((DeployedOperation) right, (DeployedOperation) left); - } else if (right instanceof DeployedStorage) { - return ModelUtils.isEqual((DeployedStorage) right, (DeployedStorage) left); - } else if (right instanceof DeployedComponent) { - return ModelUtils.isEqual((DeployedComponent) right, (DeployedComponent) left); - } else if (right instanceof DeploymentContext) { - return ModelUtils.isEqual((DeploymentContext) right, (DeploymentContext) left); - } else if (right instanceof AssemblyOperation) { - return ModelUtils.isEqual((AssemblyOperation) right, (AssemblyOperation) left); - } else if (right instanceof AssemblyComponent) { - return ModelUtils.isEqual((AssemblyComponent) right, (AssemblyComponent) left); - } else if (right instanceof AssemblyOperation) { - return ModelUtils.isEqual((AssemblyOperation) right, (AssemblyOperation) left); - } else if (right instanceof AssemblyStorage) { - return ModelUtils.isEqual((AssemblyStorage) right, (AssemblyStorage) left); - } else if (right instanceof ComponentType) { - return ModelUtils.isEqual((ComponentType) right, (ComponentType) left); - } else if (right instanceof OperationType) { - return ModelUtils.isEqual((OperationType) right, (OperationType) left); - } else if (right instanceof StorageType) { - return ModelUtils.isEqual((StorageType) right, (StorageType) left); - } else if (right instanceof AggregatedInvocation) { - return ModelUtils.isEqual((AggregatedInvocation) right, (AggregatedInvocation) left); - } else if (right instanceof AggregatedStorageAccess) { - return ModelUtils.isEqual((AggregatedStorageAccess) right, (AggregatedStorageAccess) left); - } else if (right instanceof Tuple) { - return ModelUtils.isEqual((Tuple<?, ?>) right, (Tuple<?, ?>) left); + if (left instanceof DeployedOperation) { + return ModelUtils.isEqual((DeployedOperation) left, (DeployedOperation) right); + } else if (left instanceof DeployedStorage) { + return ModelUtils.isEqual((DeployedStorage) left, (DeployedStorage) right); + } else if (left instanceof DeployedComponent) { + return ModelUtils.isEqual((DeployedComponent) left, (DeployedComponent) right); + } else if (left instanceof DeploymentContext) { + return ModelUtils.isEqual((DeploymentContext) left, (DeploymentContext) right); + } else if (left instanceof AssemblyOperation) { + return ModelUtils.isEqual((AssemblyOperation) left, (AssemblyOperation) right); + } else if (left instanceof AssemblyComponent) { + return ModelUtils.isEqual((AssemblyComponent) left, (AssemblyComponent) right); + } else if (left instanceof AssemblyOperation) { + return ModelUtils.isEqual((AssemblyOperation) left, (AssemblyOperation) right); + } else if (left instanceof AssemblyStorage) { + return ModelUtils.isEqual((AssemblyStorage) left, (AssemblyStorage) right); + } else if (left instanceof ComponentType) { + return ModelUtils.isEqual((ComponentType) left, (ComponentType) right); + } else if (left instanceof OperationType) { + return ModelUtils.isEqual((OperationType) left, (OperationType) right); + } else if (left instanceof StorageType) { + return ModelUtils.isEqual((StorageType) left, (StorageType) right); + } else if (left instanceof AggregatedInvocation) { + return ModelUtils.isEqual((AggregatedInvocation) left, (AggregatedInvocation) right); + } else if (left instanceof AggregatedStorageAccess) { + return ModelUtils.isEqual((AggregatedStorageAccess) left, (AggregatedStorageAccess) right); + } else if (left instanceof Tuple) { + return ModelUtils.isEqual((Tuple<?, ?>) left, (Tuple<?, ?>) right); } else { - System.err.println("Missing support for " + right.getClass().getCanonicalName()); + System.err.println("Missing support for " + left.getClass().getCanonicalName()); } } return false; @@ -86,29 +87,52 @@ public class ModelUtils { } public static boolean isEqual(final AggregatedStorageAccess leftStorageAccess, - final AggregatedStorageAccess storageAccess) { - return ModelUtils.isEqual(leftStorageAccess.getCode(), storageAccess.getCode()) - && leftStorageAccess.getDirection().equals(storageAccess.getDirection()) - && ModelUtils.isEqual(leftStorageAccess.getStorage(), storageAccess.getStorage()); + final AggregatedStorageAccess rightStorageAccess) { + ModelUtils.check(leftStorageAccess, "AggregatedStorageAccess leftStorageAccess"); + ModelUtils.check(rightStorageAccess, "AggregatedStorageAccess rightStorageAccess"); + return ModelUtils.isEqual(leftStorageAccess.getCode(), rightStorageAccess.getCode()) + && ModelUtils.compareDirections(leftStorageAccess.getDirection(), rightStorageAccess.getDirection()) + && ModelUtils.isEqual(leftStorageAccess.getStorage(), rightStorageAccess.getStorage()); + } + + private static boolean compareDirections(final EDirection leftDirection, final EDirection rightDirection) { + switch (leftDirection) { + case READ: + return rightDirection == EDirection.READ; + case WRITE: + return rightDirection == EDirection.WRITE; + case BOTH: + return true; + default: + throw new InternalError("Found unsupported Direction " + leftDirection.getName()); + } } public static boolean isEqual(final DeployedStorage leftStorage, final DeployedStorage storage) { + ModelUtils.check(leftStorage, "DeployedStorage leftStorage"); + ModelUtils.check(storage, "DeployedStorage storage"); return ModelUtils.isEqual(leftStorage.getAssemblyStorage(), storage.getAssemblyStorage()) && ModelUtils.isEqual(leftStorage.getComponent(), storage.getComponent()); } public static boolean isEqual(final AssemblyStorage leftAssemblyStorage, final AssemblyStorage assemblyStorage) { + ModelUtils.check(leftAssemblyStorage, "AssemblyStorage leftAssemblyStorage"); + ModelUtils.check(assemblyStorage, "AssemblyStorage assemblyStorage"); return ModelUtils.isEqual(leftAssemblyStorage.getStorageType(), assemblyStorage.getStorageType()) && ModelUtils .isEqual(leftAssemblyStorage.getAssemblyComponent(), assemblyStorage.getAssemblyComponent()); } public static boolean isEqual(final AggregatedInvocation leftInvocation, final AggregatedInvocation rightInvocation) { + ModelUtils.check(leftInvocation, "AggregatedInvocation leftInvocation"); + ModelUtils.check(rightInvocation, "AggregatedInvocation rightInvocation"); return ModelUtils.isEqual(leftInvocation.getSource(), rightInvocation.getSource()) && ModelUtils.isEqual(leftInvocation.getTarget(), rightInvocation.getTarget()); } public static boolean isEqual(final DeployedOperation leftKey, final DeployedOperation rightKey) { + ModelUtils.check(leftKey, "DeployedOperation leftKey"); + ModelUtils.check(rightKey, "DeployedOperation rightKey"); return ModelUtils.isEqual(leftKey.getComponent(), rightKey.getComponent()) && ModelUtils.isEqual(leftKey.getAssemblyOperation(), rightKey.getAssemblyOperation()); } @@ -134,6 +158,8 @@ public class ModelUtils { public static boolean isEqual(final AssemblyComponent leftAssemblyComponent, final AssemblyComponent assemblyComponent) { + ModelUtils.check(leftAssemblyComponent, "AssemblyComponent leftAssemblyComponent"); + ModelUtils.check(assemblyComponent, "AssemblyComponent assemblyComponent"); return leftAssemblyComponent.getSignature().equals(assemblyComponent.getSignature()) && ModelUtils.isEqual(leftAssemblyComponent.getComponentType(), assemblyComponent.getComponentType()); } @@ -194,4 +220,12 @@ public class ModelUtils { } } + private static void check(final EObject object, final String name) { + if (object == null) { + throw new InternalError("Object of type " + name + " is null"); + } + if (object.eIsProxy()) { + throw new InternalError("Object of type " + name + " could not be resolved."); + } + } } diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/SourceModelMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/SourceModelMerger.java new file mode 100644 index 0000000000000000000000000000000000000000..3a46c0fc5f1a604a40ca0e5e91afd2145d44826a --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/SourceModelMerger.java @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mop.merge; + +import java.util.Map.Entry; + +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.EMap; +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.ecore.EObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kieker.model.analysismodel.assembly.AssemblyModel; +import kieker.model.analysismodel.deployment.DeploymentModel; +import kieker.model.analysismodel.execution.ExecutionModel; +import kieker.model.analysismodel.sources.SourceModel; +import kieker.model.analysismodel.type.TypeModel; + +/** + * @author Reiner Jung + * @since + */ +public final class SourceModelMerger { + + private final static Logger LOGGER = LoggerFactory.getLogger(SourceModelMerger.class); + + private SourceModelMerger() { + } + + static void mergeSourceModel(final TypeModel typeModel, final AssemblyModel assemblyModel, + final DeploymentModel deploymentModel, final ExecutionModel executionModel, final SourceModel model, + final SourceModel mergeModel) { + for (final Entry<EObject, EList<String>> mergeSource : mergeModel.getSources()) { + final EObject modelKey = SourceModelMerger.findCorrespondingKey(model.getSources(), mergeSource.getKey()); + if (modelKey != null) { + final EList<String> modelSource = model.getSources().get(modelKey); + if (modelSource == null) { + SourceModelMerger.LOGGER.error("Model error no sources for existing key {}", modelKey); + model.getSources().put(modelKey, mergeSource.getValue()); + } else { + SourceModelMerger.mergeSources(modelSource, mergeSource.getValue()); + } + } else { + final EList<String> modelSources = new BasicEList<>(); + SourceModelMerger.mergeSources(modelSources, mergeSource.getValue()); + model.getSources().put(SourceModelMerger.findCorrespondingObject(typeModel, assemblyModel, + deploymentModel, executionModel, mergeSource.getKey()), modelSources); + } + } + } + + private static EObject findCorrespondingObject(final TypeModel typeModel, final AssemblyModel assemblyModel, + final DeploymentModel deploymentModel, final ExecutionModel executionModel, final EObject key) { + EObject result = SourceModelMerger.findObjectInModel(typeModel.eAllContents(), key); + if (result != null) { + return result; + } + + result = SourceModelMerger.findObjectInModel(assemblyModel.eAllContents(), key); + if (result != null) { + return result; + } + + result = SourceModelMerger.findObjectInModel(deploymentModel.eAllContents(), key); + if (result != null) { + return result; + } + + result = SourceModelMerger.findObjectInModel(executionModel.eAllContents(), key); + if (result != null) { + return result; + } + + return null; + } + + private static EObject findObjectInModel(final TreeIterator<EObject> iterator, final EObject key) { + while (iterator.hasNext()) { + final EObject item = iterator.next(); + if (ModelUtils.areObjectsEqual(key, item)) { + return item; + } + } + + return null; + } + + private static void mergeSources(final EList<String> modelSource, final EList<String> mergeSource) { + for (final String value : mergeSource) { + if (!modelSource.contains(value)) { + modelSource.add(value); + } + } + } + + private static EObject findCorrespondingKey(final EMap<EObject, EList<String>> sources, final EObject mergeKey) { + for (final EObject key : sources.keySet()) { + if (ModelUtils.areObjectsEqual(key, mergeKey)) { + return key; + } + } + return null; + } +} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/StatisticsModelCloneUtils.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/StatisticsModelCloneUtils.java similarity index 98% rename from tools/mop/src/main/java/org/oceandsl/tools/mop/operations/StatisticsModelCloneUtils.java rename to tools/mop/src/main/java/org/oceandsl/tools/mop/merge/StatisticsModelCloneUtils.java index 77b27680e3dd9e236a259b1300f7a38aeadad048..f18876f06aca7f8bf370302ff65396849e083830 100644 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/StatisticsModelCloneUtils.java +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/StatisticsModelCloneUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mop.operations; +package org.oceandsl.tools.mop.merge; import java.util.Map.Entry; diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/StatisticsModelMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/StatisticsModelMerger.java new file mode 100644 index 0000000000000000000000000000000000000000..3d52fdb9f439f7cb37e0fc1553603c54bceef218 --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/StatisticsModelMerger.java @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mop.merge; + +import java.util.Map.Entry; + +import org.apache.commons.lang3.NotImplementedException; +import org.eclipse.emf.common.util.EMap; +import org.eclipse.emf.ecore.EObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kieker.model.analysismodel.execution.AggregatedInvocation; +import kieker.model.analysismodel.execution.AggregatedStorageAccess; +import kieker.model.analysismodel.execution.ExecutionModel; +import kieker.model.analysismodel.statistics.EPredefinedUnits; +import kieker.model.analysismodel.statistics.EPropertyType; +import kieker.model.analysismodel.statistics.StatisticRecord; +import kieker.model.analysismodel.statistics.Statistics; +import kieker.model.analysismodel.statistics.StatisticsModel; + +/** + * @author Reiner Jung + * @since + */ +public final class StatisticsModelMerger { + + private final static Logger LOGGER = LoggerFactory.getLogger(StatisticsModelMerger.class); + + private StatisticsModelMerger() { + } + + static void mergeStatisticsModel(final ExecutionModel executionModel, final StatisticsModel targetModel, + final StatisticsModel mergeModel) { + for (final Entry<EObject, Statistics> mergeStatistic : mergeModel.getStatistics()) { + /* + * Unfortunately the map function containsKey does not match the correct keys, as the + * hash value is computed also over references which belong to another model. Thus, the + * containsKey always fails. + */ + final EObject targetStatisticKey = StatisticsModelMerger.findKey(targetModel.getStatistics(), + mergeStatistic.getKey()); + if (targetStatisticKey == null) { + targetModel.getStatistics().put( + StatisticsModelMerger.createExecutionModelKey(executionModel, mergeStatistic.getKey()), + StatisticsModelCloneUtils.duplicate(mergeStatistic.getValue())); + } else { + final Statistics newStatistic = targetModel.getStatistics().get(targetStatisticKey); + for (final Entry<EPredefinedUnits, StatisticRecord> statisticRecord : mergeStatistic.getValue() + .getStatistics()) { + if (!newStatistic.getStatistics().containsKey(statisticRecord.getKey())) { + newStatistic.getStatistics().put(statisticRecord.getKey(), + StatisticsModelCloneUtils.duplicate(statisticRecord.getValue())); + } else { + final StatisticRecord newRecord = newStatistic.getStatistics().get(statisticRecord.getKey()); + for (final Entry<EPropertyType, Object> property : statisticRecord.getValue().getProperties()) { + if (!newRecord.getProperties().containsKey(property.getKey())) { + newRecord.getProperties().put(property.getKey(), + StatisticsModelCloneUtils.duplicateObject(property.getValue())); + } else { + final Object newValue = StatisticsModelCloneUtils + .compute(newRecord.getProperties().get(property.getKey()), property.getValue()); + newRecord.getProperties().put(property.getKey(), newValue); + } + } + } + } + } + } + } + + private static EObject createExecutionModelKey(final ExecutionModel executionModel, final EObject key) { + if (key instanceof AggregatedInvocation) { + for (final AggregatedInvocation invocation : executionModel.getAggregatedInvocations().values()) { + if (ModelUtils.areObjectsEqual(key, invocation)) { + return invocation; + } + } + StatisticsModelMerger.LOGGER.error("Missing correpsonding {} in the merged model.", key.getClass()); + throw new InternalError(String.format("Missing correpsonding %s in the merged model.", key.getClass())); + } else if (key instanceof AggregatedStorageAccess) { + for (final AggregatedStorageAccess storageAccess : executionModel.getAggregatedStorageAccesses().values()) { + final AggregatedStorageAccess searchForStorageAccess = (AggregatedStorageAccess) key; + if (ModelUtils.areObjectsEqual(searchForStorageAccess, storageAccess)) { + return storageAccess; + } + } + StatisticsModelMerger.LOGGER.error("Missing correpsonding {} in the merged model.", key.getClass()); + throw new InternalError(String.format("Missing correpsonding %s in the merged model.", key.getClass())); + } else { + StatisticsModelMerger.LOGGER.error("Statistics related to {} objects are not yet supported.", + key.getClass()); + throw new NotImplementedException( + String.format("Statistics related to %s objects are not yet supported.", key.getClass())); + } + } + + private static EObject findKey(final EMap<EObject, Statistics> statistics, final EObject key) { + for (final EObject mapkey : statistics.keySet()) { + if (ModelUtils.areObjectsEqual(mapkey, key)) { + return mapkey; + } + } + return null; + } +} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/TypeModelCloneUtils.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/TypeModelCloneUtils.java similarity index 98% rename from tools/mop/src/main/java/org/oceandsl/tools/mop/operations/TypeModelCloneUtils.java rename to tools/mop/src/main/java/org/oceandsl/tools/mop/merge/TypeModelCloneUtils.java index 800d2f936476bfba743fd3aab3f7a5561664448f..e10a2480fb2259e71b3e2b9c904b3758395a3854 100644 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/TypeModelCloneUtils.java +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/TypeModelCloneUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mop.operations; +package org.oceandsl.tools.mop.merge; import java.util.Map.Entry; diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/TypeModelMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/TypeModelMerger.java new file mode 100644 index 0000000000000000000000000000000000000000..e6e576861cee74867b58d0a335a39069d48f896a --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/TypeModelMerger.java @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mop.merge; + +import org.eclipse.emf.common.util.EMap; + +import kieker.model.analysismodel.type.ComponentType; +import kieker.model.analysismodel.type.OperationType; +import kieker.model.analysismodel.type.StorageType; +import kieker.model.analysismodel.type.TypeModel; + +/** + * @author Reiner Jung + * @since 1.1 + */ +public final class TypeModelMerger { + + private TypeModelMerger() { + } + + static void mergeTypeModel(final TypeModel model, final TypeModel mergeModel) { + // add additional component types if necessary + for (final ComponentType mergeType : mergeModel.getComponentTypes().values()) { + if (!model.getComponentTypes().containsKey(mergeType.getSignature())) { + model.getComponentTypes().put(mergeType.getSignature(), TypeModelCloneUtils.duplicate(mergeType)); + } + } + // now merge operations + for (final ComponentType type : model.getComponentTypes().values()) { + final ComponentType mergeType = mergeModel.getComponentTypes().get(type.getSignature()); + if (mergeType != null) { + TypeModelMerger.mergeTypeOperations(type, mergeType.getProvidedOperations()); + TypeModelMerger.mergeTypeStorages(type, mergeType.getProvidedStorages()); + } + } + } + + private static void mergeTypeOperations(final ComponentType type, + final EMap<String, OperationType> mergeProvidedOperations) { + for (final OperationType mergeOperation : mergeProvidedOperations.values()) { + if (!type.getProvidedOperations().containsKey(mergeOperation.getSignature())) { + type.getProvidedOperations().put(mergeOperation.getSignature(), + TypeModelCloneUtils.duplicate(mergeOperation)); + } + } + } + + private static void mergeTypeStorages(final ComponentType type, final EMap<String, StorageType> providedStorages) { + for (final StorageType mergeStorage : providedStorages.values()) { + if (!type.getProvidedStorages().containsKey(mergeStorage.getName())) { + type.getProvidedStorages().put(mergeStorage.getName(), TypeModelCloneUtils.duplicate(mergeStorage)); + } + } + } + +} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/package-info.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..9cfb9113d8562d0c97ec952fb336752b66560d71 --- /dev/null +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/merge/package-info.java @@ -0,0 +1 @@ +package org.oceandsl.tools.mop.merge; \ No newline at end of file diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ModelRepositoryMerger.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ModelRepositoryMerger.java deleted file mode 100644 index 714f82e19ad59b1d319ca885f86de34048cf6354..0000000000000000000000000000000000000000 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/ModelRepositoryMerger.java +++ /dev/null @@ -1,424 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ -package org.oceandsl.tools.mop.operations; - -import java.util.Map.Entry; - -import org.apache.commons.lang3.NotImplementedException; -import org.eclipse.emf.common.util.BasicEList; -import org.eclipse.emf.common.util.EList; -import org.eclipse.emf.common.util.EMap; -import org.eclipse.emf.common.util.TreeIterator; -import org.eclipse.emf.ecore.EObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import kieker.analysis.stage.model.ModelRepository; -import kieker.model.analysismodel.assembly.AssemblyComponent; -import kieker.model.analysismodel.assembly.AssemblyModel; -import kieker.model.analysismodel.assembly.AssemblyOperation; -import kieker.model.analysismodel.assembly.AssemblyStorage; -import kieker.model.analysismodel.deployment.DeployedComponent; -import kieker.model.analysismodel.deployment.DeployedOperation; -import kieker.model.analysismodel.deployment.DeployedStorage; -import kieker.model.analysismodel.deployment.DeploymentContext; -import kieker.model.analysismodel.deployment.DeploymentModel; -import kieker.model.analysismodel.execution.AggregatedInvocation; -import kieker.model.analysismodel.execution.AggregatedStorageAccess; -import kieker.model.analysismodel.execution.ExecutionFactory; -import kieker.model.analysismodel.execution.ExecutionModel; -import kieker.model.analysismodel.execution.Tuple; -import kieker.model.analysismodel.sources.SourceModel; -import kieker.model.analysismodel.statistics.EPredefinedUnits; -import kieker.model.analysismodel.statistics.EPropertyType; -import kieker.model.analysismodel.statistics.StatisticRecord; -import kieker.model.analysismodel.statistics.Statistics; -import kieker.model.analysismodel.statistics.StatisticsModel; -import kieker.model.analysismodel.type.ComponentType; -import kieker.model.analysismodel.type.OperationType; -import kieker.model.analysismodel.type.StorageType; -import kieker.model.analysismodel.type.TypeModel; - -/** - * Merge two different model repositories - * - * @author Reiner Jung - * @since 1.1 - */ -public class ModelRepositoryMerger { - - final static Logger LOGGER = LoggerFactory.getLogger(ModelRepositoryMerger.class); - - public static void perform(final ModelRepository lastModelRepository, final ModelRepository mergeModelRepository) { - ModelRepositoryMerger.mergeTypeModel(lastModelRepository.getModel(TypeModel.class), - mergeModelRepository.getModel(TypeModel.class)); - ModelRepositoryMerger.mergeAssemblyModel(lastModelRepository.getModel(TypeModel.class), - lastModelRepository.getModel(AssemblyModel.class), mergeModelRepository.getModel(AssemblyModel.class)); - ModelRepositoryMerger.mergeDeploymentModel(lastModelRepository.getModel(AssemblyModel.class), - lastModelRepository.getModel(DeploymentModel.class), - mergeModelRepository.getModel(DeploymentModel.class)); - ModelRepositoryMerger.mergeExecutionModel(lastModelRepository.getModel(DeploymentModel.class), - lastModelRepository.getModel(ExecutionModel.class), - mergeModelRepository.getModel(ExecutionModel.class)); - ModelRepositoryMerger.mergeStatisticsModel(lastModelRepository.getModel(ExecutionModel.class), - lastModelRepository.getModel(StatisticsModel.class), - mergeModelRepository.getModel(StatisticsModel.class)); - ModelRepositoryMerger.mergeSourceModel(lastModelRepository.getModel(TypeModel.class), - lastModelRepository.getModel(AssemblyModel.class), lastModelRepository.getModel(DeploymentModel.class), - lastModelRepository.getModel(ExecutionModel.class), lastModelRepository.getModel(SourceModel.class), - mergeModelRepository.getModel(SourceModel.class)); - } - - private static void mergeTypeModel(final TypeModel model, final TypeModel mergeModel) { - // add additional component types if necessary - for (final ComponentType mergeType : mergeModel.getComponentTypes().values()) { - if (!model.getComponentTypes().containsKey(mergeType.getSignature())) { - model.getComponentTypes().put(mergeType.getSignature(), TypeModelCloneUtils.duplicate(mergeType)); - } - } - // now merge operations - for (final ComponentType type : model.getComponentTypes().values()) { - final ComponentType mergeType = mergeModel.getComponentTypes().get(type.getSignature()); - if (mergeType != null) { - ModelRepositoryMerger.mergeTypeOperations(type, mergeType.getProvidedOperations()); - ModelRepositoryMerger.mergeTypeStorages(type, mergeType.getProvidedStorages()); - } - } - } - - private static void mergeTypeOperations(final ComponentType type, - final EMap<String, OperationType> mergeProvidedOperations) { - for (final OperationType mergeOperation : mergeProvidedOperations.values()) { - if (!type.getProvidedOperations().containsKey(mergeOperation.getSignature())) { - type.getProvidedOperations().put(mergeOperation.getSignature(), - TypeModelCloneUtils.duplicate(mergeOperation)); - } - } - } - - private static void mergeTypeStorages(final ComponentType type, final EMap<String, StorageType> providedStorages) { - for (final StorageType mergeStorage : providedStorages.values()) { - if (!type.getProvidedStorages().containsKey(mergeStorage.getName())) { - type.getProvidedStorages().put(mergeStorage.getName(), TypeModelCloneUtils.duplicate(mergeStorage)); - } - } - } - - /** -- assembly model -- */ - - private static void mergeAssemblyModel(final TypeModel typeModel, final AssemblyModel model, - final AssemblyModel mergeModel) { - // add additional component types if necessary - for (final AssemblyComponent mergeComponent : mergeModel.getAssemblyComponents().values()) { - if (!model.getAssemblyComponents().containsKey(mergeComponent.getSignature())) { - model.getAssemblyComponents().put(mergeComponent.getSignature(), - AssemblyModelCloneUtils.duplicate(typeModel, mergeComponent)); - } - } - // now merge operations - for (final AssemblyComponent component : model.getAssemblyComponents().values()) { - final AssemblyComponent mergeComponent = mergeModel.getAssemblyComponents().get(component.getSignature()); - if (mergeComponent != null) { - ModelRepositoryMerger.mergeAssemblyOperations(component, mergeComponent.getAssemblyOperations()); - ModelRepositoryMerger.mergeAssemblyStorages(component, mergeComponent.getAssemblyStorages()); - } - } - } - - private static void mergeAssemblyOperations(final AssemblyComponent component, - final EMap<String, AssemblyOperation> assemblyOperations) { - for (final AssemblyOperation mergeOperation : assemblyOperations.values()) { - if (!component.getAssemblyOperations().containsKey(mergeOperation.getOperationType().getSignature())) { - component.getAssemblyOperations().put(mergeOperation.getOperationType().getSignature(), - AssemblyModelCloneUtils.duplicate(component.getComponentType(), mergeOperation)); - } - } - } - - private static void mergeAssemblyStorages(final AssemblyComponent component, - final EMap<String, AssemblyStorage> assemblyStorages) { - for (final AssemblyStorage mergeStorage : assemblyStorages.values()) { - if (!component.getAssemblyOperations().containsKey(mergeStorage.getStorageType().getName())) { - component.getAssemblyStorages().put(mergeStorage.getStorageType().getName(), - AssemblyModelCloneUtils.duplicate(component.getComponentType(), mergeStorage)); - } - } - } - - /** -- deployment -- */ - - private static void mergeDeploymentModel(final AssemblyModel assemblyModel, final DeploymentModel model, - final DeploymentModel mergeModel) { - // add additional contexts if necessary - for (final DeploymentContext mergeDeploymentContext : mergeModel.getDeploymentContexts().values()) { - if (!model.getDeploymentContexts().containsKey(mergeDeploymentContext.getName())) { - model.getDeploymentContexts().put(mergeDeploymentContext.getName(), - DeploymentModelCloneUtils.duplicate(assemblyModel, mergeDeploymentContext)); - } - } - // now merge operations - for (final DeploymentContext deploymentContext : model.getDeploymentContexts().values()) { - final DeploymentContext mergeDeploymentContext = mergeModel.getDeploymentContexts() - .get(deploymentContext.getName()); - if (mergeDeploymentContext != null) { - ModelRepositoryMerger.mergeDepolymentComponents(assemblyModel, deploymentContext, - mergeDeploymentContext.getComponents()); - } - } - - } - - private static void mergeDepolymentComponents(final AssemblyModel assemblyModel, - final DeploymentContext deploymentContext, final EMap<String, DeployedComponent> components) { - for (final DeployedComponent mergeComponent : components.values()) { - if (!deploymentContext.getComponents().containsKey(mergeComponent.getSignature())) { - deploymentContext.getComponents().put(mergeComponent.getSignature(), - DeploymentModelCloneUtils.duplicate(assemblyModel, mergeComponent)); - } else { - final DeployedComponent component = deploymentContext.getComponents() - .get(mergeComponent.getSignature()); - ModelRepositoryMerger.mergeDeploymentOperations(component.getAssemblyComponent(), component, - mergeComponent.getContainedOperations()); - ModelRepositoryMerger.mergeDeploymentStorages(component.getAssemblyComponent(), component, - mergeComponent.getContainedStorages()); - } - } - } - - private static void mergeDeploymentOperations(final AssemblyComponent assemblyComponent, - final DeployedComponent component, final EMap<String, DeployedOperation> containedOperations) { - for (final Entry<String, DeployedOperation> mergeOperation : containedOperations) { - if (!component.getContainedOperations().containsKey(mergeOperation.getKey())) { - component.getContainedOperations().put(mergeOperation.getKey(), - DeploymentModelCloneUtils.duplicate(assemblyComponent, mergeOperation.getValue())); - } - } - } - - private static void mergeDeploymentStorages(final AssemblyComponent assemblyComponent, - final DeployedComponent component, final EMap<String, DeployedStorage> containedStorages) { - for (final Entry<String, DeployedStorage> mergeStorage : containedStorages) { - if (!component.getContainedStorages().containsKey(mergeStorage.getKey())) { - component.getContainedStorages().put(mergeStorage.getKey(), - DeploymentModelCloneUtils.duplicate(assemblyComponent, mergeStorage.getValue())); - } - } - } - - /** -- execution model -- */ - - private static void mergeExecutionModel(final DeploymentModel deploymentModel, final ExecutionModel model, - final ExecutionModel mergeModel) { - for (final Entry<Tuple<DeployedOperation, DeployedOperation>, AggregatedInvocation> entry : mergeModel - .getAggregatedInvocations()) { - if (!ModelRepositoryMerger.compareTupleOperationKeys(model.getAggregatedInvocations(), entry.getKey())) { - final AggregatedInvocation value = ExecutionModelCloneUtils.duplicate(deploymentModel, - entry.getValue()); - final Tuple<DeployedOperation, DeployedOperation> key = ExecutionFactory.eINSTANCE.createTuple(); - key.setFirst(value.getSource()); - key.setSecond(value.getTarget()); - model.getAggregatedInvocations().put(key, value); - } - } - for (final Entry<Tuple<DeployedOperation, DeployedStorage>, AggregatedStorageAccess> entry : mergeModel - .getAggregatedStorageAccesses()) { - if (!ModelRepositoryMerger.compareTupleStorageKeys(model.getAggregatedStorageAccesses(), entry.getKey())) { - final AggregatedStorageAccess value = ExecutionModelCloneUtils.duplicate(deploymentModel, - entry.getValue()); - final Tuple<DeployedOperation, DeployedStorage> key = ExecutionFactory.eINSTANCE.createTuple(); - key.setFirst(value.getCode()); - key.setSecond(value.getStorage()); - model.getAggregatedStorageAccesses().put(key, value); - } - } - } - - private static boolean compareTupleOperationKeys( - final EMap<Tuple<DeployedOperation, DeployedOperation>, AggregatedInvocation> aggregatedInvocations, - final Tuple<DeployedOperation, DeployedOperation> key) { - for (final Tuple<DeployedOperation, DeployedOperation> invocationKey : aggregatedInvocations.keySet()) { - if (ModelUtils.isEqual(invocationKey.getFirst(), key.getFirst()) - && ModelUtils.isEqual(invocationKey.getSecond(), key.getSecond())) { - return true; - } - } - return false; - } - - private static boolean compareTupleStorageKeys( - final EMap<Tuple<DeployedOperation, DeployedStorage>, AggregatedStorageAccess> aggregatedStorageAccesses, - final Tuple<DeployedOperation, DeployedStorage> key) { - for (final Tuple<DeployedOperation, DeployedStorage> invocationKey : aggregatedStorageAccesses.keySet()) { - if (ModelUtils.isEqual(invocationKey.getFirst(), key.getFirst()) - && ModelUtils.isEqual(invocationKey.getSecond(), key.getSecond())) { - return true; - } - } - return false; - } - - /** -- statistics model -- */ - private static void mergeStatisticsModel(final ExecutionModel executionModel, final StatisticsModel model, - final StatisticsModel mergeModel) { - for (final Entry<EObject, Statistics> statistic : mergeModel.getStatistics()) { - /* - * Unfortunately th map function containsKey does not match the correct keys, as the - * hash value is computed also over references which belong to another model. Thus, the - * containsKey always fails. - */ - final EObject mergeKey = ModelRepositoryMerger.findKey(model.getStatistics(), statistic.getKey()); - if (mergeKey == null) { - model.getStatistics().put( - ModelRepositoryMerger.createExecutionModelKey(executionModel, statistic.getKey()), - StatisticsModelCloneUtils.duplicate(statistic.getValue())); - } else { - final Statistics newStatistic = model.getStatistics().get(mergeKey); - for (final Entry<EPredefinedUnits, StatisticRecord> statisticRecord : statistic.getValue() - .getStatistics()) { - if (!newStatistic.getStatistics().containsKey(statisticRecord.getKey())) { - newStatistic.getStatistics().put(statisticRecord.getKey(), - StatisticsModelCloneUtils.duplicate(statisticRecord.getValue())); - } else { - final StatisticRecord newRecord = newStatistic.getStatistics().get(statisticRecord.getKey()); - for (final Entry<EPropertyType, Object> property : statisticRecord.getValue().getProperties()) { - if (!newRecord.getProperties().containsKey(property.getKey())) { - newRecord.getProperties().put(property.getKey(), - StatisticsModelCloneUtils.duplicateObject(property.getValue())); - } else { - final Object newValue = StatisticsModelCloneUtils - .compute(newRecord.getProperties().get(property.getKey()), property.getValue()); - newRecord.getProperties().put(property.getKey(), newValue); - } - } - } - } - } - } - } - - private static EObject createExecutionModelKey(final ExecutionModel executionModel, final EObject key) { - if (key instanceof AggregatedInvocation) { - for (final AggregatedInvocation invocation : executionModel.getAggregatedInvocations().values()) { - if (ModelUtils.areObjectsEqual(key, invocation)) { - return invocation; - } - } - ModelRepositoryMerger.LOGGER.error("Missing correpsonding {} in the merged model.", key.getClass()); - throw new InternalError(String.format("Missing correpsonding %s in the merged model.", key.getClass())); - } else if (key instanceof AggregatedStorageAccess) { - for (final AggregatedStorageAccess storageAccess : executionModel.getAggregatedStorageAccesses().values()) { - if (ModelUtils.areObjectsEqual(key, storageAccess)) { - return storageAccess; - } - } - ModelRepositoryMerger.LOGGER.error("Missing correpsonding {} in the merged model.", key.getClass()); - throw new InternalError(String.format("Missing correpsonding %s in the merged model.", key.getClass())); - } else { - ModelRepositoryMerger.LOGGER.error("Statistics related to {} objects are not yet supported.", - key.getClass()); - throw new NotImplementedException( - String.format("Statistics related to %s objects are not yet supported.", key.getClass())); - } - } - - private static EObject findKey(final EMap<EObject, Statistics> statistics, final EObject key) { - for (final EObject mapkey : statistics.keySet()) { - if (ModelUtils.areObjectsEqual(mapkey, key)) { - return mapkey; - } - } - return null; - } - - /** -- source model -- */ - - private static void mergeSourceModel(final TypeModel typeModel, final AssemblyModel assemblyModel, - final DeploymentModel deploymentModel, final ExecutionModel executionModel, final SourceModel model, - final SourceModel mergeModel) { - for (final Entry<EObject, EList<String>> mergeSource : mergeModel.getSources()) { - final EObject modelKey = ModelRepositoryMerger.findCorrespondingKey(model.getSources(), - mergeSource.getKey()); - if (modelKey != null) { - final EList<String> modelSource = model.getSources().get(modelKey); - if (modelSource == null) { - ModelRepositoryMerger.LOGGER.error("Model error no sources for existing key {}", modelKey); - model.getSources().put(modelKey, mergeSource.getValue()); - } else { - ModelRepositoryMerger.mergeSources(modelSource, mergeSource.getValue()); - } - } else { - final EList<String> modelSources = new BasicEList<>(); - ModelRepositoryMerger.mergeSources(modelSources, mergeSource.getValue()); - model.getSources().put(ModelRepositoryMerger.findCorrespondingObject(typeModel, assemblyModel, - deploymentModel, executionModel, mergeSource.getKey()), modelSources); - } - } - } - - private static EObject findCorrespondingObject(final TypeModel typeModel, final AssemblyModel assemblyModel, - final DeploymentModel deploymentModel, final ExecutionModel executionModel, final EObject key) { - EObject result = ModelRepositoryMerger.findObjectInModel(typeModel.eAllContents(), key); - if (result != null) { - return result; - } - - result = ModelRepositoryMerger.findObjectInModel(assemblyModel.eAllContents(), key); - if (result != null) { - return result; - } - - result = ModelRepositoryMerger.findObjectInModel(deploymentModel.eAllContents(), key); - if (result != null) { - return result; - } - - result = ModelRepositoryMerger.findObjectInModel(executionModel.eAllContents(), key); - if (result != null) { - return result; - } - - return null; - } - - private static EObject findObjectInModel(final TreeIterator<EObject> iterator, final EObject key) { - while (iterator.hasNext()) { - final EObject item = iterator.next(); - if (ModelUtils.areObjectsEqual(key, item)) { - return item; - } - } - - return null; - } - - private static void mergeSources(final EList<String> modelSource, final EList<String> mergeSource) { - for (final String value : mergeSource) { - if (!modelSource.contains(value)) { - modelSource.add(value); - } - } - } - - private static EObject findCorrespondingKey(final EMap<EObject, EList<String>> sources, final EObject mergeKey) { - for (final EObject key : sources.keySet()) { - if (ModelUtils.areObjectsEqual(key, mergeKey)) { - return key; - } - } - return null; - } - -} diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/package-info.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/package-info.java deleted file mode 100644 index 9d9eb1ab3f62028db019fea878fd3e6c520060dd..0000000000000000000000000000000000000000 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/operations/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package org.oceandsl.tools.mop.operations; \ No newline at end of file diff --git a/tools/mop/src/main/java/org/oceandsl/tools/mop/stages/ModelProcessor.java b/tools/mop/src/main/java/org/oceandsl/tools/mop/stages/ModelProcessor.java index 790ed13d2cab65d0e3d65bc2a0e1d2044c58537b..4be74e1239f6adf271e0ffff03d67638c81e8645 100644 --- a/tools/mop/src/main/java/org/oceandsl/tools/mop/stages/ModelProcessor.java +++ b/tools/mop/src/main/java/org/oceandsl/tools/mop/stages/ModelProcessor.java @@ -16,7 +16,7 @@ package org.oceandsl.tools.mop.stages; import org.oceandsl.architecture.model.ArchitectureModelManagementFactory; -import org.oceandsl.tools.mop.operations.ModelRepositoryMerger; +import org.oceandsl.tools.mop.merge.ModelRepositoryMerger; import kieker.analysis.stage.model.ModelRepository; import teetime.framework.AbstractConsumerStage; @@ -40,6 +40,7 @@ public class ModelProcessor extends AbstractConsumerStage<ModelRepository> { @Override protected void execute(final ModelRepository element) throws Exception { + this.logger.info("Merging models {}", element.getName()); ModelRepositoryMerger.perform(this.lastModel, element); this.task++; } diff --git a/tools/mop/src/test/java/org/oceandsl/tools/mop/operations/ModelRepositoryMergerTest.java b/tools/mop/src/test/java/org/oceandsl/tools/mop/operations/ModelRepositoryMergerTest.java index 91da482a29a72dafa98a63cb9ec91dbe3c3f48fc..3314be5fac1725905900f072e360b0ac18b8c030 100644 --- a/tools/mop/src/test/java/org/oceandsl/tools/mop/operations/ModelRepositoryMergerTest.java +++ b/tools/mop/src/test/java/org/oceandsl/tools/mop/operations/ModelRepositoryMergerTest.java @@ -19,6 +19,7 @@ import java.util.Map.Entry; import org.junit.Assert; import org.junit.Test; +import org.oceandsl.tools.mop.merge.ModelRepositoryMerger; import kieker.analysis.stage.model.ModelRepository; import kieker.model.analysismodel.assembly.AssemblyComponent; @@ -46,7 +47,7 @@ public class ModelRepositoryMergerTest { /** * Test method for - * {@link org.oceandsl.tools.mop.operations.ModelRepositoryMerger#perform(kieker.analysis.stage.model.ModelRepository, kieker.analysis.stage.model.ModelRepository, org.oceandsl.tools.mop.EStrategy)}. + * {@link org.oceandsl.tools.mop.merge.ModelRepositoryMerger#perform(kieker.analysis.stage.model.ModelRepository, kieker.analysis.stage.model.ModelRepository, org.oceandsl.tools.mop.EStrategy)}. */ @Test public void testPerformType() { diff --git a/tools/mvis/build.gradle b/tools/mvis/build.gradle index d068080e90302fd96fb0ca349b23e2107b055c73..51d5232bbebd6265626c49094272faa600554c16 100644 --- a/tools/mvis/build.gradle +++ b/tools/mvis/build.gradle @@ -26,6 +26,7 @@ dependencies { implementation 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3' implementation 'com.sun.xml.bind:jaxb-impl:2.3.3' implementation 'org.apache.commons:commons-compress:1.20' + implementation 'org.mosim.refactorlizar:architecture-evaluation-tool:0.0.4' } application { diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/GraphGenerationConverter.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/GraphGenerationConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..c4c1e16d08f95337207079e481b4c2a28ad859d0 --- /dev/null +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/GraphGenerationConverter.java @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mvis; + +import com.beust.jcommander.IStringConverter; + +import org.oceandsl.tools.mvis.stages.graph.EGraphGenerationMode; + +/** + * @author reiner + * + */ +public class GraphGenerationConverter implements IStringConverter<EGraphGenerationMode> { + + @Override + public EGraphGenerationMode convert(final String value) { + for (final EGraphGenerationMode mode : EGraphGenerationMode.values()) { + if (mode.getKey().equals(value)) { + return mode; + } + } + throw new IllegalArgumentException(String.format("Graph generation mode %s is not supported.", value)); + } + +} diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/ModelVisualizationMain.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/ModelVisualizationMain.java index 4882c57ad095f29babae8a862501757f94075a7e..9b09f1cab9fb4893af7f19efa212d26d737b1598 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/ModelVisualizationMain.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/ModelVisualizationMain.java @@ -21,11 +21,10 @@ import java.nio.file.Files; import com.beust.jcommander.JCommander; -import org.oceandsl.architecture.model.ArchitectureModelManagementFactory; import org.oceandsl.architecture.model.data.table.ValueConversionErrorException; +import org.oceandsl.tools.mvis.stages.graph.EGraphGenerationMode; import org.slf4j.LoggerFactory; -import kieker.analysis.stage.model.ModelRepository; import kieker.common.configuration.Configuration; import kieker.common.exception.ConfigurationException; import kieker.tools.common.AbstractService; @@ -38,8 +37,6 @@ import kieker.tools.common.AbstractService; */ public class ModelVisualizationMain extends AbstractService<TeetimeConfiguration, Settings> { - private ModelRepository repository; - public static void main(final String[] args) { final ModelVisualizationMain main = new ModelVisualizationMain(); try { @@ -55,9 +52,7 @@ public class ModelVisualizationMain extends AbstractService<TeetimeConfiguration @Override protected TeetimeConfiguration createTeetimeConfiguration() throws ConfigurationException { try { - this.repository = ArchitectureModelManagementFactory - .loadModelRepository(this.parameterConfiguration.getInputDirectory()); - return new TeetimeConfiguration(this.logger, this.parameterConfiguration, this.repository); + return new TeetimeConfiguration(this.logger, this.parameterConfiguration); } catch (final IOException | ValueConversionErrorException e) { this.logger.error("Error reading files. Cause: {}", e.getLocalizedMessage()); throw new ConfigurationException(e); @@ -77,6 +72,16 @@ public class ModelVisualizationMain extends AbstractService<TeetimeConfiguration @Override protected boolean checkParameters(final JCommander commander) throws ConfigurationException { + if (this.parameterConfiguration.getGraphGenerationMode() == null) { + this.logger.error("You need to specify a graph generation mode: {}", + this.createModeList(EGraphGenerationMode.values())); + return false; + } + if (this.parameterConfiguration.getSelector() == null) { + this.logger.error("No valid node and edge selector specificed. Valid types are: {}", + this.createSelectorList(ESelectorKind.values())); + return false; + } if (!Files.isDirectory(this.parameterConfiguration.getOutputDirectory())) { this.logger.error("Output path {} is not directory", this.parameterConfiguration.getOutputDirectory()); return false; @@ -88,6 +93,30 @@ public class ModelVisualizationMain extends AbstractService<TeetimeConfiguration return true; } + private Object createSelectorList(final ESelectorKind[] values) { + String list = null; + for (final ESelectorKind value : values) { + if (list == null) { + list = value.name().toLowerCase(); + } else { + list += "," + value.name().toLowerCase(); + } + } + return list; + } + + private String createModeList(final EGraphGenerationMode[] values) { + String list = null; + for (final EGraphGenerationMode value : values) { + if (list == null) { + list = value.getKey(); + } else { + list += "," + value.getKey(); + } + } + return list; + } + @Override protected void shutdownService() { diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/Settings.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/Settings.java index 809ce91519158c14bb3f1cb8808bb5ed71f51383..f72e875310555de0732a5584e685db1e5c1caccd 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/Settings.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/Settings.java @@ -21,6 +21,7 @@ import java.util.List; import com.beust.jcommander.Parameter; import com.beust.jcommander.converters.PathConverter; +import org.oceandsl.tools.mvis.stages.graph.EGraphGenerationMode; import org.oceandsl.tools.mvis.stages.graph.IGraphElementSelector; /** @@ -51,6 +52,10 @@ public class Settings { "--graphs" }, required = false, variableArity = true, converter = GraphTypeConverter.class, description = "Specify which output graphs must be generated") private List<EOutputGraph> outputGraphs; + @Parameter(names = { "-m", + "--mode" }, required = true, variableArity = true, converter = GraphGenerationConverter.class, description = "Mode deciding whether an edge is added when its nodes are not selected") + private EGraphGenerationMode graphGenerationMode; + public Path getInputDirectory() { return this.inputDirectory; } @@ -70,4 +75,8 @@ public class Settings { public IGraphElementSelector getSelector() { return this.selector; } + + public EGraphGenerationMode getGraphGenerationMode() { + return this.graphGenerationMode; + } } diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/TeetimeConfiguration.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/TeetimeConfiguration.java index 48777e794860ead67c95bf91b0de987bc12a460d..34306c7f3b27c52c5a5d0b45032cc202ea87242d 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/TeetimeConfiguration.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/TeetimeConfiguration.java @@ -18,19 +18,19 @@ package org.oceandsl.tools.mvis; import java.io.IOException; import org.oceandsl.architecture.model.data.table.ValueConversionErrorException; +import org.oceandsl.architecture.model.stages.ModelRepositoryProducerStage; import org.oceandsl.architecture.model.stages.sinks.TableCSVSink; import org.oceandsl.architecture.model.stages.utils.DedicatedFileNameMapper; import org.oceandsl.tools.mvis.graph.ColorAssemblyLevelComponentDependencyGraphBuilderFactory; import org.oceandsl.tools.mvis.graph.ColorAssemblyLevelOperationDependencyGraphBuilderFactory; import org.oceandsl.tools.mvis.graph.ColoredDotExportConfigurationFactory; import org.oceandsl.tools.mvis.graph.IColorDependencyGraphBuilderConfiguration; -import org.oceandsl.tools.mvis.stages.ModelRepositoryProducerStage; -import org.oceandsl.tools.mvis.stages.SaveAllenDataStage; -import org.oceandsl.tools.mvis.stages.graph.AllenDeployedArchitectureGraphStage; +import org.oceandsl.tools.mvis.stages.entropy.AllenDeployedArchitectureGraphStage; +import org.oceandsl.tools.mvis.stages.entropy.ComputeAllenComplexityMetrics; +import org.oceandsl.tools.mvis.stages.entropy.SaveAllenDataStage; import org.oceandsl.tools.mvis.stages.graph.ColorDependencyGraphBuilderConfiguration; import org.oceandsl.tools.mvis.stages.graph.ModuleCallGraphStage; import org.oceandsl.tools.mvis.stages.graph.OperationCallGraphStage; -import org.oceandsl.tools.mvis.stages.metrics.ComputeAllenComplexityMetrics; import org.oceandsl.tools.mvis.stages.metrics.ModuleNodeCountCouplingStage; import org.oceandsl.tools.mvis.stages.metrics.NumberOfCallsStage; import org.oceandsl.tools.mvis.stages.metrics.OperationNodeCountCouplingStage; @@ -43,8 +43,6 @@ import kieker.analysis.graph.export.graphml.GraphMLFileWriterStage; import kieker.analysis.graph.util.FileExtension; import kieker.analysis.signature.NameBuilder; import kieker.analysis.stage.model.ModelRepository; -import kieker.analysis.util.stage.trigger.Trigger; -import kieker.analysis.util.stage.trigger.TriggerOnTerminationStage; import teetime.framework.Configuration; import teetime.stage.basic.distributor.Distributor; import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy; @@ -58,21 +56,18 @@ import teetime.stage.basic.distributor.strategy.CopyByReferenceStrategy; public class TeetimeConfiguration extends Configuration { private static final String OPERATION_CALLS_CSV = "operation-calls.csv"; - private static final String DISTINCT_OPERATION_DEGREE_CSV = "distinct-operatin-degree.csv"; + private static final String DISTINCT_OPERATION_DEGREE_CSV = "distinct-operation-degree.csv"; private static final String DISTINCT_MODULE_DEGREE_CSV = "distinct-module-degree.csv"; - public TeetimeConfiguration(final Logger logger, final Settings parameterConfiguration, - final ModelRepository repository) throws IOException, ValueConversionErrorException { + public TeetimeConfiguration(final Logger logger, final Settings settings) + throws IOException, ValueConversionErrorException { - final ModelRepositoryProducerStage readerStage = new ModelRepositoryProducerStage( - parameterConfiguration.getInputDirectory()); + final ModelRepositoryProducerStage readerStage = new ModelRepositoryProducerStage(settings.getInputDirectory()); - final TriggerOnTerminationStage triggerStage = new TriggerOnTerminationStage(); - final Distributor<Trigger> triggerDistributor = new Distributor<>(new CopyByReferenceStrategy()); + final Distributor<ModelRepository> triggerDistributor = new Distributor<>(new CopyByReferenceStrategy()); final DotFileWriterStage dotFileOperationDependencyWriterStage = new DotFileWriterStage( - new DedicatedFileNameMapper(parameterConfiguration.getOutputDirectory(), "operation", - FileExtension.DOT), + new DedicatedFileNameMapper(settings.getOutputDirectory(), "operation", FileExtension.DOT), new ColoredDotExportConfigurationFactory(NameBuilder.forJavaShortOperations()) .createForAssemblyLevelOperationDependencyGraph(false)); @@ -80,37 +75,32 @@ public class TeetimeConfiguration extends Configuration { /** Stages for statistics. */ final NumberOfCallsStage numberOfCallsStage = new NumberOfCallsStage(); - final OperationCallGraphStage functionCallGraphStage = new OperationCallGraphStage( - parameterConfiguration.getSelector()); + final OperationCallGraphStage functionCallGraphStage = new OperationCallGraphStage(settings.getSelector(), + settings.getGraphGenerationMode()); final OperationNodeCountCouplingStage functionNodeCouplingStage = new OperationNodeCountCouplingStage(); - final ModuleCallGraphStage moduleCallGraphStage = new ModuleCallGraphStage( - parameterConfiguration.getSelector()); + final ModuleCallGraphStage moduleCallGraphStage = new ModuleCallGraphStage(settings.getSelector(), + settings.getGraphGenerationMode()); final ModuleNodeCountCouplingStage moduleNodeCouplingStage = new ModuleNodeCountCouplingStage(); /** Sinks for metrics writing to CSV files. */ - final TableCSVSink operationCallSink = new TableCSVSink(parameterConfiguration.getOutputDirectory(), - String.format("%s-%s", parameterConfiguration.getSelector().getFilePrefix(), - TeetimeConfiguration.OPERATION_CALLS_CSV)); - final TableCSVSink distinctOperationDegreeSink = new TableCSVSink(parameterConfiguration.getOutputDirectory(), - String.format("%s-%s", parameterConfiguration.getSelector().getFilePrefix(), - TeetimeConfiguration.DISTINCT_OPERATION_DEGREE_CSV)); - final TableCSVSink distinctModuleDegreeSink = new TableCSVSink(parameterConfiguration.getOutputDirectory(), - String.format("%s-%s", parameterConfiguration.getSelector().getFilePrefix(), - TeetimeConfiguration.DISTINCT_MODULE_DEGREE_CSV)); - - final GraphMLFileWriterStage graphMLFileWriterStage = new GraphMLFileWriterStage( - parameterConfiguration.getOutputDirectory()); + final TableCSVSink operationCallSink = new TableCSVSink(settings.getOutputDirectory(), String.format("%s-%s", + settings.getSelector().getFilePrefix(), TeetimeConfiguration.OPERATION_CALLS_CSV)); + final TableCSVSink distinctOperationDegreeSink = new TableCSVSink(settings.getOutputDirectory(), String.format( + "%s-%s", settings.getSelector().getFilePrefix(), TeetimeConfiguration.DISTINCT_OPERATION_DEGREE_CSV)); + final TableCSVSink distinctModuleDegreeSink = new TableCSVSink(settings.getOutputDirectory(), String.format( + "%s-%s", settings.getSelector().getFilePrefix(), TeetimeConfiguration.DISTINCT_MODULE_DEGREE_CSV)); + + final GraphMLFileWriterStage graphMLFileWriterStage = new GraphMLFileWriterStage(settings.getOutputDirectory()); /** connecting ports. */ - this.connectPorts(statisticsDistributor.getNewOutputPort(), triggerStage.getInputPort()); - this.connectPorts(triggerStage.getOutputPort(), triggerDistributor.getInputPort()); + this.connectPorts(statisticsDistributor.getNewOutputPort(), triggerDistributor.getInputPort()); final IColorDependencyGraphBuilderConfiguration configuration = new ColorDependencyGraphBuilderConfiguration( - repository, parameterConfiguration.getSelector()); + settings.getSelector()); /** operation graph. */ - if (parameterConfiguration.getOutputGraphs().contains(EOutputGraph.DOT_OP) - || parameterConfiguration.getOutputGraphs().contains(EOutputGraph.GRAPHML)) { + if (settings.getOutputGraphs().contains(EOutputGraph.DOT_OP) + || settings.getOutputGraphs().contains(EOutputGraph.GRAPHML)) { final DependencyGraphCreatorStage<IColorDependencyGraphBuilderConfiguration> operationDependencyGraphCreatorStage = new DependencyGraphCreatorStage<>( configuration, new ColorAssemblyLevelOperationDependencyGraphBuilderFactory()); final Distributor<IGraph> graphsDistributor = new Distributor<>(new CopyByReferenceStrategy()); @@ -118,22 +108,21 @@ public class TeetimeConfiguration extends Configuration { this.connectPorts(triggerDistributor.getNewOutputPort(), operationDependencyGraphCreatorStage.getInputPort()); this.connectPorts(operationDependencyGraphCreatorStage.getOutputPort(), graphsDistributor.getInputPort()); - if (parameterConfiguration.getOutputGraphs().contains(EOutputGraph.DOT_OP)) { + if (settings.getOutputGraphs().contains(EOutputGraph.DOT_OP)) { this.connectPorts(graphsDistributor.getNewOutputPort(), dotFileOperationDependencyWriterStage.getInputPort()); } - if (parameterConfiguration.getOutputGraphs().contains(EOutputGraph.GRAPHML)) { + if (settings.getOutputGraphs().contains(EOutputGraph.GRAPHML)) { this.connectPorts(graphsDistributor.getNewOutputPort(), graphMLFileWriterStage.getInputPort()); } } /** component graph. */ - if (parameterConfiguration.getOutputGraphs().contains(EOutputGraph.DOT_COMPONENT)) { + if (settings.getOutputGraphs().contains(EOutputGraph.DOT_COMPONENT)) { final DependencyGraphCreatorStage<IColorDependencyGraphBuilderConfiguration> componentDependencyGraphCreatorStage = new DependencyGraphCreatorStage<>( configuration, new ColorAssemblyLevelComponentDependencyGraphBuilderFactory()); final DotFileWriterStage componentDependencyDotFileWriterStage = new DotFileWriterStage( - new DedicatedFileNameMapper(parameterConfiguration.getOutputDirectory(), "component", - FileExtension.DOT), + new DedicatedFileNameMapper(settings.getOutputDirectory(), "component", FileExtension.DOT), new ColoredDotExportConfigurationFactory(NameBuilder.forJavaShortOperations()) .createForAssemblyLevelComponentDependencyGraph(false)); @@ -145,10 +134,9 @@ public class TeetimeConfiguration extends Configuration { /** setup allen metrics. */ final AllenDeployedArchitectureGraphStage allenArchitectureModularGraphStage = new AllenDeployedArchitectureGraphStage( - parameterConfiguration.getSelector()); + settings.getSelector(), settings.getGraphGenerationMode()); final ComputeAllenComplexityMetrics computeAllenComplexityStage = new ComputeAllenComplexityMetrics(); - final SaveAllenDataStage saveAllenDataStage = new SaveAllenDataStage( - parameterConfiguration.getOutputDirectory()); + final SaveAllenDataStage saveAllenDataStage = new SaveAllenDataStage(settings.getOutputDirectory()); /** connect stages. */ this.connectPorts(readerStage.getOutputPort(), statisticsDistributor.getInputPort()); diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/AbstractColorDependencyGraphBuilder.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/AbstractColorDependencyGraphBuilder.java index f1bbadb2a10ba4799885fd1e7c90bb292b83cdd1..b1d7899890a70188c3dd7d8e62c8c599952955a4 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/AbstractColorDependencyGraphBuilder.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/AbstractColorDependencyGraphBuilder.java @@ -15,6 +15,8 @@ ***************************************************************************/ package org.oceandsl.tools.mvis.graph; +import java.time.temporal.ChronoUnit; + import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.ecore.EObject; @@ -23,15 +25,19 @@ import org.oceandsl.tools.mvis.stages.graph.IGraphElementSelector; import kieker.analysis.graph.IGraph; import kieker.analysis.graph.IVertex; import kieker.analysis.graph.dependency.AbstractDependencyGraphBuilder; +import kieker.analysis.graph.dependency.ResponseTimeDecorator; import kieker.analysis.stage.model.ModelRepository; +import kieker.analysis.util.ObjectIdentifierRegistry; import kieker.model.analysismodel.deployment.DeployedStorage; import kieker.model.analysismodel.execution.AggregatedInvocation; import kieker.model.analysismodel.execution.AggregatedStorageAccess; +import kieker.model.analysismodel.execution.ExecutionModel; import kieker.model.analysismodel.sources.SourceModel; import kieker.model.analysismodel.statistics.EPredefinedUnits; import kieker.model.analysismodel.statistics.EPropertyType; import kieker.model.analysismodel.statistics.StatisticRecord; import kieker.model.analysismodel.statistics.Statistics; +import kieker.model.analysismodel.statistics.StatisticsModel; /** * @author Reiner Jung @@ -40,12 +46,11 @@ import kieker.model.analysismodel.statistics.Statistics; */ public abstract class AbstractColorDependencyGraphBuilder extends AbstractDependencyGraphBuilder { - private final SourceModel sourcesModel; + private SourceModel sourcesModel; private final IGraphElementSelector selector; - public AbstractColorDependencyGraphBuilder(final ModelRepository repository, final IGraphElementSelector selector) { - super(repository); - this.sourcesModel = repository.getModel(SourceModel.class); + public AbstractColorDependencyGraphBuilder(final IGraphElementSelector selector) { + super(); this.selector = selector; } @@ -84,7 +89,15 @@ public abstract class AbstractColorDependencyGraphBuilder extends AbstractDepend } @Override - public IGraph build() { + public IGraph build(final ModelRepository repository) { + this.graph = IGraph.create(); + this.graph.setName(repository.getName()); + + this.sourcesModel = repository.getModel(SourceModel.class); + this.executionModel = repository.getModel(ExecutionModel.class); + this.statisticsModel = repository.getModel(StatisticsModel.class); + this.identifierRegistry = new ObjectIdentifierRegistry(); + this.responseTimeDecorator = new ResponseTimeDecorator(this.statisticsModel, ChronoUnit.NANOS); for (final AggregatedInvocation invocation : this.executionModel.getAggregatedInvocations().values()) { this.handleInvocation(invocation); } diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilder.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilder.java index 70a9fdaba63471fde350eefa245960de953d09d6..d06dcb86c157239f20c0b9cde130a8d06abb5146 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilder.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilder.java @@ -21,7 +21,6 @@ import org.oceandsl.tools.mvis.stages.graph.IGraphElementSelector; import kieker.analysis.graph.IVertex; import kieker.analysis.graph.dependency.PropertyConstants; import kieker.analysis.graph.dependency.vertextypes.VertexType; -import kieker.analysis.stage.model.ModelRepository; import kieker.model.analysismodel.assembly.AssemblyComponent; import kieker.model.analysismodel.assembly.AssemblyOperation; import kieker.model.analysismodel.assembly.AssemblyStorage; @@ -35,9 +34,8 @@ import kieker.model.analysismodel.deployment.DeployedStorage; */ public class ColorAssemblyLevelComponentDependencyGraphBuilder extends AbstractColorDependencyGraphBuilder { - public ColorAssemblyLevelComponentDependencyGraphBuilder(final ModelRepository repository, - final IGraphElementSelector selector) { - super(repository, selector); + public ColorAssemblyLevelComponentDependencyGraphBuilder(final IGraphElementSelector selector) { + super(selector); } @Override diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilderFactory.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilderFactory.java index 8eea6236aaf316332474a32897f84ec0944e720a..765bbd5f8a59c2a35afb9554942b73f6bb892eaf 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilderFactory.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelComponentDependencyGraphBuilderFactory.java @@ -33,8 +33,7 @@ public class ColorAssemblyLevelComponentDependencyGraphBuilderFactory @Override public IDependencyGraphBuilder createDependencyGraphBuilder( final IColorDependencyGraphBuilderConfiguration configuration) { - return new ColorAssemblyLevelComponentDependencyGraphBuilder(configuration.getModelRepository(), - configuration.getSelector()); + return new ColorAssemblyLevelComponentDependencyGraphBuilder(configuration.getSelector()); } } diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilder.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilder.java index b15872a035475f914ac4108122dad3c0f39653eb..6ad9c37701cc75e4d7375648c32d9218d3e5f3c2 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilder.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilder.java @@ -38,14 +38,13 @@ import kieker.model.analysismodel.deployment.DeployedStorage; */ public class ColorAssemblyLevelOperationDependencyGraphBuilder extends AbstractColorDependencyGraphBuilder { - public ColorAssemblyLevelOperationDependencyGraphBuilder(final ModelRepository repository, - final IGraphElementSelector selector) { - super(repository, selector); + public ColorAssemblyLevelOperationDependencyGraphBuilder(final IGraphElementSelector selector) { + super(selector); } @Override - public IGraph build() { - return super.build(); + public IGraph build(final ModelRepository repository) { + return super.build(repository); } @Override diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilderFactory.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilderFactory.java index a546c69f11246f6323f1421c52afc5dcbc98b387..55aec13702d594107794ae47081bda30d91c8e18 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilderFactory.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/graph/ColorAssemblyLevelOperationDependencyGraphBuilderFactory.java @@ -34,8 +34,7 @@ public class ColorAssemblyLevelOperationDependencyGraphBuilderFactory @Override public IDependencyGraphBuilder createDependencyGraphBuilder( final IColorDependencyGraphBuilderConfiguration configuration) { - return new ColorAssemblyLevelOperationDependencyGraphBuilder(configuration.getModelRepository(), - configuration.getSelector()); + return new ColorAssemblyLevelOperationDependencyGraphBuilder(configuration.getSelector()); } } diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/AllenDeployedArchitectureGraphStage.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/AllenDeployedArchitectureGraphStage.java similarity index 61% rename from tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/AllenDeployedArchitectureGraphStage.java rename to tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/AllenDeployedArchitectureGraphStage.java index fb21bda2cf019685be7ca868e3e2c349d1beefe1..1e7217638a4281f1578529af0144e3e3d5f4cc2c 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/AllenDeployedArchitectureGraphStage.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/AllenDeployedArchitectureGraphStage.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mvis.stages.graph; +package org.oceandsl.tools.mvis.stages.entropy; import java.util.Map.Entry; @@ -21,9 +21,11 @@ import com.google.common.graph.Graph; import com.google.common.graph.GraphBuilder; import com.google.common.graph.MutableGraph; -import org.oceandsl.architecture.model.stages.utils.RepositoryUtils; +import org.mosim.refactorlizar.architecture.evaluation.graphs.Node; +import org.oceandsl.tools.mvis.stages.graph.EGraphGenerationMode; +import org.oceandsl.tools.mvis.stages.graph.IGraphElementSelector; +import org.oceandsl.tools.mvis.stages.graph.KiekerNode; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.graphs.Node; import kieker.analysis.stage.model.ModelRepository; import kieker.model.analysismodel.deployment.DeployedComponent; import kieker.model.analysismodel.deployment.DeployedOperation; @@ -32,7 +34,6 @@ import kieker.model.analysismodel.deployment.DeploymentModel; import kieker.model.analysismodel.execution.AggregatedInvocation; import kieker.model.analysismodel.execution.ExecutionModel; import kieker.model.analysismodel.execution.Tuple; -import kieker.model.analysismodel.sources.SourceModel; import teetime.stage.basic.AbstractTransformation; /** @@ -42,10 +43,13 @@ import teetime.stage.basic.AbstractTransformation; public class AllenDeployedArchitectureGraphStage extends AbstractTransformation<ModelRepository, Graph<Node<DeployedComponent>>> { - IGraphElementSelector selector; + private final IGraphElementSelector selector; + private final EGraphGenerationMode graphGeneratioMode; - public AllenDeployedArchitectureGraphStage(final IGraphElementSelector selector) { + public AllenDeployedArchitectureGraphStage(final IGraphElementSelector selector, + final EGraphGenerationMode graphGeneratioMode) { this.selector = selector; + this.graphGeneratioMode = graphGeneratioMode; } @Override @@ -64,12 +68,6 @@ public class AllenDeployedArchitectureGraphStage if (this.selector.nodeIsSelected(operation.getValue())) { final Node<DeployedComponent> node = new KiekerNode<>(operation.getValue()); graph.addNode(node); - } else { - this.logger.error("Node was skipped {}", RepositoryUtils.getName(operation.getValue())); - final SourceModel sourceModel = repository.getModel(SourceModel.class); - for (final String source : sourceModel.getSources().get(operation.getValue())) { - this.logger.error("Node label: {}", source); - } } } } @@ -79,36 +77,34 @@ public class AllenDeployedArchitectureGraphStage if (this.selector.edgeIsSelected(entry.getValue())) { final Node<DeployedComponent> source = this.findNode(graph, entry.getValue().getSource()); final Node<DeployedComponent> target = this.findNode(graph, entry.getValue().getTarget()); - if (source != null && target != null) { - graph.putEdge(source, target); - } else { - final SourceModel sourceModel = repository.getModel(SourceModel.class); - for (final String s : sourceModel.getSources().get(entry.getValue().getSource())) { - this.logger.error("Source label: {}", s); - } - for (final String s : sourceModel.getSources().get(entry.getValue().getTarget())) { - this.logger.error("Target label: {}", s); - } - for (final String s : sourceModel.getSources().get(entry.getValue())) { - this.logger.error("Edge label: {}", s); - } - if (this.selector.nodeIsSelected(entry.getValue().getSource()) - && this.selector.nodeIsSelected(entry.getValue().getTarget())) { - this.logger.error("Both nodes should be part of the graph, but are not: {} -> {}", - RepositoryUtils.getName(entry.getValue().getSource()), - RepositoryUtils.getName(entry.getValue().getTarget())); - } else { - this.logger.warn("When an edge is selected, both nodes should be selected too: {} -> {}", - RepositoryUtils.getName(entry.getValue().getSource()), - RepositoryUtils.getName(entry.getValue().getTarget())); + switch (this.graphGeneratioMode) { + case ADD_NODES_FOR_EDGES: + graph.putEdge(this.getOrCreateNode(graph, source, entry.getValue().getSource()), + this.getOrCreateNode(graph, target, entry.getValue().getTarget())); + break; + case ONLY_EDGES_FOR_NODES: + if (source != null && target != null) { + graph.putEdge(source, target); } + break; } } } this.outputPort.send(graph); } + private Node<DeployedComponent> getOrCreateNode(final MutableGraph<Node<DeployedComponent>> graph, + final Node<DeployedComponent> node, final DeployedOperation operation) { + if (node == null) { + final Node<DeployedComponent> newNode = new KiekerNode<>(operation); + graph.addNode(newNode); + return newNode; + } else { + return node; + } + } + private Node<DeployedComponent> findNode(final Graph<Node<DeployedComponent>> graph, final DeployedOperation operation) { for (final Node<DeployedComponent> node : graph.nodes()) { @@ -119,8 +115,6 @@ public class AllenDeployedArchitectureGraphStage } } - this.logger.error("Internal error: Looked for node of an edge that does not exist: {}", - operation.getAssemblyOperation().getOperationType().getSignature()); return null; } diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/metrics/ComputeAllenComplexityMetrics.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/ComputeAllenComplexityMetrics.java similarity index 59% rename from tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/metrics/ComputeAllenComplexityMetrics.java rename to tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/ComputeAllenComplexityMetrics.java index 54d69c7c5944045ad600c4304db7d9c2bd2f9092..45678ee3b0f62ef8ce9f516344e90c29db49d2cd 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/metrics/ComputeAllenComplexityMetrics.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/ComputeAllenComplexityMetrics.java @@ -13,21 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mvis.stages.metrics; +package org.oceandsl.tools.mvis.stages.entropy; import java.util.HashMap; import java.util.Map; import com.google.common.graph.Graph; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.CalculationMode; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.codemetrics.CodeMetric; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.codemetrics.Complexity; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.codemetrics.HyperGraphSize; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.complexity.HyperGraphComplexityCalculator; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.graphs.Node; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.graphs.SystemGraphUtils; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.size.HyperGraphSizeCalculator; +import org.mosim.refactorlizar.architecture.evaluation.CalculationMode; +import org.mosim.refactorlizar.architecture.evaluation.codemetrics.CodeMetric; +import org.mosim.refactorlizar.architecture.evaluation.codemetrics.Cohesion; +import org.mosim.refactorlizar.architecture.evaluation.codemetrics.Complexity; +import org.mosim.refactorlizar.architecture.evaluation.codemetrics.Coupling; +import org.mosim.refactorlizar.architecture.evaluation.codemetrics.HyperGraphSize; +import org.mosim.refactorlizar.architecture.evaluation.cohesion.HyperGraphCohesionCalculator; +import org.mosim.refactorlizar.architecture.evaluation.complexity.HyperGraphComplexityCalculator; +import org.mosim.refactorlizar.architecture.evaluation.coupling.HyperGraphInterModuleCouplingGenerator; +import org.mosim.refactorlizar.architecture.evaluation.graphs.Node; +import org.mosim.refactorlizar.architecture.evaluation.graphs.SystemGraphUtils; +import org.mosim.refactorlizar.architecture.evaluation.size.HyperGraphSizeCalculator; +import org.oceandsl.tools.mvis.stages.metrics.KiekerArchitectureModelSystemGraphUtils; + import kieker.model.analysismodel.deployment.DeployedComponent; import teetime.stage.basic.AbstractTransformation; @@ -40,23 +46,21 @@ public class ComputeAllenComplexityMetrics @Override protected void execute(final Graph<Node<DeployedComponent>> graph) throws Exception { - final CalculationMode mode = CalculationMode.REINER; + final CalculationMode mode = CalculationMode.NO_OFFSET; final SystemGraphUtils<DeployedComponent> systemGraphUtils = new KiekerArchitectureModelSystemGraphUtils(); final HyperGraphSize size = this.calculateHyperGraphSize(mode, systemGraphUtils, graph); final Complexity graphComplexity = new HyperGraphComplexityCalculator<>(mode, systemGraphUtils) .calculate(graph); - // final Coupling graphCoupling = new HyperGraphInterModuleCouplingGenerator<>(mode, - // systemGraphUtils) - // .calculate(graph); - // final Cohesion cohesion = new HyperGraphCohesionCalculator<>(mode, - // systemGraphUtils).calculate(graph); + final Coupling graphCoupling = new HyperGraphInterModuleCouplingGenerator<>(mode, systemGraphUtils) + .calculate(graph); + final Cohesion cohesion = new HyperGraphCohesionCalculator<>(mode, systemGraphUtils).calculate(graph); final Map<Class<? extends CodeMetric>, CodeMetric> result = new HashMap<>(); result.put(HyperGraphSize.class, size); result.put(Complexity.class, graphComplexity); - // result.put(Coupling.class, graphCoupling); - // result.put(Cohesion.class, cohesion); + result.put(Coupling.class, graphCoupling); + result.put(Cohesion.class, cohesion); this.outputPort.send(result); } diff --git a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/sinks/ResultSink.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/EntropyResultSink.java similarity index 86% rename from tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/sinks/ResultSink.java rename to tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/EntropyResultSink.java index e3cfee97902ab4c496c177cc4988e78e6bc8b084..95e7eb37aa20824881c630a93713a96610e86aaf 100644 --- a/tools/create-architecture-model/src/main/java/org/oceandsl/architecture/model/stages/sinks/ResultSink.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/EntropyResultSink.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.architecture.model.stages.sinks; +package org.oceandsl.tools.mvis.stages.entropy; import java.io.BufferedWriter; import java.io.IOException; @@ -24,19 +24,20 @@ import java.nio.file.StandardOpenOption; import java.util.Map; import java.util.Map.Entry; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.codemetrics.CodeMetric; +import org.mosim.refactorlizar.architecture.evaluation.codemetrics.CodeMetric; + import teetime.framework.AbstractConsumerStage; /** * @author Reiner Jung * */ -public class ResultSink extends AbstractConsumerStage<Map<Class<? extends CodeMetric>, CodeMetric>> { +public class EntropyResultSink extends AbstractConsumerStage<Map<Class<? extends CodeMetric>, CodeMetric>> { private final BufferedWriter fileHandle; private final Path path; - public ResultSink(final Path path) throws IOException { + public EntropyResultSink(final Path path) throws IOException { this.fileHandle = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.WRITE); this.path = path; diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/SaveAllenDataStage.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/SaveAllenDataStage.java similarity index 93% rename from tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/SaveAllenDataStage.java rename to tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/SaveAllenDataStage.java index abb9a78afdd69e4ae2f5aae25d19858ebda5fad0..40e1d73a3ce56e15a8c692c4462b72bda215ca1e 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/SaveAllenDataStage.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/SaveAllenDataStage.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package org.oceandsl.tools.mvis.stages; +package org.oceandsl.tools.mvis.stages.entropy; import java.io.BufferedWriter; import java.nio.file.Files; @@ -21,7 +21,8 @@ import java.nio.file.Path; import java.util.Map; import java.util.Map.Entry; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.codemetrics.CodeMetric; +import org.mosim.refactorlizar.architecture.evaluation.codemetrics.CodeMetric; + import teetime.framework.AbstractConsumerStage; /** diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/package-info.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..915625566d32b3d1dac675f91d5d7daa04feba8e --- /dev/null +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/entropy/package-info.java @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +/** + * @author Reiner Jung + * @since 1.0 + */ +package org.oceandsl.tools.mvis.stages.entropy; \ No newline at end of file diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ColorDependencyGraphBuilderConfiguration.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ColorDependencyGraphBuilderConfiguration.java index 8aba89084eb4e8debc1ff9498e1e4b40f381cdc8..bf22808c7c348d4723e6a3622fcd892b44f9d523 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ColorDependencyGraphBuilderConfiguration.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ColorDependencyGraphBuilderConfiguration.java @@ -17,27 +17,19 @@ package org.oceandsl.tools.mvis.stages.graph; import org.oceandsl.tools.mvis.graph.IColorDependencyGraphBuilderConfiguration; -import kieker.analysis.stage.model.ModelRepository; - /** - * @author reiner + * @author Reiner Jung + * @since 1.1 * */ public class ColorDependencyGraphBuilderConfiguration implements IColorDependencyGraphBuilderConfiguration { - private final ModelRepository modelRepository; private final IGraphElementSelector selector; - public ColorDependencyGraphBuilderConfiguration(final ModelRepository modelRepository, final IGraphElementSelector selector) { - this.modelRepository = modelRepository; + public ColorDependencyGraphBuilderConfiguration(final IGraphElementSelector selector) { this.selector = selector; } - @Override - public ModelRepository getModelRepository() { - return this.modelRepository; - } - @Override public IGraphElementSelector getSelector() { return this.selector; diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/CreateGraph4AllenMetricStage.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/CreateGraph4AllenMetricStage.java index 85f15f910244d84c5b96ca8420ce648740194ca5..e5e8cd53ada0d41c847d1dd606314f8900d29d2d 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/CreateGraph4AllenMetricStage.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/CreateGraph4AllenMetricStage.java @@ -22,7 +22,8 @@ import com.google.common.graph.Graph; import com.google.common.graph.GraphBuilder; import com.google.common.graph.MutableGraph; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.graphs.Node; +import org.mosim.refactorlizar.architecture.evaluation.graphs.Node; + import kieker.analysis.stage.model.ModelRepository; import kieker.model.analysismodel.deployment.DeployedComponent; import kieker.model.analysismodel.deployment.DeployedOperation; @@ -41,6 +42,10 @@ import teetime.stage.basic.AbstractTransformation; public class CreateGraph4AllenMetricStage extends AbstractTransformation<ModelRepository, Graph<Node<DeployedComponent>>> { + public CreateGraph4AllenMetricStage() { + // TODO Auto-generated constructor stub + } + @Override protected void execute(final ModelRepository element) throws Exception { final Graph<Node<DeployedComponent>> graph = this.computeGraph(element); diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/EGraphGenerationMode.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/EGraphGenerationMode.java new file mode 100644 index 0000000000000000000000000000000000000000..eddab86075188aceb561479c845196a9a450d134 --- /dev/null +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/EGraphGenerationMode.java @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.mvis.stages.graph; + +/** + * Node and edge selection modes for graph construction. + * + * @author Reiner Jung + * @since 1.1 + * + */ +public enum EGraphGenerationMode { + ADD_NODES_FOR_EDGES("add-nodes"), // add nodes when the edge should be included in the graph + // even if they are + // not selected + ONLY_EDGES_FOR_NODES("only"); // only add edges when nodes are already present + + private final String key; + + private EGraphGenerationMode(final String key) { + this.key = key; + } + + public String getKey() { + return this.key; + } +} diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/KiekerNode.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/KiekerNode.java index 06e5495e170974a952ad86ca14bbb30d3aaff59a..c6d344361e5088939c78da4134e2d62becf7ae40 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/KiekerNode.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/KiekerNode.java @@ -18,8 +18,7 @@ package org.oceandsl.tools.mvis.stages.graph; import java.util.Objects; import org.eclipse.emf.ecore.EObject; - -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.graphs.Node; +import org.mosim.refactorlizar.architecture.evaluation.graphs.Node; /** * Central node class for graphs diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ModuleCallGraphStage.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ModuleCallGraphStage.java index 8f81bed24f1c5ea40bcc4e2c5a943b6f9fc3d9b5..8184a2408af6745778b2b25b4c5f6cfcce01caa2 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ModuleCallGraphStage.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/ModuleCallGraphStage.java @@ -31,9 +31,11 @@ import teetime.stage.basic.AbstractTransformation; public class ModuleCallGraphStage extends AbstractTransformation<ModelRepository, IGraph> { private final IGraphElementSelector selector; + private final EGraphGenerationMode graphGeneratioMode; - public ModuleCallGraphStage(final IGraphElementSelector selector) { + public ModuleCallGraphStage(final IGraphElementSelector selector, final EGraphGenerationMode graphGeneratioMode) { this.selector = selector; + this.graphGeneratioMode = graphGeneratioMode; } @Override @@ -52,9 +54,25 @@ public class ModuleCallGraphStage extends AbstractTransformation<ModelRepository if (targetSelected) { graph.addVertexIfAbsent(invocation.getTarget().getComponent()); } - if (sourceSelected && targetSelected && this.selector.edgeIsSelected(invocation)) { - graph.addEdge(invocation, graph.getVertex(invocation.getSource().getComponent()), - graph.getVertex(invocation.getTarget().getComponent())); + switch (this.graphGeneratioMode) { + case ONLY_EDGES_FOR_NODES: + if (sourceSelected && targetSelected && this.selector.edgeIsSelected(invocation)) { + graph.addEdge(invocation, graph.getVertex(invocation.getSource().getComponent()), + graph.getVertex(invocation.getTarget().getComponent())); + } + break; + case ADD_NODES_FOR_EDGES: + if (this.selector.edgeIsSelected(invocation)) { + if (!sourceSelected) { + graph.addVertexIfAbsent(invocation.getSource().getComponent()); + } + if (!targetSelected) { + graph.addVertexIfAbsent(invocation.getTarget().getComponent()); + } + graph.addEdge(invocation, graph.getVertex(invocation.getSource().getComponent()), + graph.getVertex(invocation.getTarget().getComponent())); + } + break; } } diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/OperationCallGraphStage.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/OperationCallGraphStage.java index fa354a4458b394760fceea39e84bb61f2e9aac1a..07e3c9c6f9f35841de459a82bbead6bb4af0852d 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/OperationCallGraphStage.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/graph/OperationCallGraphStage.java @@ -30,9 +30,12 @@ import teetime.stage.basic.AbstractTransformation; public class OperationCallGraphStage extends AbstractTransformation<ModelRepository, IGraph> { private final IGraphElementSelector selector; + private final EGraphGenerationMode graphGeneratioMode; - public OperationCallGraphStage(final IGraphElementSelector selector) { + public OperationCallGraphStage(final IGraphElementSelector selector, + final EGraphGenerationMode graphGeneratioMode) { this.selector = selector; + this.graphGeneratioMode = graphGeneratioMode; } @Override @@ -51,9 +54,25 @@ public class OperationCallGraphStage extends AbstractTransformation<ModelReposit if (targetSelected) { graph.addVertexIfAbsent(invocation.getTarget()); } - if (sourceSelected && targetSelected && this.selector.edgeIsSelected(invocation)) { - graph.addEdge(invocation, graph.getVertex(invocation.getSource()), - graph.getVertex(invocation.getTarget())); + switch (this.graphGeneratioMode) { + case ONLY_EDGES_FOR_NODES: + if (sourceSelected && targetSelected && this.selector.edgeIsSelected(invocation)) { + graph.addEdge(invocation, graph.getVertex(invocation.getSource()), + graph.getVertex(invocation.getTarget())); + } + break; + case ADD_NODES_FOR_EDGES: + if (this.selector.edgeIsSelected(invocation)) { + if (!sourceSelected) { + graph.addVertexIfAbsent(invocation.getSource()); + } + if (!targetSelected) { + graph.addVertexIfAbsent(invocation.getTarget()); + } + graph.addEdge(invocation, graph.getVertex(invocation.getSource()), + graph.getVertex(invocation.getTarget())); + } + break; } } diff --git a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/metrics/KiekerArchitectureModelSystemGraphUtils.java b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/metrics/KiekerArchitectureModelSystemGraphUtils.java index 8787c283436c6ad4275ad20f7e6906712d2daf4f..f5fc592106f94734c3effa92d82dadf02a90616f 100644 --- a/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/metrics/KiekerArchitectureModelSystemGraphUtils.java +++ b/tools/mvis/src/main/java/org/oceandsl/tools/mvis/stages/metrics/KiekerArchitectureModelSystemGraphUtils.java @@ -19,10 +19,10 @@ import com.google.common.graph.Graph; import com.google.common.graph.Graphs; import com.google.common.graph.MutableGraph; +import org.mosim.refactorlizar.architecture.evaluation.graphs.Node; +import org.mosim.refactorlizar.architecture.evaluation.graphs.SystemGraphUtils; import org.oceandsl.tools.mvis.stages.graph.KiekerNode; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.graphs.Node; -import edu.kit.kastel.sdq.case4lang.refactorlizar.architecture_evaluation.graphs.SystemGraphUtils; import kieker.model.analysismodel.deployment.DeployedComponent; import kieker.model.analysismodel.deployment.DeployedOperation; diff --git a/tools/relabel/build.gradle b/tools/relabel/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..a030bd27e2bc4f082d695a13cd0a6dd130fdf629 --- /dev/null +++ b/tools/relabel/build.gradle @@ -0,0 +1,34 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Java project to get you started. + * For more details take a look at the Java Quickstart chapter in the Gradle + * User Manual available at https://docs.gradle.org/6.5/userguide/tutorial_java_projects.html + */ + +plugins { + id 'java' + id 'application' +} + +dependencies { + implementation project(':common') + implementation project(':analysis') + implementation project(':tools:create-architecture-model') + + // https://mvnrepository.com/artifact/org.eclipse.emf/org.eclipse.emf.ecore + implementation 'org.eclipse.emf:org.eclipse.emf.ecore:2.23.0' + implementation 'org.eclipse.emf:org.eclipse.emf.ecore.xmi:2.16.0' + +// runtime 'org.eclipse.emf:org.eclipse.emf.ecore:2.23.0' + + implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.0' + + implementation 'jakarta.xml.bind:jakarta.xml.bind-api:2.3.3' + implementation 'com.sun.xml.bind:jaxb-impl:2.3.3' + implementation 'org.apache.commons:commons-compress:1.20' +} + +application { + mainClassName = 'org.oceandsl.tools.relable.RelabelSourceMain' +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/ModelRepositoryWriterStage.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/ModelRepositoryWriterStage.java new file mode 100644 index 0000000000000000000000000000000000000000..a1151b232794611ba04266f6f99c1d83eda7d4eb --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/ModelRepositoryWriterStage.java @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.relable; + +import java.nio.file.Path; + +import org.oceandsl.architecture.model.ArchitectureModelManagementFactory; + +import kieker.analysis.stage.model.ModelRepository; +import teetime.framework.AbstractConsumerStage; + +/** + * Write model to repository. + * + * @author Reiner Jung + * @since 1.1 + * + */ +public class ModelRepositoryWriterStage extends AbstractConsumerStage<ModelRepository> { + + private final Path outputDirectory; + + public ModelRepositoryWriterStage(final Path outputDirectory) { + this.outputDirectory = outputDirectory; + } + + @Override + protected void execute(final ModelRepository element) throws Exception { + ArchitectureModelManagementFactory.writeModelRepository(this.outputDirectory, element); + } + +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/RelabelSourceMain.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/RelabelSourceMain.java new file mode 100644 index 0000000000000000000000000000000000000000..5f65146d80848faf345d408e068e16c7853832db --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/RelabelSourceMain.java @@ -0,0 +1,76 @@ +package org.oceandsl.tools.relable; + +import java.io.File; +import java.nio.file.Files; + +import com.beust.jcommander.JCommander; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kieker.common.configuration.Configuration; +import kieker.common.exception.ConfigurationException; +import kieker.tools.common.AbstractService; + +/** + * Architecture analysis main class. + * + * @author Reiner Jung + * @since 1.1 + */ +public class RelabelSourceMain extends AbstractService<TeetimeConfiguration, Settings> { + + /** logger for all tools. */ + protected final Logger logger = LoggerFactory.getLogger(this.getClass().getCanonicalName()); // NOPMD + + public static void main(final String[] args) { + final RelabelSourceMain main = new RelabelSourceMain(); + try { + final int exitCode = main.run("relabel source information", "relabel", args, new Settings()); + java.lang.System.exit(exitCode); + } catch (final IllegalArgumentException e) { + LoggerFactory.getLogger(RelabelSourceMain.class).error("Configuration error: {}", e.getLocalizedMessage()); + java.lang.System.exit(1); + } + } + + @Override + protected boolean checkParameters(final JCommander commander) throws ConfigurationException { + if (!Files.isDirectory(this.parameterConfiguration.getInputDirectory())) { + this.logger.error("Input path {} is not a directory", this.parameterConfiguration.getInputDirectory()); + return false; + } + + if (!Files.isDirectory(this.parameterConfiguration.getOutputDirectory())) { + this.logger.error("Output path {} is not directory", this.parameterConfiguration.getOutputDirectory()); + return false; + } + + if (this.parameterConfiguration.getReplacements().size() == 0) { + this.logger.error("Need to specify at least one replacement rule."); + return false; + } + + return true; + } + + @Override + protected TeetimeConfiguration createTeetimeConfiguration() throws ConfigurationException { + return new TeetimeConfiguration(this.parameterConfiguration); + } + + @Override + protected File getConfigurationFile() { + return null; + } + + @Override + protected boolean checkConfiguration(final Configuration configuration, final JCommander commander) { + return true; + } + + @Override + protected void shutdownService() { + } + +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/ReplaceSourceLabelStage.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/ReplaceSourceLabelStage.java new file mode 100644 index 0000000000000000000000000000000000000000..74da5b26ed824be8277c3363c6ec9c4033eb5a5e --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/ReplaceSourceLabelStage.java @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.relable; + +import java.util.List; +import java.util.Map.Entry; + +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; + +import kieker.analysis.stage.model.ModelRepository; +import kieker.model.analysismodel.sources.SourceModel; +import teetime.stage.basic.AbstractFilter; + +/** + * @author Reiner Jung + * @since 1.1 + */ +public class ReplaceSourceLabelStage extends AbstractFilter<ModelRepository> { + + private final List<Replacement> replacements; + + public ReplaceSourceLabelStage(final List<Replacement> replacements) { + this.replacements = replacements; + } + + @Override + protected void execute(final ModelRepository element) throws Exception { + final SourceModel sourceModel = element.getModel(SourceModel.class); + for (final Replacement replacement : this.replacements) { + this.processModel(sourceModel, replacement); + } + this.outputPort.send(element); + } + + private void processModel(final SourceModel sourceModel, final Replacement replacement) { + for (final Entry<EObject, EList<String>> entry : sourceModel.getSources()) { + this.processReplacement(replacement, entry.getValue()); + } + } + + private void processReplacement(final Replacement replacement, final EList<String> labels) { + int matches = 0; + for (final String find : replacement.getSources()) { + if (labels.contains(find)) { + matches++; + } + } + if (matches == replacement.getSources().size()) { + for (final String find : replacement.getSources()) { + labels.remove(find); + } + if (!labels.contains(replacement.getTarget())) { + labels.add(replacement.getTarget()); + } + } + } +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/Replacement.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/Replacement.java new file mode 100644 index 0000000000000000000000000000000000000000..dbf3bce4b91af78549ffc002f8573ccd7e741deb --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/Replacement.java @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.relable; + +import java.util.List; + +/** + * Description for one replacement rule. + * + * @author Reiner Jung + * @since 1.1 + */ +public class Replacement { + + private final List<String> sources; + + private final String target; + + public Replacement(final List<String> sources, final String target) { + this.sources = sources; + this.target = target; + } + + public List<String> getSources() { + return this.sources; + } + + public String getTarget() { + return this.target; + } +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/ReplacementConverter.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/ReplacementConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..093d09bbbdb129e382261d081eb4d36c037f9418 --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/ReplacementConverter.java @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.relable; + +import java.util.Arrays; +import java.util.List; + +import com.beust.jcommander.IStringConverter; + +/** + * + * @author Reiner Jung + * @since 1.1 + */ +public class ReplacementConverter implements IStringConverter<Replacement> { + + @Override + public Replacement convert(final String value) { + final String[] rule = value.split(":"); + if (rule.length == 2) { + final List<String> sources = Arrays.asList(rule[0].split(",")); + return new Replacement(sources, rule[1]); + } else { + System.err.printf("Format of replacement rule is not supported: %s", value); + return null; + } + } + +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/Settings.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/Settings.java new file mode 100644 index 0000000000000000000000000000000000000000..3d2f32b5663d84b8db56b1021ef050acbf7622a7 --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/Settings.java @@ -0,0 +1,56 @@ +package org.oceandsl.tools.relable; + +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +import java.nio.file.Path; +import java.util.List; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.converters.PathConverter; + +/** + * All settings including command line parameters for the analysis. + * + * @author Reiner Jung + * @since 1.0 + */ +public class Settings { + + @Parameter(names = { "-i", + "--call-input" }, required = false, converter = PathConverter.class, description = "Directory for the input model") + private Path inputDirectory; + + @Parameter(names = { "-o", + "--output" }, required = true, converter = PathConverter.class, description = "Directory for the modified model") + private Path outputDirectory; + + @Parameter(names = { "-r", + "--replacements" }, required = true, variableArity = true, converter = ReplacementConverter.class, description = "Replacement for labels s1,s2:target") + private List<Replacement> replacements; + + public Path getOutputDirectory() { + return this.outputDirectory; + } + + public Path getInputDirectory() { + return this.inputDirectory; + } + + public List<Replacement> getReplacements() { + return this.replacements; + } +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/TeetimeConfiguration.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/TeetimeConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..b4c7b07f30bb32acdca390f2b7f4c3c3717b15df --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/TeetimeConfiguration.java @@ -0,0 +1,23 @@ +package org.oceandsl.tools.relable; + +import org.oceandsl.architecture.model.stages.ModelRepositoryProducerStage; + +import teetime.framework.Configuration; + +/** + * Pipe and Filter configuration relabling tool. + * + * @author Reiner Jung + * @since 1.1 + */ +public class TeetimeConfiguration extends Configuration { + + public TeetimeConfiguration(final Settings settings) { + final ModelRepositoryProducerStage readerStage = new ModelRepositoryProducerStage(settings.getInputDirectory()); + final ReplaceSourceLabelStage replaceSourceLabelStage = new ReplaceSourceLabelStage(settings.getReplacements()); + final ModelRepositoryWriterStage writerStage = new ModelRepositoryWriterStage(settings.getOutputDirectory()); + + this.connectPorts(readerStage.getOutputPort(), replaceSourceLabelStage.getInputPort()); + this.connectPorts(replaceSourceLabelStage.getOutputPort(), writerStage.getInputPort()); + } +} diff --git a/tools/relabel/src/main/java/org/oceandsl/tools/relable/package-info.java b/tools/relabel/src/main/java/org/oceandsl/tools/relable/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..45974ead480e1cd432698abe31c0239aa57df205 --- /dev/null +++ b/tools/relabel/src/main/java/org/oceandsl/tools/relable/package-info.java @@ -0,0 +1 @@ +package org.oceandsl.tools.relable; \ No newline at end of file diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/Settings.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/Settings.java index b289121f52a6b5b3fd2a74e1357570e03db35eb7..cc13ad01d53a74071cdf70764e09dae9a79081d4 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/Settings.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/Settings.java @@ -52,17 +52,18 @@ public class Settings { @Parameter(names = { "-f", "--function-names" }, required = false, variableArity = true, converter = PathConverter.class, description = "Function file map CSV file") private List<Path> functionNameFiles; - - @Parameter(names = { "-m", "--missing-functions" }, required=false, converter = PathConverter.class, description = "Output file for the list of function without an associated file") + + @Parameter(names = { "-m", + "--missing-functions" }, required = false, converter = PathConverter.class, description = "Output file for the list of function without an associated file") private Path missingFunctionsFile; - + @Parameter(names = { "-o", "--output" }, required = true, converter = PathConverter.class, description = "Output directory to store graphics and statistics") private Path outputDirectory; @Parameter(names = { "-M", - "--component-map" }, required = false, converter = PathConverter.class, description = "Component, file and function map file") - private Path componentMapFile; + "--component-map" }, required = false, variableArity = true, converter = PathConverter.class, description = "Component, file and function map file") + private List<Path> componentMapFiles; @Parameter(names = { "-l", "--source-label" }, required = true, description = "Set source label for the read data") private String sourceLabel; @@ -78,6 +79,10 @@ public class Settings { @Parameter(names = { "-E", "--experiment-name" }, required = true, description = "Name of the experiment") private String experimentName; + @Parameter(names = { "-n", + "--missing-mappings" }, required = false, converter = PathConverter.class, description = "Output file for files without a mapping in the mapping file.") + private Path missingMappingFile; + public Path getOperationCallInputFile() { return this.operationCallInputFile; } @@ -130,15 +135,19 @@ public class Settings { return this.experimentName; } - public Path getComponentMapFile() { - return this.componentMapFile; + public List<Path> getComponentMapFiles() { + return this.componentMapFiles; } public Path getDataflowInputFile() { return this.dataflowInputFile; } - public Path getMissingFunctionsFile() { - return this.missingFunctionsFile; - } + public Path getMissingFunctionsFile() { + return this.missingFunctionsFile; + } + + public Path getMissingMappingFile() { + return this.missingMappingFile; + } } diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/StaticArchitectureRecoveryMain.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/StaticArchitectureRecoveryMain.java index 400d19ab080aed773eae9170933760b86953e6fb..66617923f9cee82ae9d383f8e1dd6dc721d51309 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/StaticArchitectureRecoveryMain.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/StaticArchitectureRecoveryMain.java @@ -85,7 +85,7 @@ public class StaticArchitectureRecoveryMain { */ private void execute(final JCommander commander, final String label) throws ConfigurationException { this.repository = ArchitectureModelManagementFactory.createModelRepository( - this.settings.getExperimentName(), this.settings.getComponentMapFile() != null); + this.settings.getExperimentName(), this.settings.getComponentMapFiles() != null); if (this.settings.getOperationCallInputFile() != null) this.executeConfiguration("call", label, this.createTeetimeCallConfiguration()); diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeCallConfiguration.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeCallConfiguration.java index 7b07665329a28dfb824b95ce830cb7af78e447f1..7f7003364d907e7f9b05310a5d48d2c49f91d2ab 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeCallConfiguration.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeCallConfiguration.java @@ -22,9 +22,9 @@ import java.nio.file.Paths; import org.oceandsl.analysis.CSVFunctionCallReaderStage; import org.oceandsl.analysis.CallerCallee; import org.oceandsl.architecture.model.data.table.ValueConversionErrorException; -import org.oceandsl.architecture.model.stages.OperationCallFixPathStage; import org.oceandsl.architecture.model.stages.CSVMapperStage; import org.oceandsl.architecture.model.stages.CountUniqueCallsStage; +import org.oceandsl.architecture.model.stages.OperationCallFixPathStage; import org.oceandsl.tools.sar.stages.FileBasedCleanupComponentSignatureStage; import org.oceandsl.tools.sar.stages.MapBasedCleanupComponentSignatureStage; import org.oceandsl.tools.sar.stages.OperationAndCall4StaticDataStage; @@ -69,12 +69,14 @@ public class TeetimeCallConfiguration extends Configuration { readerPort = readCsvStage.getOutputPort(); - if ((settings.getFunctionNameFiles() != null) && !settings.getFunctionNameFiles().isEmpty()) { - final OperationCallFixPathStage fixPathStage = new OperationCallFixPathStage(settings.getFunctionNameFiles(), - settings.getNamesSplitSymbol()); + if (settings.getFunctionNameFiles() != null && !settings.getFunctionNameFiles().isEmpty()) { + final OperationCallFixPathStage fixPathStage = new OperationCallFixPathStage( + settings.getFunctionNameFiles(), settings.getNamesSplitSymbol()); if (settings.getMissingFunctionsFile() != null) { - final StringFileWriterSink missingFunctionsListSink = new StringFileWriterSink(settings.getMissingFunctionsFile()); - this.connectPorts(fixPathStage.getMissingOperationOutputPort(), missingFunctionsListSink.getInputPort()); + final StringFileWriterSink missingFunctionsListSink = new StringFileWriterSink( + settings.getMissingFunctionsFile()); + this.connectPorts(fixPathStage.getMissingOperationOutputPort(), + missingFunctionsListSink.getInputPort()); } this.connectPorts(readerPort, fixPathStage.getInputPort()); readerPort = fixPathStage.getOutputPort(); @@ -83,10 +85,11 @@ public class TeetimeCallConfiguration extends Configuration { this.connectPorts(readerPort, mapperStage.getInputPort()); readerPort = mapperStage.getOutputPort(); - if (settings.getComponentMapFile() != null) { + if (settings.getComponentMapFiles() != null) { logger.info("Map based component definition"); final MapBasedCleanupComponentSignatureStage cleanupComponentSignatureStage = new MapBasedCleanupComponentSignatureStage( - settings.getComponentMapFile(), settings.getCaseInsensitive()); + settings.getComponentMapFiles(), settings.getMissingMappingFile(), settings.getCallSplitSymbol(), + settings.getCaseInsensitive()); this.connectPorts(readerPort, cleanupComponentSignatureStage.getInputPort()); readerPort = cleanupComponentSignatureStage.getOutputPort(); @@ -110,7 +113,7 @@ public class TeetimeCallConfiguration extends Configuration { } final Path path = Paths.get(signature); final String name = path.getName(path.getNameCount() - 1).toString(); - final String rest = (path.getParent() != null) + final String rest = path.getParent() != null ? settings.getExperimentName() + "." + path.getParent().toString() : settings.getExperimentName(); componentType.setName(name); diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeDataflowConfiguration.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeDataflowConfiguration.java index 3fc524aeb5fc72975a032fedbcdd4e44d4e40851..f9599de0407b5eb907086e9c2cc906a96dfbc592 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeDataflowConfiguration.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/TeetimeDataflowConfiguration.java @@ -24,7 +24,8 @@ import org.oceandsl.tools.sar.stages.dataflow.CountUniqueDataflowCallsStage; import org.oceandsl.tools.sar.stages.dataflow.DataAccess; import org.oceandsl.tools.sar.stages.dataflow.DeploymentModelDataflowAssemblerStage; import org.oceandsl.tools.sar.stages.dataflow.ExecutionModelDataflowAssemblerStage; -import org.oceandsl.tools.sar.stages.dataflow.FileBasedCleanupComponentInDataflowSignatureStage; +import org.oceandsl.tools.sar.stages.dataflow.FileBasedCleanupInDataflowSignatureStage; +import org.oceandsl.tools.sar.stages.dataflow.MapBasedCleanupInDataflowSignatureStage; import org.oceandsl.tools.sar.stages.dataflow.TypeModelDataflowAssemblerStage; import org.slf4j.Logger; @@ -56,11 +57,17 @@ public class TeetimeDataflowConfiguration extends Configuration { readerDataflowPort = readDataflowStage.getOutputPort(); - if (settings.getComponentMapFile() != null) { + if (settings.getComponentMapFiles() != null) { logger.info("Map based component definition"); + final MapBasedCleanupInDataflowSignatureStage cleanupComponentDataflowSignatureStage = new MapBasedCleanupInDataflowSignatureStage( + settings.getComponentMapFiles(), settings.getMissingMappingFile(), settings.getCallSplitSymbol(), + settings.getCaseInsensitive()); + + this.connectPorts(readerDataflowPort, cleanupComponentDataflowSignatureStage.getInputPort()); + readerDataflowPort = cleanupComponentDataflowSignatureStage.getOutputPort(); } else { logger.info("File based component definition"); - final FileBasedCleanupComponentInDataflowSignatureStage cleanupComponentDataflowSignatureStage = new FileBasedCleanupComponentInDataflowSignatureStage( + final FileBasedCleanupInDataflowSignatureStage cleanupComponentDataflowSignatureStage = new FileBasedCleanupInDataflowSignatureStage( settings.getCaseInsensitive()); this.connectPorts(readerDataflowPort, cleanupComponentDataflowSignatureStage.getInputPort()); diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/MapBasedCleanupComponentSignatureStage.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/MapBasedCleanupComponentSignatureStage.java index 45cdb30b6bd4080bb6385af4fb4ea492862c190c..53c271703df0d0291bab43028bec515e7800d381 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/MapBasedCleanupComponentSignatureStage.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/MapBasedCleanupComponentSignatureStage.java @@ -17,10 +17,12 @@ package org.oceandsl.tools.sar.stages; import java.io.BufferedReader; import java.io.IOException; +import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.oceandsl.architecture.model.data.table.ValueConversionErrorException; @@ -32,26 +34,33 @@ import org.oceandsl.architecture.model.data.table.ValueConversionErrorException; public class MapBasedCleanupComponentSignatureStage extends AbstractCleanupComponentSignatureStage { private final Map<String, String> componentMap = new HashMap<>(); + private final PrintWriter missingMappingWriter; - public MapBasedCleanupComponentSignatureStage(final Path componentMapFile, final boolean caseInsensitive) - throws IOException, ValueConversionErrorException { + public MapBasedCleanupComponentSignatureStage(final List<Path> componentMapFiles, final Path missingMappingFile, + final String separator, final boolean caseInsensitive) throws IOException, ValueConversionErrorException { super(caseInsensitive); - this.logger.info("Reading map file {}", componentMapFile.toString()); - final BufferedReader reader = Files.newBufferedReader(componentMapFile); - String line; - while ((line = reader.readLine()) != null) { - final String[] values = line.split(","); - if (values.length == 3) { - // 0 = component name - // 1 = file name - // 2 = function name - this.componentMap.put(this.convertToLowerCase(values[1].trim()), - this.convertToLowerCase(values[0].trim().toLowerCase())); - } else { - this.logger.error("Entry incomplete '{}'", line.trim()); + if (missingMappingFile != null) { + this.missingMappingWriter = new PrintWriter(Files.newBufferedWriter(missingMappingFile)); + } else { + this.missingMappingWriter = null; + } + for (final Path componentMapFile : componentMapFiles) { + this.logger.info("Reading map file {}", componentMapFile.toString()); + final BufferedReader reader = Files.newBufferedReader(componentMapFile); + String line; + while ((line = reader.readLine()) != null) { + final String[] values = line.split(separator); + if (values.length == 2) { + // 0 = component name + // 1 = file name + this.componentMap.put(this.convertToLowerCase(values[1].trim()), + this.convertToLowerCase(values[0].trim().toLowerCase())); + } else { + this.logger.error("Entry incomplete '{}'", line.trim()); + } } + reader.close(); } - reader.close(); } private String convertToLowerCase(final String string) { @@ -76,9 +85,20 @@ public class MapBasedCleanupComponentSignatureStage extends AbstractCleanupCompo return result; } else { this.logger.warn("File '{}' has no component mapping. Signature '{}'", filename, signature); - return "??" + signature.toLowerCase(); + if (this.missingMappingWriter != null) { + this.missingMappingWriter.println(filename + "; " + signature); + } + return "unknown"; } } } + @Override + protected void onTerminating() { + if (this.missingMappingWriter != null) { + this.missingMappingWriter.close(); + } + super.onTerminating(); + } + } diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/AssemblyModelDataflowAssemblerStage.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/AssemblyModelDataflowAssemblerStage.java index 86afc7d6a691b5002ae10c36445c87a02be54ace..654e85b137eb2a4c3ca3dfa5d06aad683846a509 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/AssemblyModelDataflowAssemblerStage.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/AssemblyModelDataflowAssemblerStage.java @@ -89,14 +89,23 @@ public class AssemblyModelDataflowAssemblerStage extends AbstractDataflowAssembl final String name = assemblyStorage.getStorageType().getName(); assemblyComponent.getAssemblyStorages().removeKey(name); - final AssemblyComponent newAssemblyComponent = AssemblyFactory.eINSTANCE.createAssemblyComponent(); - newAssemblyComponent - .setComponentType(this.findComponentType(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE + "." + name)); - newAssemblyComponent.setSignature(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE + "." + name); - newAssemblyComponent.getAssemblyStorages().put(name, assemblyStorage); - - this.addObjectToSource(newAssemblyComponent); - this.assemblyModel.getAssemblyComponents().put(newAssemblyComponent.getSignature(), newAssemblyComponent); + this.findOrCreateAssemblyComponent().getAssemblyStorages().put(name, assemblyStorage); + } + + private AssemblyComponent findOrCreateAssemblyComponent() { + final AssemblyComponent existingAssemblyComponent = this.assemblyModel.getAssemblyComponents() + .get(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); + if (existingAssemblyComponent == null) { + final AssemblyComponent newAssemblyComponent = AssemblyFactory.eINSTANCE.createAssemblyComponent(); + newAssemblyComponent + .setComponentType(this.findComponentType(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE)); + newAssemblyComponent.setSignature(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); + this.addObjectToSource(newAssemblyComponent); + this.assemblyModel.getAssemblyComponents().put(newAssemblyComponent.getSignature(), newAssemblyComponent); + return newAssemblyComponent; + } else { + return existingAssemblyComponent; + } } private ComponentType findComponentType(final String componentSignature) { diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DataAccess.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DataAccess.java index 9106b59730274b68b85af75f8e843f7fe32087c1..a3c851c588106e1ba99399c4c327f4d33652fcdb 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DataAccess.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DataAccess.java @@ -22,9 +22,9 @@ package org.oceandsl.tools.sar.stages.dataflow; public class DataAccess { private String module; - private final String operation; + private String operation; private final EDirection direction; - private final String sharedData; + private String sharedData; public DataAccess(final String module, final String operation, final EDirection direction, final String sharedData) { @@ -38,10 +38,18 @@ public class DataAccess { return this.module; } + public void setModule(final String module) { + this.module = module; + } + public String getOperation() { return this.operation; } + public void setOperation(final String operation) { + this.operation = operation; + } + public EDirection getDirection() { return this.direction; } @@ -50,8 +58,7 @@ public class DataAccess { return this.sharedData; } - public void setModule(final String module) { - this.module = module; + public void setSharedData(final String sharedData) { + this.sharedData = sharedData; } - } diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DeploymentModelDataflowAssemblerStage.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DeploymentModelDataflowAssemblerStage.java index 5834669d613868d71ce96d7dde30119a0b24f984..f9f66ee9afb405edf7713355fb7a47c2d3adf74f 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DeploymentModelDataflowAssemblerStage.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/DeploymentModelDataflowAssemblerStage.java @@ -105,8 +105,6 @@ public class DeploymentModelDataflowAssemblerStage extends AbstractDataflowAssem } else { DeployedComponent deployedComponent = deployedContext.getComponents().get(element.getModule()); if (deployedComponent == null) { - this.logger.warn("Cannot find deployed component for {}", element.getModule()); - deployedComponent = DeploymentFactory.eINSTANCE.createDeployedComponent(); deployedComponent.setSignature(element.getModule()); deployedComponent.setAssemblyComponent(this.findAssemblyComponent(element.getModule())); @@ -116,8 +114,6 @@ public class DeploymentModelDataflowAssemblerStage extends AbstractDataflowAssem DeployedOperation deployedOperation = deployedComponent.getContainedOperations() .get(element.getOperation()); if (deployedOperation == null) { - this.logger.warn("Operation {} cannot be found in model.", element.getOperation()); - final AssemblyComponent assemblyComponent = this.assemblyModel.getAssemblyComponents() .get(element.getModule()); final AssemblyOperation assemblyOperation = assemblyComponent.getAssemblyOperations() @@ -136,15 +132,23 @@ public class DeploymentModelDataflowAssemblerStage extends AbstractDataflowAssem final String name = deployedStorage.getAssemblyStorage().getStorageType().getName(); deployedComponent.getContainedStorages().removeKey(name); - final DeployedComponent newDeployedComponent = DeploymentFactory.eINSTANCE.createDeployedComponent(); - newDeployedComponent.setAssemblyComponent( - this.findAssemblyComponent(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE + "." + name)); - newDeployedComponent.setSignature(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE + "." + name); - newDeployedComponent.getContainedStorages().put(name, deployedStorage); + final DeploymentContext context = deployedComponent.getDeploymentContext(); + + final DeployedComponent existingComponent = context.getComponents() + .get(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); - this.addObjectToSource(newDeployedComponent); - this.deploymentModel.getDeploymentContexts().get(0).getValue().getComponents() - .put(newDeployedComponent.getSignature(), newDeployedComponent); + if (existingComponent == null) { + final DeployedComponent newDeployedComponent = DeploymentFactory.eINSTANCE.createDeployedComponent(); + newDeployedComponent + .setAssemblyComponent(this.findAssemblyComponent(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE)); + newDeployedComponent.setSignature(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); + newDeployedComponent.getContainedStorages().put(name, deployedStorage); + + this.addObjectToSource(newDeployedComponent); + context.getComponents().put(newDeployedComponent.getSignature(), newDeployedComponent); + } else { + existingComponent.getContainedStorages().put(name, deployedStorage); + } } private AssemblyComponent findAssemblyComponent(final String signature) { diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/FileBasedCleanupComponentInDataflowSignatureStage.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/FileBasedCleanupInDataflowSignatureStage.java similarity index 73% rename from tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/FileBasedCleanupComponentInDataflowSignatureStage.java rename to tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/FileBasedCleanupInDataflowSignatureStage.java index 2f07bf7d2d897fb005123089a14c183561c86fdb..8e10eccc256742c9528e61da0e2d4188b054a779 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/FileBasedCleanupComponentInDataflowSignatureStage.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/FileBasedCleanupInDataflowSignatureStage.java @@ -21,20 +21,25 @@ import java.nio.file.Paths; import teetime.stage.basic.AbstractTransformation; /** - * @author Reiner Jung + * Cleanup names and make them lower case if requested. * + * @author Reiner Jung + * @since 1.1 */ -public class FileBasedCleanupComponentInDataflowSignatureStage extends AbstractTransformation<DataAccess, DataAccess> { +public class FileBasedCleanupInDataflowSignatureStage extends AbstractTransformation<DataAccess, DataAccess> { private final boolean caseInsensitive; - public FileBasedCleanupComponentInDataflowSignatureStage(final boolean caseInsensitive) { + public FileBasedCleanupInDataflowSignatureStage(final boolean caseInsensitive) { this.caseInsensitive = caseInsensitive; } @Override protected void execute(final DataAccess element) throws Exception { - element.setModule(this.convertToLowerCase(this.processComponentSignature(element.getModule()))); + element.setModule(this.convertToLowerCase(this.processSignature(element.getModule()))); + element.setOperation(this.convertToLowerCase(this.processSignature(element.getOperation()))); + element.setSharedData(this.convertToLowerCase(this.processSignature(element.getSharedData()))); + this.outputPort.send(element); } @@ -48,7 +53,7 @@ public class FileBasedCleanupComponentInDataflowSignatureStage extends AbstractT return this.caseInsensitive ? value.toLowerCase() : value; } - private String processComponentSignature(final String signature) { + private String processSignature(final String signature) { if ("<<no-file>>".equals(signature)) { return signature; } else { diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/MapBasedCleanupInDataflowSignatureStage.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/MapBasedCleanupInDataflowSignatureStage.java new file mode 100644 index 0000000000000000000000000000000000000000..1c5286a8f3b967f260c3cf69dca0fa6694bcdcbe --- /dev/null +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/MapBasedCleanupInDataflowSignatureStage.java @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package org.oceandsl.tools.sar.stages.dataflow; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import teetime.stage.basic.AbstractTransformation; + +/** + * Cleanup names and make them lower case if requested. + * + * @author Reiner Jung + * @since 1.1 + */ +public class MapBasedCleanupInDataflowSignatureStage extends AbstractTransformation<DataAccess, DataAccess> { + + private final boolean caseInsensitive; + private final Map<String, String> componentMap = new HashMap<>(); + + public MapBasedCleanupInDataflowSignatureStage(final List<Path> componentMapFiles, final Path missingMappingFile, + final String seperator, final boolean caseInsensitive) throws IOException { + this.caseInsensitive = caseInsensitive; + this.setupMap(componentMapFiles, seperator); + } + + private void setupMap(final List<Path> componentMapFiles, final String separator) throws IOException { + for (final Path componentMapFile : componentMapFiles) { + this.logger.info("Reading map file {}", componentMapFile.toString()); + final BufferedReader reader = Files.newBufferedReader(componentMapFile); + String line; + while ((line = reader.readLine()) != null) { + final String[] values = line.split(separator); + if (values.length == 2) { + // 0 = component name + // 1 = file name + this.componentMap.put(this.convertToLowerCase(values[1].trim()), + this.convertToLowerCase(values[0].trim().toLowerCase())); + } else { + this.logger.error("Entry incomplete '{}'", line.trim()); + } + } + reader.close(); + } + } + + @Override + protected void execute(final DataAccess element) throws Exception { + element.setModule(this.convertToLowerCase(this.processComponentSignature(element.getModule()))); + element.setOperation(this.convertToLowerCase(this.processSignature(element.getOperation()))); + element.setSharedData(this.convertToLowerCase(this.processSignature(element.getSharedData()))); + + this.outputPort.send(element); + } + + private String convertToLowerCase(final String string) { + String value; + if (string.endsWith("_")) { + value = string.substring(0, string.length() - 1); + } else { + value = string; + } + return this.caseInsensitive ? value.toLowerCase() : value; + } + + private String processSignature(final String signature) { + if ("<<no-file>>".equals(signature)) { + return signature; + } else { + final Path path = Paths.get(signature); + return this.convertToLowerCase(path.getName(path.getNameCount() - 1).toString()); + } + } + + private String processComponentSignature(final String signature) { + if ("<<no-file>>".equals(signature)) { + return signature; + } else { + final Path path = Paths.get(signature); + final String filename = this.convertToLowerCase(path.getName(path.getNameCount() - 1).toString()); + final String result = this.componentMap.get(filename); + if (result != null) { + return result; + } else { + this.logger.warn("File '{}' has no component mapping. Signature '{}'", filename, signature); + return "unknown"; + } + } + } +} diff --git a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/TypeModelDataflowAssemblerStage.java b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/TypeModelDataflowAssemblerStage.java index daab258ca02ed7ad0386f1c23f53466f735f0937..24a732cfc41ad5b81170d5f06f703053ab445cef 100644 --- a/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/TypeModelDataflowAssemblerStage.java +++ b/tools/sar/src/main/java/org/oceandsl/tools/sar/stages/dataflow/TypeModelDataflowAssemblerStage.java @@ -89,14 +89,25 @@ public class TypeModelDataflowAssemblerStage extends AbstractDataflowAssemblerSt final ComponentType componentType) { componentType.getProvidedStorages().removeKey(storageType.getName()); - final ComponentType newComponentType = TypeFactory.eINSTANCE.createComponentType(); - newComponentType.setName(storageType.getName()); - newComponentType.setPackage(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); - newComponentType.setSignature(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE + "." + storageType.getName()); - newComponentType.getProvidedStorages().put(storageType.getName(), storageType); - - this.addObjectToSource(newComponentType); - this.typeModel.getComponentTypes().put(newComponentType.getSignature(), newComponentType); + this.findOrCreateGlobalComponentType().getProvidedStorages().put(storageType.getName(), storageType); + } + + private ComponentType findOrCreateGlobalComponentType() { + final ComponentType componentType = this.typeModel.getComponentTypes() + .get(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); + if (componentType != null) { + return componentType; + } else { + final ComponentType newComponentType = TypeFactory.eINSTANCE.createComponentType(); + newComponentType.setName(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); + newComponentType.setPackage(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); + newComponentType.setSignature(TypeModelDataflowAssemblerStage.GLOBAL_PACKAGE); + + this.typeModel.getComponentTypes().put(newComponentType.getSignature(), newComponentType); + this.addObjectToSource(newComponentType); + + return newComponentType; + } } private OperationType findOperation(final DataAccess element) { @@ -111,7 +122,7 @@ public class TypeModelDataflowAssemblerStage extends AbstractDataflowAssemblerSt this.typeModel.getComponentTypes().put(element.getModule(), componentType); final OperationType operationType = this.createOperation(element.getOperation()); componentType.getProvidedOperations().put(element.getOperation(), operationType); - + return operationType; } else { for (final OperationType operation : componentType.getProvidedOperations().values()) {