Skip to content

Commit

Permalink
Merge pull request #2442 from siemens/feat/rest_addConfigToGenericLic…
Browse files Browse the repository at this point in the history
…InfoReport

fix(rest) : Move GenerateLicenseInfoFile rest end point to SW360reportcontroller

Reviewed-by: [email protected]
Tested-by: [email protected]
  • Loading branch information
GMishx authored Oct 17, 2024
2 parents 1f9b08c + 144ea5b commit 500514b
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ public Function<ProjectLink, ProjectLink> createProjectLinkMapper(Function<Relea
};
}

protected List<ProjectLink> createLinkedProjects(Project project,
public List<ProjectLink> createLinkedProjects(Project project,
Function<ProjectLink, ProjectLink> projectLinkMapper, boolean deep, User user) {
final Collection<ProjectLink> linkedProjects = SW360Utils
.flattenProjectLinkTree(SW360Utils.getLinkedProjects(project, deep, new ThriftClients(), log, user));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public class SW360ReportController implements RepresentationModelProcessor<Repos

public static final String REPORTS_URL = "/reports";

private static final String LICENSE_INFO = "licenseInfo";

private static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

@NonNull
Expand Down Expand Up @@ -104,7 +106,10 @@ public void getProjectReport(
request, sw360User, module);
break;
case LICENSES:
getLicensesReports(response, sw360User, module);
getLicensesReports(request, response, sw360User, module);
break;
case LICENSE_INFO:
getLicensesInfoReports(request, response, sw360User, module, projectId);
break;
default:
break;
Expand All @@ -126,7 +131,7 @@ private void getProjectReports(boolean withLinkedReleases, boolean mailRequest,
responseJson.addProperty("response", "The downloaded report link will be send to the end user.");
response.getWriter().write(responseJson.toString());
} else {
downloadExcelReport(withLinkedReleases, response, sw360User, module, projectId);
downloadExcelReport(withLinkedReleases, request, response, sw360User, module, projectId);
}
} catch (Exception e) {
throw new TException(e.getMessage());
Expand All @@ -142,22 +147,30 @@ private void getComponentsReports(boolean withLinkedReleases, boolean mailReques
responseJson.addProperty("response", "Component report download link will get send to the end user.");
response.getWriter().write(responseJson.toString());
} else {
downloadExcelReport(withLinkedReleases, response, sw360User, module, null);
downloadExcelReport(withLinkedReleases, request, response, sw360User, module, null);
}
} catch (Exception e) {
throw new TException(e.getMessage());
}
}

