diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java index dba3f579..69d8f6dd 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java @@ -38,6 +38,8 @@ public class FileScancodeRawComponentInfoProvider implements ScancodeRawComponen private String repoBasePath; + private String scancodeFileName = "scancode.json"; + private long maxContentFileSize = 1000000L; // set this to the default even if spring is not used private AllKindsPackageURLHandler packageURLHandler; @@ -76,6 +78,17 @@ public void setMaxContentFileSize(long maxContentFileSize) { this.maxContentFileSize = maxContentFileSize; } + /** + * Sets the name of the scancode json file. + * + * @param scancodeFileName new value of {@link #scancodeFileName}. + */ + @Value("${solicitor.scancode.file-name:scancode.json}") + public void setScancodeFileName(String scancodeFileName) { + + this.scancodeFileName = scancodeFileName; + } + /** * Retrieve the {@link ScancodeRawComponentInfo} for the package given by its PackageURL. * @@ -90,7 +103,7 @@ public ScancodeRawComponentInfo readScancodeData(String packageUrl) throws ComponentInfoAdapterException, ScancodeProcessingFailedException { String packagePathPart = this.packageURLHandler.pathFor(packageUrl); - String path = IOHelper.secureFilePath(this.repoBasePath, packagePathPart, "scancode.json"); + String path = IOHelper.secureFilePath(this.repoBasePath, packagePathPart, this.scancodeFileName); File scanCodeFile = new File(path); if (!scanCodeFile.exists()) { diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV31ComponentInfoProvider.java similarity index 84% rename from core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProvider.java rename to core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV31ComponentInfoProvider.java index 5765b383..d659c808 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProvider.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV31ComponentInfoProvider.java @@ -11,36 +11,27 @@ import org.springframework.stereotype.Component; import com.devonfw.tools.solicitor.common.LogMessages; -import com.devonfw.tools.solicitor.common.packageurl.AllKindsPackageURLHandler; import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; import com.devonfw.tools.solicitor.componentinfo.CurationDataHandle; import com.devonfw.tools.solicitor.componentinfo.DataStatusValue; -import com.devonfw.tools.solicitor.componentinfo.DefaultComponentInfoImpl; import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; import com.devonfw.tools.solicitor.componentinfo.curation.CurationProvider; -import com.devonfw.tools.solicitor.componentinfo.curation.FilteredComponentInfoProvider; import com.devonfw.tools.solicitor.componentinfo.curation.model.ComponentInfoCuration; import com.devonfw.tools.solicitor.componentinfo.curation.model.CopyrightCuration; import com.devonfw.tools.solicitor.componentinfo.curation.model.CurationOperation; import com.devonfw.tools.solicitor.componentinfo.curation.model.LicenseCuration; import com.devonfw.tools.solicitor.componentinfo.scancode.ScancodeComponentInfo.ScancodeComponentInfoData; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.github.packageurl.PackageURL; /** - * {@link FilteredComponentInfoProvider} which delivers data based on scancode data. + * {@link FilteredScancodeVersionComponentInfoProvider} which delivers data based on scancode data. * */ @Component -public class FilteredScancodeComponentInfoProvider implements FilteredComponentInfoProvider { +public class FilteredScancodeV31ComponentInfoProvider implements FilteredScancodeVersionComponentInfoProvider { - private static final Logger LOG = LoggerFactory.getLogger(FilteredScancodeComponentInfoProvider.class); - - private static final ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + private static final Logger LOG = LoggerFactory.getLogger(FilteredScancodeV31ComponentInfoProvider.class); private double minLicenseScore; @@ -56,13 +47,12 @@ public class FilteredScancodeComponentInfoProvider implements FilteredComponentI * The constructor. * * @param fileScancodeRawComponentInfoProvider the provide for the raw scancode data - * @param packageURLHandler the handler for dealing with {@link PackageURL}s. * @param curationProvider for getting the filter information used for filtering findings based on the paths in the * code */ @Autowired - public FilteredScancodeComponentInfoProvider(ScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider, - AllKindsPackageURLHandler packageURLHandler, CurationProvider curationProvider) { + public FilteredScancodeV31ComponentInfoProvider(ScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider, + CurationProvider curationProvider) { this.fileScancodeRawComponentInfoProvider = fileScancodeRawComponentInfoProvider; this.curationProvider = curationProvider; @@ -91,32 +81,29 @@ public void setMinLicensefileNumberOfLines(int minLicensefileNumberOfLines) { this.minLicensefileNumberOfLines = minLicensefileNumberOfLines; } + @Override + public boolean accept(String toolVersion) { + + return toolVersion.startsWith("30.") || toolVersion.startsWith("31."); + } + /** - * Read scancode information for the given package from local file storage. + * Reads Scancode information for the given package from local file storage. * - * @param packageUrl The package url of the package - * @param curationDataHandle identifies which source should be used for the curation data. - * @return the read scancode information - * @throws ComponentInfoAdapterException if there was an exception when reading the data. In case that there is no - * data available no exception will be thrown. Instead null will be returned in such a case. - * @throws CurationInvalidException if the curation data is not valid + * @param packageUrl the package URL of the package + * @param curationDataHandle identifies the source for the curation data + * @param rawScancodeData the raw Scancode data + * @param scancodeJson the parsed Scancode JSON data + * @return the component information based on the Scancode data + * @throws ComponentInfoAdapterException if an error occurs while reading the data + * @throws CurationInvalidException if the curation data is invalid */ @Override - public ComponentInfo getComponentInfo(String packageUrl, CurationDataHandle curationDataHandle) + public ComponentInfo getComponentInfo(String packageUrl, CurationDataHandle curationDataHandle, + ScancodeRawComponentInfo rawScancodeData, JsonNode scancodeJson) throws ComponentInfoAdapterException, CurationInvalidException { - ScancodeRawComponentInfo rawScancodeData; - try { - rawScancodeData = this.fileScancodeRawComponentInfoProvider.readScancodeData(packageUrl); - } catch (ScancodeProcessingFailedException e) { - return new DefaultComponentInfoImpl(packageUrl, DataStatusValue.PROCESSING_FAILED); - } - if (rawScancodeData == null) { - return new DefaultComponentInfoImpl(packageUrl, DataStatusValue.NOT_AVAILABLE); - } - - ScancodeComponentInfo componentScancodeInfos = parseAndMapScancodeJson(packageUrl, rawScancodeData, - curationDataHandle); + ScancodeComponentInfo componentScancodeInfos = mapScancodeJson(packageUrl, scancodeJson, curationDataHandle); addSupplementedData(rawScancodeData, componentScancodeInfos); LOG.debug("Scancode info for package {}: {} license, {} copyrights, {} NOTICE files", packageUrl, componentScancodeInfos.getComponentInfoData().getLicenses().size(), @@ -127,8 +114,10 @@ public ComponentInfo getComponentInfo(String packageUrl, CurationDataHandle cura } /** - * @param rawScancodeData - * @param componentScancodeInfos + * Adds supplemented data to the component Scancode information. + * + * @param rawScancodeData the raw Scancode data + * @param componentScancodeInfos the component Scancode information to be updated */ private void addSupplementedData(ScancodeRawComponentInfo rawScancodeData, ScancodeComponentInfo componentScancodeInfos) { @@ -138,18 +127,25 @@ private void addSupplementedData(ScancodeRawComponentInfo rawScancodeData, } /** - * Parses and maps scancode JSON to create ScancodeComponentInfo. + * Maps scancode JSON to create ScancodeComponentInfo. * - * @param packageUrl package URL of the package - * @param rawScancodeData raw scancode data - * @param curationDataHandle identifies which source should be used for the curation data. - * @return the ScancodeComponentInfo - * @throws ComponentInfoAdapterException if there was an issue during parsing - * @throws CurationInvalidException if the curation data is not valid + * @param packageUrl the URL of the package for which Scancode data is being processed + * @param scancodeJson the parsed JSON data from Scancode results + * @param curationDataHandle identifies which source should be used for the curation data + * @return the {@link ScancodeComponentInfo} containing the processed data + * @throws ComponentInfoAdapterException if there is an issue with parsing the Scancode JSON or if a suitable provider + * for the Scancode version is not found + * @throws CurationInvalidException if the curation data is not valid or if there is an error applying curation data */ - private ScancodeComponentInfo parseAndMapScancodeJson(String packageUrl, ScancodeRawComponentInfo rawScancodeData, + private ScancodeComponentInfo mapScancodeJson(String packageUrl, JsonNode scancodeJson, CurationDataHandle curationDataHandle) throws ComponentInfoAdapterException, CurationInvalidException { + String toolVersion = scancodeJson.get("headers").get(0).get("tool_version").asText(); + if (!accept(toolVersion)) { + throw new ComponentInfoAdapterException( + "Can only handle version 30 and 31 but found version was '" + toolVersion + "'"); + } + ScancodeComponentInfo componentScancodeInfos = new ScancodeComponentInfo(this.minLicenseScore, this.minLicensefileNumberOfLines); componentScancodeInfos.setPackageUrl(packageUrl); @@ -172,13 +168,6 @@ private ScancodeComponentInfo parseAndMapScancodeJson(String packageUrl, Scancod copyrightCurations = componentInfoCuration.getCopyrightCurations(); } - JsonNode scancodeJson; - try { - scancodeJson = mapper.readTree(rawScancodeData.rawScancodeResult); - } catch (JsonProcessingException e) { - throw new ComponentInfoAdapterException("Could not parse Scancode JSON", e); - } - // Skip all files, whose path have a prefix which is in the excluded path list for (JsonNode file : scancodeJson.get("files")) { String path = file.get("path").asText(); @@ -328,10 +317,15 @@ private ScancodeComponentInfo parseAndMapScancodeJson(String packageUrl, Scancod /** * Gets the effective license info after possibly applying curations for a single license finding. * - * @param path - * @param li - * @param licenseCurations - * @return + * @param path the path of the license finding which is used in the curation rules matching. + * @param li a {@link JsonNode} representing the license finding data that includes information such as the matched + * rule identifier, matched text, and SPDX license key. + * @param licenseCurations s a list of {@link LicenseCuration} objects that may contain rules for curating license + * data. + * @return a {@link LicenseCuration.NewLicenseData} object containing the effective license information after applying + * the curation. If no applicable curation is found or if the curation list is {@code null}, a new + * {@link LicenseCuration.NewLicenseData} instance with all members being {@code null} is returned, indicating + * no change. */ private LicenseCuration.NewLicenseData getEffectiveLicenseInfoWithCuration(String path, JsonNode li, List licenseCurations) { @@ -406,10 +400,10 @@ private void addLicensesByCuration(String packageUrl, String path, List copyrightCurations) { @@ -516,4 +510,5 @@ private boolean isExcluded(String path, List excludedPaths) { } return false; } + } diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV32ComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV32ComponentInfoProvider.java new file mode 100644 index 00000000..e101e4cf --- /dev/null +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV32ComponentInfoProvider.java @@ -0,0 +1,563 @@ +package com.devonfw.tools.solicitor.componentinfo.scancode; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import com.devonfw.tools.solicitor.common.LogMessages; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; +import com.devonfw.tools.solicitor.componentinfo.CurationDataHandle; +import com.devonfw.tools.solicitor.componentinfo.DataStatusValue; +import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; +import com.devonfw.tools.solicitor.componentinfo.curation.CurationProvider; +import com.devonfw.tools.solicitor.componentinfo.curation.model.ComponentInfoCuration; +import com.devonfw.tools.solicitor.componentinfo.curation.model.CopyrightCuration; +import com.devonfw.tools.solicitor.componentinfo.curation.model.CurationOperation; +import com.devonfw.tools.solicitor.componentinfo.curation.model.LicenseCuration; +import com.devonfw.tools.solicitor.componentinfo.scancode.ScancodeComponentInfo.ScancodeComponentInfoData; +import com.fasterxml.jackson.databind.JsonNode; + +/** + * {@link FilteredScancodeVersionComponentInfoProvider} which delivers data based on scancode data. + * + */ +@Component +public class FilteredScancodeV32ComponentInfoProvider implements FilteredScancodeVersionComponentInfoProvider { + + private static final Logger LOG = LoggerFactory.getLogger(FilteredScancodeV32ComponentInfoProvider.class); + + private double minLicenseScore; + + private int minLicensefileNumberOfLines; + + private double licenseToTextRatioToTakeCompleteFile = 90; + + private ScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; + + private CurationProvider curationProvider; + + /** + * The constructor. + * + * @param fileScancodeRawComponentInfoProvider the provide for the raw scancode data + * @param curationProvider for getting the filter information used for filtering findings based on the paths in the + * code + */ + @Autowired + public FilteredScancodeV32ComponentInfoProvider(ScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider, + CurationProvider curationProvider) { + + this.fileScancodeRawComponentInfoProvider = fileScancodeRawComponentInfoProvider; + this.curationProvider = curationProvider; + + } + + /** + * Sets minLicenseScore. + * + * @param minLicenseScore new value of minLicenseScore. + */ + @Value("${solicitor.scancode.min-license-score}") + public void setMinLicenseScore(double minLicenseScore) { + + this.minLicenseScore = minLicenseScore; + } + + /** + * Sets minLicensefileNumberOfLines. + * + * @param minLicensefileNumberOfLines new value of minLicensefileNumberOfLines. + */ + @Value("${solicitor.scancode.min-licensefile-number-of-lines}") + public void setMinLicensefileNumberOfLines(int minLicensefileNumberOfLines) { + + this.minLicensefileNumberOfLines = minLicensefileNumberOfLines; + } + + @Override + public boolean accept(String toolVersion) { + + return toolVersion.startsWith("32."); + } + + /** + * Reads Scancode information for the given package from local file storage. + * + * @param packageUrl the package URL of the package + * @param curationDataHandle identifies the source for the curation data + * @param rawScancodeData the raw Scancode data + * @param scancodeJson the parsed Scancode JSON data + * @return the component information based on the Scancode data + * @throws ComponentInfoAdapterException if an error occurs while reading the data + * @throws CurationInvalidException if the curation data is invalid + */ + @Override + public ComponentInfo getComponentInfo(String packageUrl, CurationDataHandle curationDataHandle, + ScancodeRawComponentInfo rawScancodeData, JsonNode scancodeJson) + throws ComponentInfoAdapterException, CurationInvalidException { + + ScancodeComponentInfo componentScancodeInfos = mapScancodeJson(packageUrl, scancodeJson, curationDataHandle); + addSupplementedData(rawScancodeData, componentScancodeInfos); + LOG.debug("Scancode info for package {}: {} license, {} copyrights, {} NOTICE files", packageUrl, + componentScancodeInfos.getComponentInfoData().getLicenses().size(), + componentScancodeInfos.getComponentInfoData().getCopyrights().size(), + componentScancodeInfos.getComponentInfoData().getNoticeFileUrl() != null ? 1 : 0); + + return componentScancodeInfos; + } + + /** + * Adds supplemented data to the component Scancode information. + * + * @param rawScancodeData the raw Scancode data + * @param componentScancodeInfos the component Scancode information to be updated + */ + private void addSupplementedData(ScancodeRawComponentInfo rawScancodeData, + ScancodeComponentInfo componentScancodeInfos) { + + componentScancodeInfos.getComponentInfoData().setSourceDownloadUrl(rawScancodeData.sourceDownloadUrl); + componentScancodeInfos.getComponentInfoData().setPackageDownloadUrl(rawScancodeData.packageDownloadUrl); + } + + /** + * Maps scancode JSON to create ScancodeComponentInfo. + * + * @param packageUrl the URL of the package for which Scancode data is being processed + * @param scancodeJson the parsed JSON data from Scancode results + * @param curationDataHandle identifies which source should be used for the curation data + * @return the {@link ScancodeComponentInfo} containing the processed data + * @throws ComponentInfoAdapterException if there is an issue with parsing the Scancode JSON or if a suitable provider + * for the Scancode version is not found + * @throws CurationInvalidException if the curation data is not valid or if there is an error applying curation data + */ + private ScancodeComponentInfo mapScancodeJson(String packageUrl, JsonNode scancodeJson, + CurationDataHandle curationDataHandle) throws ComponentInfoAdapterException, CurationInvalidException { + + String toolVersion = scancodeJson.get("headers").get(0).get("tool_version").asText(); + if (!accept(toolVersion)) { + throw new ComponentInfoAdapterException("Can only handle version 32 but found version was '" + toolVersion + "'"); + } + + ScancodeComponentInfo componentScancodeInfos = new ScancodeComponentInfo(this.minLicenseScore, + this.minLicensefileNumberOfLines); + componentScancodeInfos.setPackageUrl(packageUrl); + // set status to NO_ISSUES. This might be overridden later if issues are detected or curations are applied + componentScancodeInfos.setDataStatus(DataStatusValue.NO_ISSUES); + + // get the object which hold the actual data + ScancodeComponentInfoData scancodeComponentInfoData = componentScancodeInfos.getComponentInfoData(); + + // Get the curation for a given packageUrl + ComponentInfoCuration componentInfoCuration = this.curationProvider.findCurations(packageUrl, curationDataHandle); + + // Get all excludedPaths in this curation + List excludedPaths = null; + List licenseCurations = null; + List copyrightCurations = null; + if (componentInfoCuration != null) { + excludedPaths = componentInfoCuration.getExcludedPaths(); + licenseCurations = componentInfoCuration.getLicenseCurations(); + copyrightCurations = componentInfoCuration.getCopyrightCurations(); + } + + Map licenseReferencesMap = createLicenseReferencesMap(scancodeJson); + + // Skip all files, whose path have a prefix which is in the excluded path list + for (JsonNode file : scancodeJson.get("files")) { + String path = file.get("path").asText(); + if (isExcluded(path, excludedPaths)) { + // this is a curation operation, so set the status + componentScancodeInfos.setDataStatus(DataStatusValue.CURATED); + continue; + } + if ("directory".equals(file.get("type").asText())) { + continue; + } + if (path.contains("/NOTICE")) { + scancodeComponentInfoData + .addNoticeFileUrl(this.fileScancodeRawComponentInfoProvider.pkgContentUriFromPath(packageUrl, path), 100.0); + } + double licenseTextRatio = file.get("percentage_of_license_text").asDouble(); + boolean takeCompleteFile = licenseTextRatio >= this.licenseToTextRatioToTakeCompleteFile; + for (JsonNode cr : file.get("copyrights")) { + String copyright; + copyright = cr.get("copyright").asText(); + String copyrightAfterCuration = getEffectiveCopyrightWithCuration(path, copyright, copyrightCurations); + if (copyrightAfterCuration != null) { + if (!copyrightAfterCuration.equals(copyright)) { + // the copyright info changed due to applying a curation, so set the status + componentScancodeInfos.setDataStatus(DataStatusValue.CURATED); + } + scancodeComponentInfoData.addCopyright(copyrightAfterCuration); + } else { + if (copyright != null) { + // the copyright info was removed due to applying a curation, so set the status + componentScancodeInfos.setDataStatus(DataStatusValue.CURATED); + + } + } + } + + // special handling for Classpath-exception-2.0 + Map spdxIdMap = new HashMap<>(); + boolean classPathExceptionExists = false; + int numberOfGplLicenses = 0; + for (JsonNode ld : file.get("license_detections")) { + for (JsonNode ma : ld.get("matches")) { + String licenseExpression = ma.get("spdx_license_expression").asText(); + String[] spdxIds = spdxIdsFromExpression(licenseExpression); + for (String spdxId : spdxIds) { + LicenseCuration.NewLicenseData effective = getEffectiveLicenseInfoWithCuration(path, ma, spdxId, + licenseCurations); + if (effective == null) { + // license finding to be REMOVED via finding + continue; + } + String licenseName = effective.license != null ? effective.license : spdxId; + + if ("Classpath-exception-2.0".equals(licenseName)) { + classPathExceptionExists = true; + } + if (!spdxIdMap.containsKey(licenseName)) { + spdxIdMap.put(licenseName, licenseName); + if (licenseName.startsWith("GPL")) { + numberOfGplLicenses++; + } + } + } + } + } + if (classPathExceptionExists) { + if (numberOfGplLicenses == 0) { + LOG.warn(LogMessages.CLASSPATHEXCEPTION_WITHOUT_GPL.msg(), packageUrl); + } else if (numberOfGplLicenses > 1) { + LOG.warn(LogMessages.CLASSPATHEXCEPTION_MULTIPLE_GPL.msg(), packageUrl); + } else { + LOG.debug("Adjusting GPL license to contain WITH Classpath-execption-2.0 for " + packageUrl); + for (String licenseName : spdxIdMap.keySet()) { + if (licenseName.startsWith("GPL")) { + spdxIdMap.put(licenseName, licenseName + " WITH Classpath-exception-2.0"); + } + } + // do not output the Classpath-exception-2.0 as separate License + spdxIdMap.remove("Classpath-exception-2.0"); + } + } + for (JsonNode ld : file.get("license_detections")) { + for (JsonNode ma : ld.get("matches")) { + + String licenseExpression = ma.get("spdx_license_expression").asText(); + String[] spdxIds = spdxIdsFromExpression(licenseExpression); + for (String spdxId : spdxIds) { + LicenseCuration.NewLicenseData effective = getEffectiveLicenseInfoWithCuration(path, ma, spdxId, + licenseCurations); + if (effective == null) { + // license finding to be REMOVED via finding + // this is a curation operation, so set the status + componentScancodeInfos.setDataStatus(DataStatusValue.CURATED); + continue; + } + if (effective.license != null || effective.url != null) { + // license or url are altered due to curation, so set the status + componentScancodeInfos.setDataStatus(DataStatusValue.CURATED); + } + String licenseName = effective.license != null ? effective.license : spdxId; + String effectiveLicenseName = spdxIdMap.get(licenseName); + if (effectiveLicenseName == null) { + // not contained in map --> this must be the Classpath-exception-2.0 + continue; + } else { + licenseName = effectiveLicenseName; + } + // get the default license Url + String licenseDefaultUrl = null; + JsonNode licenseReference = licenseReferencesMap.get(spdxId); + if (licenseReference != null) { + licenseDefaultUrl = licenseReference.get("scancode_url").asText(); + } + if (effective.url != null) { + licenseDefaultUrl = effective.url; + } + licenseDefaultUrl = normalizeLicenseUrl(packageUrl, licenseDefaultUrl); + double score = ma.get("score").asDouble(); + String licenseUrl = path; + int startLine = ma.get("start_line").asInt(); + int endLine = ma.get("end_line").asInt(); + if (!takeCompleteFile) { + licenseUrl += "#L" + startLine; + if (endLine != startLine) { + licenseUrl += "-L" + endLine; + } + } + if (effective.url != null) { + // curation redefined the license URL + licenseUrl = effective.url; + // enforce that the filescore always exceeds the threshold + startLine = 0; + endLine = Integer.MAX_VALUE; + } + + licenseUrl = normalizeLicenseUrl(packageUrl, licenseUrl); + String givenLicenseText = null; + if (licenseUrl != null) { + givenLicenseText = this.fileScancodeRawComponentInfoProvider.retrieveContent(packageUrl, licenseUrl); + } + + scancodeComponentInfoData.addLicense(licenseName, licenseName, licenseDefaultUrl, score, licenseUrl, + givenLicenseText, endLine - startLine); + } + } + + } + + // do any per scanned file postprocessing + addCopyrightsByCuration(path, copyrightCurations, componentScancodeInfos); + addLicensesByCuration(packageUrl, path, licenseCurations, componentScancodeInfos); + + } + // add copyrights / licenses due to curations on package level + addCopyrightsByCuration(null, copyrightCurations, componentScancodeInfos); + addLicensesByCuration(packageUrl, null, licenseCurations, componentScancodeInfos); + + if (scancodeComponentInfoData.getNoticeFileUrl() != null) { + scancodeComponentInfoData.setNoticeFileContent(this.fileScancodeRawComponentInfoProvider + .retrieveContent(packageUrl, scancodeComponentInfoData.getNoticeFileUrl())); + } + return componentScancodeInfos; + } + + /** + * Extracts the array of spdxIds (licenses and exceptions) from a given SPDX expression. Ignores all structural + * information as AND, OR, WITH. + * + * @param licenseExpression the spdx expression + * @return array of found spdx ids. + */ + private String[] spdxIdsFromExpression(String licenseExpression) { + + String plainString = licenseExpression.replace("(", " ").replace(")", " ").replace(" AND ", " ") + .replace(" OR ", " ").replace(" WITH ", " "); + return plainString.split("\\s+"); + } + + /** + * Creates a map which holds the license references information. + * + * @param scancodeJson the parsed scancode json + * @return the map of license references from the scancode result. The key of the map is the spdx_license_key. + */ + private Map createLicenseReferencesMap(JsonNode scancodeJson) { + + Map result = new HashMap<>(); + for (JsonNode licenseReference : scancodeJson.get("license_references")) { + String spdxLicenseKey = licenseReference.get("spdx_license_key").asText(); + result.put(spdxLicenseKey, licenseReference); + } + return result; + } + + /** + * Gets the effective license info after possibly applying curations for a single license finding. + * + * @param path the path of the license finding which is used in the curation rules matching. + * @param ma a {@link JsonNode} representing the matches finding data that includes information such as the matched + * rule identifier, matched text, and SPDX license key. + * @param spdxId the spdxId of a single license or Exception + * @param licenseCurations s a list of {@link LicenseCuration} objects that may contain rules for curating license + * data. + * @return a {@link LicenseCuration.NewLicenseData} object containing the effective license information after applying + * the curation. If no applicable curation is found or if the curation list is {@code null}, a new + * {@link LicenseCuration.NewLicenseData} instance with all members being {@code null} is returned, indicating + * no change. + */ + private LicenseCuration.NewLicenseData getEffectiveLicenseInfoWithCuration(String path, JsonNode ma, String spdxId, + List licenseCurations) { + + if (licenseCurations == null) { + // NewLicenseData with all members being null indicates: no change + return new LicenseCuration.NewLicenseData(); + } + + String ruleIdentifier = ma.get("rule_identifier").asText(); + String matchedText = ma.get("matched_text").asText(); + + for (LicenseCuration rule : licenseCurations) { + if (rule.matches(path, ruleIdentifier, matchedText, spdxId)) { + LicenseCuration.NewLicenseData result = rule.newLicenseData(); + if (LOG.isDebugEnabled()) { + if (result == null) { + LOG.debug("License finding of rule '{}' in '{}' will be ignored due to remove license curation", + ruleIdentifier, path); + } else { + LOG.debug("License finding of rule '{}' in '{}' will be replaced by SPDX-ID '{}' and URL '{}'", + ruleIdentifier, path, result.license, result.url); + + } + } + return result; + } + } + // NewLicenseData with all members being null indicates: no change + return new LicenseCuration.NewLicenseData(); + } + + /** + * Adds license entries due to curations. + * + * @param packageUrl + * @param path + * @param licenseCurations + * @param componentScancodeInfos + */ + private void addLicensesByCuration(String packageUrl, String path, List licenseCurations, + ScancodeComponentInfo componentScancodeInfos) { + + if (licenseCurations == null) { + // no curations available: return empty collection + return; + } + + for (LicenseCuration rule : licenseCurations) { + if (rule.matches(path)) { + if (rule.getOperation() == CurationOperation.ADD) { + LicenseCuration.NewLicenseData license = rule.newLicenseData(); + if (LOG.isDebugEnabled()) { + LOG.debug( + "License finding with SPDX-ID '{}' and url '{}' in '{}' will be added due to ADD copyright curation", + license.license, license.url, path); + } + String licenseUrl = normalizeLicenseUrl(packageUrl, license.url); + String givenLicenseText = this.fileScancodeRawComponentInfoProvider.retrieveContent(packageUrl, licenseUrl); + + componentScancodeInfos.getComponentInfoData().addLicense(license.license, license.license, license.url, 100, + licenseUrl, givenLicenseText, Integer.MAX_VALUE); + componentScancodeInfos.setDataStatus(DataStatusValue.CURATED); + } else { + throw new IllegalStateException("This seems to be a bug"); + } + } + } + } + + /** + * Gets the effective copyright after possibly applying curations for a single copyright finding. + * + * @param path the path of the file or component for which the copyright curation is applied + * @param copyright the original copyright information + * @param copyrightCurations a list of copyright curation rules to be applied + * @return the effective copyright string after applying curations + */ + private String getEffectiveCopyrightWithCuration(String path, String copyright, + List copyrightCurations) { + + if (copyrightCurations == null) { + // no curations available: return the original copyright + return copyright; + } + + for (CopyrightCuration rule : copyrightCurations) { + if (rule.matches(path, copyright)) { + if (rule.getOperation() == CurationOperation.REMOVE) { + if (LOG.isDebugEnabled()) { + LOG.debug("Copyright finding '{}' in '{}' will be ignored due to remove copyright curation", copyright, + path); + } + return null; + } + if (rule.getOperation() == CurationOperation.REPLACE) { + if (LOG.isDebugEnabled()) { + LOG.debug("Copyright finding '{}' in '{}' will be ignored due to remove copyright curation", copyright, + path); + } + return rule.getNewCopyright(); + } + throw new IllegalStateException("This seems to be a bug"); + } + } + // no curations applied: return the original copyright + return copyright; + } + + /** + * Adds copyrights entries due to curations. + * + * @param path + * @param copyrightCurations + * @param componentScancodeInfos + */ + private void addCopyrightsByCuration(String path, List copyrightCurations, + ScancodeComponentInfo componentScancodeInfos) { + + if (copyrightCurations == null) { + // no curations available: return empty collection + return; + } + + for (CopyrightCuration rule : copyrightCurations) { + if (rule.matches(path)) { + if (rule.getOperation() == CurationOperation.ADD) { + String copyrightToBeAdded = rule.getNewCopyright(); + if (LOG.isDebugEnabled()) { + LOG.debug("Copyright finding '{}' in '{}' will be added due to ADD copyright curation", copyrightToBeAdded, + path); + } + componentScancodeInfos.getComponentInfoData().addCopyright(copyrightToBeAdded); + componentScancodeInfos.setDataStatus(DataStatusValue.CURATED); + } else { + throw new IllegalStateException("This seems to be a bug"); + } + } + } + } + + /** + * Adjustment of license paths/urls so that they might retrieved + * + * @param packageUrl package url of the package + * @param licenseUrl the original path or URL + * @return the adjusted path or url as a url + */ + private String normalizeLicenseUrl(String packageUrl, String licenseUrl) { + + String adjustedLicenseUrl = licenseUrl; + if (licenseUrl != null) { + if (licenseUrl.startsWith("http")) { + adjustedLicenseUrl = licenseUrl.replace( + "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses", + "https://scancode-licensedb.aboutcode.org"); + adjustedLicenseUrl = adjustedLicenseUrl.replace("github.com", "raw.github.com").replace("/tree", ""); + } else if (this.fileScancodeRawComponentInfoProvider.isLocalContentPath(packageUrl, licenseUrl)) { + adjustedLicenseUrl = this.fileScancodeRawComponentInfoProvider.pkgContentUriFromPath(packageUrl, licenseUrl); + LOG.debug("LOCAL LICENSE: " + licenseUrl); + } + } + return adjustedLicenseUrl; + } + + /** + * Check if the given path prefix is excluded in the curation. + * + * @param path in the scancode data + * @param excludedPaths all excluded paths defined in the curation + * @return true if path prefix is excluded in curation + */ + private boolean isExcluded(String path, List excludedPaths) { + + if (excludedPaths != null) { + for (String excludedPath : excludedPaths) { + if (path.startsWith(excludedPath)) { + return true; + } + } + } + return false; + } + +} diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeVersionComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeVersionComponentInfoProvider.java new file mode 100644 index 00000000..9507aca8 --- /dev/null +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeVersionComponentInfoProvider.java @@ -0,0 +1,39 @@ +package com.devonfw.tools.solicitor.componentinfo.scancode; + +import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoProvider; +import com.devonfw.tools.solicitor.componentinfo.CurationDataHandle; +import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; +import com.fasterxml.jackson.databind.JsonNode; + +/** + * A {@link ComponentInfoProvider} which provides filtered {@link ComponentInfo}s based on Scancode data of a specific + * scancode tool version. + * + */ +public interface FilteredScancodeVersionComponentInfoProvider { + + /** + * Checks if the given tool version is accepted by this provider. + * + * @param toolVersion the version of the tool + * @return true if the version is accepted, false otherwise + */ + boolean accept(String toolVersion); + + /** + * Retrieves the component information for a package identified by the given package URL. + * + * @param packageUrl the identifier of the package for which information is requested + * @param curationDataHandle identifies which source should be used for the curation data + * @param rawScancodeData the raw scancode data + * @param scancodeJson the parsed scancode JSON + * @return the data for the component + * @throws ComponentInfoAdapterException if there was an exception when reading the data + * @throws CurationInvalidException if the curation data is not valid + */ + ComponentInfo getComponentInfo(String packageUrl, CurationDataHandle curationDataHandle, + ScancodeRawComponentInfo rawScancodeData, JsonNode scancodeJson) + throws ComponentInfoAdapterException, CurationInvalidException; +} \ No newline at end of file diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/MultiversionFilteredScancodeComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/MultiversionFilteredScancodeComponentInfoProvider.java new file mode 100644 index 00000000..e7a6beff --- /dev/null +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/MultiversionFilteredScancodeComponentInfoProvider.java @@ -0,0 +1,117 @@ +package com.devonfw.tools.solicitor.componentinfo.scancode; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; +import com.devonfw.tools.solicitor.componentinfo.CurationDataHandle; +import com.devonfw.tools.solicitor.componentinfo.DataStatusValue; +import com.devonfw.tools.solicitor.componentinfo.DefaultComponentInfoImpl; +import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; +import com.devonfw.tools.solicitor.componentinfo.curation.FilteredComponentInfoProvider; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +/** + * A provider that filters and retrieves component information based on Scancode results for multiple versions. This + * component utilizes different {@link FilteredScancodeVersionComponentInfoProvider} implementations depending on the + * version of the Scancode tool used. + */ +@Component +public class MultiversionFilteredScancodeComponentInfoProvider implements FilteredComponentInfoProvider { + + private static final ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); + + private FilteredScancodeVersionComponentInfoProvider[] filteredScancodeVersionComponentInfoProviders; + + private ScancodeRawComponentInfoProvider rawComponentInfoProvider; + + /** + * Constructs a {@link MultiversionFilteredScancodeComponentInfoProvider} with the given providers. + * + * @param filteredScancodeVersionComponentInfoProviders the array of + * {@link FilteredScancodeVersionComponentInfoProvider} implementations to use based on Scancode tool versions. + * @param rawComponentInfoProvider the {@link ScancodeRawComponentInfoProvider} for reading raw Scancode data. + */ + @Autowired + public MultiversionFilteredScancodeComponentInfoProvider( + FilteredScancodeVersionComponentInfoProvider[] filteredScancodeVersionComponentInfoProviders, + ScancodeRawComponentInfoProvider rawComponentInfoProvider) { + + this.filteredScancodeVersionComponentInfoProviders = filteredScancodeVersionComponentInfoProviders; + this.rawComponentInfoProvider = rawComponentInfoProvider; + } + + @Override + public ComponentInfo getComponentInfo(String packageUrl, CurationDataHandle curationDataHandle) + throws ComponentInfoAdapterException, CurationInvalidException { + + ScancodeRawComponentInfo rawScancodeData; + JsonNode scancodeJson; + + try { + rawScancodeData = this.rawComponentInfoProvider.readScancodeData(packageUrl); + } catch (ScancodeProcessingFailedException e) { + return new DefaultComponentInfoImpl(packageUrl, DataStatusValue.PROCESSING_FAILED); + } + if (rawScancodeData == null) { + return new DefaultComponentInfoImpl(packageUrl, DataStatusValue.NOT_AVAILABLE); + } + + scancodeJson = parseScancodeJson(rawScancodeData); + String toolVersion = extractToolVersion(scancodeJson); + + for (FilteredScancodeVersionComponentInfoProvider candidate : this.filteredScancodeVersionComponentInfoProviders) { + if (candidate.accept(toolVersion)) { + return candidate.getComponentInfo(packageUrl, curationDataHandle, rawScancodeData, scancodeJson); + } + } + + throw new ComponentInfoAdapterException( + "No suitable FilteredScancodeVersionComponentInfoProvider for given scancode JSON"); + } + + /** + * Parses the Scancode JSON data from the raw component information. + * + * @param rawScancodeData the raw Scancode data containing JSON results. + * @return the parsed {@link JsonNode} from the Scancode JSON data. + * @throws ComponentInfoAdapterException if an error occurs while parsing the JSON data. + */ + private JsonNode parseScancodeJson(ScancodeRawComponentInfo rawScancodeData) throws ComponentInfoAdapterException { + + try { + return mapper.readTree(rawScancodeData.rawScancodeResult); + } catch (JsonProcessingException e) { + throw new ComponentInfoAdapterException("Could not parse Scancode JSON", e); + } + } + + /** + * Extracts the tool version from the Scancode JSON data. + * + * @param scancodeJson the parsed Scancode JSON data. + * @return the tool version as a {@link String}. + * @throws ComponentInfoAdapterException if an error occurs while extracting the tool version. + */ + private String extractToolVersion(JsonNode scancodeJson) throws ComponentInfoAdapterException { + + JsonNode headers = scancodeJson.get("headers"); + if (headers == null || !headers.isArray() || headers.size() == 0) { + throw new ComponentInfoAdapterException("Headers not found in Scancode JSON"); + } + JsonNode firstHeader = headers.get(0); + if (firstHeader == null) { + throw new ComponentInfoAdapterException("First header not found in Scancode JSON"); + } + JsonNode toolVersionNode = firstHeader.get("tool_version"); + if (toolVersionNode == null) { + throw new ComponentInfoAdapterException("Tool version not found in Scancode JSON"); + } + return toolVersionNode.asText(); + + } +} \ No newline at end of file diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java index 151acd8c..9293ada4 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java @@ -33,7 +33,8 @@ public class ScancodeComponentInfoAdapter extends CuratingComponentInfoAdapter { * @param componentInfoCurator the curator to use */ @Autowired - public ScancodeComponentInfoAdapter(FilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider, + public ScancodeComponentInfoAdapter( + MultiversionFilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider, ComponentInfoCurator componentInfoCurator) { super(filteredScancodeComponentInfoProvider, componentInfoCurator); diff --git a/core/src/main/resources/application.properties b/core/src/main/resources/application.properties index ffd53a77..1bb57763 100644 --- a/core/src/main/resources/application.properties +++ b/core/src/main/resources/application.properties @@ -54,6 +54,8 @@ solicitor.scancode.automapping.blacklistpatterns=.*unknown.*,.*proprietary.* solicitor.scancode.automapping.ignorelistpatterns= ## Parameters for controlling the processing of scancode information +# the name of the file which contains the scancode data +#solicitor.scancode.file-name=scancode.json # minimum score of detected license findings to be taken into account for Solicitor processing solicitor.scancode.min-license-score=90.0 # minimum number of lines of detected license text for a file to be possibly taken as license text diff --git a/core/src/main/resources/com/devonfw/tools/solicitor/templates/ScancodeScanScript.vm b/core/src/main/resources/com/devonfw/tools/solicitor/templates/ScancodeScanScript.vm index 2cb0d707..0b293217 100644 --- a/core/src/main/resources/com/devonfw/tools/solicitor/templates/ScancodeScanScript.vm +++ b/core/src/main/resources/com/devonfw/tools/solicitor/templates/ScancodeScanScript.vm @@ -1,4 +1,4 @@ -scancodeoptions="--processes 16 --copyright --only-findings --license --license-text --consolidate" +scancodeoptions="--processes 16 --copyright --only-findings --license --license-text --license-references --consolidate" beginning=$(pwd) mkdir scancodeOutput so=$(pwd)/scancodeOutput diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV31ComponentInfoProviderTest.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV31ComponentInfoProviderTest.java new file mode 100644 index 00000000..561c8cac --- /dev/null +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV31ComponentInfoProviderTest.java @@ -0,0 +1,170 @@ +package com.devonfw.tools.solicitor.componentinfo.scancode; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.devonfw.tools.solicitor.common.packageurl.AllKindsPackageURLHandler; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; +import com.devonfw.tools.solicitor.componentinfo.SelectorCurationDataHandle; +import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; +import com.devonfw.tools.solicitor.componentinfo.curation.SingleFileCurationProvider; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * This class contains JUnit test methods for the {@link FilteredScancodeV31ComponentInfoProvider} class. + */ +public class FilteredScancodeV31ComponentInfoProviderTest { + + // the object under test + FilteredScancodeV31ComponentInfoProvider filteredScancodeV31ComponentInfoProvider; + + FileScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; + + SingleFileCurationProvider singleFileCurationProvider; + + @BeforeEach + public void setup() { + + AllKindsPackageURLHandler packageURLHandler = Mockito.mock(AllKindsPackageURLHandler.class); + + Mockito.when(packageURLHandler.pathFor("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0")) + .thenReturn("pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0"); + + this.fileScancodeRawComponentInfoProvider = new FileScancodeRawComponentInfoProvider(packageURLHandler); + this.fileScancodeRawComponentInfoProvider.setRepoBasePath("src/test/resources/scancodefileadapter/Source/repo"); + this.fileScancodeRawComponentInfoProvider.setScancodeFileName("scancodeV31.json"); + + this.singleFileCurationProvider = new SingleFileCurationProvider(packageURLHandler); + this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); + + this.filteredScancodeV31ComponentInfoProvider = new FilteredScancodeV31ComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, this.singleFileCurationProvider); + + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String,String,ScancodeRawComponentInfo,JsonNode)} + * method when no curations file exists + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException if the curation data is not valid + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoWithoutCurations() throws ComponentInfoAdapterException, CurationInvalidException, + ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/nonexisting.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeV31ComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + scancodeComponentInfo.getPackageUrl()); + assertEquals("This is a dummy notice file for testing. Code is under Apache-2.0.", + scancodeComponentInfo.getComponentInfoData().getNoticeFileContent()); + assertEquals(1, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertEquals("Copyright 2023 devonfw", scancodeComponentInfo.getComponentInfoData().getCopyrights().toArray()[0]); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String,String,ScancodeRawComponentInfo,JsonNode)} + * method when the /src directory is excluded + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException if the curation data is not valid + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoWithCurationsAndExclusions() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/curations_with_exclusions.yaml"); + + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + // when + ComponentInfo scancodeComponentInfo = this.filteredScancodeV31ComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + scancodeComponentInfo.getPackageUrl()); + assertEquals("This is a dummy notice file for testing. Code is under Apache-2.0.", + scancodeComponentInfo.getComponentInfoData().getNoticeFileContent()); + assertEquals(0, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); // since the copyright is + // found under + // /src/../SampleClass.java1, it will be excluded + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String,String,ScancodeRawComponentInfo,JsonNode)} + * method when curations exist but no paths are excluded + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException if the curation data is not valid + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoWithCurationsAndWithoutExclusions() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); + + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + // when + ComponentInfo scancodeComponentInfo = this.filteredScancodeV31ComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + scancodeComponentInfo.getPackageUrl()); + assertEquals("This is a dummy notice file for testing. Code is under Apache-2.0.", + scancodeComponentInfo.getComponentInfoData().getNoticeFileContent()); + assertEquals(1, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertEquals("Copyright 2023 devonfw", scancodeComponentInfo.getComponentInfoData().getCopyrights().toArray()[0]); // The + // copyright + // curation does not + // apply on the + // scancodeComponentInfo + // object. + } +} diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProviderTests.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV32ComponentInfoProviderTest.java similarity index 59% rename from core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProviderTests.java rename to core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV32ComponentInfoProviderTest.java index 5e95bb00..0fbf350e 100644 --- a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProviderTests.java +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeV32ComponentInfoProviderTest.java @@ -13,14 +13,18 @@ import com.devonfw.tools.solicitor.componentinfo.SelectorCurationDataHandle; import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; import com.devonfw.tools.solicitor.componentinfo.curation.SingleFileCurationProvider; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; /** - * This class contains JUnit test methods for the {@link FilteredScancodeComponentInfoProvider} class. + * This class contains JUnit test methods for the {@link FilteredScancodeV31ComponentInfoProvider} class. */ -public class FilteredScancodeComponentInfoProviderTests { +public class FilteredScancodeV32ComponentInfoProviderTest { // the object under test - FilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider; + FilteredScancodeV32ComponentInfoProvider filteredScancodeV32ComponentInfoProvider; FileScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; @@ -40,28 +44,37 @@ public void setup() { this.singleFileCurationProvider = new SingleFileCurationProvider(packageURLHandler); this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); - this.filteredScancodeComponentInfoProvider = new FilteredScancodeComponentInfoProvider( - this.fileScancodeRawComponentInfoProvider, packageURLHandler, this.singleFileCurationProvider); + this.filteredScancodeV32ComponentInfoProvider = new FilteredScancodeV32ComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, this.singleFileCurationProvider); } /** - * Test the {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String,String)} method when no curations - * file exists + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String,String,ScancodeRawComponentInfo,JsonNode)} + * method when no curations file exists * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException if the curation data is not valid + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoWithoutCurations() throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoWithoutCurations() throws ComponentInfoAdapterException, CurationInvalidException, + ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/nonexisting.yaml"); // when - ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeV32ComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -74,23 +87,32 @@ public void testGetComponentInfoWithoutCurations() throws ComponentInfoAdapterEx } /** - * Test the {@link ScancodeComponentInfoAdapter#getComponentInfo(String,String)} method when the /src directory is - * excluded + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String,String,ScancodeRawComponentInfo,JsonNode)} + * method when the /src directory is excluded * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException if the curation data is not valid + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoWithCurationsAndExclusions() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoWithCurationsAndExclusions() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/curations_with_exclusions.yaml"); + + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + // when - ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + ComponentInfo scancodeComponentInfo = this.filteredScancodeV32ComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -104,23 +126,31 @@ public void testGetComponentInfoWithCurationsAndExclusions() } /** - * Test the {@link ScancodeComponentInfoAdapter#getComponentInfo(String,String)} method when curations exist but no - * paths are excluded + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String,String,ScancodeRawComponentInfo,JsonNode)} + * method when curations exist but no paths are excluded * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException if the curation data is not valid + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoWithCurationsAndWithoutExclusions() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoWithCurationsAndWithoutExclusions() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + // when - ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + ComponentInfo scancodeComponentInfo = this.filteredScancodeV32ComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/MultiversionFilteredScancodeComponentInfoProviderTest.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/MultiversionFilteredScancodeComponentInfoProviderTest.java new file mode 100644 index 00000000..ef18d950 --- /dev/null +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/MultiversionFilteredScancodeComponentInfoProviderTest.java @@ -0,0 +1,183 @@ +package com.devonfw.tools.solicitor.componentinfo.scancode; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; +import com.devonfw.tools.solicitor.componentinfo.CurationDataHandle; +import com.devonfw.tools.solicitor.componentinfo.DataStatusValue; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Unit test for {@link MultiversionFilteredScancodeComponentInfoProvider}. + * + * This test class verifies the behavior of the {@link MultiversionFilteredScancodeComponentInfoProvider} class, + * ensuring it correctly delegates component information retrieval to the appropriate version-specific provider based on + * the version of the Scancode data provided. + */ +public class MultiversionFilteredScancodeComponentInfoProviderTest { + + @Mock + private FilteredScancodeV31ComponentInfoProvider filteredScancodeV31Provider; + + @Mock + private FilteredScancodeV32ComponentInfoProvider filteredScancodeV32Provider; + + @Mock + private ScancodeRawComponentInfoProvider rawComponentInfoProvider; + + private MultiversionFilteredScancodeComponentInfoProvider provider; + + private ObjectMapper mapper = new ObjectMapper(); + + /** + * Sets up the test environment by initializing mocks and the + * {@link MultiversionFilteredScancodeComponentInfoProvider} instance. + */ + @BeforeEach + void setUp() { + + MockitoAnnotations.openMocks(this); + when(this.filteredScancodeV31Provider.accept("31.2.6")).thenReturn(true); + when(this.filteredScancodeV31Provider.accept("32.1.0")).thenReturn(false); + when(this.filteredScancodeV31Provider.accept("99.1.0")).thenReturn(false); + when(this.filteredScancodeV32Provider.accept("31.2.6")).thenReturn(false); + when(this.filteredScancodeV32Provider.accept("32.1.0")).thenReturn(true); + when(this.filteredScancodeV32Provider.accept("99.1.0")).thenReturn(false); + this.provider = new MultiversionFilteredScancodeComponentInfoProvider( + new FilteredScancodeVersionComponentInfoProvider[] { this.filteredScancodeV31Provider, + this.filteredScancodeV32Provider }, this.rawComponentInfoProvider); + } + + /** + * Loads JSON data from a file located in the test resources directory. + * + * @param fileName the name of the file to load + * @return the JSON data as a string + * @throws IOException if an error occurs while reading the file + */ + private String loadJsonData(String fileName) throws IOException { + + return new String(Files.readAllBytes(Paths.get("src/test/resources/scancode/" + fileName))); + } + + /** + * Tests the {@link MultiversionFilteredScancodeComponentInfoProvider#getComponentInfo} method when version 31 is + * used. + * + * @throws Exception if an error occurs during the test + */ + @Test + void testGetComponentInfoVersion31() throws Exception { + + String packageUrl = "pkg:maven/com.mycompany/mycomponent@1.0.0"; + CurationDataHandle curationDataHandle = mock(CurationDataHandle.class); + + String jsonData = loadJsonData("scancode_v31.json"); + ScancodeRawComponentInfo rawScancodeData = new ScancodeRawComponentInfo(); + rawScancodeData.rawScancodeResult = jsonData; + + JsonNode scancodeJson = this.mapper.readTree(rawScancodeData.rawScancodeResult); + + when(this.rawComponentInfoProvider.readScancodeData(packageUrl)).thenReturn(rawScancodeData); + when(this.filteredScancodeV31Provider.getComponentInfo(eq(packageUrl), eq(curationDataHandle), any(), any())) + .thenReturn(mock(ComponentInfo.class)); + + ComponentInfo result = this.provider.getComponentInfo(packageUrl, curationDataHandle); + + assertNotNull(result); + verify(this.filteredScancodeV31Provider).getComponentInfo(eq(packageUrl), eq(curationDataHandle), any(), any()); + } + + /** + * Tests the {@link MultiversionFilteredScancodeComponentInfoProvider#getComponentInfo} method when version 32 is + * used. + * + * @throws Exception if an error occurs during the test + */ + @Test + void testGetComponentInfoVersion32() throws Exception { + + String packageUrl = "pkg:maven/com.mycompany/mycomponent@1.0.0"; + CurationDataHandle curationDataHandle = mock(CurationDataHandle.class); + + String jsonData = loadJsonData("scancode_v32.json"); + ScancodeRawComponentInfo rawScancodeData = new ScancodeRawComponentInfo(); + rawScancodeData.rawScancodeResult = jsonData; + + // JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + when(this.rawComponentInfoProvider.readScancodeData(packageUrl)).thenReturn(rawScancodeData); + when(this.filteredScancodeV32Provider.getComponentInfo(eq(packageUrl), eq(curationDataHandle), any(), any())) + .thenReturn(mock(ComponentInfo.class)); + + ComponentInfo result = this.provider.getComponentInfo(packageUrl, curationDataHandle); + + assertNotNull(result); + verify(this.filteredScancodeV32Provider).getComponentInfo(eq(packageUrl), eq(curationDataHandle), any(), any()); + } + + /** + * Tests the {@link MultiversionFilteredScancodeComponentInfoProvider#getComponentInfo} method when an unsupported + * version is used. + * + * @throws Exception if an error occurs during the test + */ + @Test + void testGetComponentInfoVersionNotSupported() throws Exception { + + String packageUrl = "pkg:maven/com.mycompany/mycomponent@1.0.0"; + CurationDataHandle curationDataHandle = mock(CurationDataHandle.class); + + String jsonData = loadJsonData("scancode_v99.json"); + ScancodeRawComponentInfo rawScancodeData = new ScancodeRawComponentInfo(); + rawScancodeData.rawScancodeResult = jsonData; + + when(this.rawComponentInfoProvider.readScancodeData(packageUrl)).thenReturn(rawScancodeData); + + assertThrows(ComponentInfoAdapterException.class, () -> { + this.provider.getComponentInfo(packageUrl, curationDataHandle); + }); + } + + /** + * This test ensures that the provider returns a {@link ComponentInfo} with a {@link DataStatusValue#NOT_AVAILABLE} + * status if the raw Scancode data is null. + * + * @throws Exception if an error occurs during the test + */ + @Test + void testGetComponentInfoScancodeDataNull() throws Exception { + + // Arrange + String packageUrl = "pkg:maven/com.mycompany/mycomponent@1.0.0"; + CurationDataHandle curationDataHandle = mock(CurationDataHandle.class); + + when(this.rawComponentInfoProvider.readScancodeData(packageUrl)).thenReturn(null); + + // Act + ComponentInfo result = this.provider.getComponentInfo(packageUrl, curationDataHandle); + + // Assert + assertNotNull(result); + assertEquals(DataStatusValue.NOT_AVAILABLE, result.getDataStatus()); + } + +} diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTestV31.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTestV31.java new file mode 100644 index 00000000..45c9082b --- /dev/null +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTestV31.java @@ -0,0 +1,791 @@ +package com.devonfw.tools.solicitor.componentinfo.scancode; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.devonfw.tools.solicitor.common.packageurl.AllKindsPackageURLHandler; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; +import com.devonfw.tools.solicitor.componentinfo.DataStatusValue; +import com.devonfw.tools.solicitor.componentinfo.LicenseInfo; +import com.devonfw.tools.solicitor.componentinfo.SelectorCurationDataHandle; +import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; +import com.devonfw.tools.solicitor.componentinfo.curation.SingleFileCurationProvider; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * This class contains JUnit test methods for the testing the raw curations of + * {@link FilteredScancodeV31ComponentInfoProvider} class. + */ + +public class RawCurationTestV31 { + + // the object under test + FilteredScancodeV31ComponentInfoProvider filteredScancodeComponentInfoProvider; + + FileScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; + + SingleFileCurationProvider singleFileCurationProvider; + + @BeforeEach + public void setup() { + + AllKindsPackageURLHandler packageURLHandler = Mockito.mock(AllKindsPackageURLHandler.class); + Mockito.when(packageURLHandler.pathFor("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0")) + .thenReturn("pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0"); + + this.fileScancodeRawComponentInfoProvider = new FileScancodeRawComponentInfoProvider(packageURLHandler); + this.fileScancodeRawComponentInfoProvider.setRepoBasePath("src/test/resources/scancodefileadapter/Source/repo"); + + this.singleFileCurationProvider = new SingleFileCurationProvider(packageURLHandler); + this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); + + this.filteredScancodeComponentInfoProvider = new FilteredScancodeV31ComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, this.singleFileCurationProvider); + + this.fileScancodeRawComponentInfoProvider.setScancodeFileName("scancodeV31.json"); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_1.yaml"); + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(1, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + assertEquals("Apache-2.0", + scancodeComponentInfo.getComponentInfoData().getLicenses().iterator().next().getSpdxid()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndPathNotMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_2.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndRuleIdentifierNotMet() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_3.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + */ + @Test + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndOldLicenseNotMet() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_4.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndMatchedTextNotMet() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_5.yaml"); + + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseRemove_OnlyPathConditionSetAndMetForAllFiles() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_7.yaml"); + + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(0, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + + @Test + public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_replace_curation_1.yaml"); + + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + boolean found = false; + for (LicenseInfo license : scancodeComponentInfo.getComponentInfoData().getLicenses()) { + if (license.getSpdxid().equals("NewLicense")) { + found = true; + assertEquals("pkgcontent:/src/main/java/com/devonfw/tools/test/SampleClass2.java#L3", license.getLicenseUrl()); + assertTrue(license.getGivenLicenseText() + .startsWith(" * This file is part of the test data for deep license scan support in Solicitor..")); + } + } + assertTrue(found); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMetOnlyLicenseReplaced() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_replace_curation_2.yaml"); + + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + boolean found = false; + for (LicenseInfo license : scancodeComponentInfo.getComponentInfoData().getLicenses()) { + if (license.getSpdxid().equals("NewLicense")) { + found = true; + assertEquals("pkgcontent:/src/main/java/com/devonfw/tools/test/SampleClass2.java#L4", license.getLicenseUrl()); + assertTrue(license.getGivenLicenseText() + .startsWith(" * It is licensed under the same license as the rest of Solicitor.")); + } + } + assertTrue(found); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws JsonProcessingException + * @throws JsonMappingException + * @throws ScancodeProcessingFailedException + */ + @Test + public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMetOnlyUrlReplaced() + throws ComponentInfoAdapterException, CurationInvalidException, JsonMappingException, JsonProcessingException, + ScancodeProcessingFailedException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_replace_curation_3.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + boolean found = false; + for (LicenseInfo license : scancodeComponentInfo.getComponentInfoData().getLicenses()) { + if (license.getSpdxid().equals("LicenseRef-scancode-unknown-license-reference")) { + found = true; + assertEquals("pkgcontent:/src/main/java/com/devonfw/tools/test/SampleClass2.java#L3", license.getLicenseUrl()); + assertTrue(license.getGivenLicenseText() + .startsWith(" * This file is part of the test data for deep license scan support in Solicitor..")); + } + } + assertTrue(found); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseAdd_WithPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_add_curation_1.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(3, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + boolean found = false; + for (LicenseInfo license : scancodeComponentInfo.getComponentInfoData().getLicenses()) { + if (license.getSpdxid().equals("NewLicense")) { + found = true; + assertEquals("pkgcontent:/src/main/java/com/devonfw/tools/test/SampleClass2.java#L3", license.getLicenseUrl()); + assertTrue(license.getGivenLicenseText() + .startsWith(" * This file is part of the test data for deep license scan support in Solicitor..")); + } + } + assertTrue(found); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseAdd_WithoutPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_add_curation_2.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(3, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + boolean found = false; + for (LicenseInfo license : scancodeComponentInfo.getComponentInfoData().getLicenses()) { + if (license.getSpdxid().equals("NewLicense")) { + found = true; + assertEquals("pkgcontent:/src/main/java/com/devonfw/tools/test/SampleClass2.java#L3", license.getLicenseUrl()); + assertTrue(license.getGivenLicenseText() + .startsWith(" * This file is part of the test data for deep license scan support in Solicitor..")); + } + } + assertTrue(found); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseAdd_WithPathNotMatching() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_add_curation_3.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawCopyrightRemove_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_1.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(0, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawCopyrightRemove_AllConditionsSetAndPathNotMet() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_2.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(1, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertEquals("Copyright 2023 devonfw", + scancodeComponentInfo.getComponentInfoData().getCopyrights().iterator().next()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndOldCopyrightNotMet() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_4.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(1, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertEquals("Copyright 2023 devonfw", + scancodeComponentInfo.getComponentInfoData().getCopyrights().iterator().next()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawCopyrightRemove_OnlyPathConditionSetAndMetForAllFiles() + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_7.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(0, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawCopyrightReplace_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_replace_curation_1.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(1, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertEquals("(c) 2023 devonfw", scancodeComponentInfo.getComponentInfoData().getCopyrights().iterator().next()); + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawCopyrightAdd_WithPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_add_curation_1.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertTrue(scancodeComponentInfo.getComponentInfoData().getCopyrights().contains("(c) 2024 devonfw")); + assertTrue(scancodeComponentInfo.getComponentInfoData().getCopyrights().contains("Copyright 2023 devonfw")); + + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawCopyrightAdd_WithoutPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_add_curation_2.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(2, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertTrue(scancodeComponentInfo.getComponentInfoData().getCopyrights().contains("(c) 2024 devonfw")); + assertTrue(scancodeComponentInfo.getComponentInfoData().getCopyrights().contains("Copyright 2023 devonfw")); + + } + + /** + * Test the + * {@link FilteredScancodeV31ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * + * + * @throws ComponentInfoAdapterException if something goes wrong + * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + @Test + public void testGetComponentInfoRawCopyrightAdd_WithPathNotMatching() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_add_curation_3.yaml"); + + // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); + + // then + assertNotNull(scancodeComponentInfo.getComponentInfoData()); + assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); + assertEquals(1, scancodeComponentInfo.getComponentInfoData().getCopyrights().size()); + assertTrue(scancodeComponentInfo.getComponentInfoData().getCopyrights().contains("Copyright 2023 devonfw")); + + } + +} diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTest.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTestV32.java similarity index 58% rename from core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTest.java rename to core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTestV32.java index d749c27d..0ca25ef6 100644 --- a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTest.java +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/RawCurationTestV32.java @@ -17,15 +17,20 @@ import com.devonfw.tools.solicitor.componentinfo.SelectorCurationDataHandle; import com.devonfw.tools.solicitor.componentinfo.curation.CurationInvalidException; import com.devonfw.tools.solicitor.componentinfo.curation.SingleFileCurationProvider; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; /** * This class contains JUnit test methods for the testing the raw curations of - * {@link FilteredScancodeComponentInfoProvider} class. + * {@link FilteredScancodeV32ComponentInfoProvider} class. */ -public class RawCurationTest { + +public class RawCurationTestV32 { // the object under test - FilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider; + FilteredScancodeV32ComponentInfoProvider filteredScancodeComponentInfoProvider; FileScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; @@ -35,7 +40,6 @@ public class RawCurationTest { public void setup() { AllKindsPackageURLHandler packageURLHandler = Mockito.mock(AllKindsPackageURLHandler.class); - Mockito.when(packageURLHandler.pathFor("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0")) .thenReturn("pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0"); @@ -45,33 +49,37 @@ public void setup() { this.singleFileCurationProvider = new SingleFileCurationProvider(packageURLHandler); this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); - this.filteredScancodeComponentInfoProvider = new FilteredScancodeComponentInfoProvider( - this.fileScancodeRawComponentInfoProvider, packageURLHandler, this.singleFileCurationProvider); + this.filteredScancodeComponentInfoProvider = new FilteredScancodeV32ComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, this.singleFileCurationProvider); } /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndMet() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { - // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_1.yaml"); - // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); - // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); assertEquals(1, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); @@ -81,26 +89,31 @@ public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndMet() /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndPathNotMet() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndPathNotMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { - // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_2.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); - // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); @@ -108,26 +121,32 @@ public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndPathNotMet() /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndRuleIdentifierNotMet() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { - // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_3.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); - // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); @@ -135,7 +154,7 @@ public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndRuleIdentifi /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong @@ -143,18 +162,21 @@ public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndRuleIdentifi */ @Test public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndOldLicenseNotMet() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { - // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_4.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); - // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); @@ -162,26 +184,31 @@ public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndOldLicenseNo /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndMatchedTextNotMet() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { - // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_5.yaml"); - // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); - // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); @@ -189,26 +216,31 @@ public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndMatchedTextN /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test public void testGetComponentInfoRawLicenseRemove_OnlyPathConditionSetAndMetForAllFiles() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { - // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_remove_curation_7.yaml"); - // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); - // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); assertEquals(0, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); @@ -216,24 +248,30 @@ public void testGetComponentInfoRawLicenseRemove_OnlyPathConditionSetAndMetForAl /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ + @Test - public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMet() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { - // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_replace_curation_1.yaml"); - // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -253,24 +291,31 @@ public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMet() /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMetOnlyLicenseReplaced() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_replace_curation_2.yaml"); - // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -290,24 +335,32 @@ public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMetOnlyLice /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws JsonProcessingException + * @throws JsonMappingException + * @throws ScancodeProcessingFailedException */ @Test public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMetOnlyUrlReplaced() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, JsonMappingException, JsonProcessingException, + ScancodeProcessingFailedException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_replace_curation_3.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -323,29 +376,35 @@ public void testGetComponentInfoRawLicenseReplace_AllConditionsSetAndMetOnlyUrlR } } assertTrue(found); - } /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawLicenseAdd_WithPath() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawLicenseAdd_WithPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_add_curation_1.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -361,29 +420,35 @@ public void testGetComponentInfoRawLicenseAdd_WithPath() } } assertTrue(found); - } /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawLicenseAdd_WithoutPath() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawLicenseAdd_WithoutPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_add_curation_2.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -399,57 +464,69 @@ public void testGetComponentInfoRawLicenseAdd_WithoutPath() } } assertTrue(found); - } /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawLicenseAdd_WithPathNotMatching() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawLicenseAdd_WithPathNotMatching() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/license_add_curation_3.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertNotEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); assertEquals(2, scancodeComponentInfo.getComponentInfoData().getLicenses().size()); - } /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawCopyrightRemove_AllConditionsSetAndMet() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawCopyrightRemove_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_1.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -459,24 +536,32 @@ public void testGetComponentInfoRawCopyrightRemove_AllConditionsSetAndMet() /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test public void testGetComponentInfoRawCopyrightRemove_AllConditionsSetAndPathNotMet() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_2.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -488,24 +573,32 @@ public void testGetComponentInfoRawCopyrightRemove_AllConditionsSetAndPathNotMet /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndOldCopyrightNotMet() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_4.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -517,24 +610,32 @@ public void testGetComponentInfoRawLicenseRemove_AllConditionsSetAndOldCopyright /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test public void testGetComponentInfoRawCopyrightRemove_OnlyPathConditionSetAndMetForAllFiles() - throws ComponentInfoAdapterException, CurationInvalidException { + throws ComponentInfoAdapterException, CurationInvalidException, ScancodeProcessingFailedException, + JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_remove_curation_7.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -544,25 +645,31 @@ public void testGetComponentInfoRawCopyrightRemove_OnlyPathConditionSetAndMetFor /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawCopyrightReplace_AllConditionsSetAndMet() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawCopyrightReplace_AllConditionsSetAndMet() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_replace_curation_1.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); - + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); @@ -572,24 +679,31 @@ public void testGetComponentInfoRawCopyrightReplace_AllConditionsSetAndMet() /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawCopyrightAdd_WithPath() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawCopyrightAdd_WithPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_add_curation_1.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); @@ -602,26 +716,32 @@ public void testGetComponentInfoRawCopyrightAdd_WithPath() /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawCopyrightAdd_WithoutPath() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawCopyrightAdd_WithoutPath() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_add_curation_2.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); - // then // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); assertEquals(DataStatusValue.CURATED, scancodeComponentInfo.getDataStatus()); @@ -633,24 +753,31 @@ public void testGetComponentInfoRawCopyrightAdd_WithoutPath() /** * Test the - * {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} + * {@link FilteredScancodeV32ComponentInfoProvider#getComponentInfo(String, com.devonfw.tools.solicitor.componentinfo.CurationDataHandle)} * * * @throws ComponentInfoAdapterException if something goes wrong * @throws CurationInvalidException + * @throws ScancodeProcessingFailedException + * @throws JsonProcessingException + * @throws JsonMappingException */ @Test - public void testGetComponentInfoRawCopyrightAdd_WithPathNotMatching() - throws ComponentInfoAdapterException, CurationInvalidException { + public void testGetComponentInfoRawCopyrightAdd_WithPathNotMatching() throws ComponentInfoAdapterException, + CurationInvalidException, ScancodeProcessingFailedException, JsonMappingException, JsonProcessingException { // given this.singleFileCurationProvider .setCurationsFileName("src/test/resources/scancodefileadapter/rawcurations/copyright_add_curation_3.yaml"); // when + ScancodeRawComponentInfo rawScancodeData = this.fileScancodeRawComponentInfoProvider + .readScancodeData("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0"); + JsonNode scancodeJson = new ObjectMapper().readTree(rawScancodeData.rawScancodeResult); + ComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", - new SelectorCurationDataHandle("someCurationSelector")); + new SelectorCurationDataHandle("someCurationSelector"), rawScancodeData, scancodeJson); // then assertNotNull(scancodeComponentInfo.getComponentInfoData()); diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java index acb981e5..455f7f98 100644 --- a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java @@ -32,10 +32,14 @@ class ScancodeComponentInfoAdapterTest { // the object under test ScancodeComponentInfoAdapter scancodeComponentInfoAdapter; - FilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider; + FilteredScancodeV31ComponentInfoProvider filteredScancodeComponentInfoProvider31; + + FilteredScancodeV32ComponentInfoProvider filteredScancodeComponentInfoProvider32; FileScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; + MultiversionFilteredScancodeComponentInfoProvider multiversionFilteredScancodeComponentInfoProvider; + ComponentInfoCurator componentInfoCuratorImpl; SingleFileCurationProvider singleFileCurationProvider; @@ -57,16 +61,25 @@ public void setup() { this.singleFileCurationProvider = new SingleFileCurationProvider(packageURLHandler); this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); - this.filteredScancodeComponentInfoProvider = new FilteredScancodeComponentInfoProvider( - this.fileScancodeRawComponentInfoProvider, packageURLHandler, this.singleFileCurationProvider); - this.filteredScancodeComponentInfoProvider.setMinLicensefileNumberOfLines(5); - this.filteredScancodeComponentInfoProvider.setMinLicenseScore(90.0); + this.filteredScancodeComponentInfoProvider31 = new FilteredScancodeV31ComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, this.singleFileCurationProvider); + this.filteredScancodeComponentInfoProvider31.setMinLicensefileNumberOfLines(5); + this.filteredScancodeComponentInfoProvider31.setMinLicenseScore(90.0); + + this.filteredScancodeComponentInfoProvider32 = new FilteredScancodeV32ComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, this.singleFileCurationProvider); + this.filteredScancodeComponentInfoProvider32.setMinLicensefileNumberOfLines(5); + this.filteredScancodeComponentInfoProvider32.setMinLicenseScore(90.0); + + this.multiversionFilteredScancodeComponentInfoProvider = new MultiversionFilteredScancodeComponentInfoProvider( + new FilteredScancodeVersionComponentInfoProvider[] { this.filteredScancodeComponentInfoProvider32, + this.filteredScancodeComponentInfoProvider31 }, this.fileScancodeRawComponentInfoProvider); this.componentInfoCuratorImpl = new ComponentInfoCuratorImpl(this.singleFileCurationProvider, this.fileScancodeRawComponentInfoProvider); - this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter(this.filteredScancodeComponentInfoProvider, - this.componentInfoCuratorImpl); + this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter( + this.multiversionFilteredScancodeComponentInfoProvider, this.componentInfoCuratorImpl); this.scancodeComponentInfoAdapter.setFeatureFlag(true); } @@ -160,8 +173,8 @@ public void testGetComponentCheckCurationDataSelector() this.componentInfoCuratorImpl = new ComponentInfoCuratorImpl(curationProvider, this.fileScancodeRawComponentInfoProvider); - this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter(this.filteredScancodeComponentInfoProvider, - this.componentInfoCuratorImpl); + this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter( + this.multiversionFilteredScancodeComponentInfoProvider, this.componentInfoCuratorImpl); this.scancodeComponentInfoAdapter.setFeatureFlag(true); // when diff --git a/core/src/test/resources/scancode/scancode_v31.json b/core/src/test/resources/scancode/scancode_v31.json new file mode 100644 index 00000000..a8503270 --- /dev/null +++ b/core/src/test/resources/scancode/scancode_v31.json @@ -0,0 +1,313 @@ +{ + "headers": [ + { + "tool_name": "scancode-toolkit", + "tool_version": "31.2.6", + "options": { + "input": [ + "/repo/pkg/npm/bl/1.2.2/sources" + ], + "--consolidate": true, + "--copyright": true, + "--json-pp": "/repo/pkg/npm/bl/1.2.2/scancode.json", + "--license": true, + "--license-text": true, + "--only-findings": true, + "--processes": "16", + "--timeout": "600.0" + }, + "notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "start_timestamp": "2024-07-17T091055.917196", + "end_timestamp": "2024-07-17T091058.606991", + "output_format_version": "2.0.0", + "duration": 2.6898107528686523, + "message": null, + "errors": [], + "warnings": [ + "The --consolidate option will be deprecated in a future version of scancode-toolkit." + ], + "extra_data": { + "system_environment": { + "operating_system": "linux", + "cpu_architecture": "64", + "platform": "Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.29", + "platform_version": "#1 SMP Thu Jan 11 04:09:03 UTC 2024", + "python_version": "3.8.10 (default, Nov 22 2023, 10:22:35) \n[GCC 9.4.0]" + }, + "spdx_license_list_version": "3.18", + "files_count": 3 + } + } + ], + "consolidated_components": [ + { + "type": "holders", + "identifier": "bl_contributors_1", + "consolidated_license_expression": "mit", + "consolidated_holders": [ + "bl contributors" + ], + "consolidated_copyright": "Copyright (c) bl contributors", + "core_license_expression": "mit", + "core_holders": [ + "bl contributors" + ], + "other_license_expression": null, + "other_holders": [], + "files_count": 2 + } + ], + "consolidated_packages": [], + "files": [ + { + "path": "sources/package", + "type": "directory", + "licenses": [], + "license_expressions": [], + "percentage_of_license_text": 0, + "copyrights": [], + "holders": [], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + }, + { + "path": "sources/package/LICENSE.md", + "type": "file", + "licenses": [ + { + "key": "mit", + "score": 100.0, + "name": "MIT License", + "short_name": "MIT License", + "category": "Permissive", + "is_exception": false, + "is_unknown": false, + "owner": "MIT", + "homepage_url": "http://opensource.org/licenses/mit-license.php", + "text_url": "http://opensource.org/licenses/mit-license.php", + "reference_url": "https://scancode-licensedb.aboutcode.org/mit", + "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml", + "spdx_license_key": "MIT", + "spdx_url": "https://spdx.org/licenses/MIT", + "start_line": 1, + "end_line": 1, + "matched_rule": { + "identifier": "mit_26.RULE", + "license_expression": "mit", + "licenses": [ + "mit" + ], + "referenced_filenames": [], + "is_license_text": false, + "is_license_notice": false, + "is_license_reference": true, + "is_license_tag": false, + "is_license_intro": false, + "has_unknown": false, + "matcher": "2-aho", + "rule_length": 4, + "matched_length": 4, + "match_coverage": 100.0, + "rule_relevance": 100 + }, + "matched_text": "The MIT License (MIT)" + }, + { + "key": "mit", + "score": 100.0, + "name": "MIT License", + "short_name": "MIT License", + "category": "Permissive", + "is_exception": false, + "is_unknown": false, + "owner": "MIT", + "homepage_url": "http://opensource.org/licenses/mit-license.php", + "text_url": "http://opensource.org/licenses/mit-license.php", + "reference_url": "https://scancode-licensedb.aboutcode.org/mit", + "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml", + "spdx_license_key": "MIT", + "spdx_url": "https://spdx.org/licenses/MIT", + "start_line": 9, + "end_line": 13, + "matched_rule": { + "identifier": "mit.LICENSE", + "license_expression": "mit", + "licenses": [ + "mit" + ], + "referenced_filenames": [], + "is_license_text": true, + "is_license_notice": false, + "is_license_reference": false, + "is_license_tag": false, + "is_license_intro": false, + "has_unknown": false, + "matcher": "2-aho", + "rule_length": 161, + "matched_length": 161, + "match_coverage": 100.0, + "rule_relevance": 100 + }, + "matched_text": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\n subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + } + ], + "license_expressions": [ + "mit", + "mit" + ], + "percentage_of_license_text": 91.16, + "copyrights": [ + { + "copyright": "Copyright (c) 2013-2016 bl contributors", + "start_line": 4, + "end_line": 4 + } + ], + "holders": [ + { + "holder": "bl contributors", + "start_line": 4, + "end_line": 4 + } + ], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + }, + { + "path": "sources/package/package.json", + "type": "file", + "licenses": [ + { + "key": "mit", + "score": 100.0, + "name": "MIT License", + "short_name": "MIT License", + "category": "Permissive", + "is_exception": false, + "is_unknown": false, + "owner": "MIT", + "homepage_url": "http://opensource.org/licenses/mit-license.php", + "text_url": "http://opensource.org/licenses/mit-license.php", + "reference_url": "https://scancode-licensedb.aboutcode.org/mit", + "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml", + "spdx_license_key": "MIT", + "spdx_url": "https://spdx.org/licenses/MIT", + "start_line": 25, + "end_line": 25, + "matched_rule": { + "identifier": "mit_30.RULE", + "license_expression": "mit", + "licenses": [ + "mit" + ], + "referenced_filenames": [], + "is_license_text": false, + "is_license_notice": false, + "is_license_reference": false, + "is_license_tag": true, + "is_license_intro": false, + "has_unknown": false, + "matcher": "2-aho", + "rule_length": 2, + "matched_length": 2, + "match_coverage": 100.0, + "rule_relevance": 100 + }, + "matched_text": " \"license\": \"MIT\"," + } + ], + "license_expressions": [ + "mit" + ], + "percentage_of_license_text": 1.87, + "copyrights": [], + "holders": [], + "authors": [ + { + "author": "authors' Rod Vagg (https://github.com/rvagg)', Matteo Collina (https://github.com/mcollina)", + "start_line": 14, + "end_line": 16 + } + ], + "consolidated_to": [], + "scan_errors": [] + }, + { + "path": "sources/package/README.md", + "type": "file", + "licenses": [ + { + "key": "mit", + "score": 50.0, + "name": "MIT License", + "short_name": "MIT License", + "category": "Permissive", + "is_exception": false, + "is_unknown": false, + "owner": "MIT", + "homepage_url": "http://opensource.org/licenses/mit-license.php", + "text_url": "http://opensource.org/licenses/mit-license.php", + "reference_url": "https://scancode-licensedb.aboutcode.org/mit", + "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.yml", + "spdx_license_key": "MIT", + "spdx_url": "https://spdx.org/licenses/MIT", + "start_line": 208, + "end_line": 208, + "matched_rule": { + "identifier": "mit_478.RULE", + "license_expression": "mit", + "licenses": [ + "mit" + ], + "referenced_filenames": [], + "is_license_text": false, + "is_license_notice": true, + "is_license_reference": false, + "is_license_tag": false, + "is_license_intro": false, + "has_unknown": false, + "matcher": "3-seq", + "rule_length": 16, + "matched_length": 8, + "match_coverage": 50.0, + "rule_relevance": 100 + }, + "matched_text": "is licensed under the MIT license. All rights not explicitly granted in the MIT license" + } + ], + "license_expressions": [ + "mit" + ], + "percentage_of_license_text": 0.55, + "copyrights": [ + { + "copyright": "Copyright (c) 2013-2016 bl contributors", + "start_line": 206, + "end_line": 206 + } + ], + "holders": [ + { + "holder": "bl contributors", + "start_line": 206, + "end_line": 206 + } + ], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/scancode/scancode_v32.json b/core/src/test/resources/scancode/scancode_v32.json new file mode 100644 index 00000000..fc213740 --- /dev/null +++ b/core/src/test/resources/scancode/scancode_v32.json @@ -0,0 +1,310 @@ +{ + "headers": [ + { + "tool_name": "scancode-toolkit", + "tool_version": "32.1.0", + "options": { + "input": [ + "/repo/pkg/npm/bl/1.2.2/sources" + ], + "--consolidate": true, + "--copyright": true, + "--json-pp": "/repo/pkg/npm/bl/1.2.2/scancode.json", + "--license": true, + "--license-text": true, + "--only-findings": true, + "--processes": "16", + "--timeout": "600.0" + }, + "notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "start_timestamp": "2024-07-17T085604.785243", + "end_timestamp": "2024-07-17T085608.745285", + "output_format_version": "3.1.0", + "duration": 3.960059881210327, + "message": null, + "errors": [], + "warnings": [ + "The --consolidate option will be deprecated in a future version of scancode-toolkit." + ], + "extra_data": { + "system_environment": { + "operating_system": "linux", + "cpu_architecture": "64", + "platform": "Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35", + "platform_version": "#1 SMP Thu Jan 11 04:09:03 UTC 2024", + "python_version": "3.10.12 (main, Mar 22 2024, 16:50:05) [GCC 11.4.0]" + }, + "spdx_license_list_version": "3.23", + "files_count": 3 + } + } + ], + "license_detections": [ + { + "identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee", + "license_expression": "mit", + "license_expression_spdx": "MIT", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "sources/package/package.json", + "start_line": 25, + "end_line": 25, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 2, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_30.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", + "matched_text": " \"license\": \"MIT\"," + } + ] + }, + { + "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a", + "license_expression": "mit", + "license_expression_spdx": "MIT", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 9, + "end_line": 13, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 161, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit.LICENSE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "matched_text": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\n subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + } + ] + }, + { + "identifier": "mit-d5ea549d-8e03-2a31-f0cc-bdb0a5b86996", + "license_expression": "mit", + "license_expression_spdx": "MIT", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 4, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_26.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_26.RULE", + "matched_text": "The MIT License (MIT)" + } + ] + } + ], + "consolidated_components": [ + { + "type": "holders", + "identifier": "bl_contributors_1", + "consolidated_license_expression": "mit", + "consolidated_holders": [ + "bl contributors" + ], + "consolidated_copyright": "Copyright (c) bl contributors", + "core_license_expression": "mit", + "core_holders": [ + "bl contributors" + ], + "other_license_expression": null, + "other_holders": [], + "files_count": 2 + } + ], + "consolidated_packages": [], + "files": [ + { + "path": "sources/package", + "type": "directory", + "detected_license_expression": null, + "detected_license_expression_spdx": null, + "license_detections": [], + "license_clues": [], + "percentage_of_license_text": 0, + "copyrights": [], + "holders": [], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + }, + { + "path": "sources/package/LICENSE.md", + "type": "file", + "detected_license_expression": "mit", + "detected_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 4, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_26.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_26.RULE", + "matched_text": "The MIT License (MIT)" + } + ], + "identifier": "mit-d5ea549d-8e03-2a31-f0cc-bdb0a5b86996" + }, + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 9, + "end_line": 13, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 161, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit.LICENSE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "matched_text": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\n subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + } + ], + "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a" + } + ], + "license_clues": [], + "percentage_of_license_text": 91.16, + "copyrights": [ + { + "copyright": "Copyright (c) 2013-2016 bl contributors", + "start_line": 4, + "end_line": 4 + } + ], + "holders": [ + { + "holder": "bl contributors", + "start_line": 4, + "end_line": 4 + } + ], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + }, + { + "path": "sources/package/package.json", + "type": "file", + "detected_license_expression": "mit", + "detected_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/package.json", + "start_line": 25, + "end_line": 25, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 2, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_30.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", + "matched_text": " \"license\": \"MIT\"," + } + ], + "identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee" + } + ], + "license_clues": [], + "percentage_of_license_text": 1.87, + "copyrights": [], + "holders": [], + "authors": [ + { + "author": "Rod Vagg (https://github.com/rvagg) Matteo Collina (https://github.com/mcollina)", + "start_line": 14, + "end_line": 16 + } + ], + "consolidated_to": [], + "scan_errors": [] + }, + { + "path": "sources/package/README.md", + "type": "file", + "detected_license_expression": null, + "detected_license_expression_spdx": null, + "license_detections": [], + "license_clues": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/README.md", + "start_line": 208, + "end_line": 208, + "matcher": "3-seq", + "score": 50.0, + "matched_length": 8, + "match_coverage": 50.0, + "rule_relevance": 100, + "rule_identifier": "mit_478.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_478.RULE", + "matched_text": "is licensed under the MIT license. All rights not explicitly granted in the MIT license" + } + ], + "percentage_of_license_text": 0.55, + "copyrights": [ + { + "copyright": "Copyright (c) 2013-2016 bl contributors", + "start_line": 206, + "end_line": 206 + } + ], + "holders": [ + { + "holder": "bl contributors", + "start_line": 206, + "end_line": 206 + } + ], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/scancode/scancode_v99.json b/core/src/test/resources/scancode/scancode_v99.json new file mode 100644 index 00000000..ce88f44b --- /dev/null +++ b/core/src/test/resources/scancode/scancode_v99.json @@ -0,0 +1,310 @@ +{ + "headers": [ + { + "tool_name": "scancode-toolkit", + "tool_version": "99.1.0", + "options": { + "input": [ + "/repo/pkg/npm/bl/1.2.2/sources" + ], + "--consolidate": true, + "--copyright": true, + "--json-pp": "/repo/pkg/npm/bl/1.2.2/scancode.json", + "--license": true, + "--license-text": true, + "--only-findings": true, + "--processes": "16", + "--timeout": "600.0" + }, + "notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "start_timestamp": "2024-07-17T085604.785243", + "end_timestamp": "2024-07-17T085608.745285", + "output_format_version": "3.1.0", + "duration": 3.960059881210327, + "message": null, + "errors": [], + "warnings": [ + "The --consolidate option will be deprecated in a future version of scancode-toolkit." + ], + "extra_data": { + "system_environment": { + "operating_system": "linux", + "cpu_architecture": "64", + "platform": "Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35", + "platform_version": "#1 SMP Thu Jan 11 04:09:03 UTC 2024", + "python_version": "3.10.12 (main, Mar 22 2024, 16:50:05) [GCC 11.4.0]" + }, + "spdx_license_list_version": "3.23", + "files_count": 3 + } + } + ], + "license_detections": [ + { + "identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee", + "license_expression": "mit", + "license_expression_spdx": "MIT", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "sources/package/package.json", + "start_line": 25, + "end_line": 25, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 2, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_30.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", + "matched_text": " \"license\": \"MIT\"," + } + ] + }, + { + "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a", + "license_expression": "mit", + "license_expression_spdx": "MIT", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 9, + "end_line": 13, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 161, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit.LICENSE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "matched_text": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\n subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + } + ] + }, + { + "identifier": "mit-d5ea549d-8e03-2a31-f0cc-bdb0a5b86996", + "license_expression": "mit", + "license_expression_spdx": "MIT", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 4, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_26.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_26.RULE", + "matched_text": "The MIT License (MIT)" + } + ] + } + ], + "consolidated_components": [ + { + "type": "holders", + "identifier": "bl_contributors_1", + "consolidated_license_expression": "mit", + "consolidated_holders": [ + "bl contributors" + ], + "consolidated_copyright": "Copyright (c) bl contributors", + "core_license_expression": "mit", + "core_holders": [ + "bl contributors" + ], + "other_license_expression": null, + "other_holders": [], + "files_count": 2 + } + ], + "consolidated_packages": [], + "files": [ + { + "path": "sources/package", + "type": "directory", + "detected_license_expression": null, + "detected_license_expression_spdx": null, + "license_detections": [], + "license_clues": [], + "percentage_of_license_text": 0, + "copyrights": [], + "holders": [], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + }, + { + "path": "sources/package/LICENSE.md", + "type": "file", + "detected_license_expression": "mit", + "detected_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 4, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_26.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_26.RULE", + "matched_text": "The MIT License (MIT)" + } + ], + "identifier": "mit-d5ea549d-8e03-2a31-f0cc-bdb0a5b86996" + }, + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/LICENSE.md", + "start_line": 9, + "end_line": 13, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 161, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit.LICENSE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "matched_text": "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\n subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." + } + ], + "identifier": "mit-cacd5c0c-204a-85c2-affc-e4c125b2492a" + } + ], + "license_clues": [], + "percentage_of_license_text": 91.16, + "copyrights": [ + { + "copyright": "Copyright (c) 2013-2016 bl contributors", + "start_line": 4, + "end_line": 4 + } + ], + "holders": [ + { + "holder": "bl contributors", + "start_line": 4, + "end_line": 4 + } + ], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + }, + { + "path": "sources/package/package.json", + "type": "file", + "detected_license_expression": "mit", + "detected_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "license_expression_spdx": "MIT", + "matches": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/package.json", + "start_line": 25, + "end_line": 25, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 2, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "mit_30.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_30.RULE", + "matched_text": " \"license\": \"MIT\"," + } + ], + "identifier": "mit-3fce6ea2-8abd-6c6b-3ede-a37af7c6efee" + } + ], + "license_clues": [], + "percentage_of_license_text": 1.87, + "copyrights": [], + "holders": [], + "authors": [ + { + "author": "Rod Vagg (https://github.com/rvagg) Matteo Collina (https://github.com/mcollina)", + "start_line": 14, + "end_line": 16 + } + ], + "consolidated_to": [], + "scan_errors": [] + }, + { + "path": "sources/package/README.md", + "type": "file", + "detected_license_expression": null, + "detected_license_expression_spdx": null, + "license_detections": [], + "license_clues": [ + { + "license_expression": "mit", + "spdx_license_expression": "MIT", + "from_file": "sources/package/README.md", + "start_line": 208, + "end_line": 208, + "matcher": "3-seq", + "score": 50.0, + "matched_length": 8, + "match_coverage": 50.0, + "rule_relevance": 100, + "rule_identifier": "mit_478.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_478.RULE", + "matched_text": "is licensed under the MIT license. All rights not explicitly granted in the MIT license" + } + ], + "percentage_of_license_text": 0.55, + "copyrights": [ + { + "copyright": "Copyright (c) 2013-2016 bl contributors", + "start_line": 206, + "end_line": 206 + } + ], + "holders": [ + { + "holder": "bl contributors", + "start_line": 206, + "end_line": 206 + } + ], + "authors": [], + "consolidated_to": [ + "bl_contributors_1" + ], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/core/src/test/resources/scancodefileadapter/Source/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancode.json b/core/src/test/resources/scancodefileadapter/Source/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancode.json index ea167971..85aeb102 100644 --- a/core/src/test/resources/scancodefileadapter/Source/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancode.json +++ b/core/src/test/resources/scancodefileadapter/Source/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancode.json @@ -2,24 +2,25 @@ "headers": [ { "tool_name": "scancode-toolkit", - "tool_version": "31.0.2", + "tool_version": "32.2.1", "options": { "input": [ - "/somepath/Source/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/sources" + "/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/sources" ], "--consolidate": true, "--copyright": true, - "--json-pp": "/somepath/Source/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancode.json", + "--json-pp": "/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancode.json", "--license": true, + "--license-references": true, "--license-text": true, "--only-findings": true, - "--processes": "16" + "--timeout": "1800.0" }, "notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", - "start_timestamp": "2023-08-10T143029.366986", - "end_timestamp": "2023-08-10T143032.887088", - "output_format_version": "2.0.0", - "duration": 3.520116090774536, + "start_timestamp": "2024-08-24T083940.257103", + "end_timestamp": "2024-08-24T083944.248372", + "output_format_version": "3.2.0", + "duration": 3.991281509399414, "message": null, "errors": [], "warnings": [ @@ -29,15 +30,86 @@ "system_environment": { "operating_system": "linux", "cpu_architecture": "64", - "platform": "Linux-5.10.102.1-microsoft-standard-WSL2-x86_64-with-glibc2.29", - "platform_version": "#1 SMP Wed Mar 2 00:30:59 UTC 2022", - "python_version": "3.8.10 (default, Jun 22 2022, 20:18:18) \n[GCC 9.4.0]" + "platform": "Linux-5.15.153.1-microsoft-standard-WSL2-x86_64-with-glibc2.29", + "platform_version": "#1 SMP Fri Mar 29 23:14:13 UTC 2024", + "python_version": "3.8.10 (default, Nov 22 2023, 10:22:35) \n[GCC 9.4.0]" }, - "spdx_license_list_version": "3.17", + "spdx_license_list_version": "3.24", "files_count": 3 } } ], + "license_detections": [ + { + "identifier": "apache_2_0-c4e30bcd-ccfd-bbc3-d2f1-196ab911e47d", + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "from_file": "sources/src/main/java/com/devonfw/tools/test/SampleClass1.java", + "start_line": 5, + "end_line": 15, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 85, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "apache-2.0_7.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/apache-2.0_7.RULE", + "matched_text": " * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License." + } + ] + }, + { + "identifier": "apache_2_0-d66ab77d-a5cc-7104-e702-dc7df61fe9e8", + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "from_file": "sources/NOTICE.txt", + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "matched_text": "This is a dummy notice file for testing. Code is under Apache-2.0." + } + ] + }, + { + "identifier": "unknown_license_reference-3c9c2028-b661-e979-786c-5b593f730974", + "license_expression": "unknown-license-reference", + "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", + "detection_count": 1, + "reference_matches": [ + { + "license_expression": "unknown-license-reference", + "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", + "from_file": "sources/src/main/java/com/devonfw/tools/test/SampleClass2.java", + "start_line": 4, + "end_line": 4, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "license-intro_26.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/license-intro_26.RULE", + "matched_text": " * It is licensed under the same license as the rest of Solicitor." + } + ] + } + ], "consolidated_components": [ { "type": "holders", @@ -57,54 +129,202 @@ } ], "consolidated_packages": [], + "license_references": [ + { + "key": "apache-2.0", + "language": "en", + "short_name": "Apache 2.0", + "name": "Apache License 2.0", + "category": "Permissive", + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "notes": "Per SPDX.org, this version was released January 2004 This license is OSI\ncertified\n", + "is_builtin": true, + "is_exception": false, + "is_unknown": false, + "is_generic": false, + "spdx_license_key": "Apache-2.0", + "other_spdx_license_keys": [ + "LicenseRef-Apache", + "LicenseRef-Apache-2.0" + ], + "osi_license_key": "Apache-2.0", + "text_urls": [ + "http://www.apache.org/licenses/LICENSE-2.0" + ], + "osi_url": "http://opensource.org/licenses/apache2.0.php", + "faq_url": "http://www.apache.org/foundation/licence-FAQ.html", + "other_urls": [ + "http://www.opensource.org/licenses/Apache-2.0", + "https://opensource.org/licenses/Apache-2.0", + "https://www.apache.org/licenses/LICENSE-2.0" + ], + "key_aliases": [], + "minimum_coverage": 0, + "standard_notice": null, + "ignorable_copyrights": [], + "ignorable_holders": [], + "ignorable_authors": [], + "ignorable_urls": [ + "http://www.apache.org/licenses/", + "http://www.apache.org/licenses/LICENSE-2.0" + ], + "ignorable_emails": [], + "text": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n \n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n \n 1. Definitions.\n \n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n \n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n \n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n \n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n \n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n \n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n \n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n \n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n \n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n \n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n \n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n \n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n \n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n \n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n \n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n \n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n \n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n \n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n \n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n \n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n \n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n \n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n \n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n \n END OF TERMS AND CONDITIONS\n \n APPENDIX: How to apply the Apache License to your work.\n \n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"[]\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n \n Copyright [yyyy] [name of copyright owner]\n \n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n \n http://www.apache.org/licenses/LICENSE-2.0\n \n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.", + "scancode_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.LICENSE", + "licensedb_url": "https://scancode-licensedb.aboutcode.org/apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0" + }, + { + "key": "unknown-license-reference", + "language": "en", + "short_name": "Unknown License reference", + "name": "Unknown License file reference", + "category": "Unstated License", + "owner": "Unspecified", + "homepage_url": null, + "notes": "This applies to the case of a file with no clear license, which may be referenced via URL or text such as \"See license in...\" or \"This file is licensed under...\", but where the reference cannot be resolved to a specific named, public license.", + "is_builtin": true, + "is_exception": false, + "is_unknown": true, + "is_generic": false, + "spdx_license_key": "LicenseRef-scancode-unknown-license-reference", + "other_spdx_license_keys": [], + "osi_license_key": null, + "text_urls": [], + "osi_url": null, + "faq_url": null, + "other_urls": [], + "key_aliases": [], + "minimum_coverage": 0, + "standard_notice": null, + "ignorable_copyrights": [], + "ignorable_holders": [], + "ignorable_authors": [], + "ignorable_urls": [], + "ignorable_emails": [], + "text": "", + "scancode_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE", + "licensedb_url": "https://scancode-licensedb.aboutcode.org/unknown-license-reference", + "spdx_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE" + } + ], + "license_rule_references": [ + { + "license_expression": "apache-2.0", + "identifier": "apache-2.0_7.RULE", + "language": "en", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/apache-2.0_7.RULE", + "is_license_text": false, + "is_license_notice": true, + "is_license_reference": false, + "is_license_tag": false, + "is_license_intro": false, + "is_license_clue": false, + "is_continuous": false, + "is_builtin": true, + "is_from_license": false, + "is_synthetic": false, + "length": 85, + "relevance": 100, + "minimum_coverage": 0, + "referenced_filenames": [], + "notes": "apache 2.0 with disclaimer", + "ignorable_copyrights": [], + "ignorable_holders": [], + "ignorable_authors": [], + "ignorable_urls": [ + "http://www.apache.org/licenses/LICENSE-2.0" + ], + "ignorable_emails": [], + "text": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n# \n# http://www.apache.org/licenses/LICENSE-2.0\n# \n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License." + }, + { + "license_expression": "unknown-license-reference", + "identifier": "license-intro_26.RULE", + "language": "en", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/license-intro_26.RULE", + "is_license_text": false, + "is_license_notice": false, + "is_license_reference": false, + "is_license_tag": false, + "is_license_intro": true, + "is_license_clue": false, + "is_continuous": false, + "is_builtin": true, + "is_from_license": false, + "is_synthetic": false, + "length": 3, + "relevance": 100, + "minimum_coverage": 80, + "referenced_filenames": [], + "notes": null, + "ignorable_copyrights": [], + "ignorable_holders": [], + "ignorable_authors": [], + "ignorable_urls": [], + "ignorable_emails": [], + "text": "Licensed under the" + }, + { + "license_expression": "apache-2.0", + "identifier": "spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "language": "en", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "is_license_text": false, + "is_license_notice": false, + "is_license_reference": true, + "is_license_tag": false, + "is_license_intro": false, + "is_license_clue": false, + "is_continuous": false, + "is_builtin": true, + "is_from_license": false, + "is_synthetic": false, + "length": 3, + "relevance": 100, + "minimum_coverage": 100, + "referenced_filenames": [], + "notes": "Used to detect a bare SPDX license id", + "ignorable_copyrights": [], + "ignorable_holders": [], + "ignorable_authors": [], + "ignorable_urls": [], + "ignorable_emails": [], + "text": "apache-2.0" + } + ], "files": [ { "path": "sources/NOTICE.txt", "type": "file", - "licenses": [ + "detected_license_expression": "apache-2.0", + "detected_license_expression_spdx": "Apache-2.0", + "license_detections": [ { - "key": "apache-2.0", - "score": 100.0, - "name": "Apache License 2.0", - "short_name": "Apache 2.0", - "category": "Permissive", - "is_exception": false, - "is_unknown": false, - "owner": "Apache Software Foundation", - "homepage_url": "http://www.apache.org/licenses/", - "text_url": "http://www.apache.org/licenses/LICENSE-2.0", - "reference_url": "https://scancode-licensedb.aboutcode.org/apache-2.0", - "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.LICENSE", - "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.yml", - "spdx_license_key": "Apache-2.0", - "spdx_url": "https://spdx.org/licenses/Apache-2.0", - "start_line": 1, - "end_line": 1, - "matched_rule": { - "identifier": "spdx_license_id_apache-2.0_for_apache-2.0.RULE", - "license_expression": "apache-2.0", - "licenses": [ - "apache-2.0" - ], - "referenced_filenames": [], - "is_license_text": false, - "is_license_notice": false, - "is_license_reference": true, - "is_license_tag": false, - "is_license_intro": false, - "has_unknown": false, - "matcher": "2-aho", - "rule_length": 3, - "matched_length": 3, - "match_coverage": 100.0, - "rule_relevance": 100 - }, - "matched_text": "This is a dummy notice file for testing. Code is under Apache-2.0." + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "matches": [ + { + "license_expression": "apache-2.0", + "spdx_license_expression": "Apache-2.0", + "from_file": "sources/NOTICE.txt", + "start_line": 1, + "end_line": 1, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "matched_text": "This is a dummy notice file for testing. Code is under Apache-2.0." + } + ], + "identifier": "apache_2_0-d66ab77d-a5cc-7104-e702-dc7df61fe9e8" } ], - "license_expressions": [ - "apache-2.0" - ], + "license_clues": [], "percentage_of_license_text": 23.08, "copyrights": [], "holders": [], @@ -115,8 +335,10 @@ { "path": "sources/src/main/java/com/devonfw/tools/test", "type": "directory", - "licenses": [], - "license_expressions": [], + "detected_license_expression": null, + "detected_license_expression_spdx": null, + "license_detections": [], + "license_clues": [], "percentage_of_license_text": 0, "copyrights": [], "holders": [], @@ -129,50 +351,33 @@ { "path": "sources/src/main/java/com/devonfw/tools/test/SampleClass1.java", "type": "file", - "licenses": [ + "detected_license_expression": "apache-2.0", + "detected_license_expression_spdx": "Apache-2.0", + "license_detections": [ { - "key": "apache-2.0", - "score": 100.0, - "name": "Apache License 2.0", - "short_name": "Apache 2.0", - "category": "Permissive", - "is_exception": false, - "is_unknown": false, - "owner": "Apache Software Foundation", - "homepage_url": "http://www.apache.org/licenses/", - "text_url": "http://www.apache.org/licenses/LICENSE-2.0", - "reference_url": "https://scancode-licensedb.aboutcode.org/apache-2.0", - "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.LICENSE", - "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.yml", - "spdx_license_key": "Apache-2.0", - "spdx_url": "https://spdx.org/licenses/Apache-2.0", - "start_line": 5, - "end_line": 15, - "matched_rule": { - "identifier": "apache-2.0_7.RULE", - "license_expression": "apache-2.0", - "licenses": [ - "apache-2.0" - ], - "referenced_filenames": [], - "is_license_text": false, - "is_license_notice": true, - "is_license_reference": false, - "is_license_tag": false, - "is_license_intro": false, - "has_unknown": false, - "matcher": "2-aho", - "rule_length": 85, - "matched_length": 85, - "match_coverage": 100.0, - "rule_relevance": 100 - }, - "matched_text": " * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License." + "license_expression": "apache-2.0", + "license_expression_spdx": "Apache-2.0", + "matches": [ + { + "license_expression": "apache-2.0", + "spdx_license_expression": "Apache-2.0", + "from_file": "sources/src/main/java/com/devonfw/tools/test/SampleClass1.java", + "start_line": 5, + "end_line": 15, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 85, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "apache-2.0_7.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/apache-2.0_7.RULE", + "matched_text": " * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License." + } + ], + "identifier": "apache_2_0-c4e30bcd-ccfd-bbc3-d2f1-196ab911e47d" } ], - "license_expressions": [ - "apache-2.0" - ], + "license_clues": [], "percentage_of_license_text": 89.47, "copyrights": [ { @@ -197,50 +402,33 @@ { "path": "sources/src/main/java/com/devonfw/tools/test/SampleClass2.java", "type": "file", - "licenses": [ + "detected_license_expression": "unknown-license-reference", + "detected_license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", + "license_detections": [ { - "key": "unknown-license-reference", - "score": 100.0, - "name": "Unknown License file reference", - "short_name": "Unknown License reference", - "category": "Unstated License", - "is_exception": false, - "is_unknown": true, - "owner": "Unspecified", - "homepage_url": null, - "text_url": "", - "reference_url": "https://scancode-licensedb.aboutcode.org/unknown-license-reference", - "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE", - "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.yml", - "spdx_license_key": "LicenseRef-scancode-unknown-license-reference", - "spdx_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE", - "start_line": 4, - "end_line": 4, - "matched_rule": { - "identifier": "license-intro_26.RULE", - "license_expression": "unknown-license-reference", - "licenses": [ - "unknown-license-reference" - ], - "referenced_filenames": [], - "is_license_text": false, - "is_license_notice": false, - "is_license_reference": false, - "is_license_tag": false, - "is_license_intro": true, - "has_unknown": true, - "matcher": "2-aho", - "rule_length": 3, - "matched_length": 3, - "match_coverage": 100.0, - "rule_relevance": 100 - }, - "matched_text": " * It is licensed under the same license as the rest of Solicitor." + "license_expression": "unknown-license-reference", + "license_expression_spdx": "LicenseRef-scancode-unknown-license-reference", + "matches": [ + { + "license_expression": "unknown-license-reference", + "spdx_license_expression": "LicenseRef-scancode-unknown-license-reference", + "from_file": "sources/src/main/java/com/devonfw/tools/test/SampleClass2.java", + "start_line": 4, + "end_line": 4, + "matcher": "2-aho", + "score": 100.0, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100, + "rule_identifier": "license-intro_26.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/license-intro_26.RULE", + "matched_text": " * It is licensed under the same license as the rest of Solicitor." + } + ], + "identifier": "unknown_license_reference-3c9c2028-b661-e979-786c-5b593f730974" } ], - "license_expressions": [ - "unknown-license-reference" - ], + "license_clues": [], "percentage_of_license_text": 8.82, "copyrights": [], "holders": [], diff --git a/core/src/test/resources/scancodefileadapter/Source/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancodeV31.json b/core/src/test/resources/scancodefileadapter/Source/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancodeV31.json new file mode 100644 index 00000000..ea167971 --- /dev/null +++ b/core/src/test/resources/scancodefileadapter/Source/repo/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancodeV31.json @@ -0,0 +1,252 @@ +{ + "headers": [ + { + "tool_name": "scancode-toolkit", + "tool_version": "31.0.2", + "options": { + "input": [ + "/somepath/Source/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/sources" + ], + "--consolidate": true, + "--copyright": true, + "--json-pp": "/somepath/Source/pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0/scancode.json", + "--license": true, + "--license-text": true, + "--only-findings": true, + "--processes": "16" + }, + "notice": "Generated with ScanCode and provided on an \"AS IS\" BASIS, WITHOUT WARRANTIES\nOR CONDITIONS OF ANY KIND, either express or implied. No content created from\nScanCode should be considered or used as legal advice. Consult an Attorney\nfor any legal advice.\nScanCode is a free software code scanning tool from nexB Inc. and others.\nVisit https://github.com/nexB/scancode-toolkit/ for support and download.", + "start_timestamp": "2023-08-10T143029.366986", + "end_timestamp": "2023-08-10T143032.887088", + "output_format_version": "2.0.0", + "duration": 3.520116090774536, + "message": null, + "errors": [], + "warnings": [ + "The --consolidate option will be deprecated in a future version of scancode-toolkit." + ], + "extra_data": { + "system_environment": { + "operating_system": "linux", + "cpu_architecture": "64", + "platform": "Linux-5.10.102.1-microsoft-standard-WSL2-x86_64-with-glibc2.29", + "platform_version": "#1 SMP Wed Mar 2 00:30:59 UTC 2022", + "python_version": "3.8.10 (default, Jun 22 2022, 20:18:18) \n[GCC 9.4.0]" + }, + "spdx_license_list_version": "3.17", + "files_count": 3 + } + } + ], + "consolidated_components": [ + { + "type": "holders", + "identifier": "devonfw_1", + "consolidated_license_expression": "apache-2.0", + "consolidated_holders": [ + "devonfw" + ], + "consolidated_copyright": "Copyright (c) devonfw", + "core_license_expression": "apache-2.0", + "core_holders": [ + "devonfw" + ], + "other_license_expression": null, + "other_holders": [], + "files_count": 1 + } + ], + "consolidated_packages": [], + "files": [ + { + "path": "sources/NOTICE.txt", + "type": "file", + "licenses": [ + { + "key": "apache-2.0", + "score": 100.0, + "name": "Apache License 2.0", + "short_name": "Apache 2.0", + "category": "Permissive", + "is_exception": false, + "is_unknown": false, + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://scancode-licensedb.aboutcode.org/apache-2.0", + "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.LICENSE", + "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.yml", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 1, + "end_line": 1, + "matched_rule": { + "identifier": "spdx_license_id_apache-2.0_for_apache-2.0.RULE", + "license_expression": "apache-2.0", + "licenses": [ + "apache-2.0" + ], + "referenced_filenames": [], + "is_license_text": false, + "is_license_notice": false, + "is_license_reference": true, + "is_license_tag": false, + "is_license_intro": false, + "has_unknown": false, + "matcher": "2-aho", + "rule_length": 3, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100 + }, + "matched_text": "This is a dummy notice file for testing. Code is under Apache-2.0." + } + ], + "license_expressions": [ + "apache-2.0" + ], + "percentage_of_license_text": 23.08, + "copyrights": [], + "holders": [], + "authors": [], + "consolidated_to": [], + "scan_errors": [] + }, + { + "path": "sources/src/main/java/com/devonfw/tools/test", + "type": "directory", + "licenses": [], + "license_expressions": [], + "percentage_of_license_text": 0, + "copyrights": [], + "holders": [], + "authors": [], + "consolidated_to": [ + "devonfw_1" + ], + "scan_errors": [] + }, + { + "path": "sources/src/main/java/com/devonfw/tools/test/SampleClass1.java", + "type": "file", + "licenses": [ + { + "key": "apache-2.0", + "score": 100.0, + "name": "Apache License 2.0", + "short_name": "Apache 2.0", + "category": "Permissive", + "is_exception": false, + "is_unknown": false, + "owner": "Apache Software Foundation", + "homepage_url": "http://www.apache.org/licenses/", + "text_url": "http://www.apache.org/licenses/LICENSE-2.0", + "reference_url": "https://scancode-licensedb.aboutcode.org/apache-2.0", + "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.LICENSE", + "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/apache-2.0.yml", + "spdx_license_key": "Apache-2.0", + "spdx_url": "https://spdx.org/licenses/Apache-2.0", + "start_line": 5, + "end_line": 15, + "matched_rule": { + "identifier": "apache-2.0_7.RULE", + "license_expression": "apache-2.0", + "licenses": [ + "apache-2.0" + ], + "referenced_filenames": [], + "is_license_text": false, + "is_license_notice": true, + "is_license_reference": false, + "is_license_tag": false, + "is_license_intro": false, + "has_unknown": false, + "matcher": "2-aho", + "rule_length": 85, + "matched_length": 85, + "match_coverage": 100.0, + "rule_relevance": 100 + }, + "matched_text": " * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n * http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License." + } + ], + "license_expressions": [ + "apache-2.0" + ], + "percentage_of_license_text": 89.47, + "copyrights": [ + { + "copyright": "Copyright 2023 devonfw", + "start_line": 3, + "end_line": 3 + } + ], + "holders": [ + { + "holder": "devonfw", + "start_line": 3, + "end_line": 3 + } + ], + "authors": [], + "consolidated_to": [ + "devonfw_1" + ], + "scan_errors": [] + }, + { + "path": "sources/src/main/java/com/devonfw/tools/test/SampleClass2.java", + "type": "file", + "licenses": [ + { + "key": "unknown-license-reference", + "score": 100.0, + "name": "Unknown License file reference", + "short_name": "Unknown License reference", + "category": "Unstated License", + "is_exception": false, + "is_unknown": true, + "owner": "Unspecified", + "homepage_url": null, + "text_url": "", + "reference_url": "https://scancode-licensedb.aboutcode.org/unknown-license-reference", + "scancode_text_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE", + "scancode_data_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.yml", + "spdx_license_key": "LicenseRef-scancode-unknown-license-reference", + "spdx_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/unknown-license-reference.LICENSE", + "start_line": 4, + "end_line": 4, + "matched_rule": { + "identifier": "license-intro_26.RULE", + "license_expression": "unknown-license-reference", + "licenses": [ + "unknown-license-reference" + ], + "referenced_filenames": [], + "is_license_text": false, + "is_license_notice": false, + "is_license_reference": false, + "is_license_tag": false, + "is_license_intro": true, + "has_unknown": true, + "matcher": "2-aho", + "rule_length": 3, + "matched_length": 3, + "match_coverage": 100.0, + "rule_relevance": 100 + }, + "matched_text": " * It is licensed under the same license as the rest of Solicitor." + } + ], + "license_expressions": [ + "unknown-license-reference" + ], + "percentage_of_license_text": 8.82, + "copyrights": [], + "holders": [], + "authors": [], + "consolidated_to": [], + "scan_errors": [] + } + ] +} \ No newline at end of file diff --git a/documentation/files/application.properties b/documentation/files/application.properties index ffd53a77..1bb57763 100644 --- a/documentation/files/application.properties +++ b/documentation/files/application.properties @@ -54,6 +54,8 @@ solicitor.scancode.automapping.blacklistpatterns=.*unknown.*,.*proprietary.* solicitor.scancode.automapping.ignorelistpatterns= ## Parameters for controlling the processing of scancode information +# the name of the file which contains the scancode data +#solicitor.scancode.file-name=scancode.json # minimum score of detected license findings to be taken into account for Solicitor processing solicitor.scancode.min-license-score=90.0 # minimum number of lines of detected license text for a file to be possibly taken as license text diff --git a/documentation/master-solicitor.asciidoc b/documentation/master-solicitor.asciidoc index 26ef8605..a93b7d7a 100644 --- a/documentation/master-solicitor.asciidoc +++ b/documentation/master-solicitor.asciidoc @@ -1453,7 +1453,7 @@ The scripts generated by _Solicitor_ to download sources and run ScanCode are in So either run it on a system using natively Bash (linux) or install an appropriate environment (e.g. Git Bash) if you are using a windows environment. ==== ScanCode -Download and install ScanCode from https://github.com/nexB/scancode-toolkit/releases. +Download and install ScanCode (Solicitor is assuming version 32, tested with 32.2.1) from https://github.com/nexB/scancode-toolkit/releases. Make sure that the executable is included in the search PATH for executables. ==== Activate feature @@ -1899,6 +1899,7 @@ Spring beans implementing this interface will be called at certain points in the [appendix] == Release Notes Changes in 1.26.0:: +* https://github.com/devonfw/solicitor/issues/281: Solicitor now assumes ScanCode v32 to be used within the ScanCode integration. ScanCode JSON result files of v30 and v31 can still be processed but the scripting for doing the scans assumes v32 to be installed. Changes in 1.25.0:: * https://github.com/devonfw/solicitor/issues/277: When reading content (license texts or notice files) within the scancode adapter files which are greater than 1 million bytes will be skipped. This avoids large memory consumption and resulting instability.