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.plugins.cpd; 021 022 import java.util.ArrayList; 023 import java.util.Collections; 024 import java.util.Comparator; 025 import java.util.HashSet; 026 import java.util.List; 027 import java.util.Set; 028 029 import org.sonar.api.batch.SensorContext; 030 import org.sonar.api.measures.CoreMetrics; 031 import org.sonar.api.measures.Measure; 032 import org.sonar.api.resources.Resource; 033 034 public class DuplicationsData { 035 036 private Resource resource; 037 private Set<Integer> duplicatedLines = new HashSet<Integer>(); 038 private double duplicatedBlocks; 039 private List<XmlEntry> duplicationXMLEntries = new ArrayList<XmlEntry>(); 040 041 private SensorContext context; 042 043 public DuplicationsData(Resource resource, SensorContext context) { 044 this.resource = resource; 045 this.context = context; 046 } 047 048 public void cumulate(String targetResource, int targetDuplicationStartLine, int duplicationStartLine, int duplicatedLines) { 049 duplicationXMLEntries.add(new XmlEntry(targetResource, targetDuplicationStartLine, duplicationStartLine, duplicatedLines)); 050 for (int duplicatedLine = duplicationStartLine; duplicatedLine < duplicationStartLine + duplicatedLines; duplicatedLine++) { 051 this.duplicatedLines.add(duplicatedLine); 052 } 053 } 054 055 public void cumulate(Resource targetResource, int targetDuplicationStartLine, int duplicationStartLine, int duplicatedLines) { 056 cumulate(context.saveResource(targetResource), targetDuplicationStartLine, duplicationStartLine, duplicatedLines); 057 } 058 059 public void incrementDuplicatedBlock() { 060 duplicatedBlocks++; 061 } 062 063 public void save() { 064 context.saveMeasure(resource, CoreMetrics.DUPLICATED_FILES, 1d); 065 context.saveMeasure(resource, CoreMetrics.DUPLICATED_LINES, (double) duplicatedLines.size()); 066 context.saveMeasure(resource, CoreMetrics.DUPLICATED_BLOCKS, duplicatedBlocks); 067 context.saveMeasure(resource, new Measure(CoreMetrics.DUPLICATIONS_DATA, getDuplicationXMLData())); 068 } 069 070 private String getDuplicationXMLData() { 071 Collections.sort(duplicationXMLEntries, COMPARATOR); 072 StringBuilder duplicationXML = new StringBuilder("<duplications>"); 073 for (XmlEntry xmlEntry : duplicationXMLEntries) { 074 duplicationXML.append(xmlEntry.toString()); 075 } 076 duplicationXML.append("</duplications>"); 077 return duplicationXML.toString(); 078 } 079 080 private static final Comparator<XmlEntry> COMPARATOR = new Comparator<XmlEntry>() { 081 public int compare(XmlEntry o1, XmlEntry o2) { 082 if (o1.startLine == o2.startLine) { 083 return o1.lines - o2.lines; 084 } 085 return o1.startLine - o2.startLine; 086 } 087 }; 088 089 private static final class XmlEntry { 090 private String target; 091 private int targetStartLine; 092 private int startLine; 093 private int lines; 094 095 private XmlEntry(String target, int targetStartLine, int startLine, int lines) { 096 this.target = target; 097 this.targetStartLine = targetStartLine; 098 this.startLine = startLine; 099 this.lines = lines; 100 } 101 102 @Override 103 public String toString() { 104 return new StringBuilder().append("<duplication lines=\"").append(lines) 105 .append("\" start=\"").append(startLine) 106 .append("\" target-start=\"").append(targetStartLine) 107 .append("\" target-resource=\"").append(target).append("\"/>") 108 .toString(); 109 } 110 } 111 112 }