001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 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 java.util.Collection;
023    import java.util.Date;
024    import java.util.List;
025    import java.util.Set;
026    
027    import com.google.common.collect.Lists;
028    import org.sonar.api.batch.DecoratorContext;
029    import org.sonar.api.batch.Event;
030    import org.sonar.api.batch.SonarIndex;
031    import org.sonar.api.design.Dependency;
032    import org.sonar.api.measures.Measure;
033    import org.sonar.api.measures.MeasuresFilter;
034    import org.sonar.api.measures.MeasuresFilters;
035    import org.sonar.api.measures.Metric;
036    import org.sonar.api.resources.Project;
037    import org.sonar.api.resources.Resource;
038    import org.sonar.api.rules.Violation;
039    import org.sonar.api.violations.ViolationQuery;
040    
041    public class DefaultDecoratorContext implements DecoratorContext {
042    
043      private SonarIndex index;
044      private Resource resource;
045      private boolean readOnly = false;
046    
047      private List<DecoratorContext> childrenContexts;
048    
049      public DefaultDecoratorContext(Resource resource,
050                                     SonarIndex index,
051                                     List<DecoratorContext> childrenContexts) {
052        this.index = index;
053        this.resource = resource;
054        this.childrenContexts = childrenContexts;
055      }
056    
057      public DefaultDecoratorContext setReadOnly(boolean b) {
058        readOnly = b;
059        childrenContexts = null;
060        return this;
061      }
062    
063      public Project getProject() {
064        return index.getProject();
065      }
066    
067      public List<DecoratorContext> getChildren() {
068        checkReadOnly("getModules");
069        return childrenContexts;
070      }
071    
072      private void checkReadOnly(String methodName) {
073        if (readOnly) {
074          throw new IllegalStateException("Method DecoratorContext." + methodName + "() can not be executed on children.");
075        }
076      }
077    
078      public <M> M getMeasures(MeasuresFilter<M> filter) {
079        return index.getMeasures(resource, filter);
080      }
081    
082      public Measure getMeasure(Metric metric) {
083        return index.getMeasure(resource, metric);
084      }
085    
086      public Collection<Measure> getChildrenMeasures(MeasuresFilter filter) {
087        List<Measure> result = Lists.newArrayList();
088        for (DecoratorContext childContext : childrenContexts) {
089          Object childResult = childContext.getMeasures(filter);
090          if (childResult != null) {
091            if (childResult instanceof Collection) {
092              result.addAll((Collection) childResult);
093            } else {
094              result.add((Measure) childResult);
095            }
096          }
097        }
098        return result;
099      }
100    
101      public Collection<Measure> getChildrenMeasures(Metric metric) {
102        return getChildrenMeasures(MeasuresFilters.metric(metric));
103      }
104    
105      public Resource getResource() {
106        return resource;
107      }
108    
109      public DecoratorContext saveMeasure(Measure measure) {
110        checkReadOnly("saveMeasure");
111        index.addMeasure(resource, measure);
112        return this;
113      }
114    
115      public DecoratorContext saveMeasure(Metric metric, Double value) {
116        checkReadOnly("saveMeasure");
117        index.addMeasure(resource, new Measure(metric, value));
118        return this;
119      }
120    
121      /**
122      * {@inheritDoc}
123      */
124      public List<Violation> getViolations(ViolationQuery violationQuery) {
125        return index.getViolations(violationQuery);
126      }
127      
128      /**
129      * {@inheritDoc}
130      */
131      public List<Violation> getViolations() {
132        return index.getViolations(resource);
133      }
134    
135      public Dependency saveDependency(Dependency dependency) {
136        checkReadOnly("addDependency");
137        return index.addDependency(dependency);
138      }
139    
140      public Set<Dependency> getDependencies() {
141        return index.getDependencies();
142      }
143    
144      public Collection<Dependency> getIncomingDependencies() {
145        return index.getIncomingEdges(resource);
146      }
147    
148      public Collection<Dependency> getOutgoingDependencies() {
149        return index.getOutgoingEdges(resource);
150      }
151    
152      public List<Event> getEvents() {
153        return index.getEvents(resource);
154      }
155    
156      public Event createEvent(String name, String description, String category, Date date) {
157        return index.addEvent(resource, name, description, category, date);
158      }
159    
160      public void deleteEvent(Event event) {
161        index.deleteEvent(event);
162      }
163    
164      public DefaultDecoratorContext saveViolation(Violation violation, boolean force) {
165        if (violation.getResource() == null) {
166          violation.setResource(resource);
167        }
168        index.addViolation(violation, force);
169        return this;
170      }
171    
172      public DefaultDecoratorContext saveViolation(Violation violation) {
173        return saveViolation(violation, false);
174      }
175    }