001/* 002 * SonarQube 003 * Copyright (C) 2009-2017 SonarSource SA 004 * mailto:info AT sonarsource DOT com 005 * 006 * This program 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 * This program 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 com.google.common.base.Preconditions; 023import java.io.Serializable; 024import javax.annotation.Nullable; 025import org.apache.commons.lang.builder.EqualsBuilder; 026import org.apache.commons.lang.builder.HashCodeBuilder; 027import org.sonar.api.batch.fs.InputComponent; 028import org.sonar.api.batch.measure.Metric; 029import org.sonar.api.batch.sensor.internal.DefaultStorable; 030import org.sonar.api.batch.sensor.internal.SensorStorage; 031import org.sonar.api.batch.sensor.measure.Measure; 032import org.sonar.api.batch.sensor.measure.NewMeasure; 033 034public class DefaultMeasure<G extends Serializable> extends DefaultStorable implements Measure<G>, NewMeasure<G> { 035 036 private InputComponent component; 037 private Metric<G> metric; 038 private G value; 039 private boolean fromCore = false; 040 041 public DefaultMeasure() { 042 super(); 043 } 044 045 public DefaultMeasure(@Nullable SensorStorage storage) { 046 super(storage); 047 } 048 049 @Override 050 public DefaultMeasure<G> on(InputComponent component) { 051 Preconditions.checkArgument(component != null, "Component can't be null"); 052 Preconditions.checkState(this.component == null, "on() already called"); 053 this.component = component; 054 return this; 055 } 056 057 @Override 058 public DefaultMeasure<G> forMetric(Metric<G> metric) { 059 Preconditions.checkState(this.metric == null, "Metric already defined"); 060 Preconditions.checkNotNull(metric, "metric should be non null"); 061 this.metric = metric; 062 return this; 063 } 064 065 @Override 066 public DefaultMeasure<G> withValue(G value) { 067 Preconditions.checkState(this.value == null, "Measure value already defined"); 068 Preconditions.checkNotNull(value, "Measure value can't be null"); 069 this.value = value; 070 return this; 071 } 072 073 /** 074 * For internal use. 075 */ 076 public boolean isFromCore() { 077 return fromCore; 078 } 079 080 /** 081 * For internal use. Used by core components to bypass check that prevent a plugin to store core measures. 082 */ 083 public DefaultMeasure<G> setFromCore() { 084 this.fromCore = true; 085 return this; 086 } 087 088 @Override 089 public void doSave() { 090 Preconditions.checkNotNull(this.value, "Measure value can't be null"); 091 Preconditions.checkNotNull(this.metric, "Measure metric can't be null"); 092 Preconditions.checkState(this.metric.valueType().equals(this.value.getClass()), "Measure value should be of type %s", this.metric.valueType()); 093 storage.store(this); 094 } 095 096 @Override 097 public Metric<G> metric() { 098 return metric; 099 } 100 101 @Override 102 public InputComponent inputComponent() { 103 return component; 104 } 105 106 @Override 107 public G value() { 108 return value; 109 } 110 111 // For testing purpose 112 113 @Override 114 public boolean equals(Object obj) { 115 if (obj == null) { 116 return false; 117 } 118 if (obj == this) { 119 return true; 120 } 121 if (obj.getClass() != getClass()) { 122 return false; 123 } 124 DefaultMeasure<?> rhs = (DefaultMeasure<?>) obj; 125 return new EqualsBuilder() 126 .append(component, rhs.component) 127 .append(metric, rhs.metric) 128 .append(value, rhs.value) 129 .isEquals(); 130 } 131 132 @Override 133 public int hashCode() { 134 return new HashCodeBuilder(27, 45).append(component).append(metric).append(value).toHashCode(); 135 } 136 137}