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 863d5c1e6d6695be9b29eeb7437c1ec4efc71c57..7fcef617d54f557d53a7cbb3af10a8c0221116ed 100644 --- a/org.fortiss.tooling.ext.quality.ui/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.ext.quality.ui/META-INF/MANIFEST.MF @@ -10,4 +10,6 @@ Require-Bundle: org.eclipse.ui.ide;visibility:=reexport, org.fortiss.tooling.kernel, org.fortiss.tooling.kernel.ui, org.fortiss.tooling.ext.reuse, - org.eclipse.emf.ecore + org.eclipse.emf.ecore, + org.fortiss.tooling.ext.quality +Import-Package: org.fortiss.af3.project.model diff --git a/org.fortiss.tooling.ext.quality.ui/plugin.xml b/org.fortiss.tooling.ext.quality.ui/plugin.xml index 99b8f591c261e36578c0f28348f3ae0019814fcd..29c7ad1646b7a67aa0d97602fb355f22a891410d 100644 --- a/org.fortiss.tooling.ext.quality.ui/plugin.xml +++ b/org.fortiss.tooling.ext.quality.ui/plugin.xml @@ -5,7 +5,7 @@ <plugin> <extension point="org.fortiss.tooling.kernel.ui.contextMenuContribution"> <contextMenuContribution - contributor="org.fortiss.tooling.ext.quality.ui.MetricExtractionMenu"> + contributor="org.fortiss.tooling.ext.quality.ui.ModelQualityExtractionMenu"> </contextMenuContribution> </extension> </plugin> \ No newline at end of file diff --git a/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/MetricExtractionMenu.java b/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/ModelQualityExtractionMenu.java similarity index 82% rename from org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/MetricExtractionMenu.java rename to org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/ModelQualityExtractionMenu.java index a268a43bf4639f8966f71b30ad8144a6ad00f59c..fae5ff921137188465dd443716137f256599b19d 100644 --- a/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/MetricExtractionMenu.java +++ b/org.fortiss.tooling.ext.quality.ui/src/org/fortiss/tooling/ext/quality/ui/ModelQualityExtractionMenu.java @@ -16,6 +16,7 @@ package org.fortiss.tooling.ext.quality.ui; | limitations under the License. | +--------------------------------------------------------------------------*/ import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static org.fortiss.tooling.kernel.ui.service.IContextMenuService.BOTTOM_MOST_MENU_SECTION_ID; @@ -26,6 +27,8 @@ import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.resource.ImageDescriptor; +import org.fortiss.af3.project.model.FileProject; +import org.fortiss.tooling.ext.quality.service.ModelQualityService; import org.fortiss.tooling.kernel.ui.extension.IContextMenuContributor; import org.fortiss.tooling.kernel.ui.extension.data.ContextMenuContextProvider; @@ -34,7 +37,7 @@ import org.fortiss.tooling.kernel.ui.extension.data.ContextMenuContextProvider; * * @author munaro */ -public class MetricExtractionMenu implements IContextMenuContributor { +public class ModelQualityExtractionMenu implements IContextMenuContributor { /** String appearing in the context menu. */ private static final String MENU_NAME = "Extract metrics"; @@ -43,8 +46,11 @@ public class MetricExtractionMenu implements IContextMenuContributor { @Override public List<IContributionItem> getContributedItems(EObject selection, ContextMenuContextProvider contextProvider) { + if(!(selection instanceof FileProject)) { + return emptyList(); + } return asList(new IContributionItem[] { - new ActionContributionItem(new MetricExtractionAction())}); + new ActionContributionItem(new MetricExtractionAction((FileProject)selection))}); } /** {@inheritDoc} */ @@ -61,14 +67,19 @@ public class MetricExtractionMenu implements IContextMenuContributor { /** Action for generating the set of . */ protected class MetricExtractionAction extends Action { + private final FileProject fp; /** Constructor. */ - public MetricExtractionAction() { + public MetricExtractionAction(FileProject fp) { super(MENU_NAME, getActionIcon()); + this.fp = fp; } /** {@inheritDoc} */ @Override public void run() { + ModelQualityService ms = new ModelQualityService(); + ms.performMetricAnalysis(this.fp); + System.out.println("We print something"); } } diff --git a/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF b/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF index e2351f8911be3349d2ca653ceedf337b2205a971..b7c38972483fd679b1a43050023abd8bf68d2fc0 100644 --- a/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF +++ b/org.fortiss.tooling.ext.quality/META-INF/MANIFEST.MF @@ -10,7 +10,8 @@ Bundle-Activator: org.fortiss.tooling.ext.quality.AF3QualityActivator Require-Bundle: org.eclipse.core.runtime, org.eclipse.emf.ecore;visibility:=reexport, org.fortiss.tooling.base;visibility:=reexport, - org.fortiss.tooling.kernel;visibility:=reexport + org.fortiss.tooling.kernel;visibility:=reexport, + org.fortiss.af3.project Export-Package: org.fortiss.tooling.ext.quality, org.fortiss.tooling.ext.quality.service diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/AF3QualityActivator.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/AF3QualityActivator.java index f2afb5fbd34cc511fed42c990a9ce35f097e077a..0f067724e692516876f78c2c0119aa2fa5de93da 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/AF3QualityActivator.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/AF3QualityActivator.java @@ -17,7 +17,7 @@ package org.fortiss.tooling.ext.quality; +--------------------------------------------------------------------------*/ import org.eclipse.core.runtime.Plugin; -import org.fortiss.tooling.ext.quality.service.MetricService; +import org.fortiss.tooling.ext.quality.service.ModelQualityService; import org.osgi.framework.BundleContext; /** @@ -38,7 +38,7 @@ public class AF3QualityActivator extends Plugin { super.start(context); plugin = this; System.out.println("[Plugin] " + PLUGIN_ID + " started."); - MetricService.getInstance().startService(); + ModelQualityService.getInstance().startService(); } /** {@inheritDoc} */ 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 new file mode 100644 index 0000000000000000000000000000000000000000..41bc8536d9bf3eed0d7785c0ee4b85714f50c731 --- /dev/null +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/HierarchicElementSizeProvider.java @@ -0,0 +1,328 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2023 fortiss GmbH | +| | +| 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.fortiss.tooling.ext.quality.service; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.fortiss.tooling.base.model.element.IHierarchicElement; + +/** + * {@link IModelQualityProvider} to count the ratio of filled out comments of + * INamedCommentedElements. + * + * @author blaschke + */ +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 + */ + + /** {@inheritDoc} */ + @Override + public Map<String, Double> 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()); + + for(IHierarchicElement child : ele.getContainedElements()) { + apply(child); + } + return sizes; + } + + /** + * @param currentElement + * @param consumers + */ + public void traverse(IHierarchicElement currentElement, Set<ICounter> consumers) { + consumers.forEach(c -> c.apply(currentElement)); + for(IHierarchicElement child : currentElement.getContainedElements()) { + traverse(child, consumers); + } + } + + /** */ + public interface ICounter { + /** + * @param ele + */ + public void apply(IHierarchicElement ele); + + /** */ + public int getCounter(); + } + + /** */ + 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(); + } + } + + /** */ + private class ElementCounter implements ICounter { + /** Returns port number. */ + int counter = 0; + + /** {@inheritDoc} */ + @Override + public int getCounter() { + return counter; + } + + /** */ + @Override + public void apply(IHierarchicElement element) { + counter += 1; + } + } +} + +/* + * 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()); + * } + * } + * } + */ diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IMetricProvider.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IModelQualityProvider.java similarity index 82% rename from org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IMetricProvider.java rename to org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IModelQualityProvider.java index d4ac7a33e5895a442f78bb2761c60a0f701729f1..db893d2a232f236df3cebbf606289751d412dfa7 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IMetricProvider.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IModelQualityProvider.java @@ -15,7 +15,7 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.ext.quality.service; -import java.util.List; +import java.util.Map; import org.eclipse.emf.ecore.EObject; import org.fortiss.tooling.kernel.service.base.IEObjectAware; @@ -23,15 +23,12 @@ import org.fortiss.tooling.kernel.service.base.IEObjectAware; /** * Interface for the migration provider implementations. * <P> - * migration provider extensions are handled by {@link IMetricService}. + * migration provider extensions are handled by {@link IModelQualityService}. * * @author blaschke */ -public interface IMetricProvider<C extends EObject> extends IEObjectAware<EObject> { +public interface IModelQualityProvider<C extends EObject> extends IEObjectAware<EObject> { /** Applies the IMetricProvider to the given model element. */ - List<String> apply(C modelElement); - - /** defines if metric is applicable for the element */ - boolean isApplicable(EObject modelElement); + Map<String, Double> apply(C element); } diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IMetricService.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IModelQualityService.java similarity index 82% rename from org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IMetricService.java rename to org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IModelQualityService.java index f2813520a1c4420b902907d67d323077a58b76db..b5b7310ca15887e2c101bc2564fdd2bbf6ddc780 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IMetricService.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/IModelQualityService.java @@ -15,20 +15,22 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.ext.quality.service; +import java.util.Map; + /** * The migration service checks and upgrades the old models from the last release. * * @author mou */ -public interface IMetricService { +public interface IModelQualityService { /** Returns the service instance. */ - public static IMetricService getInstance() { - return MetricService.getInstance(); + public static IModelQualityService getInstance() { + return ModelQualityService.getInstance(); } /** Registers the metric provider with the service. */ - void registerMetricProvider(IMetricProvider<?> provider, Class<?> modelElementClass); + void registerMetricProvider(IModelQualityProvider<?> provider, Class<?> modelElementClass); /** trigger extraction to csv document */ - void metricExtractionToCSV(); + void metricExtractionToCSV(Map<String, Double> data); } diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricCommentProvider.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricCommentProvider.java deleted file mode 100644 index 3e5fe0a62a0331f6abff935ddd68414b3d07d670..0000000000000000000000000000000000000000 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricCommentProvider.java +++ /dev/null @@ -1,388 +0,0 @@ -/*-------------------------------------------------------------------------+ -| Copyright 2023 fortiss GmbH | -| | -| 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.fortiss.tooling.ext.quality.service; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -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.eclipse.emf.ecore.EObject; -//import org.fortiss.af3.component.model.InputPort; -//import org.fortiss.af3.component.model.PortSpecification; -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.ext.quality.service.IMetricProvider; -import org.fortiss.tooling.kernel.model.INamedCommentedElement; - -/** - * {@link IMetricProvider} to count the ratio of filled out comments of - * INamedCommentedElements. - * - * @author blaschke - */ -public class MetricCommentProvider implements IMetricProvider<IHierarchicElement> { - - /** */ - ArrayList<String> strings = new ArrayList<String>(); - - /** {@inheritDoc} */ - @Override - public List<String> apply(IHierarchicElement topComponent) { - extractComment(topComponent); - for(IHierarchicElement child : topComponent.getContainedElements()) { - apply(child); - } - return strings; - } - - /** */ - public void startRecursion(IHierarchicElement topElement) { - - Set<IElementConsumer> consumers = new HashSet<MetricCommentProvider.IElementConsumer>(); - consumers.add(new PortCounter()); - consumers.add(new ConnectionCounter()); - consumers.add(new ElementCounter()); - consumers.add(new CommentCompleteness()); - // consumers.add(new CloneDetection()); - - traverse(topElement, consumers); - - consumers.forEach(c -> c.printResult()); - - new PortCounter() - .printShare((HierarchicElementBase)topElement.getContainedElements().get(0)); - } - - public void traverse(IHierarchicElement currentElement, Set<IElementConsumer> consumers) { - - consumers.forEach(c -> c.apply(currentElement)); - - for(IHierarchicElement child : currentElement.getContainedElements()) { - traverse(child, consumers); - } - - } - - public interface IElementConsumer { - - public void apply(IHierarchicElement element); - - public void printResult(); - } - - public static class MetricCSVWriter { - private static final String FILE_PATH = "data_ultra_cool.csv"; - private static final String CSV_SEPARATOR = ","; - - private BufferedWriter writer; - - public void openFile() throws IOException { - writer = new BufferedWriter(new FileWriter(FILE_PATH, true)); - } - - public void writeData(int value1, int value2) { - try { - String timestamp = getCurrentTimestamp(); - String dataLine = timestamp + CSV_SEPARATOR + value1 + CSV_SEPARATOR + value2; - writer.write(dataLine); - writer.newLine(); - writer.flush(); - } catch(IOException e) { - e.printStackTrace(); - } - } - - public void closeFile() throws IOException { - if(writer != null) { - writer.close(); - } - } - - private String getCurrentTimestamp() { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date now = new Date(); - return dateFormat.format(now); - } - } - - 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 printResult() { - System.out.println("[CommentCompleteness] Total:" + total_amount + " With:" + - with_comments + " Ratio:" + (with_comments / (double)total_amount)); - } - - @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 abstract class CounterConsumer implements IElementConsumer { - - protected int count; - - public CounterConsumer() { - count = 0; - } - - @Override - public void printResult() { - System.out - .println("[" + this.getClass().getSimpleName() + "] Found " + count + " total"); - } - - public int getCount() { - return count; - } - - 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 PortCounter extends CounterConsumer { - - @Override - public void apply(IHierarchicElement element) { - count += element.getConnectors().size(); - } - } - - public class ConnectionCounter extends CounterConsumer { - - @Override - public void apply(IHierarchicElement element) { - count += element.getConnections().size(); - } - } - - public class ElementCounter extends CounterConsumer { - @Override - public void apply(IHierarchicElement element) { - count++; - } - - } - - public Map<String, Integer> sizeMetrics(IHierarchicElement ele) { - return null; - // anzahl elemente im baum ab hierarchiebene ele - // anzahl ports ab ...... - // anzahl channels....... - // completness von comments #eleMitComment/#ele - // kamelCase names - - // State Automoton - // Annotations - - // tooling.kernel -> tooling.body -> ext packages -> af3 -> rcp - } - - /** */ - private void extractComment(IHierarchicElement c) { - strings.add(((INamedCommentedElement)c).getComment()); - } - - /** {@inheritDoc} */ - @Override - public boolean isApplicable(EObject modelElement) { - // TODO Auto-generated method stub - return false; - } -} diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricService.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/ModelQualityService.java similarity index 54% rename from org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricService.java rename to org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/ModelQualityService.java index abaf5ed5e701d66146d741397b8ec1b74fb63e8b..6398acae0a252e27b39d39103e60a2ecb9598aa1 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/MetricService.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/service/ModelQualityService.java @@ -18,11 +18,21 @@ package org.fortiss.tooling.ext.quality.service; import static java.util.Collections.emptyList; import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstChildWithType; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.eclipse.emf.ecore.EObject; +import org.fortiss.af3.project.model.FileProject; +import org.fortiss.tooling.base.model.element.IHierarchicElement; import org.fortiss.tooling.kernel.introspection.IIntrospectionDetailsItem; import org.fortiss.tooling.kernel.introspection.IIntrospectionItem; import org.fortiss.tooling.kernel.introspection.IIntrospectiveKernelService; @@ -35,13 +45,13 @@ import org.fortiss.tooling.kernel.service.base.EObjectAwareServiceBase; * * @author blaschke */ -public class MetricService extends EObjectAwareServiceBase<IMetricProvider<?>> - implements IIntrospectiveKernelService, IMetricService { +public class ModelQualityService extends EObjectAwareServiceBase<IModelQualityProvider<?>> + implements IIntrospectiveKernelService, IModelQualityService { /** The singleton instance. */ - private static final MetricService INSTANCE = new MetricService(); + private static final ModelQualityService INSTANCE = new ModelQualityService(); /** Returns singleton instance of the service. */ - public static MetricService getInstance() { + public static ModelQualityService getInstance() { return INSTANCE; } @@ -63,7 +73,8 @@ public class MetricService extends EObjectAwareServiceBase<IMetricProvider<?>> /** Registers the migration provider with the service. */ @Override - public void registerMetricProvider(IMetricProvider<?> provider, Class<?> modelElementClass) { + public void registerMetricProvider(IModelQualityProvider<?> provider, + Class<?> modelElementClass) { addHandler(modelElementClass, provider); } @@ -77,39 +88,45 @@ public class MetricService extends EObjectAwareServiceBase<IMetricProvider<?>> "\n\nThe service extension point is '" + EXTENSION_POINT_NAME + "'."; } - /** Get all suitable {@link IMetricProvider} for the given input. */ + /** Get all suitable {@link IModelQualityProvider} for the given input. */ @SuppressWarnings("unused") - private List<IMetricProvider<?>> getAllMetricProviders(EObject input) { - List<IMetricProvider<?>> providers = new ArrayList<>(); - for(Entry<Class<?>, List<IMetricProvider<?>>> migEntry : handlerMap.entrySet()) { + private List<IModelQualityProvider<?>> getAllMetricProviders(EObject input) { + List<IModelQualityProvider<?>> providers = new ArrayList<>(); + for(Entry<Class<?>, List<IModelQualityProvider<?>>> migEntry : handlerMap.entrySet()) { if(getFirstChildWithType(input, migEntry.getKey()) != null) { providers.addAll(migEntry.getValue()); } } + System.out.println("These are the providers:" + providers); return providers; } /** - * public List<IMetricProvider<? extends EObject>> performAllMetricAnalysis(EObject - * modelElement) { - * List<IMetricProvider<? extends EObject>> result = - * new LinkedList<IMetricProvider<? extends EObject>>(); - * List<IMetricProvider<?>> handlers = getRegisteredHandlers(modelElement.getClass()); - * if(handlers == null) { - * return null; - * } - * for(IMetricProvider<?> checker : handlers) { - * if(checker.isApplicable(modelElement)) { - * List<? extends IMetricProvider<? extends EObject>> metricsList = - * checker.apply(modelElement); - * if(metrics != null) { - * metricsList.addAll(metrics); - * } - * } - * } - * return result; - * } + * @param modelElement + * @return */ + public List<IModelQualityProvider<? extends EObject>> + performMetricAnalysis(FileProject modelElement) { + List<IModelQualityProvider<? extends EObject>> result = + new LinkedList<IModelQualityProvider<? extends EObject>>(); + // List<IModelQualityProvider<?>> handlers = getRegisteredHandlers(modelElement.getClass()); + Map<String, Double> qualityData = new HashMap<String, Double>(); + List<IModelQualityProvider<?>> hierarchicHandlers = + getRegisteredHandlers(IHierarchicElement.class); + List<IModelQualityProvider<?>> hierarchicHandlers2 = getRegisteredHandlers(EObject.class); + // if(handlers == null) { + // return null; + // } + + // for(IModelQualityProvider<?> qualityProv : handlers) { + // List<? extends IModelQualityProvider<? extends EObject>> collectedProviders = + // qualityProv.apply(modelElement); + // if(metrics != null) { + // metricsList.addAll(metrics); + // } + // } + return result; + } /** */ @Override @@ -155,8 +172,70 @@ public class MetricService extends EObjectAwareServiceBase<IMetricProvider<?>> /** {@inheritDoc} */ @Override - public void metricExtractionToCSV() { - // TODO Auto-generated method stub + public void metricExtractionToCSV(Map<String, Double> data) { + MetricCSVWriter writer = new MetricCSVWriter(); + try { + writer.openFile(); + writer.writeData(data); + } catch(IOException e) { + e.printStackTrace(); + } finally { + try { + writer.closeFile(); + } catch(IOException e) { + e.printStackTrace(); + } + } + } + + /** + * + * @author blaschke + */ + public static class MetricCSVWriter { + /** */ + private static final String FILE_PATH = "data_ultra_cool.csv"; + /** */ + private BufferedWriter writer; + + /** + * @throws IOException + */ + public void openFile() throws IOException { + writer = new BufferedWriter(new FileWriter(FILE_PATH, true)); + } + /** + * @param data + */ + public void writeData(Map<String, Double> data) { + try { + String timestamp = getCurrentTimestamp(); + writer.write(timestamp + ": "); + for(Map.Entry<String, Double> entry : data.entrySet()) { + writer.write(entry.getKey() + ":" + entry.getValue() + ","); + writer.newLine(); + } + writer.flush(); + } catch(IOException e) { + e.printStackTrace(); + } + } + + /** + * @throws IOException + */ + public void closeFile() throws IOException { + if(writer != null) { + writer.close(); + } + } + + /** */ + private String getCurrentTimestamp() { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date now = new Date(); + return dateFormat.format(now); + } } } diff --git a/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java b/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java index d49fd8750f7366198e94d29a28ab3059cdddb890..cdccf9627b49fd19215f86efe927c7172288ddcd 100644 --- a/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java +++ b/org.fortiss.tooling.ext.quality/test-src/test/org/fortiss/tooling/ext/quality/metric/MetricTest.java @@ -15,17 +15,7 @@ +--------------------------------------------------------------------------*/ package test.org.fortiss.tooling.ext.quality.metric; -//import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.findFirstComponentArchitecture; -//import static org.fortiss.af3.project.utils.TestCaseProjectUtils.loadTestProject; - -import java.io.IOException; - -//import org.fortiss.af3.project.model.FileProject; -import org.fortiss.tooling.base.model.element.IHierarchicElement; -import org.fortiss.tooling.ext.quality.service.MetricCommentProvider; -import org.fortiss.tooling.ext.quality.service.MetricCommentProvider.MetricCSVWriter; import org.junit.Before; -import org.junit.Test; /** * Tests for the constraints checker of state machines based on @@ -35,39 +25,14 @@ import org.junit.Test; */ public class MetricTest { - /** Top component. */ - private IHierarchicElement topComponent; - /** Setup the test. */ @Before public void setup() { // FileProject project = // loadTestProject(AF3QualityActivator.PLUGIN_ID, "test-data/ACC.af3_23"); // "test-data/carla_ff1_rover.af3_23"); - // topComponent = (IHierarchicElement) project.getRootElements().get(2); // topComponent = findFirstComponentArchitecture(project).getTopComponent(); } - /** Test constraint checker for actions. */ - @Test - public void actionsConstraintCheck() { - MetricCommentProvider mcp = new MetricCommentProvider(); - MetricCSVWriter writer = new MetricCSVWriter(); - mcp.startRecursion(topComponent); - try { - writer.openFile(); - writer.writeData(2, 3); - writer.writeData(3, 4); - } catch(IOException e) { - e.printStackTrace(); - } finally { - try { - writer.closeFile(); - } catch(IOException e) { - e.printStackTrace(); - } - } - - } }