private void getLicensesReports(HttpServletResponse response, User sw360User, String module) throws TException {
private void getLicensesReports(HttpServletRequest request, HttpServletResponse response, User sw360User, String module) throws TException {
try {
downloadExcelReport(false, response, sw360User, module, null);
downloadExcelReport(false, request, response, sw360User, module, null);
} catch (Exception e) {
throw new TException(e.getMessage());
}
}

private void downloadExcelReport(boolean withLinkedReleases, HttpServletResponse response, User user, String module, String projectId)
private void getLicensesInfoReports(HttpServletRequest request, HttpServletResponse response, User sw360User, String module, String projectId) throws TException {
try {
downloadExcelReport(false, request, response, sw360User, module, projectId);
}catch (Exception e) {
throw new TException(e.getMessage());
}
}

private void downloadExcelReport(boolean withLinkedReleases, HttpServletRequest request , HttpServletResponse response, User user, String module, String projectId)
throws TException {
try {
ByteBuffer buffer = null;
Expand All @@ -171,6 +184,13 @@ private void downloadExcelReport(boolean withLinkedReleases, HttpServletResponse
case LICENSES:
buffer = sw360ReportService.getLicenseBuffer();
break;
case LICENSE_INFO:
final String generatorClassName = request.getParameter("generatorClassName");
final String variant = request.getParameter("variant");
final String template = request.getParameter("template");
final String externalIds = request.getParameter("externalIds");
buffer = sw360ReportService.getLicenseInfoBuffer(user, projectId, generatorClassName, variant, template, externalIds);
break;
default:
break;
}
Expand Down Expand Up @@ -247,7 +267,9 @@ public void downloadExcel(
fileName = String.format("licenses-%s.xlsx", SW360Utils.getCreatedOn());
} else if(module.equals(PROJECTS)) {
fileName = sw360ReportService.getDocumentName(user, request.getParameter("projectId"));
}else {
} else if(module.equals(LICENSE_INFO)) {
fileName = sw360ReportService.getGenericLicInfoFileName(request, user);
} else {
fileName = sw360ReportService.getDocumentName(user, null);
}
response.setContentType(CONTENT_TYPE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,60 @@

import lombok.RequiredArgsConstructor;

import static org.eclipse.sw360.rest.resourceserver.Sw360ResourceServer.REPORT_FILENAME_MAPPING;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.eclipse.sw360.datahandler.common.SW360Constants;
import org.eclipse.sw360.datahandler.thrift.Source;
import org.eclipse.sw360.datahandler.thrift.attachments.Attachment;
import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentUsage;
import org.eclipse.sw360.datahandler.thrift.attachments.UsageData;
import org.eclipse.sw360.datahandler.thrift.components.Release;
import org.eclipse.sw360.datahandler.thrift.components.ReleaseLink;
import org.eclipse.sw360.datahandler.thrift.licenseinfo.LicenseInfo;
import org.eclipse.sw360.datahandler.thrift.licenseinfo.LicenseInfoFile;
import org.eclipse.sw360.datahandler.thrift.licenseinfo.LicenseInfoParsingResult;
import org.eclipse.sw360.datahandler.thrift.licenseinfo.LicenseNameWithText;
import org.eclipse.sw360.datahandler.thrift.licenseinfo.OutputFormatInfo;
import org.eclipse.sw360.datahandler.thrift.projects.ProjectLink;
import org.eclipse.sw360.rest.resourceserver.attachment.Sw360AttachmentService;
import org.eclipse.sw360.rest.resourceserver.component.Sw360ComponentService;
import org.eclipse.sw360.rest.resourceserver.license.Sw360LicenseService;
import org.eclipse.sw360.rest.resourceserver.licenseinfo.Sw360LicenseInfoService;
import org.eclipse.sw360.rest.resourceserver.project.Sw360ProjectService;
import com.google.common.base.Strings;

import lombok.NonNull;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SW360ReportService {

@NonNull
private final Sw360ProjectService projectService;

@NonNull
private final Sw360LicenseService licenseService;

@NonNull
private final Sw360ComponentService componentService;

@NonNull
private final Sw360AttachmentService attachmentService;

@NonNull
private final Sw360LicenseInfoService licenseInfoService;

ThriftClients thriftClients = new ThriftClients();
ProjectService.Iface projectclient = thriftClients.makeProjectClient();
ComponentService.Iface componentclient = thriftClients.makeComponentClient();
Expand Down Expand Up @@ -129,4 +179,99 @@ public ByteBuffer getLicenseReportStreamFromURl(String token)
public void sendComponentExportSpreadsheetSuccessMail(String emailURL, String email) throws TException {
componentclient.sendExportSpreadsheetSuccessMail(emailURL, email);
}

public ByteBuffer getLicenseInfoBuffer(User sw360User, String id, String generatorClassName, String variant, String template, String externalIds) throws TException {
final Project sw360Project = projectService.getProjectForUserById(id, sw360User);

List<ProjectLink> mappedProjectLinks = projectService.createLinkedProjects(sw360Project,
projectService.filterAndSortAttachments(SW360Constants.LICENSE_INFO_ATTACHMENT_TYPES), true, sw360User);

List<AttachmentUsage> attchmntUsg = attachmentService.getAttachemntUsages(id);

Map<Source, Set<String>> releaseIdToExcludedLicenses = attchmntUsg.stream()
.collect(Collectors.toMap(AttachmentUsage::getOwner,
x -> x.getUsageData().getLicenseInfo().getExcludedLicenseIds(), (li1, li2) -> li1));

Map<String, Boolean> usedAttachmentContentIds = attchmntUsg.stream()
.collect(Collectors.toMap(AttachmentUsage::getAttachmentContentId, attUsage -> {
if (attUsage.isSetUsageData()
&& attUsage.getUsageData().getSetField().equals(UsageData._Fields.LICENSE_INFO)) {
return Boolean.valueOf(attUsage.getUsageData().getLicenseInfo().isIncludeConcludedLicense());
}
return Boolean.FALSE;
}, (li1, li2) -> li1));

final Map<String, Map<String, Boolean>> selectedReleaseAndAttachmentIds = new HashMap<>();
final Map<String, Set<LicenseNameWithText>> excludedLicensesPerAttachments = new HashMap<>();

getSelectedAttchIdsAndExcludedLicInfo(sw360User, mappedProjectLinks, releaseIdToExcludedLicenses,
usedAttachmentContentIds, selectedReleaseAndAttachmentIds, excludedLicensesPerAttachments);

String outputGeneratorClassNameWithVariant = generatorClassName + "::" + variant;
String fileName = "";
if (CommonUtils.isNotNullEmptyOrWhitespace(template)
&& CommonUtils.isNotNullEmptyOrWhitespace(REPORT_FILENAME_MAPPING)) {
Map<String, String> orgToTemplate = Arrays.stream(REPORT_FILENAME_MAPPING.split(","))
.collect(Collectors.toMap(k -> k.split(":")[0], v -> v.split(":")[1]));
fileName = orgToTemplate.get(template);
}
final LicenseInfoFile licenseInfoFile = licenseInfoService.getLicenseInfoFile(sw360Project, sw360User,
outputGeneratorClassNameWithVariant, selectedReleaseAndAttachmentIds, excludedLicensesPerAttachments,
externalIds, fileName);
return licenseInfoFile.bufferForGeneratedOutput();
}

private void getSelectedAttchIdsAndExcludedLicInfo(User sw360User, List<ProjectLink> mappedProjectLinks,
Map<Source, Set<String>> releaseIdToExcludedLicenses, Map<String, Boolean> usedAttachmentContentIds,
final Map<String, Map<String, Boolean>> selectedReleaseAndAttachmentIds,
final Map<String, Set<LicenseNameWithText>> excludedLicensesPerAttachments) {
mappedProjectLinks.forEach(projectLink -> wrapTException(() -> projectLink.getLinkedReleases().stream()
.filter(ReleaseLink::isSetAttachments).forEach(releaseLink -> {
String releaseLinkId = releaseLink.getId();
Set<String> excludedLicenseIds = releaseIdToExcludedLicenses.get(Source.releaseId(releaseLinkId));

if (!selectedReleaseAndAttachmentIds.containsKey(releaseLinkId)) {
selectedReleaseAndAttachmentIds.put(releaseLinkId, new HashMap<>());
}
final List<Attachment> attachments = releaseLink.getAttachments();
Release release = componentService.getReleaseById(releaseLinkId, sw360User);
for (final Attachment attachment : attachments) {
String attachemntContentId = attachment.getAttachmentContentId();
if (usedAttachmentContentIds.containsKey(attachemntContentId)) {
boolean includeConcludedLicense = usedAttachmentContentIds.get(attachemntContentId);
List<LicenseInfoParsingResult> licenseInfoParsingResult = licenseInfoService
.getLicenseInfoForAttachment(release, sw360User, attachemntContentId,
includeConcludedLicense);
excludedLicensesPerAttachments.put(attachemntContentId,
getExcludedLicenses(excludedLicenseIds, licenseInfoParsingResult));
selectedReleaseAndAttachmentIds.get(releaseLinkId).put(attachemntContentId,
includeConcludedLicense);
}
}
})));
}

public String getGenericLicInfoFileName(HttpServletRequest request, User sw360User) throws TException {
final String variant = request.getParameter("variant");
final Project sw360Project = projectService.getProjectForUserById(request.getParameter("projectId"), sw360User);
final String generatorClassName = request.getParameter("generatorClassName");
final String timestamp = SW360Utils.getCreatedOnTime().replaceAll("\\s", "_").replace(":", "_");
final OutputFormatInfo outputFormatInfo = licenseInfoService
.getOutputFormatInfoForGeneratorClass(generatorClassName);
return String.format("%s-%s%s-%s.%s",
Strings.nullToEmpty(variant).equals("DISCLOSURE") ? "LicenseInfo" : "ProjectClearingReport",
sw360Project.getName(),
StringUtils.isBlank(sw360Project.getVersion()) ? "" : "-" + sw360Project.getVersion(), timestamp,
outputFormatInfo.getFileExtension());
}

private Set<LicenseNameWithText> getExcludedLicenses(Set<String> excludedLicenseIds,
List<LicenseInfoParsingResult> licenseInfoParsingResult) {
Predicate<LicenseNameWithText> filteredLicense = licenseNameWithText -> excludedLicenseIds
.contains(licenseNameWithText.getLicenseName());
Function<LicenseInfo, Stream<LicenseNameWithText>> streamLicenseNameWithTexts = licenseInfo -> licenseInfo
.getLicenseNamesWithTexts().stream();
return licenseInfoParsingResult.stream().map(LicenseInfoParsingResult::getLicenseInfo)
.flatMap(streamLicenseNameWithTexts).filter(filteredLicense).collect(Collectors.toSet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2062,15 +2062,17 @@ public void should_document_update_project_release_relationship() throws Excepti
public void should_document_get_download_license_info() throws Exception {
this.mockMvc.perform(get("/api/projects/" + project.getId()+ "/licenseinfo?generatorClassName=XhtmlGenerator&variant=DISCLOSURE&externalIds=portal-id,main-project-id")
.header("Authorization", TestHelper.generateAuthHeader(testUserId, testUserPassword))
.param("module", "licenseInfo")
.param("projectId", project.getId())
.param("generatorClassName", "XhtmlGenerator")
.param("variant", "DISCLOSURE")
.param("externalIds", "portal-id,main-project-id")
.accept("application/xhtml+xml"))
.andExpect(status().isOk())
.andDo(this.documentationHandler
.document(queryParameters(
parameterWithName("generatorClassName")
.description("All possible values for output generator class names are "
+ Arrays.asList("DocxGenerator", "XhtmlGenerator", "TextGenerator")),
parameterWithName("variant").description("All the possible values for variants are "
+ Arrays.asList(OutputFormatVariant.values())),
parameterWithName("generatorClassName").description("Projects download format. Possible values are `<DocxGenerator|XhtmlGenerator|TextGenerator>`"),
parameterWithName("variant").description("All the possible values for variants are `<REPORT|DISCLOSURE>`"),
parameterWithName("externalIds").description("The external Ids of the project")
)));
}
Expand Down

0 comments on commit 500514b

Please sign in to comment.