diff --git a/org.fortiss.tooling.ext.quality.ui/META-INF/MANIFEST.MF b/org.fortiss.tooling.ext.quality.ui/META-INF/MANIFEST.MF index 7fcef617d54f557d53a7cbb3af10a8c0221116ed..6aae7a77c90d056622cece521f411aad8dc34a23 100644 --- a/org.fortiss.tooling.ext.quality.ui/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.ext.quality.ui/META-INF/MANIFEST.MF @@ -5,6 +5,8 @@ Bundle-SymbolicName: org.fortiss.tooling.ext.quality.ui;singleton:=true Bundle-Version: 1.0.0 Automatic-Module-Name: org.fortiss.tooling.ext.quality.ui Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Vendor: %providerName +Bundle-Activator: org.fortiss.tooling.ext.quality.AF3QualityActivator Require-Bundle: org.eclipse.ui.ide;visibility:=reexport, org.fortiss.tooling.base.ui;visibility:=reexport, org.fortiss.tooling.kernel, diff --git a/org.fortiss.tooling.ext.quality/build.properties b/org.fortiss.tooling.ext.quality/build.properties index 6daa0b7a184cb3c8adeae7a24965033b25f8bdbe..25fdb6e843a649299fcb624d133d5b893f1db2bb 100644 --- a/org.fortiss.tooling.ext.quality/build.properties +++ b/org.fortiss.tooling.ext.quality/build.properties @@ -2,10 +2,7 @@ source.. = src/,\ - generated-src/ -output.. = build/ + test-src/ bin.includes = .,\ - model/,\ META-INF/,\ - plugin.xml,\ - plugin.properties + plugin.xml diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/HierarchicElementSizeProvider.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/HierarchicElementSizeProvider.java index 350d038e89a71528ba0c13249f209f61f1ed07d2..f0a2fbbc77bc9d3b17d58aeb66ae4dac74b9b625 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/HierarchicElementSizeProvider.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/HierarchicElementSizeProvider.java @@ -15,12 +15,20 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.ext.quality.service; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; +import org.eclipse.emf.common.util.EList; +import org.fortiss.tooling.base.model.base.HierarchicElementBase; +import org.fortiss.tooling.base.model.element.IConnector; import org.fortiss.tooling.base.model.element.IHierarchicElement; +import org.fortiss.tooling.base.model.element.IModelElementSpecification; +import org.fortiss.tooling.kernel.model.INamedCommentedElement; +import org.fortiss.tooling.kernel.model.INamedElement; /** * {@link IModelQualityProvider} to count the ratio of filled out comments of @@ -30,315 +38,147 @@ import org.fortiss.tooling.base.model.element.IHierarchicElement; */ public class HierarchicElementSizeProvider implements IModelQualityProvider<IHierarchicElement> { /** - * returns an array of integers or <String,Double> Map - * Number of children of the hierarchical Element (on this level) - * Number of ports on the hierarchical Element (on this level) - * Number of channels in the hierarchical element (on this level) - * Number of totalPorts in whole tree - * Number of totalElements in whole tree - * Average SubTree Size + * returns an array of integers or <String,Double> Map Number of children of the + * hierarchical Element (on this level) Number of ports on the hierarchical + * Element (on this level) Number of channels in the hierarchical element (on + * this level) Number of totalPorts in whole tree Number of totalElements in + * whole tree Average SubTree Size */ - /* */ - private final String rootName; - /** */ - Map<String, Double> sizes = new HashMap<String, Double>(); - /** */ - public HierarchicElementSizeProvider(String rootName) { - super(); - this.rootName = rootName; - // TODO Auto-generated constructor stub - } - - /** */ - public String getName() { - return this.rootName; - } - - /** {@inheritDoc} */ - @Override - public void apply(IHierarchicElement ele) { - Map<String, Double> sizes = new HashMap<String, Double>(); - sizes.put("numberOfPorts", (double)ele.getConnectors().size()); - sizes.put("numberOfChildren", (double)ele.getContainedElements().size()); - sizes.put("numberOfChannels", (double)ele.getConnections().size()); - - // depth metrics - Set<ICounter> depthMetrics = new HashSet<HierarchicElementSizeProvider.ICounter>(); - PortCounter pc = new PortCounter(); - ElementCounter ec = new ElementCounter(); - depthMetrics.add(new PortCounter()); - depthMetrics.add(new ElementCounter()); - // traverse whole tree - traverse(ele, depthMetrics); - - // put in entries for subtrees - sizes.put("numberOfTotalPorts:", (double)pc.getCounter()); - sizes.put("numberOfTotalElements:", (double)ec.getCounter()); + public static final String NUMBER_OF_PORTS = "numberOfPorts"; + public static final String NUMBER_OF_CONTAINED_ELEMENTS = "numberOfContainedElements"; + public static final String NUMBER_OF_CHANNELS = "numberOfChannels"; - for(IHierarchicElement child : ele.getContainedElements()) { - apply(child); - } - this.sizes = sizes; - } + public static final String NUMBER_OF_TOTAL_PORTS = "numberOfTotalPorts"; + public static final String NUMBER_OF_TOTAL_ELEMENTS = "numberOfTotalElements"; + public static final String NUMBER_OF_TOTAL_COMMENTABLE_ELEMENTS = "numberOfTotalCommentableElements"; + public static final String NUMBER_OF_TOTAL_COMMENTED_ELEMENTS = "numberOfTotalCommentedElements"; + /** Map containing all metrics concerning the current IHierarchicElement */ + private Map<String, Double> storedMetrics; /** - * @param currentElement - * @param consumers + * List containing all HierarchicElementSizeProvider for components inside the + * IHierarchicElement */ - public void traverse(IHierarchicElement currentElement, Set<ICounter> consumers) { - consumers.forEach(c -> c.apply(currentElement)); - for(IHierarchicElement child : currentElement.getContainedElements()) { - traverse(child, consumers); - } - } + private List<HierarchicElementSizeProvider> containedProviders; - /** */ - public interface ICounter { - /** - * @param ele - */ - public void apply(IHierarchicElement ele); - - /** */ - public int getCounter(); + public Map<String, Double> getStoredMetrics() { + return storedMetrics; } /** */ - private class PortCounter implements ICounter { - /** Returns port number. */ - int counter = 0; - - /** {@inheritDoc} */ - @Override - public int getCounter() { - return counter; - } - - /** */ - @Override - public void apply(IHierarchicElement element) { - counter = getCounter() + element.getConnectors().size(); - } + public HierarchicElementSizeProvider() { + super(); + this.storedMetrics = new HashMap<>(); + this.containedProviders = new ArrayList<>(); } - /** */ - private class ElementCounter implements ICounter { - /** Returns port number. */ - int counter = 0; + /** {@inheritDoc} */ + @Override + public void apply(IHierarchicElement currentElement) { - /** {@inheritDoc} */ - @Override - public int getCounter() { - return counter; - } + storedMetrics.put(NUMBER_OF_PORTS, (double) currentElement.getConnectors().size()); + storedMetrics.put(NUMBER_OF_CONTAINED_ELEMENTS, (double) currentElement.getContainedElements().size()); + storedMetrics.put(NUMBER_OF_CHANNELS, (double) currentElement.getConnections().size()); - /** */ - @Override - public void apply(IHierarchicElement element) { - counter += 1; + // depth metrics + storedMetrics.put(NUMBER_OF_TOTAL_PORTS, (double) currentElement.getConnectors().size()); + storedMetrics.put(NUMBER_OF_TOTAL_ELEMENTS, 1.0); + + boolean isElementCommentable = currentElement instanceof INamedCommentedElement; + storedMetrics.put(NUMBER_OF_TOTAL_COMMENTABLE_ELEMENTS, isElementCommentable ? 1.0 : 0.0); + String comment = isElementCommentable ? ((INamedCommentedElement) currentElement).getComment() : null; + storedMetrics.put(NUMBER_OF_TOTAL_COMMENTED_ELEMENTS, comment != null && comment != "" ? 1.0 : 0.0); + + for (IHierarchicElement containedElement : currentElement.getContainedElements()) { + HierarchicElementSizeProvider provider = new HierarchicElementSizeProvider(); + containedProviders.add(provider); + provider.apply(containedElement); + + for (String key : new String[] { NUMBER_OF_TOTAL_PORTS, NUMBER_OF_TOTAL_ELEMENTS, + NUMBER_OF_TOTAL_COMMENTABLE_ELEMENTS, NUMBER_OF_TOTAL_COMMENTED_ELEMENTS }) { + storedMetrics.merge(key, provider.storedMetrics.get(key), Double::sum); + } } +// System.out.println("Finished traversing Node: " +// + ((currentElement instanceof INamedElement) ? ((INamedElement) currentElement).getName() +// : "Not Named")); } -} -/* - * public abstract class MultiMethodDemo implements IElementConsumer { - * - * @Override - * public void apply(IHierarchicElement element) { - * if(element instanceof INamedCommentedElement) { - * consume((INamedCommentedElement)element); - * } else { - * consume(element); - * } - * } - * - * public abstract void consume(IHierarchicElement element); - * - * public abstract void consume(INamedCommentedElement element); - * - * } - */ - -// public class CloneDetection implements IElementConsumer { -// -// private Map<Integer, List<IHierarchicElement>> map = new HashMap<>(); -// -// @Override -// public void printResult() { -// System.out.println("Stuff"); -// } -// -// @Override -// public void apply(IHierarchicElement element) { -// int hash = 1; -// for(IConnector connector : element.getConnectors()) { -// EList<IModelElementSpecification> specifications = connector.getSpecifications(); -// //if(!specifications.isEmpty() && -// // connector.getSpecifications().get(0) instanceof PortSpecification) { -// -// // PortSpecification port = -// // (PortSpecification)connector.getSpecifications().get(0); -// // hash = 31 * hash + (connector instanceof InputPort ? 1 : 2) * -// // port.getType().getClass().hashCode(); -// } else { -// // Clone Detection for State diagrams not supported -// return; -// } -// }map.putIfAbsent(hash,new ArrayList<>()); -// -// List<IHierarchicElement> elements = map.get(hash); -// -// for( -// IHierarchicElement element_b:elements) -// { -// -// List<String> element_a_input = new ArrayList<String>(); -// List<String> element_b_input = new ArrayList<String>(); -// List<String> element_a_output = new ArrayList<String>(); -// List<String> element_b_output = new ArrayList<String>(); -// -// for(IConnector connector : element.getConnectors()) { -// PortSpecification port = (PortSpecification)connector.getSpecifications().get(0); -// String type = port.getType().getClass().getSimpleName(); -// if(connector instanceof InputPort) { -// element_a_input.add(type); -// } else { -// element_a_output.add(type); -// } -// } -// -// for(IConnector connector : element_b.getConnectors()) { -// PortSpecification port = (PortSpecification)connector.getSpecifications().get(0); -// String type = port.getType().getClass().getSimpleName(); -// if(connector instanceof InputPort) { -// element_b_input.add(type); -// } else { -// element_b_output.add(type); -// } -// } -// -// boolean equals = true; -// -// for(String type_a_input : element_a_input) { -// if(!element_b_input.remove(type_a_input)) { -// equals = false; -// break; -// } -// -// } -// -// for(String type_a_output : element_a_output) { -// if(!element_b_output.remove(type_a_output)) { -// equals = false; -// break; -// } -// -// } -// if(equals) { -// System.out -// .println("Found duplicate: " + ((INamedCommentedElement)element).getName() + -// ", " + ((INamedCommentedElement)element_b).getName()); -// break; -// } else { -// System.out.println("Same but not duplicate"); -// } -// }elements.add(element); -// } - -/* - * public class CommentCompleteness extends MultiMethodDemo { - * private int total_amount; - * private int with_comments; - * - * public CommentCompleteness() { - * total_amount = 0; - * with_comments = 0; - * } - * - * @Override - * public void consume(IHierarchicElement element) { - * total_amount++; - * } - * - * @Override - * public void consume(INamedCommentedElement element) { - * if(element.getComment() != "") { - * with_comments++; - * } - * total_amount++; - * } - * } - */ -/* - * public class Tuple<T1, T2> { - * private T1 element1; - * private T2 element2; - * - * public Tuple(T1 element1, T2 element2) { - * this.element1 = element1; - * this.element2 = element2; - * } - * - * public T1 getElement1() { - * return element1; - * } - * - * public T2 getElement2() { - * return element2; - * } - * } - */ -/* - * public void printShare(HierarchicElementBase element) { - * - * Set<Tuple<String, Integer>> counts = new HashSet<>(); - * this.apply(element); - * counts.add(new Tuple<>("[Self]" + element.getName(), count)); - * count = 0; - * - * for(IHierarchicElement child : element.getContainedElements()) { - * - * HierarchicElementBase real_child = (HierarchicElementBase)child; - * - * recursiveDescent(real_child, this); - * - * counts.add(new Tuple<>(real_child.getName(), count)); - * count = 0; - * } - * - * double total = counts.stream().mapToInt(t -> t.getElement2()).sum(); - * - * System.out.println("[" + this.getClass().getSimpleName() + "] shares:"); - * for(Tuple<String, Integer> tuple : counts) { - * System.out.println("\t " + String.format("%05.2f%%", tuple.element2 / total * 100) + - * ", " + tuple.element2 + ": " + tuple.element1); - * } - * } - */ - -/* - * protected void recursiveDescent(HierarchicElementBase element, CounterConsumer consumer) { - * consumer.apply(element); - * - * for(IHierarchicElement child : element.getContainedElements()) { - * HierarchicElementBase real_child = (HierarchicElementBase)child; - * recursiveDescent(real_child, consumer); - * } - * } - */ - -/* - * public class ConnectionCounter { - * public void apply(IHierarchicElement element) { - * count += element.getConnections().size(); - * } - * - * } - * - * private void extractComment(IHierarchicElement c) { - * strings.add(((INamedCommentedElement)c).getComment()); - * } - * } - * } - */ + /* + * + * CLONE DETECTION START public class CloneDetection { + * + * private Map<Integer, List<IHierarchicElement>> map = new HashMap<>(); + * + * public void printResult() { System.out.println("Stuff"); } + * + * public void apply(IHierarchicElement element) { int hash = 1; for(IConnector + * connector : element.getConnectors()) { EList<IModelElementSpecification> + * specifications = connector.getSpecifications(); if(!specifications.isEmpty() + * && connector.getSpecifications().get(0) instanceof PortSpecification) { + * + * PortSpecification port = + * (PortSpecification)connector.getSpecifications().get(0); hash = 31 * hash + + * (connector instanceof InputPort ? 1 : 2) * + * port.getType().getClass().hashCode(); } else { // Clone Detection for State + * diagrams not supported return; } }map.putIfAbsent(hash,new ArrayList<>()); + * + * List<IHierarchicElement> elements = map.get(hash); + * + * for( IHierarchicElement element_b:elements) { + * + * List<String> element_a_input = new ArrayList<String>(); List<String> + * element_b_input = new ArrayList<String>(); List<String> element_a_output = + * new ArrayList<String>(); List<String> element_b_output = new + * ArrayList<String>(); + * + * for(IConnector connector : element.getConnectors()) { PortSpecification port + * = (PortSpecification)connector.getSpecifications().get(0); String type = + * port.getType().getClass().getSimpleName(); if(connector instanceof InputPort) + * { element_a_input.add(type); } else { element_a_output.add(type); } } + * + * for(IConnector connector : element_b.getConnectors()) { PortSpecification + * port = (PortSpecification)connector.getSpecifications().get(0); String type = + * port.getType().getClass().getSimpleName(); if(connector instanceof InputPort) + * { element_b_input.add(type); } else { element_b_output.add(type); } } + * + * boolean equals = true; + * + * for(String type_a_input : element_a_input) { + * if(!element_b_input.remove(type_a_input)) { equals = false; break; } + * + * } + * + * for(String type_a_output : element_a_output) { + * if(!element_b_output.remove(type_a_output)) { equals = false; break; } + * + * } if(equals) { System.out .println("Found duplicate: " + + * ((INamedCommentedElement)element).getName() + ", " + + * ((INamedCommentedElement)element_b).getName()); break; } else { + * System.out.println("Same but not duplicate"); } }elements.add(element); } + * CLONE DETECTION END + * + * + * public void printShare(HierarchicElementBase element) { + * + * Set<Tuple<String, Integer>> counts = new HashSet<>(); this.apply(element); + * counts.add(new Tuple<>("[Self]" + element.getName(), count)); this.count = 0; + * + * for(IHierarchicElement child : element.getContainedElements()) { + * + * HierarchicElementBase real_child = (HierarchicElementBase)child; + * + * recursiveDescent(real_child, this); + * + * counts.add(new Tuple<>(real_child.getName(), count)); count = 0; } + * + * double total = counts.stream().mapToInt(t -> t.getElement2()).sum(); + * + * System.out.println("[" + this.getClass().getSimpleName() + "] shares:"); + * for(Tuple<String, Integer> tuple : counts) { System.out.println("\t " + + * String.format("%05.2f%%", tuple.element2 / total * 100) + ", " + + * tuple.element2 + ": " + tuple.element1); } } + * + */ +} 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 2fa1be0c7b06cde84b0e47f24c1aa2a6c7c57f82..a14e4e0f27d7c8245cb7adf8cfd1391e37a76b25 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 @@ -107,13 +107,20 @@ public class ModelQualityService extends EObjectAwareServiceBase<IModelQualityPr */ public List<IModelQualityProvider<? extends EObject>> performMetricAnalysis(FileProject fp) { List<IModelQualityProvider<? extends EObject>> result = - new LinkedList<IModelQualityProvider<? extends EObject>>(); + new LinkedList<>(); for(IProjectRootElement ele : fp.getRootElements()) { if(ele instanceof IHierarchicElement) { + + //TODO check get(0) + IHierarchicElement firstNode = ((IHierarchicElement) ele).getContainedElements().get(0); + HierarchicElementSizeProvider hes = - new HierarchicElementSizeProvider(ele.getName()); - hes.apply((IHierarchicElement)ele); - System.out.println("checked in hierarchic metrics for: " + hes.getName()); + new HierarchicElementSizeProvider(); + hes.apply(firstNode); + System.out.println("checked in hierarchic metrics for: " + ele.getName()); + double commentable = hes.getStoredMetrics().getOrDefault(HierarchicElementSizeProvider.NUMBER_OF_TOTAL_COMMENTABLE_ELEMENTS, 0.0); + double commented = hes.getStoredMetrics().getOrDefault(HierarchicElementSizeProvider.NUMBER_OF_TOTAL_COMMENTED_ELEMENTS, 0.0); + System.out.println("Commented to total: "+commented+", "+commentable+", "+commented/commentable); result.add(hes); } } @@ -134,6 +141,7 @@ public class ModelQualityService extends EObjectAwareServiceBase<IModelQualityPr // metricsList.addAll(metrics); // } // } + return result; }