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