38dde124549c9bd816f07195ac2a1fd5df4eff3d
[sdc.git] /
1 package org.openecomp.sdc.onboarding.pmd;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.ObjectInputStream;
9 import java.io.ObjectOutputStream;
10 import java.io.OutputStream;
11 import java.io.UncheckedIOException;
12 import java.nio.file.Files;
13 import java.nio.file.StandardOpenOption;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Scanner;
19 import java.util.Set;
20 import java.util.concurrent.atomic.AtomicInteger;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23 import org.apache.maven.plugin.logging.Log;
24 import org.apache.maven.project.MavenProject;
25
26 public class PMDHelperUtils {
27
28     private PMDHelperUtils() {
29         // default constructor. donot remove.
30     }
31
32     private static Map<String, String> pmdLink = new HashMap<>();
33
34     static {
35         pmdLink.put("one", "errorprone");
36         pmdLink.put("ign", "design");
37         pmdLink.put("ing", "multithreading");
38         pmdLink.put("nce", "performance");
39         pmdLink.put("ity", "security");
40         pmdLink.put("yle", "codestyle");
41         pmdLink.put("ces", "bestpractices");
42     }
43
44     static String readInputStream(InputStream is) {
45         try (Scanner s = new Scanner(is).useDelimiter("\\A")) {
46             return s.hasNext() ? s.next() : "";
47         }
48     }
49
50     static File getStateFile(String moduleCoordinate, MavenProject proj, String filePath) {
51         return new File(getTopParentProject(moduleCoordinate, proj).getBasedir(),
52                 filePath.substring(filePath.indexOf('/') + 1));
53     }
54
55     private static MavenProject getTopParentProject(String moduleCoordinate, MavenProject proj) {
56         if (getModuleCoordinate(proj).equals(moduleCoordinate) || proj.getParent() == null) {
57             return proj;
58         } else {
59             return getTopParentProject(moduleCoordinate, proj.getParent());
60         }
61     }
62
63     private static String getModuleCoordinate(MavenProject project) {
64         return project.getGroupId() + ":" + project.getArtifactId();
65     }
66
67     private static <T> T readState(String fileName, Class<T> clazz) {
68         try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
69              ObjectInputStream ois = new ObjectInputStream(is)) {
70             return clazz.cast(ois.readObject());
71         } catch (Exception ioe) {
72             return null;
73         }
74     }
75
76     static <T> T readState(File file, Class<T> clazz) {
77         try (InputStream is = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(is)) {
78             return clazz.cast(ois.readObject());
79         } catch (Exception ioe) {
80             return null;
81         }
82     }
83
84     static boolean evaluateCodeQuality(Map<String, List<Violation>> stats, Map<String, List<Violation>> current,
85             File file, Log logger) {
86         boolean qualityCheckPassed = true;
87         Map<String, String> table = new HashMap<>();
88         Set<String> classes = current.keySet();
89         int counter = 0;
90         for (String clazz : classes) {
91             List<Violation> orgViolation = stats.get(clazz) == null ? new ArrayList<>() : stats.get(clazz);
92             List<Violation> currViolation = current.get(clazz) == null ? new ArrayList<>() : current.get(clazz);
93             if (diffViolation(orgViolation, currViolation) > 0) {
94                 Map<String, Integer> lDetails = diffCategory(orgViolation, currViolation);
95                 for (String cat : lDetails.keySet()) {
96                     String lineNo = getLineNumbers(currViolation, cat);
97                     table.put(++counter + clazz, cat + ":" + lDetails.get(cat) + ":" + lineNo);
98                 }
99             }
100         }
101         if (!table.isEmpty()) {
102             qualityCheckPassed = false;
103             try {
104                 Files.write(file.toPath(),
105                         new Table(getTableHeaders(true), getContents(table, true)).drawTable().getBytes(),
106                         StandardOpenOption.CREATE);
107             } catch (IOException e) {
108                 throw new UncheckedIOException(e);
109             }
110             logger.error(new Table(getTableHeaders(false), getContents(table, false)).drawTable());
111         }
112         return qualityCheckPassed;
113     }
114
115     private static ArrayList<String> getTableHeaders(boolean addLink) {
116         ArrayList<String> list = new ArrayList<>();
117         list.add("Class Name");
118         list.add("Rule Category");
119         list.add("Rule Name");
120         list.add("Fix");
121         list.add("Source Line No");
122         if (addLink) {
123             list.add("Help Link");
124         }
125         return list;
126     }
127
128     private static ArrayList<ArrayList<String>> getContents(Map<String, String> data, boolean addLink) {
129         ArrayList<ArrayList<String>> list = new ArrayList<>();
130         Pattern p = Pattern.compile("(.*):(.*):(.*):(.*)");
131         for (String s : data.keySet()) {
132             ArrayList<String> l = new ArrayList<>();
133             l.add(s.substring(s.indexOf("::") + 2));
134             Matcher m = p.matcher(data.get(s));
135             if (m.find()) {
136                 l.add(m.group(1));
137                 l.add(m.group(2));
138                 l.add(m.group(3) + " at least");
139                 l.add(m.group(4));
140                 if (addLink) {
141                     l.add("http://pmd.sourceforge.net/snapshot/pmd_rules_java_" + getLinkCategory(m.group(1)) + ".html#"
142                                   + m.group(2).toLowerCase());
143                 }
144             }
145             list.add(l);
146         }
147         return list;
148     }
149
150     private static String getLinkCategory(String cat) {
151         for (String category : pmdLink.keySet()) {
152             if (cat.contains(category)) {
153                 return pmdLink.get(category);
154             }
155         }
156         return "ERROR";
157     }
158
159     private static int diffViolation(List<Violation> org, List<Violation> curr) {
160         int diff = 0;
161         if (org == null || org.isEmpty()) {
162             if (curr != null && !curr.isEmpty()) {
163                 diff = curr.size();
164             }
165         } else {
166             if (curr != null && !curr.isEmpty()) {
167                 diff = curr.size() - org.size();
168             }
169         }
170         return diff;
171     }
172
173     private static Map<String, Integer> diffCategory(List<Violation> org, List<Violation> curr) {
174         Map<String, AtomicInteger> currData = new HashMap<>();
175         Map<String, AtomicInteger> orgData = new HashMap<>();
176         countViolations(curr, currData);
177         countViolations(org, orgData);
178         Map<String, Integer> val = new HashMap<>();
179         for (String cat : currData.keySet()) {
180             if (orgData.get(cat) == null) {
181                 val.put(cat, currData.get(cat).intValue());
182             } else if (currData.get(cat).intValue() > orgData.get(cat).intValue()) {
183                 val.put(cat, currData.get(cat).intValue() - orgData.get(cat).intValue());
184             }
185         }
186         return val;
187     }
188
189     private static void countViolations(List<Violation> violations,  Map<String, AtomicInteger> store){
190         for (Violation v : violations) {
191             if (store.get(v.getCategory() + ":" + v.getRule()) == null) {
192                 store.put(v.getCategory() + ":" + v.getRule(), new AtomicInteger(1));
193             } else {
194                 store.get(v.getCategory() + ":" + v.getRule()).incrementAndGet();
195             }
196         }
197     }
198
199     private static void processOriginalViolations(List<Violation> org){
200
201     }
202     private static String getLineNumbers(List<Violation> vList, String category) {
203         String val = "";
204         boolean firstOver = false;
205         for (Violation v : vList) {
206             if (category.equals(v.getCategory() + ":" + v.getRule())) {
207                 if (firstOver) {
208                     val += ",";
209                 }
210                 val += v.getLine();
211                 firstOver = true;
212             }
213         }
214         return val;
215     }
216
217     static Map<String, List<Violation>> readCurrentPMDState(String fileName) {
218         Map<String, List<Violation>> val = readState(fileName, HashMap.class);
219         return val == null ? new HashMap<>() : val;
220     }
221
222     static Map<String, List<Violation>> readCurrentPMDState(File file) {
223         Map<String, List<Violation>> val = readState(file, HashMap.class);
224         return val == null ? new HashMap<>() : val;
225     }
226
227     static void writeCurrentPMDState(File file, Map<String, List<Violation>> data) {
228         try (OutputStream os = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(os)) {
229             oos.writeObject(data);
230         } catch (IOException ioe) {
231             throw new UncheckedIOException(ioe);
232         }
233     }
234
235     static boolean isReportEmpty(File reportFile){
236         try {
237             return !reportFile.exists() || Files.readAllLines(reportFile.toPath()).size()<=1;
238         } catch (IOException e) {
239             throw new UncheckedIOException(e);
240         }
241     }
242 }