");
+ return htmlBuilder.toString();
+ }
+
+ /**
+ * Retrieves the explanation for a specific license conflict.
+ *
+ * @param lic1 the first license involved in the conflict
+ * @param lic2 the second license involved in the conflict
+ * @return the explanation for the specified license conflict
+ */
+ private String getExplanationForLicenseConflict(String lic1, String lic2) {
+ return "These two licenses are incompatible due to their conflicting terms and conditions. "
+ + "It is recommended to resolve this conflict by choosing either "
+ + lic1
+ + " or "
+ + lic2
+ + " for the affected components.";
+ }
+
+ /**
+ * Generates the license table HTML content.
+ *
+ * @param detectedLicenseInfo grouped scan results by license SPDX ID and access type, component name and vendor
+ * @param webhookConfig configuration related to the repository and webhook
+ * @param vcs the string representation of the version control system
+ * @return the HTML content for the license table
+ */
+ private String generateLicenseTableHTML(
+ Map> detectedLicenseInfo, LPVSQueue webhookConfig, LPVSVcs vcs) {
+ StringBuilder htmlBuilder = new StringBuilder();
+ htmlBuilder.append("
");
+ return htmlBuilder.toString();
+ }
+
+ /**
+ * Adds a block of HTML content for a specific license type to the license table.
+ *
+ * @param htmlBuilder the StringBuilder object to which the HTML content will be appended
+ * @param detectedLicenseInfo grouped scan results by license SPDX ID and access type, component name and vendor
+ * @param type the license type for which to add the block of HTML content
+ * @param webhookConfig configuration related to the repository and webhook
+ * @param vcs the string representation of the version control system
+ */
+ private void addBlockOfTableForLicenseTypeHTML(
+ StringBuilder htmlBuilder,
+ Map> detectedLicenseInfo,
+ String type,
+ LPVSQueue webhookConfig,
+ LPVSVcs vcs) {
+ long detectedLicenseCountByType = getDetectedLicenseCountByType(detectedLicenseInfo, type);
+ boolean isNewRow;
+ if (detectedLicenseCountByType > 0) {
+ htmlBuilder.append("
");
+ isNewRow = false;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieves the explanation for a specific license type.
+ *
+ * @param type the license type for which to retrieve the explanation
+ * @return the explanation for the specified license type
+ */
+ private String getExplanationForLicenseType(String type) {
+ switch (type.toUpperCase()) {
+ case prohibited:
+ return "This license prohibits the use of the licensed code in certain contexts, such as commercial software development.";
+ case restricted:
+ return "This license required compliance with specific obligations. It is crucial to carefully review and adhere to these obligations before using the licensed code.";
+ case unreviewed:
+ return "This license has not been reviewed thoroughly and may contain unknown risks or limitations. It is recommended to review these licenses carefully before using the licensed code.";
+ case permitted:
+ return "This license permits free usage, modification, and distribution of the licensed code without any restrictions.";
+ default:
+ throw new IllegalStateException("Unexpected value for the license type: " + type);
+ }
+ }
+
+ /**
+ * Function that returns the number of licenses detected for the given type.
+ *
+ * @param detectedLicenseInfo grouped scan results by license SPDX ID and access type, component name and vendor
+ * @param type the license type to count
+ * @return the number of licenses detected for the given type
+ */
+ private long getDetectedLicenseCountByType(
+ Map> detectedLicenseInfo, String type) {
+ if (detectedLicenseInfo == null || detectedLicenseInfo.get(type) == null) {
+ return 0;
+ }
+ return ((Map>) detectedLicenseInfo.get(type).elements).size();
+ }
+
+ /**
+ * Function that returns the converted list of LPVS files with a single license.
+ *
+ * @param scanResults the results of the license scan
+ * @return a list of LPVS files with a single license
+ */
+ private List getLpvsFilesFromScanResults(List scanResults) {
+ List filesScanResults = new ArrayList<>();
+ for (LPVSFile file : scanResults) {
+ Set licenses = file.getLicenses();
+ for (LPVSLicense license : licenses) {
+ LPVSFile file_ =
+ new LPVSFile() {
+ {
+ setFilePath(file.getFilePath());
+ setAbsoluteFilePath(file.getAbsoluteFilePath());
+ setSnippetType(file.getSnippetType());
+ setSnippetMatch(file.getSnippetMatch());
+ setMatchedLines(file.getMatchedLines());
+ setLicenses(new HashSet<>(Collections.singletonList(license)));
+ setComponentFilePath(file.getComponentFilePath());
+ setComponentFileUrl(file.getComponentFileUrl());
+ setComponentName(file.getComponentName());
+ setComponentLines(file.getComponentLines());
+ setComponentUrl(file.getComponentUrl());
+ setComponentVendor(file.getComponentVendor());
+ setComponentVersion(file.getComponentVersion());
+ }
+ };
+ filesScanResults.add(file_);
+ }
+ }
+ return filesScanResults;
+ }
+
+ /**
+ * Groups the scan results by license type for display in the license table.
+ *
+ * @param scanResults the results of the license scan
+ */
+ private Map> groupScanResultsForLicenseTable(List scanResults) {
+ Map> detectedLicenseInfo = null;
+ if (scanResults != null && !scanResults.isEmpty()) {
+ List filesScanResults = getLpvsFilesFromScanResults(scanResults);
+
+ detectedLicenseInfo =
+ filesScanResults.stream()
+ .collect(
+ Collectors.groupingBy(
+ this::getLicenseAccess,
+ Collectors.collectingAndThen(
+ Collectors.groupingBy(
+ this::getLicenseSpdxId,
+ Collectors.collectingAndThen(
+ Collectors.groupingBy(
+ this::getComponentKey,
+ Collectors
+ .collectingAndThen(
+ Collectors
+ .toList(),
+ files ->
+ new GroupInfo<>(
+ files
+ .size(),
+ files))),
+ this::sumGroupInfo)),
+ this::sumGroupInfo)));
+ }
+ return detectedLicenseInfo;
+ }
+
+ /**
+ * Sums the counts of all GroupInfo objects in the given map and returns a new GroupInfo object
+ * containing the total count and the original map.
+ *
+ * @param groupedBy a map of strings to GroupInfo objects
+ * @return a new GroupInfo object containing the total count of all GroupInfo objects in the map
+ * and the original map
+ */
+ private GroupInfo