001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2012 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.batch;
021
022 import org.sonar.api.batch.*;
023 import org.sonar.api.measures.FormulaData;
024 import org.sonar.api.measures.Measure;
025 import org.sonar.api.measures.Metric;
026 import org.sonar.api.resources.Project;
027 import org.sonar.api.resources.Resource;
028
029 import java.util.Collection;
030 import java.util.Collections;
031 import java.util.List;
032 import java.util.Set;
033
034 /**
035 * A pre-implementation of a decorator using a simple calculation formula
036 * @since 1.11
037 */
038 public final class FormulaDecorator implements Decorator {
039
040 private Metric metric;
041 private DefaultFormulaContext formulaContext;
042 private Set<Decorator> executeAfterDecorators;
043
044 /**
045 * Creates a FormulaDecorator
046 *
047 * @param metric the metric should have an associated formula
048 *
049 * @throws IllegalArgumentException if no formula is associated to the metric
050 */
051 public FormulaDecorator(Metric metric, Set<Decorator> executeAfterDecorators) {
052 if (metric.getFormula() == null) {
053 throw new IllegalArgumentException("No formula defined on metric");
054 }
055 this.metric = metric;
056 this.formulaContext = new DefaultFormulaContext(metric);
057 this.executeAfterDecorators = executeAfterDecorators;
058 }
059
060 public FormulaDecorator(Metric metric) {
061 this(metric, Collections.<Decorator>emptySet());
062 }
063
064 /**
065 * {@inheritDoc}
066 */
067 public boolean shouldExecuteOnProject(Project project) {
068 return true;
069 }
070
071 /**
072 * @return metric generated by the decorator
073 */
074 @DependedUpon
075 public Metric generatesMetric() {
076 return metric;
077 }
078
079 /**
080 * @return metric the decorator depends upon
081 */
082 @DependsUpon
083 public List<Metric> dependsUponMetrics() {
084 return metric.getFormula().dependsUponMetrics();
085 }
086
087 @DependsUpon
088 public Collection<Decorator> dependsUponDecorators() {
089 return executeAfterDecorators;
090 }
091
092 /**
093 * {@inheritDoc}
094 */
095 public void decorate(Resource resource, DecoratorContext context) {
096 if (context.getMeasure(metric) != null) {
097 return;
098 }
099
100 formulaContext.setDecoratorContext(context);
101 FormulaData data = new DefaultFormulaData(context);
102 Measure measure = metric.getFormula().calculate(data, formulaContext);
103 if (measure != null) {
104 context.saveMeasure(measure);
105 }
106 }
107
108 @Override
109 public boolean equals(Object o) {
110 if (this == o) {
111 return true;
112 }
113 if (o == null || getClass() != o.getClass()) {
114 return false;
115 }
116 FormulaDecorator that = (FormulaDecorator) o;
117 return !(metric != null ? !metric.equals(that.metric) : that.metric != null);
118 }
119
120 @Override
121 public int hashCode() {
122 return metric != null ? metric.hashCode() : 0;
123 }
124
125 @Override
126 public String toString() {
127 return new StringBuilder().append("f(").append(metric.getKey()).append(")").toString();
128 }
129 }