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