001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 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.squid.bridges; 021 022 import com.google.common.collect.Lists; 023 import org.sonar.api.measures.CoreMetrics; 024 import org.sonar.api.measures.Measure; 025 import org.sonar.api.measures.PersistenceMode; 026 import org.sonar.api.resources.Qualifiers; 027 import org.sonar.api.resources.Resource; 028 import org.sonar.java.bytecode.asm.AsmField; 029 import org.sonar.java.bytecode.asm.AsmMethod; 030 import org.sonar.java.bytecode.asm.AsmResource; 031 import org.sonar.squid.api.SourceFile; 032 import org.sonar.squid.measures.Metric; 033 034 import java.util.Collections; 035 import java.util.Comparator; 036 import java.util.List; 037 import java.util.Set; 038 039 public class Lcom4BlocksBridge extends Bridge { 040 041 protected Lcom4BlocksBridge() { 042 super(true); 043 } 044 045 @Override 046 public void onFile(SourceFile squidFile, Resource sonarFile) { 047 List<Set<AsmResource>> blocks = (List<Set<AsmResource>>) squidFile.getData(Metric.LCOM4_BLOCKS); 048 049 // This measure includes AsmResource objects and it is used only by this bridge, so 050 // it can be removed from memory. 051 squidFile.removeMeasure(Metric.LCOM4_BLOCKS); 052 053 if (blocks != null && !blocks.isEmpty()) { 054 Measure measure = new Measure(CoreMetrics.LCOM4_BLOCKS, serialize(blocks)); 055 measure.setPersistenceMode(PersistenceMode.DATABASE); 056 context.saveMeasure(sonarFile, measure); 057 } 058 } 059 060 protected void sortBlocks(List<Set<AsmResource>> blocks) { 061 Collections.sort(blocks, new Comparator<Set>() { 062 public int compare(Set set1, Set set2) { 063 return set1.size() - set2.size(); 064 } 065 }); 066 } 067 068 protected String serialize(List<Set<AsmResource>> blocks) { 069 sortBlocks(blocks); 070 071 StringBuilder sb = new StringBuilder(); 072 sb.append('['); 073 074 for (int indexBlock = 0; indexBlock < blocks.size(); indexBlock++) { 075 blocks.get(indexBlock); 076 Set<AsmResource> block = blocks.get(indexBlock); 077 if (!block.isEmpty()) { 078 if (indexBlock > 0) { 079 sb.append(','); 080 } 081 sb.append('['); 082 serializeBlock(block, sb); 083 sb.append(']'); 084 } 085 } 086 sb.append(']'); 087 return sb.toString(); 088 } 089 090 private void serializeBlock(Set<AsmResource> block, StringBuilder sb) { 091 List<AsmResource> sortedResources = sortResourcesInBlock(block); 092 int indexResource = 0; 093 for (AsmResource resource : sortedResources) { 094 if (indexResource++ > 0) { 095 sb.append(','); 096 } 097 serializeResource(resource, sb); 098 } 099 } 100 101 private void serializeResource(AsmResource resource, StringBuilder sb) { 102 sb.append("{\"q\":\""); 103 sb.append(toQualifier(resource)); 104 sb.append("\",\"n\":\""); 105 sb.append(resource.toString()); 106 sb.append("\"}"); 107 } 108 109 protected List<AsmResource> sortResourcesInBlock(Set<AsmResource> block) { 110 List<AsmResource> result = Lists.newArrayList(); 111 result.addAll(block); 112 113 Collections.sort(result, new Comparator<AsmResource>() { 114 public int compare(AsmResource asmResource1, AsmResource asmResource2) { 115 int result = compareType(asmResource1, asmResource2); 116 if (result == 0) { 117 result = asmResource1.toString().compareTo(asmResource2.toString()); 118 } 119 return result; 120 } 121 122 private int compareType(AsmResource asmResource1, AsmResource asmResource2) { 123 if (asmResource1 instanceof AsmField) { 124 return (asmResource2 instanceof AsmField) ? 0 : -1; 125 } 126 return (asmResource2 instanceof AsmMethod) ? 0 : 1; 127 } 128 }); 129 130 return result; 131 } 132 133 private static String toQualifier(AsmResource asmResource) { 134 if (asmResource instanceof AsmField) { 135 return Qualifiers.FIELD; 136 } 137 if (asmResource instanceof AsmMethod) { 138 return Qualifiers.METHOD; 139 } 140 throw new IllegalArgumentException("Wrong ASM resource: " + asmResource.getClass()); 141 } 142 }