3636import java .io .File ;
3737import java .io .FileNotFoundException ;
3838import java .io .IOException ;
39- import java .util .ArrayList ;
40- import java .util .List ;
4139
4240public class LizardReportParser {
4341 private static final Logger LOGGER = LoggerFactory .getLogger (LizardReportParser .class );
4442 private static final String MEASURE = "measure" ;
4543 private static final String MEASURE_TYPE = "type" ;
44+ private static final String MEASURE_LABELS = "label" ;
4645 private static final String MEASURE_ITEM = "item" ;
4746 private static final String FILE_MEASURE = "file" ;
48- private static final String FUNCTION_MEASURE = "Function " ;
47+ private static final String FUNCTION_MEASURE = "function " ;
4948 private static final String NAME = "name" ;
5049 private static final String VALUE = "value" ;
51- private static final int CYCLOMATIC_COMPLEXITY_INDEX = 2 ;
52- private static final int FUNCTIONS_INDEX = 3 ;
50+ private static final String LINE_COUNT_LABEL = "NCSS" ;
51+ private static final String CYCLOMATIC_COMPLEXITY_LABEL = "CCN" ;
52+ private static final String FUNCTION_COUNT_LABEL = "Functions" ;
5353 private final SensorContext context ;
54+ private int lineCountIndex ;
55+ private int cyclomaticComplexityIndex ;
56+ private int functionCountIndex ;
5457
5558 public LizardReportParser (final SensorContext context ) {
5659 this .context = context ;
@@ -63,13 +66,13 @@ public void parseReport(final File xmlFile) {
6366 Document document = builder .parse (xmlFile );
6467 parseFile (document );
6568 } catch (final FileNotFoundException e ) {
66- LoggerFactory . getLogger ( getClass ()) .error ("Lizard Report not found {}" , xmlFile , e );
69+ LOGGER .error ("Lizard Report not found {}" , xmlFile , e );
6770 } catch (final IOException e ) {
68- LoggerFactory . getLogger ( getClass ()) .error ("Error processing file named {}" , xmlFile , e );
71+ LOGGER .error ("Error processing file named {}" , xmlFile , e );
6972 } catch (final ParserConfigurationException e ) {
70- LoggerFactory . getLogger ( getClass ()) .error ("Error parsing file named {}" , xmlFile , e );
73+ LOGGER .error ("Error parsing file named {}" , xmlFile , e );
7174 } catch (final SAXException e ) {
72- LoggerFactory . getLogger ( getClass ()) .error ("Error processing file named {}" , xmlFile , e );
75+ LOGGER .error ("Error processing file named {}" , xmlFile , e );
7376 }
7477 }
7578
@@ -79,14 +82,30 @@ private void parseFile(Document document) {
7982 Node node = nodeList .item (i );
8083 if (node .getNodeType () == Node .ELEMENT_NODE ) {
8184 Element element = (Element ) node ;
82- NodeList nl = element .getElementsByTagName (MEASURE_ITEM );
83- parseMeasure (element .getAttribute (MEASURE_TYPE ), nl );
85+ updateIndexes (element .getElementsByTagName (MEASURE_LABELS ));
86+
87+ parseMeasure (element .getAttribute (MEASURE_TYPE ), element .getElementsByTagName (MEASURE_ITEM ));
88+ }
89+ }
90+ }
91+
92+ private void updateIndexes (NodeList nodeList ) {
93+ for (int i = 0 ; i < nodeList .getLength (); i ++) {
94+ Node node = nodeList .item (i );
95+ if (node .getNodeType () == Node .ELEMENT_NODE ) {
96+ Element element = (Element ) node ;
97+ String label = element .getTextContent ();
98+ if (LINE_COUNT_LABEL .equalsIgnoreCase (label ))
99+ lineCountIndex = i ;
100+ else if (CYCLOMATIC_COMPLEXITY_LABEL .equalsIgnoreCase (label ))
101+ cyclomaticComplexityIndex = i ;
102+ else if (FUNCTION_COUNT_LABEL .equalsIgnoreCase (label ))
103+ functionCountIndex = i ;
84104 }
85105 }
86106 }
87107
88108 private void parseMeasure (String type , NodeList itemList ) {
89- List <SwiftFunction > functions = new ArrayList <>();
90109 for (int i = 0 ; i < itemList .getLength (); i ++) {
91110 Node item = itemList .item (i );
92111 if (item .getNodeType () == Node .ELEMENT_NODE ) {
@@ -97,87 +116,92 @@ private void parseMeasure(String type, NodeList itemList) {
97116 if (FILE_MEASURE .equalsIgnoreCase (type )) {
98117 addComplexityFileMeasures (name ,values );
99118 } else if (FUNCTION_MEASURE .equalsIgnoreCase (type )) {
100- String measure = values .item (CYCLOMATIC_COMPLEXITY_INDEX ).getTextContent ();
101- functions .add (new SwiftFunction (name , Integer .parseInt (measure )));
119+ addComplexityFunctionMeasures (new SwiftFunction (name ),values );
102120 }
103121 }
104122 }
105- if (!functions .isEmpty ()) {
106- addComplexityFunctionMeasures (functions );
107- }
108123 }
109124
110125 private void addComplexityFileMeasures (String fileName , NodeList values ) {
111- File file = new File (fileName );
112- FilePredicate fp = context .fileSystem ().predicates ().hasAbsolutePath (file .getAbsolutePath ());
126+ FilePredicate fp = context .fileSystem ().predicates ().hasRelativePath (fileName );
113127 if (!context .fileSystem ().hasFiles (fp )){
114128 LOGGER .warn ("file not included in sonar {}" , fileName );
115129 return ;
116130 }
117131 InputFile component = context .fileSystem ().inputFile (fp );
118- int complexity = Integer .parseInt (values .item (CYCLOMATIC_COMPLEXITY_INDEX ).getTextContent ());
132+ int complexity = Integer .parseInt (values .item (cyclomaticComplexityIndex ).getTextContent ());
119133 context .<Integer >newMeasure ()
120134 .on (component )
121135 .forMetric (CoreMetrics .COMPLEXITY )
122136 .withValue (complexity )
123137 .save ();
124138
125- int numberOfFunctions = Integer .parseInt (values .item (FUNCTIONS_INDEX ).getTextContent ());
139+ int numberOfFunctions = Integer .parseInt (values .item (functionCountIndex ).getTextContent ());
126140 context .<Integer >newMeasure ()
127141 .on (component )
128142 .forMetric (CoreMetrics .FUNCTIONS )
129143 .withValue (numberOfFunctions )
130144 .save ();
131145
132- double fileComplexity = Double . parseDouble (values .item (CYCLOMATIC_COMPLEXITY_INDEX ).getTextContent ());
133- context .<Double >newMeasure ()
146+ int numberOfLines = Integer . parseInt (values .item (lineCountIndex ).getTextContent ());
147+ context .<Integer >newMeasure ()
134148 .on (component )
135- .forMetric (CoreMetrics .FILE_COMPLEXITY )
136- .withValue (fileComplexity )
149+ .forMetric (CoreMetrics .LINES )
150+ .withValue (numberOfLines )
137151 .save ();
138152 }
139153
140- private void addComplexityFunctionMeasures (List <SwiftFunction > functions ) {
141- int count = 0 ;
142- int complexityInFunctions = 0 ;
143-
144- for (SwiftFunction func : functions ) {
145- count ++;
146- complexityInFunctions += func .getCyclomaticComplexity ();
147-
148- context .<Integer >newMeasure ()
149- .on (func )
150- .forMetric (CoreMetrics .COMPLEXITY_IN_FUNCTIONS )
151- .withValue (complexityInFunctions )
152- .save ();
153- }
154+ private void addComplexityFunctionMeasures (SwiftFunction component , NodeList values ) {
155+ int complexity = Integer .parseInt (values .item (cyclomaticComplexityIndex ).getTextContent ());
156+ context .<Integer >newMeasure ()
157+ .on (component )
158+ .forMetric (CoreMetrics .COMPLEXITY )
159+ .withValue (complexity )
160+ .save ();
154161
155- if ( count != 0 ) {
156- context .<Double >newMeasure ()
157- . forMetric ( CoreMetrics . FUNCTION_COMPLEXITY )
158- . withValue ((( double ) complexityInFunctions )/ count )
159- . save ();
160- }
162+ int numberOfLines = Integer . parseInt ( values . item ( lineCountIndex ). getTextContent ());
163+ context .<Integer >newMeasure ()
164+ . on ( component )
165+ . forMetric ( CoreMetrics . LINES )
166+ . withValue ( numberOfLines )
167+ . save ();
161168 }
162169
163170 private static class SwiftFunction implements InputModule {
171+ private String name ;
164172 private String key ;
165- private int cyclomaticComplexity ;
166-
167- public SwiftFunction (String functionName , int cyclomaticComplexity ) {
168- this .key = functionName ;
169- this .cyclomaticComplexity = cyclomaticComplexity ;
170- }
171-
172- public int getCyclomaticComplexity () {
173- return cyclomaticComplexity ;
173+ private String file ;
174+ private int lineNumber ;
175+
176+ public SwiftFunction (String name ) {
177+ String [] vals = name .split (" " );
178+ if (vals .length >= 3 ){
179+ this .name = vals [0 ].substring (0 ,vals [0 ].indexOf ("(" ));
180+ this .file = vals [2 ].substring (0 ,vals [2 ].lastIndexOf (":" ));
181+ this .lineNumber = Integer .parseInt (vals [2 ].substring (vals [2 ].lastIndexOf (":" )+1 ));
182+ this .key = file .substring (0 ,file .lastIndexOf ('.' )+1 )+name ;
183+ }else {
184+ this .key = name ;
185+ }
174186 }
175187
176188 @ Override
177189 public String key () {
178190 return key ;
179191 }
180192
193+ public String getName (){
194+ return name ;
195+ }
196+
197+ public String getFile (){
198+ return file ;
199+ }
200+
201+ public int getLineNumber (){
202+ return lineNumber ;
203+ }
204+
181205 @ Override
182206 public boolean isFile () {
183207 return false ;
0 commit comments