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 */
020package org.sonar.batch.index;
021
022import com.google.common.collect.ArrayListMultimap;
023import com.google.common.collect.ListMultimap;
024import com.google.common.collect.Lists;
025import org.sonar.api.measures.Measure;
026import org.sonar.api.measures.MeasuresFilter;
027import org.sonar.api.measures.MeasuresFilters;
028import org.sonar.api.resources.Resource;
029import org.sonar.api.rules.Violation;
030import org.sonar.api.utils.SonarException;
031
032import java.util.Collection;
033import java.util.Collections;
034import java.util.List;
035
036public final class Bucket {
037
038  private Resource resource;
039  private ListMultimap<String, Measure> measuresByMetric = ArrayListMultimap.create();
040  private List<Violation> violations = Lists.newLinkedList();
041
042  private Bucket parent;
043  private List<Bucket> children;
044
045  public Bucket(Resource resource) {
046    this.resource = resource;
047  }
048
049  public Resource getResource() {
050    return resource;
051  }
052
053  public Bucket setParent(Bucket parent) {
054    this.parent = parent;
055    if (parent != null) {
056      parent.addChild(this);
057    }
058    return this;
059  }
060
061  private Bucket addChild(Bucket child) {
062    if (children == null) {
063      children = Lists.newArrayList();
064    }
065    children.add(child);
066    return this;
067  }
068
069  private void removeChild(Bucket child) {
070    if (children != null) {
071      children.remove(child);
072    }
073  }
074
075  public List<Bucket> getChildren() {
076    return (children == null ? Collections.<Bucket>emptyList() : children);
077  }
078
079  public Bucket getParent() {
080    return parent;
081  }
082
083  public void addViolation(Violation violation) {
084    violations.add(violation);
085  }
086
087  public List<Violation> getViolations() {
088    return violations;
089  }
090
091  public void addMeasure(Measure measure) {
092    List<Measure> metricMeasures = measuresByMetric.get(measure.getMetric().getKey());
093
094    boolean add = true;
095    if (metricMeasures != null) {
096      int index = metricMeasures.indexOf(measure);
097      if (index > -1) {
098        if (metricMeasures.get(index) == measure) {
099          add = false;
100        } else {
101          throw new SonarException("Can not add twice the same measure on " + resource + ": " + measure);
102        }
103      }
104    }
105    if (add) {
106      measuresByMetric.put(measure.getMetric().getKey(), measure);
107    }
108  }
109
110  public void clear() {
111    measuresByMetric = null;
112    violations = null;
113    children = null;
114    if (parent != null) {
115      parent.removeChild(this);
116      parent = null;
117    }
118  }
119
120  public <M> M getMeasures(final MeasuresFilter<M> filter) {
121    Collection<Measure> unfiltered;
122    if (filter instanceof MeasuresFilters.MetricFilter) {
123      unfiltered = measuresByMetric.get(((MeasuresFilters.MetricFilter) filter).filterOnMetricKey());
124    } else {
125      unfiltered = measuresByMetric.values();
126    }
127    return filter.filter(unfiltered);
128  }
129
130  public boolean isExcluded() {
131    return resource.isExcluded();
132  }
133
134  @Override
135  public boolean equals(Object o) {
136    if (this == o) {
137      return true;
138    }
139    if (o == null || getClass() != o.getClass()) {
140      return false;
141    }
142    Bucket that = (Bucket) o;
143    return resource.equals(that.resource);
144  }
145
146  @Override
147  public int hashCode() {
148    return resource.hashCode();
149  }
150}