001 /* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2014 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube 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 * SonarQube 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 */ 020 package org.sonar.xoo.lang; 021 022 import org.apache.commons.io.FileUtils; 023 import org.apache.commons.lang.StringUtils; 024 import org.slf4j.Logger; 025 import org.slf4j.LoggerFactory; 026 import org.sonar.api.batch.fs.InputFile; 027 import org.sonar.api.batch.measure.MetricFinder; 028 import org.sonar.api.batch.sensor.Sensor; 029 import org.sonar.api.batch.sensor.SensorContext; 030 import org.sonar.api.batch.sensor.SensorDescriptor; 031 import org.sonar.api.batch.sensor.measure.Measure; 032 import org.sonar.api.batch.sensor.measure.MeasureBuilder; 033 import org.sonar.api.measures.CoreMetrics; 034 import org.sonar.xoo.Xoo; 035 036 import java.io.File; 037 import java.io.IOException; 038 import java.io.Serializable; 039 import java.util.List; 040 041 /** 042 * Parse files *.xoo.measures 043 */ 044 public class MeasureSensor implements Sensor { 045 046 private static final Logger LOG = LoggerFactory.getLogger(MeasureSensor.class); 047 048 private static final String MEASURES_EXTENSION = ".measures"; 049 050 private MetricFinder metricFinder; 051 052 public MeasureSensor(MetricFinder metricFinder) { 053 this.metricFinder = metricFinder; 054 } 055 056 private void processFileMeasures(InputFile inputFile, SensorContext context) { 057 File ioFile = inputFile.file(); 058 File measureFile = new File(ioFile.getParentFile(), ioFile.getName() + MEASURES_EXTENSION); 059 if (measureFile.exists()) { 060 LOG.debug("Processing " + measureFile.getAbsolutePath()); 061 try { 062 List<String> lines = FileUtils.readLines(measureFile, context.fileSystem().encoding().name()); 063 int lineNumber = 0; 064 for (String line : lines) { 065 lineNumber++; 066 if (StringUtils.isBlank(line) || line.startsWith("#")) { 067 continue; 068 } 069 processMeasure(inputFile, context, measureFile, lineNumber, line); 070 } 071 } catch (IOException e) { 072 throw new IllegalStateException(e); 073 } 074 } 075 } 076 077 private void processMeasure(InputFile inputFile, SensorContext context, File measureFile, int lineNumber, String line) { 078 try { 079 String metricKey = StringUtils.substringBefore(line, ":"); 080 String value = line.substring(metricKey.length() + 1); 081 context.addMeasure(createMeasure(context, inputFile, metricKey, value)); 082 } catch (Exception e) { 083 throw new IllegalStateException("Error processing line " + lineNumber + " of file " + measureFile.getAbsolutePath(), e); 084 } 085 } 086 087 private Measure createMeasure(SensorContext context, InputFile xooFile, String metricKey, String value) { 088 org.sonar.api.batch.measure.Metric<Serializable> metric = metricFinder.findByKey(metricKey); 089 if (metric == null) { 090 throw new IllegalStateException("Unknow metric with key: " + metricKey); 091 } 092 MeasureBuilder<Serializable> builder = context.measureBuilder() 093 .forMetric(metric) 094 .onFile(xooFile); 095 if (Boolean.class.equals(metric.valueType())) { 096 builder.withValue(Boolean.parseBoolean(value)); 097 } else if (Integer.class.equals(metric.valueType())) { 098 builder.withValue(Integer.valueOf(value)); 099 } else if (Double.class.equals(metric.valueType())) { 100 builder.withValue(Double.valueOf(value)); 101 } else if (String.class.equals(metric.valueType())) { 102 builder.withValue(value); 103 } else if (Long.class.equals(metric.valueType())) { 104 builder.withValue(Long.valueOf(value)); 105 } else { 106 throw new UnsupportedOperationException("Unsupported type :" + metric.valueType()); 107 } 108 return builder.build(); 109 } 110 111 @Override 112 public void describe(SensorDescriptor descriptor) { 113 descriptor 114 .name("Xoo Measure Sensor") 115 .provides(CoreMetrics.LINES) 116 .workOnLanguages(Xoo.KEY) 117 .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST); 118 } 119 120 @Override 121 public void execute(SensorContext context) { 122 for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) { 123 processFileMeasures(file, context); 124 } 125 } 126 }