/* * Copyright 2005-2016 Sixth and Red River Software, Bas Leijdekkers * * 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 com.sixrr.metrics.metricModel; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.SmartPointerManager; import com.intellij.psi.SmartPsiElementPointer; import com.sixrr.metrics.Metric; import com.sixrr.metrics.MetricType; import com.sixrr.metrics.profile.MetricInstance; import com.sixrr.metrics.profile.MetricsProfile; import com.sixrr.metrics.utils.StringToFractionMap; import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class MetricsResultImpl implements MetricsResult { private final Map<Metric, StringToFractionMap> values = new HashMap<Metric, StringToFractionMap>(32); private final Set<String> measuredObjects = new HashSet<String>(32); private final Set<Metric> metrics = new HashSet<Metric>(32); private final Map<String, SmartPsiElementPointer<PsiElement>> elements = new HashMap<String, SmartPsiElementPointer<PsiElement>>(1024); @Override public void postValue(Metric metric, String measured, double value) { postValue(metric, measured, value, 1.0); } @Override public void postValue(Metric metric, String measured, double numerator, double denominator) { if (measured == null) { return; } StringToFractionMap metricValues = values.get(metric); if (metricValues == null) { metricValues = new StringToFractionMap(); values.put(metric, metricValues); } metricValues.put(measured, numerator, denominator); measuredObjects.add(measured); metrics.add(metric); } @Override @Nullable public Double getValueForMetric(Metric metric, String measured) { final StringToFractionMap metricValues = values.get(metric); if (metricValues == null) { return null; } return metricValues.containsKey(measured) ? Double.valueOf(metricValues.get(measured)) : null; } @Override public String[] getMeasuredObjects() { return measuredObjects.toArray(new String[measuredObjects.size()]); } @Override public Metric[] getMetrics() { return metrics.toArray(new Metric[metrics.size()]); } @Override @Nullable public Double getMinimumForMetric(Metric metric) { final StringToFractionMap metricValues = values.get(metric); if (metricValues == null) { return Double.valueOf(0.0); } return Double.valueOf(metricValues.getMinimum()); } @Override @Nullable public Double getMaximumForMetric(Metric metric) { final StringToFractionMap metricValues = values.get(metric); if (metricValues == null) { return Double.valueOf(0.0); } return Double.valueOf(metricValues.getMaximum()); } @Override @Nullable public Double getTotalForMetric(Metric metric) { final MetricType metricType = metric.getType(); if (metricType != MetricType.Count) { return null; } final StringToFractionMap metricValues = values.get(metric); if (metricValues == null) { return Double.valueOf(0.0); } return Double.valueOf(metricValues.getTotal()); } @Override @Nullable public Double getAverageForMetric(Metric metric) { final MetricType metricType = metric.getType(); if (metricType == MetricType.RecursiveCount || metricType == MetricType.RecursiveRatio) { return null; } final StringToFractionMap metricValues = values.get(metric); if (metricValues == null) { return Double.valueOf(0.0); } return Double.valueOf(metricValues.getAverage()); } @Override public void setElementForMeasuredObject(String measuredObject, PsiElement element) { final Project project = element.getProject(); final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project); final SmartPsiElementPointer<PsiElement> pointer = pointerManager.createSmartPsiElementPointer(element); elements.put(measuredObject, pointer); } @Override @Nullable public PsiElement getElementForMeasuredObject(String measuredObject) { final SmartPsiElementPointer<PsiElement> pointer = elements.get(measuredObject); if (pointer == null) { return null; } return pointer.getElement(); } @Override public boolean hasWarnings(MetricsProfile profile) { for (Metric metric : metrics) { final MetricInstance metricInstance = profile.getMetricInstance(metric); assert metricInstance != null : "no instance found for " + metric.getID(); final StringToFractionMap valuesForMetric = values.get(metric); for (String measuredObject : measuredObjects) { final double value = valuesForMetric.get(measuredObject); if (metricInstance.isUpperThresholdEnabled() && value > metricInstance.getUpperThreshold()) { return true; } if (metricInstance.isLowerThresholdEnabled() && value < metricInstance.getLowerThreshold()) { return true; } } } return false; } @Override public MetricsResult filterRowsWithoutWarnings(MetricsProfile profile) { final MetricsResult out = new MetricsResultImpl(); for (String measuredObject : measuredObjects) { boolean found = false; for (Metric metric : metrics) { final MetricInstance metricInstance = profile.getMetricInstance(metric); assert metricInstance != null : "no instance found for " + metric.getID(); if (!metricInstance.isEnabled()) { continue; } final StringToFractionMap valuesForMetric = values.get(metric); if (!valuesForMetric.containsKey(measuredObject)) { continue; } final double value = valuesForMetric.get(measuredObject); if (metricInstance.isUpperThresholdEnabled() && value > metricInstance.getUpperThreshold()) { found = true; break; } if (metricInstance.isLowerThresholdEnabled() && value < metricInstance.getLowerThreshold()) { found = true; break; } } if (found) { for (Metric metric : metrics) { final StringToFractionMap valuesForMetric = values.get(metric); final double value = valuesForMetric.get(measuredObject); out.postValue(metric, measuredObject, value, 1.0); //not quite right } final PsiElement elementForMeasuredObject = getElementForMeasuredObject(measuredObject); if (elementForMeasuredObject != null) { out.setElementForMeasuredObject(measuredObject, elementForMeasuredObject); } } } return out; } }