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