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.plugins.core.timemachine;
021
022import org.sonar.api.batch.*;
023import org.sonar.api.database.DatabaseSession;
024import org.sonar.api.database.model.RuleFailureModel;
025import org.sonar.api.database.model.Snapshot;
026import org.sonar.api.resources.Project;
027import org.sonar.api.resources.Resource;
028import org.sonar.api.rules.Rule;
029import org.sonar.api.rules.RuleFinder;
030import org.sonar.api.rules.Violation;
031import org.sonar.api.violations.ViolationQuery;
032import org.sonar.batch.index.ResourcePersister;
033import org.sonar.core.NotDryRun;
034
035import java.util.List;
036
037@NotDryRun
038@DependsUpon({ DecoratorBarriers.END_OF_VIOLATION_TRACKING, DecoratorBarriers.START_VIOLATION_PERSISTENCE })
039@DependedUpon(DecoratorBarriers.END_OF_VIOLATION_PERSISTENCE)
040public class ViolationPersisterDecorator implements Decorator {
041
042  private ViolationTrackingDecorator tracker;
043  private ResourcePersister persister;
044  private RuleFinder ruleFinder;
045  private DatabaseSession session;
046
047  public ViolationPersisterDecorator(ViolationTrackingDecorator tracker, ResourcePersister persister, RuleFinder ruleFinder, DatabaseSession session) {
048    this.tracker = tracker;
049    this.persister = persister;
050    this.ruleFinder = ruleFinder;
051    this.session = session;
052  }
053
054  public boolean shouldExecuteOnProject(Project project) {
055    return true;
056  }
057
058  public void decorate(Resource resource, DecoratorContext context) {
059    saveViolations(context.getProject(), context.getViolations(ViolationQuery.create().forResource(resource).setSwitchMode(ViolationQuery.SwitchMode.BOTH)));
060  }
061
062  void saveViolations(Project project, List<Violation> violations) {
063    for (Violation violation : violations) {
064      RuleFailureModel referenceViolation = tracker.getReferenceViolation(violation);
065      save(project, violation, referenceViolation);
066    }
067    session.commit();
068  }
069
070  public void save(Project project, Violation violation, RuleFailureModel referenceViolation) {
071    Snapshot snapshot = persister.saveResource(project, violation.getResource());
072
073    RuleFailureModel model = createModel(violation);
074    if (referenceViolation != null) {
075      model.setPermanentId(referenceViolation.getPermanentId());
076    }
077    model.setSnapshotId(snapshot.getId());
078    session.saveWithoutFlush(model);
079
080    if (model.getPermanentId() == null) {
081      model.setPermanentId(model.getId());
082      session.saveWithoutFlush(model);
083    }
084    violation.setMessage(model.getMessage());// the message can be changed in the class RuleFailure (truncate + trim)
085  }
086
087
088  private RuleFailureModel createModel(Violation violation) {
089    RuleFailureModel model = new RuleFailureModel();
090    Rule rule = ruleFinder.findByKey(violation.getRule().getRepositoryKey(), violation.getRule().getKey());
091    model.setRuleId(rule.getId());
092    model.setPriority(violation.getSeverity());
093    model.setLine(violation.getLineId());
094    model.setMessage(violation.getMessage());
095    model.setCost(violation.getCost());
096    model.setChecksum(violation.getChecksum());
097    model.setCreatedAt(violation.getCreatedAt());
098    model.setSwitchedOff(violation.isSwitchedOff());
099    model.setPersonId(violation.getPersonId());
100    return model;
101  }
102}