diff --git a/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/.ratings b/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/.ratings index 1a4f853f0311d640eddcdd6d0f6b1f82b3c2213b..f2581491b6ce845015d5808db1b1573d72f1a7ff 100644 --- a/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/.ratings +++ b/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/.ratings @@ -1,7 +1,3 @@ IModelQualityViewPart.java 708f8089645df12098ea67190805cce343045d2e YELLOW -<<<<<<< HEAD -ModelQualityFXController.java ec593e9c70ce70f4f2734cf6750cec8a844e6a47 YELLOW -======= -ModelQualityFXController.java 78b503c4344226585c0d57cb548787a3ddd649a6 RED ->>>>>>> branch '4310' of https://git.fortiss.org/af3/kernel.git +ModelQualityFXController.java e39386b6d4a3f51e71be89d1f1f633342ece79ea YELLOW ModelQualityFXViewPart.java 179abf18d6e3b6c844076620f53b43ac8a42c217 YELLOW diff --git a/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/ModelQualityFXController.java b/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/ModelQualityFXController.java index c91a75f22247c3f373112bbf3e51212d13cdb96a..e39386b6d4a3f51e71be89d1f1f633342ece79ea 100644 --- a/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/ModelQualityFXController.java +++ b/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/view/fx/ModelQualityFXController.java @@ -221,7 +221,7 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan if(node != null) { - updateChoiceBoxes(node); + //updateChoiceBoxes(node); if(!node.getChildren().isEmpty()) { @@ -461,81 +461,4 @@ public class ModelQualityFXController extends CompositeFXControllerBase<SplitPan lastViewedElements.remove(0); } } - - /** - * Updates all choice boxes, such that they only allow the selection of keys for which we can - * display data. - * Keys for which the metric is 0.0 in all children are removed - * - * @param node - * used to calculate the allowed keys - */ - private void updateChoiceBoxes(MetricTreeNode node) { - Set<MetricKey> validKeys = getAllChildrenKeys(node); - - // This code removes choices for which all children have zero as value, which is not - // useful data to display - Iterator<MetricKey> iterator = validKeys.iterator(); - while(iterator.hasNext()) { - MetricKey key = iterator.next(); - - // Check if the metric is non zero for any child - if(node.getChildren().stream().anyMatch(child -> child.getValueAsDouble(key) != 0.0)) { - // Continue to next child - continue; - } - // If all children have a zero value for the metric, remove the key - iterator.remove(); - } - - updateChoiceBox(childMetricChoiceBox, validKeys); - updateChoiceBox(xScatterMetricChoiceBox, validKeys); - updateChoiceBox(yScatterMetricChoiceBox, validKeys); - } - - /** - * Collects all keys for which values can be retrieved in at least on child - * - * @param node - * for which children the keys should be selected - * @return set of keys which have stored values - */ - private static Set<MetricKey> getAllChildrenKeys(MetricTreeNode node) { - // Get all keys which are stored in the children - Set<MetricKey> childrenKeys = new HashSet<>(); - for(MetricTreeNode child : node.getChildren()) { - childrenKeys.addAll(child.getStoredDoubles().keySet()); - childrenKeys.addAll(child.getStoredIntegers().keySet()); - } - return childrenKeys; - } - - /** - * Updates the choice box, such that it will only give the option to select one of the provided - * keys - * - * @param choiceBox - * to be updated - * @param validKeys - * which will be displayed for selection - */ - private static void updateChoiceBox(ChoiceBox<MetricKey> choiceBox, Set<MetricKey> validKeys) { - // Update choice box, so only valid choices can be selected - ObservableList<MetricKey> choices = choiceBox.getItems(); - // Remove all non valid keys - choices.retainAll(validKeys); - // Add all keys not - for(MetricKey key : validKeys) { - if(!choices.contains(key)) { - choices.add(key); - } - } - - // Check if a choice is selected, and that the choice is valid - if(!choices.isEmpty() && - (choiceBox.getValue() == null || !choices.contains(choiceBox.getValue()))) { - // Set choice box to first element in choices, if there are any valid choices - choiceBox.setValue(choices.get(0)); - } - } } diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/.ratings b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/.ratings index 27c82a4bd5b286f4b4dc8765f3fbba5347110fb8..4ab24eee160784828a84e31f249eaa61566eba2a 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/.ratings +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/.ratings @@ -1,5 +1,5 @@ AF3QualityActivator.java 353c3d99f423997e4e99a896b3c095fd77d81431 YELLOW GraphMetricsProvider.java b00a3b47acfcb6df3ab948f1258ff256ab07728c YELLOW -HierarchicElementProvider.java 721c03e40f618955867e662a46e55b4b6a8cd7bc YELLOW +HierarchicElementProvider.java 14d99b4d76ec28191ecd0f2654f43b92c36f1302 YELLOW IMetricProvider.java 99fc8993b0e65b2f8757978eeb0481d912f5608c YELLOW IMetricUpdateListener.java c24dc7c0f282623bbf1eefac1fbbb6752c97ddf0 YELLOW diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/HierarchicElementProvider.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/HierarchicElementProvider.java index 721c03e40f618955867e662a46e55b4b6a8cd7bc..14d99b4d76ec28191ecd0f2654f43b92c36f1302 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/HierarchicElementProvider.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/HierarchicElementProvider.java @@ -54,7 +54,7 @@ public class HierarchicElementProvider implements IMetricProvider<IHierarchicEle node.setName("Unnamable Element"); } - integers.put(MetricKey.UNQIUE_ID, (currentElement instanceof IIdLabeled) + integers.put(MetricKey.UNIQUE_ID, (currentElement instanceof IIdLabeled) ? ((IIdLabeled)currentElement).getId() : -1); } diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/.ratings b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/.ratings index 60d87b8aebad3573bcae1d1e960a9ce939da49d8..39c11d23b8ae826708c09a559e900e082c6633cb 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/.ratings +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/.ratings @@ -1,9 +1,4 @@ -<<<<<<< HEAD DataRootElement.java d54ab629fc0dc9069586a3c7edfec0734e35dd86 YELLOW MetricDataManager.java f9e2d04edeb31f0af094d5ad92f6a573c1b90373 YELLOW -======= -DataRootElement.java d54ab629fc0dc9069586a3c7edfec0734e35dd86 RED -MetricDataManager.java f9e2d04edeb31f0af094d5ad92f6a573c1b90373 RED ->>>>>>> branch '4310' of https://git.fortiss.org/af3/kernel.git -MetricKey.java aeca14c4ee3ee4bdcb7d18d8332981aa3d04604d YELLOW +MetricKey.java fa68a7e6025738534345708f13165acf014b4c8d YELLOW MetricTreeNode.java d89ef9aab7171a66ff7fc30c904e06f50d164ff9 YELLOW diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/MetricKey.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/MetricKey.java index aeca14c4ee3ee4bdcb7d18d8332981aa3d04604d..fa68a7e6025738534345708f13165acf014b4c8d 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/MetricKey.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/data/MetricKey.java @@ -29,7 +29,7 @@ public enum MetricKey { // Metrics provided by the HierarchicElementProvider // /** Unique ID of the element */ - UNQIUE_ID(false), + UNIQUE_ID(false), /** Key for the metric counting ports */ NUMBER_OF_CONNECTORS(false), diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/.ratings b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/.ratings index b8085f71e2c82b5adb9f6ad26f9da1466fd0551e..6d7c1b24c456c78ed37341326b664dc1bc3d47f6 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/.ratings +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/.ratings @@ -1,7 +1,2 @@ -<<<<<<< HEAD IModelQualityService.java b530e32826340efaa3872e110d71e1c3a720dc07 YELLOW -ModelQualityService.java da65b2e0e657f13a01b914e7090dc7fa0b60eb87 YELLOW -======= -IModelQualityService.java f653e228ce55ad3a03d60a4a561664ee3213d7a5 RED -ModelQualityService.java eb4009f2ed7c2188fccce6505b627684cdfa925e RED ->>>>>>> branch '4310' of https://git.fortiss.org/af3/kernel.git +ModelQualityService.java e7623bd438d8c0152a00481662fb32954d143c57 YELLOW diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/ModelQualityService.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/ModelQualityService.java index 866323ee8e3460dff99df584bbecc9fe69b35581..e7623bd438d8c0152a00481662fb32954d143c57 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/ModelQualityService.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/ModelQualityService.java @@ -17,6 +17,8 @@ package org.fortiss.tooling.ext.quality.service; import static java.util.Collections.emptyList; +import java.io.IOException; +import java.security.NoSuchAlgorithmException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; @@ -101,18 +103,21 @@ public class ModelQualityService extends EObjectAwareServiceBase<IMetricProvider @Override protected IStatus run(IProgressMonitor monitor) { - do { if(monitor.isCanceled()) { return Status.CANCEL_STATUS; } - ITopLevelElement toBeProcessed = queuedProcessableElements.poll(); if(toBeProcessed == null) { return Status.OK_STATUS; } - - performMetricCollection(toBeProcessed); + try { + performMetricCollection(toBeProcessed); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } } while(true); } }; @@ -159,8 +164,10 @@ public class ModelQualityService extends EObjectAwareServiceBase<IMetricProvider * * @param topLevelElement * the {@link ITopLevelElement} on which the analysis should be performed + * @throws IOException + * @throws NoSuchAlgorithmException */ - private void performMetricCollection(ITopLevelElement topLevelElement) { + private void performMetricCollection(ITopLevelElement topLevelElement) throws NoSuchAlgorithmException, IOException { // Sort root elements, as some metrics are saved into trees from other root elements // To avoid these problems, the elements have to be processed in a certain order diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings index 2be8b125dca445fcf142a9bc8d4a777331b7750c..1f9621e24c22d65c1ef2c6703c25e6902362d815 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings @@ -1,2 +1,2 @@ -CSVFileWriter.java 6476dbb630bab3592cb68541ceb1535c0a920a66 YELLOW -ModelQualityStorageManager.java 124faddb3d297d23448c15379446cc847a2790a9 YELLOW +CSVFileWriter.java 6ee652cdd7a270ad22a29e30d19e6f7f2a41f611 YELLOW +ModelQualityStorageManager.java 50f1fa35b82bc42b564d75fb9510a989b129533f YELLOW diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java index eaf6b7fddc2541bfc09584d8ed2f07a86dd8aef3..6ee652cdd7a270ad22a29e30d19e6f7f2a41f611 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java @@ -21,8 +21,12 @@ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -55,9 +59,11 @@ public class CSVFileWriter { * * @param map * to convert into csv + * @throws IOException + * @throws NoSuchAlgorithmException * */ - public static void metricExtractionToCSV(Map<IProjectRootElement, DataRootElement> map) { + public static void metricExtractionToCSV(Map<IProjectRootElement, DataRootElement> map) throws NoSuchAlgorithmException, IOException { // check if there is any data to export if(map == null || map.isEmpty()) { @@ -75,7 +81,10 @@ public class CSVFileWriter { String projectName = firstValue.getTopLevelElement().getSaveableName(); Path path = new File(ModelQualityStorageManager.MODEL_QUALITY_PROJECT_DIR, projectName.replace(ModelQualityStorageManager.AF3_PRJ_SUFFIX,ModelQualityStorageManager.CSV)).toPath(); - + + Path af3File = new File(ModelQualityStorageManager.MODEL_PROJECT_DIR,firstValue.getTopLevelElement().getSaveableName()).toPath(); + String projectHash = computeGitHash(af3File); + List<String> allKeys = new ArrayList<>(); boolean createNewIndex = true; @@ -91,13 +100,12 @@ public class CSVFileWriter { e.printStackTrace(); } } - writeMetricsToFile(map, allKeys, path, createNewIndex); + writeMetricsToFile(map, allKeys, path, createNewIndex, projectName,projectHash); } /** * Function to write the specified metrics into a csv file. * - * * @param map * of the metrics which are written into the file * @param allKeys @@ -106,9 +114,13 @@ public class CSVFileWriter { * location of the file * @param createNewIndex * if a index should be written before writing any values + * @param projectName + * the name of the base fileProject for this map currently in the focus + * @param projectHash + * the af3 file hash value saved for version identification */ private static void writeMetricsToFile(Map<IProjectRootElement, DataRootElement> map, - List<String> allKeys, Path path, boolean createNewIndex) { + List<String> allKeys, Path path, boolean createNewIndex, String projectName, String projectHash) { try(var writer = new BufferedWriter(new FileWriter(path.toFile(), true))) { @@ -116,6 +128,7 @@ public class CSVFileWriter { // Create new index and write it into the first line of the file allKeys.add("timestamp"); allKeys.add("project_name"); + allKeys.add("project_hash"); allKeys.add("root_element_name"); allKeys.add("name"); allKeys.add("children"); @@ -128,8 +141,8 @@ public class CSVFileWriter { writer.write(String.join(",", allKeys)); writer.write("\n"); } - // Remove first 4 keys as they are not provided by the provider - List<String> valueKeys = allKeys.subList(5, allKeys.size()); + // Remove first 6 keys as they are not provided by the provider + List<String> valueKeys = allKeys.subList(6, allKeys.size()); LocalDateTime dateTime = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; @@ -138,9 +151,6 @@ public class CSVFileWriter { map.forEach((rootElement, dataRootElement) -> { // iterate over all project roots String rootName = rootElement.getClass().getSimpleName(); - var topLevelElement = dataRootElement.getTopLevelElement(); - String projectName = topLevelElement.getSaveableName(); - var rootNode = dataRootElement.getRootNode(); rootNode.traverseTree(node -> { var integers = node.getStoredIntegers(); @@ -148,11 +158,11 @@ public class CSVFileWriter { var strings = node.getStoredStrings(); // collect IDs of children String children_ids = node.getChildren().stream() - .map(n -> n.getStoredIntegers().get(MetricKey.UNQIUE_ID)) + .map(n -> n.getStoredIntegers().get(MetricKey.UNIQUE_ID)) .map(id -> id.toString()).reduce((a, b) -> a + " " + b).orElse(""); - // These 4 data entries are just concatenated in front - var startStream = Stream.of(formattedDateTime, projectName, rootName, + // These 6 data entries are just concatenated in front + var startStream = Stream.of(formattedDateTime, projectName, projectHash, rootName, node.getName(), children_ids); // Collect all values from provider in the correct order and combine var values = Stream.concat(startStream, valueKeys.stream() @@ -176,4 +186,25 @@ public class CSVFileWriter { e.printStackTrace(); } } + + /** Function to generate the hash for a fileProject to later on identify the versions with the saved metrics. */ + private static String computeGitHash(Path filePath) throws NoSuchAlgorithmException, IOException { + String fileAsString = new String(Files.readAllBytes(Paths.get(filePath.toString()))); + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + byte[] hash = digest.digest(fileAsString.getBytes(StandardCharsets.UTF_8)); + return bytesToHex(hash); + } + + /** Switching from bytes to Hex notation. */ + private static String bytesToHex(byte[] hash) { + StringBuilder hexString = new StringBuilder(2 * hash.length); + for (byte b : hash) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } } diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/ModelQualityStorageManager.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/ModelQualityStorageManager.java index 5dab1bd135b22f53498e782799c7ce394524698f..50f1fa35b82bc42b564d75fb9510a989b129533f 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/ModelQualityStorageManager.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/ModelQualityStorageManager.java @@ -30,6 +30,9 @@ public class ModelQualityStorageManager { /** The name of the general quality plugin directory. */ public static final String AF3_QUALITY_DIRECTORY_NAME = "AF3-Model-Quality-Directory"; + + /** The name of the general project directory. */ + public static final String AF3_PROJECT_DIRECTORY_NAME = "AF3-Project-Directory"; /** The current workspace root. */ public static final IWorkspaceRoot WORKSPACE_ROOT = getWorkspace().getRoot(); @@ -37,10 +40,14 @@ public class ModelQualityStorageManager { /** {@link File} representing the directory where all data is saved. */ public static final File MODEL_QUALITY_PROJECT_DIR = new File(WORKSPACE_ROOT.getLocation() + File.separator + AF3_QUALITY_DIRECTORY_NAME); + + /** {@link File} representing the directory where all data is saved. */ + public static final File MODEL_PROJECT_DIR = + new File(WORKSPACE_ROOT.getLocation() + File.separator + AF3_PROJECT_DIRECTORY_NAME); /** Defines the suffix of AF3 project files. */ public static final String AF3_PRJ_SUFFIX = "af3_23"; - /** Name of the file in which the data is written. */ + /** Suffix of the file in which the data is written. */ public static final String CSV = "csv"; }