diff --git a/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/LicenseInfoHandler.java b/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/LicenseInfoHandler.java index 73abed993f..72b29611a4 100644 --- a/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/LicenseInfoHandler.java +++ b/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/LicenseInfoHandler.java @@ -94,7 +94,7 @@ protected LicenseInfoHandler(AttachmentDatabaseHandler attachmentDatabaseHandler new TextGenerator(DISCLOSURE, "License Disclosure as TEXT"), new XhtmlGenerator(DISCLOSURE, "License Disclosure as XHTML"), new DocxGenerator(DISCLOSURE, "License Disclosure as DOCX"), - new DocxGenerator(REPORT, "License Report as DOCX") + new DocxGenerator(REPORT, "Project Clearing Report as DOCX") ); // @formatter:on } diff --git a/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/outputGenerators/DocxGenerator.java b/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/outputGenerators/DocxGenerator.java index 63dd39e41c..6abc2909c0 100644 --- a/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/outputGenerators/DocxGenerator.java +++ b/backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/outputGenerators/DocxGenerator.java @@ -15,6 +15,7 @@ import org.apache.log4j.Logger; import org.apache.poi.xwpf.usermodel.*; import org.apache.thrift.TException; +import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlException; import org.eclipse.sw360.datahandler.common.CommonUtils; import org.eclipse.sw360.datahandler.common.SW360Utils; @@ -47,13 +48,14 @@ public class DocxGenerator extends OutputGenerator { private static final Logger LOGGER = Logger.getLogger(DocxGenerator.class); private static final String UNKNOWN_LICENSE_NAME = "Unknown license name"; private static final String UNKNOWN_FILE_NAME = "Unknown file name"; + private static final String UNKNOWN_LICENSE = "Unknown"; private static final String TODO_DEFAULT_TEXT = "todo not determined so far."; private static final String DOCX_TEMPLATE_FILE = "/templateFrontpageContent.docx"; private static final String DOCX_TEMPLATE_REPORT_FILE = "/templateReport.docx"; private static final String DOCX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; private static final String DOCX_OUTPUT_TYPE = "docx"; - public static final String UNKNOWN_LICENSE = "Unknown"; + private static final long ADDITIONAL_REQ_THRESHOLD = 3; public static final int ADDITIONAL_REQ_TABLE_INDEX = 5; public static final int DEV_DETAIL_TABLE_INDEX = 2; @@ -136,7 +138,7 @@ private void fillDisclosureDocument( fillReleaseBulletList(document, projectLicenseInfoResults); fillReleaseDetailList(document, projectLicenseInfoResults, includeObligations); fillLicenseList(document, projectLicenseInfoResults); - } + } private void fillReportDocument( XWPFDocument document, @@ -147,6 +149,7 @@ private void fillReportDocument( Collection obligationResults, User user) throws XmlException, TException { + String businessUnit = project.getBusinessUnit(); String projectName = project.getName(); String projectVersion = project.getVersion(); String obligationsText = project.getObligationsText(); @@ -157,11 +160,13 @@ private void fillReportDocument( String deliveryChannelsText = project.getDeliveryChannels(); String remarksAdditionalRequirementsText = project.getRemarksAdditionalRequirements(); String projectDescription = project.getDescription(); - + // extract licenses that appear at least ADDITIONAL_REQ_THRESHOLD times + Set mostLicenses = extractMostCommonLicenses(obligationResults, ADDITIONAL_REQ_THRESHOLD); fillOwnerGroup(document, project); fillAttendeesTable(document, project); + replaceText(document, "$bunit", businessUnit); replaceText(document, "$license-info-header", licenseInfoHeaderText); replaceText(document, "$project-name", projectName); replaceText(document, "$project-version", projectVersion); @@ -180,8 +185,6 @@ private void fillReportDocument( fillCommonRulesTable(document, project); fillAdditionalRequirementsTable(document, obligationResults); - // because of the impossible API component subsections must be the last thing in the docx file - // the rest of the sections must be generated after this writeComponentSubsections(document, projectLicenseInfoResults, obligationResults); } @@ -194,9 +197,9 @@ private void fillOwnerGroup(XWPFDocument document, Project project) throws XmlEx } private void fillAttendeesTable(XWPFDocument document, Project project) throws XmlException, TException { - XWPFTable table = document.getTables().get(0); + XWPFTable table = document.getTables().get(OVERVIEW_TABLE_INDEX); - int currentRow = 6; + int currentRow = 7; UserService.Iface userClient = new ThriftClients().makeUserClient(); @@ -220,7 +223,12 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X continue; } - User user = userClient.getByEmail(email); + User user = null; + try { + user = userClient.getByEmail(email); + } catch (TException te) { + + } XWPFTableRow row = table.insertNewTableRow(currentRow++); String name = email; @@ -229,7 +237,7 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X } String department = "N.A."; if(user != null) { - name = user.getDepartment(); + department = user.getDepartment(); } row.addNewTableCell().setText(name); @@ -241,7 +249,7 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X } private void fillSpecialOSSRisksTable(XWPFDocument document, Project project, Collection obligationResults) throws XmlException, TException { - XWPFTable table = document.getTables().get(1); + XWPFTable table = document.getTables().get(SPECIAL_OSS_RISKS_TABLE_INDEX); final int[] currentRow = new int[]{0}; obligationResults.stream() @@ -260,7 +268,7 @@ private void fillSpecialOSSRisksTable(XWPFDocument document, Project project, Co } private void fillOverview3rdPartyComponentTable(XWPFDocument document, Collection projectLicenseInfoResults) throws XmlException { - XWPFTable table = document.getTables().get(3); + XWPFTable table = document.getTables().get(THIRD_PARTY_COMPONENT_OVERVIEW_TABLE_INDEX); int currentRow = 1; for(LicenseInfoParsingResult result : projectLicenseInfoResults) { @@ -292,17 +300,31 @@ private static Optional obligationsForRelease(Release r return obligationResults.stream().filter(opr -> opr.getRelease() == release).findFirst(); } - private void writeComponentSubsections(XWPFDocument document, Collection projectLicenseInfoResults, Collection obligationResults) throws XmlException { + private void writeComponentSubsections(XWPFDocument document, Collection projectLicenseInfoResults, Collection obligationResults) throws SW360Exception, XmlException { + XmlCursor cursor = document.getTables().get(ADDITIONAL_REQ_TABLE_INDEX).getCTTbl().newCursor(); + cursor.toEndToken(); for (LicenseInfoParsingResult result : projectLicenseInfoResults) { + while (cursor.currentTokenType() != XmlCursor.TokenType.START && cursor.hasNextToken()) { + cursor.toNextToken(); + } + + if (cursor.currentTokenType() != XmlCursor.TokenType.START) { + throw new SW360Exception("Corrupt template; unable find start token"); + } - XWPFParagraph title = document.createParagraph(); + XWPFParagraph title = document.insertNewParagraph(cursor); title.setStyle(STYLE_HEADING_3); title.setNumID(new BigInteger("2")); XWPFRun titleRun = title.createRun(); titleRun.setText(result.getVendor() + " " + result.getName()); - XWPFParagraph description = document.createParagraph(); + if (cursor.hasNextToken()) { + cursor.toNextToken(); + } else { + throw new SW360Exception("Corrupt template; unable to proceed to next token"); + } + XWPFParagraph description = document.insertNewParagraph(cursor); XWPFRun descriptionRun = description.createRun(); LicenseInfo licenseInfo = result.getLicenseInfo(); @@ -331,7 +353,7 @@ private void writeComponentSubsections(XWPFDocument document, Collection obligations = obligationsResult.getObligations(); - XWPFTable table = document.createTable(); + XWPFTable table = document.insertNewTbl(cursor); for (Obligation o : obligations) { XWPFTableRow row = table.insertNewTableRow(currentRow++); String licensesString = String.join(" ", o.getLicenseIDs()); @@ -359,13 +381,13 @@ private void fillDevelopmentDetailsTable(XWPFDocument document, Project project, row.addNewTableCell().setText(component.getName()); - String operatingSystems = component.getOperatingSystemsSize() == 0 ? "Unknown operating systems" : String.join(" ", component.getOperatingSystems()); + String operatingSystems = component.getOperatingSystemsSize() == 0 ? "N/A" : String.join(" ", component.getOperatingSystems()); row.addNewTableCell().setText(operatingSystems); - String langs = component.getLanguagesSize() == 0 ? "Unknown languages" : String.join(" ", component.getLanguages()); + String langs = component.getLanguagesSize() == 0 ? "N/A" : String.join(" ", component.getLanguages()); row.addNewTableCell().setText(langs); - String platforms = component.getSoftwarePlatformsSize() == 0 ? "Unknown platforms" : String.join(" ", component.getSoftwarePlatforms()); + String platforms = component.getSoftwarePlatformsSize() == 0 ? "N/A" : String.join(" ", component.getSoftwarePlatforms()); row.addNewTableCell().setText(platforms); } } @@ -379,13 +401,11 @@ protected static Set extractMostCommonLicenses(Collection entry.getValue().longValue() >= threshold) .map(entry -> entry.getKey()) + .map(license -> license.replace("\n", "").replace("\r", "")) .collect(Collectors.toSet()); } - private void fillAdditionalRequirementsTable(XWPFDocument document, Collection obligationResults) throws XmlException { - // extract licenses that appear at least ADDITIONAL_REQ_THRESHOLD times - Set mostLicenses = extractMostCommonLicenses(obligationResults, ADDITIONAL_REQ_THRESHOLD); - + private void fillAdditionalRequirementsTable(XWPFDocument document, Collection obligationResults, Set mostLicenses) throws XmlException { XWPFTable table = document.getTables().get(ADDITIONAL_REQ_TABLE_INDEX); final int[] currentRow = new int[]{0}; @@ -393,7 +413,7 @@ private void fillAdditionalRequirementsTable(XWPFDocument document, Collection opr.getStatus() == ObligationInfoRequestStatus.SUCCESS) .flatMap(opr -> opr.getObligations().stream()) .filter(o -> o.getLicenseIDs().stream() - .anyMatch(lid -> mostLicenses.parallelStream().anyMatch(mlid -> mlid.equals(lid)))) + .anyMatch(lid -> mostLicenses.parallelStream().anyMatch(mlid -> mlid.equals(lid.replace("\n", "").replace("\r", ""))))) .forEach(o -> { currentRow[0] = currentRow[0] + 1; XWPFTableRow row = table.insertNewTableRow(currentRow[0]); diff --git a/frontend/sw360-portlet/src/main/java/org/eclipse/sw360/portal/portlets/projects/ProjectPortlet.java b/frontend/sw360-portlet/src/main/java/org/eclipse/sw360/portal/portlets/projects/ProjectPortlet.java index ad0b1edf52..ee5468fa4a 100644 --- a/frontend/sw360-portlet/src/main/java/org/eclipse/sw360/portal/portlets/projects/ProjectPortlet.java +++ b/frontend/sw360-portlet/src/main/java/org/eclipse/sw360/portal/portlets/projects/ProjectPortlet.java @@ -293,8 +293,9 @@ private void downloadLicenseInfo(ResourceRequest request, ResourceResponse respo } private void sendLicenseInfoResponse(ResourceRequest request, ResourceResponse response, Project project, LicenseInfoFile licenseInfoFile) throws IOException { - OutputFormatInfo outputFormatInfo = licenseInfoFile.getOutputFormatInfo(); - String filename = String.format("LicenseInfo-%s%s-%s.%s", project.getName(), + OutputFormatInfo outputFormatInfo = licenseInfoFile.getOutputFormatInfo(); + String documentVariant = licenseInfoFile.getOutputFormatInfo().getVariant() == OutputFormatVariant.DISCLOSURE ? "LicenseInfo" : "ProjectClearingReport"; + String filename = String.format("%s-%s%s-%s.%s", documentVariant, project.getName(), StringUtils.isBlank(project.getVersion()) ? "" : "-" + project.getVersion(), SW360Utils.getCreatedOnTime().replaceAll("\\s", "_").replace(":", "_"), outputFormatInfo.getFileExtension()); diff --git a/frontend/sw360-portlet/src/main/webapp/html/components/editRelease.jsp b/frontend/sw360-portlet/src/main/webapp/html/components/editRelease.jsp index 9e4d08af4e..033846c82e 100644 --- a/frontend/sw360-portlet/src/main/webapp/html/components/editRelease.jsp +++ b/frontend/sw360-portlet/src/main/webapp/html/components/editRelease.jsp @@ -53,6 +53,7 @@ + @@ -179,6 +180,7 @@ Liferay.on('allPortletsReady', function() { autocomplete.prepareForMultipleHits('programminglanguages', ${programmingLanguages}); autocomplete.prepareForMultipleHits('op_systems', ${operatingSystemsAutoC}); + autocomplete.prepareForMultipleHits('platformsTB', ${platformsAutoC}); sw360Validate.validateWithInvalidHandlerNoIgnore('#releaseEditForm'); diff --git a/frontend/sw360-portlet/src/main/webapp/html/components/includes/releases/editReleaseInformation.jspf b/frontend/sw360-portlet/src/main/webapp/html/components/includes/releases/editReleaseInformation.jspf index 8efa9c9e8c..fefa062cab 100644 --- a/frontend/sw360-portlet/src/main/webapp/html/components/includes/releases/editReleaseInformation.jspf +++ b/frontend/sw360-portlet/src/main/webapp/html/components/includes/releases/editReleaseInformation.jspf @@ -16,7 +16,7 @@ - + @@ -38,21 +38,28 @@ - - - +
Release SummaryRelease Summary
+ + "/> + + + "/> + operatingSystems, 54: optional COTSDetails cotsDetails, 55: optional EccInformation eccInformation, + 56: optional set softwarePlatforms, 65: optional set mainLicenseIds, diff --git a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java index 4c5fe054ac..2bcc82c2b8 100644 --- a/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java +++ b/rest/resource-server/src/main/java/org/eclipse/sw360/rest/resourceserver/project/ProjectController.java @@ -28,6 +28,7 @@ import org.eclipse.sw360.datahandler.thrift.licenseinfo.LicenseInfoFile; import org.eclipse.sw360.datahandler.thrift.licenseinfo.LicenseNameWithText; import org.eclipse.sw360.datahandler.thrift.licenseinfo.OutputFormatInfo; +import org.eclipse.sw360.datahandler.thrift.licenseinfo.OutputFormatVariant; import org.eclipse.sw360.datahandler.thrift.licenses.License; import org.eclipse.sw360.datahandler.thrift.projects.Project; import org.eclipse.sw360.datahandler.thrift.projects.ProjectRelationship; @@ -282,9 +283,10 @@ public void downloadLicenseInfo(@PathVariable("id") String id, final String projectName = sw360Project.getName(); final String projectVersion = sw360Project.getVersion(); - final String timestamp = SW360Utils.getCreatedOnTime().replaceAll("\\s", "_").replace(":", "_"); - final OutputFormatInfo outputFormatInfo = licenseInfoService.getOutputFormatInfoForGeneratorClass(generatorClassName); - final String filename = String.format("LicenseInfo-%s%s-%s.%s", projectName, + final String timestamp = SW360Utils.getCreatedOnTime().replaceAll("\\s", "_").replace(":", "_"); + final OutputFormatInfo outputFormatInfo = licenseInfoService.getOutputFormatInfoForGeneratorClass(generatorClassName); + final String variant = outputFormatInfo.variant == OutputFormatVariant.DISCLOSURE ? "LicenseInfo" : "ProjectClearingReport"; + final String filename = String.format("%s-%s%s-%s.%s", variant, projectName, StringUtils.isBlank(projectVersion) ? "" : "-" + projectVersion, timestamp, outputFormatInfo.getFileExtension());