001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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 License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.batch.sensor.measure.internal;
021
022import org.sonar.api.batch.sensor.internal.SensorStorage;
023
024import com.google.common.base.Preconditions;
025import org.apache.commons.lang.builder.EqualsBuilder;
026import org.apache.commons.lang.builder.HashCodeBuilder;
027import org.sonar.api.batch.fs.InputFile;
028import org.sonar.api.batch.measure.Metric;
029import org.sonar.api.batch.sensor.internal.DefaultStorable;
030import org.sonar.api.batch.sensor.measure.Measure;
031import org.sonar.api.batch.sensor.measure.NewMeasure;
032
033import javax.annotation.CheckForNull;
034import javax.annotation.Nullable;
035
036import java.io.Serializable;
037
038public class DefaultMeasure<G extends Serializable> extends DefaultStorable implements Measure<G>, NewMeasure<G> {
039
040  private boolean onProject = false;
041  private InputFile file;
042  private Metric<G> metric;
043  private G value;
044  private boolean fromCore = false;
045
046  public DefaultMeasure() {
047    super();
048  }
049
050  public DefaultMeasure(@Nullable SensorStorage storage) {
051    super(storage);
052  }
053
054  @Override
055  public DefaultMeasure<G> onFile(InputFile inputFile) {
056    Preconditions.checkState(!this.onProject, "onProject already called");
057    Preconditions.checkState(this.file == null, "onFile already called");
058    Preconditions.checkNotNull(inputFile, "InputFile should be non null");
059    this.file = inputFile;
060    return this;
061  }
062
063  @Override
064  public DefaultMeasure<G> onProject() {
065    Preconditions.checkState(!this.onProject, "onProject already called");
066    Preconditions.checkState(this.file == null, "onFile already called");
067    this.onProject = true;
068    return this;
069  }
070
071  @Override
072  public DefaultMeasure<G> forMetric(Metric<G> metric) {
073    Preconditions.checkState(metric != null, "Metric already defined");
074    Preconditions.checkNotNull(metric, "metric should be non null");
075    this.metric = metric;
076    return this;
077  }
078
079  @Override
080  public DefaultMeasure<G> withValue(G value) {
081    Preconditions.checkState(this.value == null, "Measure value already defined");
082    Preconditions.checkNotNull(value, "Measure value can't be null");
083    this.value = value;
084    return this;
085  }
086
087  /**
088   * For internal use.
089   */
090  public boolean isFromCore() {
091    return fromCore;
092  }
093
094  /**
095   * For internal use. Used by core components to bypass check that prevent a plugin to store core measures.
096   */
097  public DefaultMeasure<G> setFromCore() {
098    this.fromCore = true;
099    return this;
100  }
101
102  @Override
103  public void doSave() {
104    Preconditions.checkNotNull(this.value, "Measure value can't be null");
105    Preconditions.checkNotNull(this.metric, "Measure metric can't be null");
106    Preconditions.checkState(this.metric.valueType().equals(this.value.getClass()), "Measure value should be of type " + this.metric.valueType());
107    storage.store(this);
108  }
109
110  @Override
111  public Metric<G> metric() {
112    return metric;
113  }
114
115  @Override
116  @CheckForNull
117  public InputFile inputFile() {
118    return file;
119  }
120
121  @Override
122  public G value() {
123    return value;
124  }
125
126  // For testing purpose
127
128  @Override
129  public boolean equals(Object obj) {
130    if (obj == null) {
131      return false;
132    }
133    if (obj == this) {
134      return true;
135    }
136    if (obj.getClass() != getClass()) {
137      return false;
138    }
139    DefaultMeasure rhs = (DefaultMeasure) obj;
140    return new EqualsBuilder()
141      .append(file, rhs.file)
142      .append(metric, rhs.metric)
143      .append(value, rhs.value)
144      .isEquals();
145  }
146
147  @Override
148  public int hashCode() {
149    return new HashCodeBuilder(27, 45).
150      append(file).
151      append(metric).
152      append(value).
153      toHashCode();
154  }
155
156}