Skip to content

Commit 04d1965

Browse files
author
Nikolas Sepos
committed
fix(report): corrections to report
As per: siemens#18 Signed-off-by: Nikolas Sepos <[email protected]>
1 parent 79eaabd commit 04d1965

File tree

9 files changed

+102
-49
lines changed

9 files changed

+102
-49
lines changed

backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/LicenseInfoHandler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ protected LicenseInfoHandler(AttachmentDatabaseHandler attachmentDatabaseHandler
9494
new TextGenerator(DISCLOSURE, "License Disclosure as TEXT"),
9595
new XhtmlGenerator(DISCLOSURE, "License Disclosure as XHTML"),
9696
new DocxGenerator(DISCLOSURE, "License Disclosure as DOCX"),
97-
new DocxGenerator(REPORT, "License Report as DOCX")
97+
new DocxGenerator(REPORT, "Project Clearing Report as DOCX")
9898
);
9999
// @formatter:on
100100
}

backend/src/src-licenseinfo/src/main/java/org/eclipse/sw360/licenseinfo/outputGenerators/DocxGenerator.java

+68-33
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.apache.log4j.Logger;
1616
import org.apache.poi.xwpf.usermodel.*;
1717
import org.apache.thrift.TException;
18+
import org.apache.xmlbeans.XmlCursor;
1819
import org.apache.xmlbeans.XmlException;
1920
import org.eclipse.sw360.datahandler.common.CommonUtils;
2021
import org.eclipse.sw360.datahandler.common.SW360Utils;
@@ -29,6 +30,8 @@
2930
import org.eclipse.sw360.datahandler.thrift.licenses.LicenseService;
3031
import org.eclipse.sw360.datahandler.thrift.licenses.Todo;
3132
import org.eclipse.sw360.datahandler.thrift.projects.Project;
33+
import org.eclipse.sw360.datahandler.thrift.projects.ProjectLink;
34+
import org.eclipse.sw360.datahandler.thrift.projects.ProjectService;
3235
import org.eclipse.sw360.datahandler.thrift.users.User;
3336
import org.eclipse.sw360.datahandler.thrift.users.UserService;
3437

@@ -47,17 +50,24 @@ public class DocxGenerator extends OutputGenerator<byte[]> {
4750
private static final Logger LOGGER = Logger.getLogger(DocxGenerator.class);
4851
private static final String UNKNOWN_LICENSE_NAME = "Unknown license name";
4952
private static final String UNKNOWN_FILE_NAME = "Unknown file name";
53+
private static final String UNKNOWN_LICENSE = "Unknown";
5054
private static final String TODO_DEFAULT_TEXT = "todo not determined so far.";
5155

5256
private static final String DOCX_TEMPLATE_FILE = "/templateFrontpageContent.docx";
5357
private static final String DOCX_TEMPLATE_REPORT_FILE = "/templateReport.docx";
5458
private static final String DOCX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
5559
private static final String DOCX_OUTPUT_TYPE = "docx";
56-
public static final String UNKNOWN_LICENSE = "Unknown";
60+
5761
private static final long ADDITIONAL_REQ_THRESHOLD = 3;
58-
public static final int ADDITIONAL_REQ_TABLE_INDEX = 5;
62+
63+
public static final int OVERVIEW_TABLE_INDEX = 0;
64+
public static final int SPECIAL_OSS_RISKS_TABLE_INDEX = 1;
5965
public static final int DEV_DETAIL_TABLE_INDEX = 2;
66+
public static final int THIRD_PARTY_COMPONENT_OVERVIEW_TABLE_INDEX = 3;
6067
private static final int COMMON_RULES_TABLE_INDEX = 4;
68+
public static final int ADDITIONAL_REQ_TABLE_INDEX = 5;
69+
70+
6171

6272
public DocxGenerator(OutputFormatVariant outputFormatVariant, String description) {
6373
super(DOCX_OUTPUT_TYPE, description, true, DOCX_MIME_TYPE, outputFormatVariant);
@@ -136,7 +146,7 @@ private void fillDisclosureDocument(
136146
fillReleaseBulletList(document, projectLicenseInfoResults);
137147
fillReleaseDetailList(document, projectLicenseInfoResults, includeObligations);
138148
fillLicenseList(document, projectLicenseInfoResults);
139-
}
149+
}
140150

141151
private void fillReportDocument(
142152
XWPFDocument document,
@@ -147,6 +157,7 @@ private void fillReportDocument(
147157
Collection<ObligationParsingResult> obligationResults,
148158
User user) throws XmlException, TException {
149159

160+
String businessUnit = project.getBusinessUnit();
150161
String projectName = project.getName();
151162
String projectVersion = project.getVersion();
152163
String obligationsText = project.getObligationsText();
@@ -157,11 +168,13 @@ private void fillReportDocument(
157168
String deliveryChannelsText = project.getDeliveryChannels();
158169
String remarksAdditionalRequirementsText = project.getRemarksAdditionalRequirements();
159170
String projectDescription = project.getDescription();
160-
171+
// extract licenses that appear at least ADDITIONAL_REQ_THRESHOLD times
172+
Set<String> mostLicenses = extractMostCommonLicenses(obligationResults, ADDITIONAL_REQ_THRESHOLD);
161173

162174
fillOwnerGroup(document, project);
163175
fillAttendeesTable(document, project);
164176

177+
replaceText(document, "$bunit", businessUnit);
165178
replaceText(document, "$license-info-header", licenseInfoHeaderText);
166179
replaceText(document, "$project-name", projectName);
167180
replaceText(document, "$project-version", projectVersion);
@@ -175,13 +188,13 @@ private void fillReportDocument(
175188
replaceText(document, "$product-description", projectDescription);
176189

177190
fillSpecialOSSRisksTable(document, project, obligationResults);
178-
fillDevelopmentDetailsTable(document, project, user);
191+
fillDevelopmentDetailsTable(document, project, user, projectLicenseInfoResults);
179192
fillOverview3rdPartyComponentTable(document, projectLicenseInfoResults);
193+
180194
fillCommonRulesTable(document, project);
181-
fillAdditionalRequirementsTable(document, obligationResults);
195+
replaceText(document, "$list_comma_sep_licenses_above_threshold", String.join(", ", mostLicenses));
196+
fillAdditionalRequirementsTable(document, obligationResults, mostLicenses);
182197

183-
// because of the impossible API component subsections must be the last thing in the docx file
184-
// the rest of the sections must be generated after this
185198
writeComponentSubsections(document, projectLicenseInfoResults, obligationResults);
186199
}
187200

@@ -194,9 +207,9 @@ private void fillOwnerGroup(XWPFDocument document, Project project) throws XmlEx
194207
}
195208

196209
private void fillAttendeesTable(XWPFDocument document, Project project) throws XmlException, TException {
197-
XWPFTable table = document.getTables().get(0);
210+
XWPFTable table = document.getTables().get(OVERVIEW_TABLE_INDEX);
198211

199-
int currentRow = 6;
212+
int currentRow = 7;
200213

201214
UserService.Iface userClient = new ThriftClients().makeUserClient();
202215

@@ -220,7 +233,12 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X
220233
continue;
221234
}
222235

223-
User user = userClient.getByEmail(email);
236+
User user = null;
237+
try {
238+
user = userClient.getByEmail(email);
239+
} catch (TException te) {
240+
// a resulting null user object is handled below by replacing with email
241+
}
224242

225243
XWPFTableRow row = table.insertNewTableRow(currentRow++);
226244
String name = email;
@@ -229,7 +247,7 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X
229247
}
230248
String department = "N.A.";
231249
if(user != null) {
232-
name = user.getDepartment();
250+
department = user.getDepartment();
233251
}
234252

235253
row.addNewTableCell().setText(name);
@@ -241,7 +259,7 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X
241259
}
242260

243261
private void fillSpecialOSSRisksTable(XWPFDocument document, Project project, Collection<ObligationParsingResult> obligationResults) throws XmlException, TException {
244-
XWPFTable table = document.getTables().get(1);
262+
XWPFTable table = document.getTables().get(SPECIAL_OSS_RISKS_TABLE_INDEX);
245263
final int[] currentRow = new int[]{0};
246264

247265
obligationResults.stream()
@@ -260,7 +278,7 @@ private void fillSpecialOSSRisksTable(XWPFDocument document, Project project, Co
260278
}
261279

262280
private void fillOverview3rdPartyComponentTable(XWPFDocument document, Collection<LicenseInfoParsingResult> projectLicenseInfoResults) throws XmlException {
263-
XWPFTable table = document.getTables().get(3);
281+
XWPFTable table = document.getTables().get(THIRD_PARTY_COMPONENT_OVERVIEW_TABLE_INDEX);
264282

265283
int currentRow = 1;
266284
for(LicenseInfoParsingResult result : projectLicenseInfoResults) {
@@ -292,17 +310,31 @@ private static Optional<ObligationParsingResult> obligationsForRelease(Release r
292310
return obligationResults.stream().filter(opr -> opr.getRelease() == release).findFirst();
293311
}
294312

295-
private void writeComponentSubsections(XWPFDocument document, Collection<LicenseInfoParsingResult> projectLicenseInfoResults, Collection<ObligationParsingResult> obligationResults) throws XmlException {
313+
private void writeComponentSubsections(XWPFDocument document, Collection<LicenseInfoParsingResult> projectLicenseInfoResults, Collection<ObligationParsingResult> obligationResults) throws SW360Exception, XmlException {
314+
XmlCursor cursor = document.getTables().get(ADDITIONAL_REQ_TABLE_INDEX).getCTTbl().newCursor();
315+
cursor.toEndToken();
296316

297317
for (LicenseInfoParsingResult result : projectLicenseInfoResults) {
318+
while (cursor.currentTokenType() != XmlCursor.TokenType.START && cursor.hasNextToken()) {
319+
cursor.toNextToken();
320+
}
298321

299-
XWPFParagraph title = document.createParagraph();
322+
if (cursor.currentTokenType() != XmlCursor.TokenType.START) {
323+
throw new SW360Exception("Corrupt template; unable find start token");
324+
}
325+
326+
XWPFParagraph title = document.insertNewParagraph(cursor);
300327
title.setStyle(STYLE_HEADING_3);
301328
title.setNumID(new BigInteger("2"));
302329
XWPFRun titleRun = title.createRun();
303330
titleRun.setText(result.getVendor() + " " + result.getName());
304331

305-
XWPFParagraph description = document.createParagraph();
332+
if (cursor.hasNextToken()) {
333+
cursor.toNextToken();
334+
} else {
335+
throw new SW360Exception("Corrupt template; unable to proceed to next token");
336+
}
337+
XWPFParagraph description = document.insertNewParagraph(cursor);
306338
XWPFRun descriptionRun = description.createRun();
307339

308340
LicenseInfo licenseInfo = result.getLicenseInfo();
@@ -331,7 +363,7 @@ private void writeComponentSubsections(XWPFDocument document, Collection<License
331363

332364
int currentRow = 0;
333365
Collection<Obligation> obligations = obligationsResult.getObligations();
334-
XWPFTable table = document.createTable();
366+
XWPFTable table = document.insertNewTbl(cursor);
335367
for (Obligation o : obligations) {
336368
XWPFTableRow row = table.insertNewTableRow(currentRow++);
337369
String licensesString = String.join(" ", o.getLicenseIDs());
@@ -343,29 +375,34 @@ private void writeComponentSubsections(XWPFDocument document, Collection<License
343375
}
344376
}
345377

346-
private void fillDevelopmentDetailsTable(XWPFDocument document, Project project, User user) throws TException {
378+
private void fillDevelopmentDetailsTable(XWPFDocument document, Project project, User user, Collection<LicenseInfoParsingResult> projectLicenseInfoResults) throws TException {
347379
XWPFTable table = document.getTables().get(DEV_DETAIL_TABLE_INDEX);
348380

349381
int currentRow = 1;
350382

351-
ComponentService.Iface compClient = new ThriftClients().makeComponentClient();
352-
List<ReleaseLink> rll = compClient.getLinkedReleases(project.getReleaseIdToUsage());
383+
for(LicenseInfoParsingResult result : projectLicenseInfoResults) {
384+
if (result.getStatus() != LicenseInfoRequestStatus.SUCCESS) {
385+
// this error handling is for extra safety since projectLicenseInfoResults is provided by the caller
386+
// and we assume valid input so we silently ignoring it.
387+
continue;
388+
}
353389

354-
for (ReleaseLink rl : rll) {
355-
Release r = compClient.getReleaseById(rl.getId(), user);
356-
Component component = compClient.getComponentById(r.getComponentId(), user);
390+
Release r = result.getRelease();
391+
if (r == null) {
392+
continue;
393+
}
357394

358395
XWPFTableRow row = table.insertNewTableRow(currentRow++);
359396

360-
row.addNewTableCell().setText(component.getName());
397+
row.addNewTableCell().setText(r.getName());
361398

362-
String operatingSystems = component.getOperatingSystemsSize() == 0 ? "Unknown operating systems" : String.join(" ", component.getOperatingSystems());
399+
String operatingSystems = r.getOperatingSystemsSize() == 0 ? "N/A" : String.join(" ", r.getOperatingSystems());
363400
row.addNewTableCell().setText(operatingSystems);
364401

365-
String langs = component.getLanguagesSize() == 0 ? "Unknown languages" : String.join(" ", component.getLanguages());
402+
String langs = r.getLanguagesSize() == 0 ? "N/A" : String.join(" ", r.getLanguages());
366403
row.addNewTableCell().setText(langs);
367404

368-
String platforms = component.getSoftwarePlatformsSize() == 0 ? "Unknown platforms" : String.join(" ", component.getSoftwarePlatforms());
405+
String platforms = r.getSoftwarePlatformsSize() == 0 ? "N/A" : String.join(" ", r.getSoftwarePlatforms());
369406
row.addNewTableCell().setText(platforms);
370407
}
371408
}
@@ -379,21 +416,19 @@ protected static Set<String> extractMostCommonLicenses(Collection<ObligationPars
379416
.entrySet().stream()
380417
.filter(entry -> entry.getValue().longValue() >= threshold)
381418
.map(entry -> entry.getKey())
419+
.map(license -> license.replace("\n", "").replace("\r", ""))
382420
.collect(Collectors.toSet());
383421
}
384422

385-
private void fillAdditionalRequirementsTable(XWPFDocument document, Collection<ObligationParsingResult> obligationResults) throws XmlException {
386-
// extract licenses that appear at least ADDITIONAL_REQ_THRESHOLD times
387-
Set<String> mostLicenses = extractMostCommonLicenses(obligationResults, ADDITIONAL_REQ_THRESHOLD);
388-
423+
private void fillAdditionalRequirementsTable(XWPFDocument document, Collection<ObligationParsingResult> obligationResults, Set<String> mostLicenses) throws XmlException {
389424
XWPFTable table = document.getTables().get(ADDITIONAL_REQ_TABLE_INDEX);
390425
final int[] currentRow = new int[]{0};
391426

392427
obligationResults.stream()
393428
.filter(opr -> opr.getStatus() == ObligationInfoRequestStatus.SUCCESS)
394429
.flatMap(opr -> opr.getObligations().stream())
395430
.filter(o -> o.getLicenseIDs().stream()
396-
.anyMatch(lid -> mostLicenses.parallelStream().anyMatch(mlid -> mlid.equals(lid))))
431+
.anyMatch(lid -> mostLicenses.parallelStream().anyMatch(mlid -> mlid.equals(lid.replace("\n", "").replace("\r", "")))))
397432
.forEach(o -> {
398433
currentRow[0] = currentRow[0] + 1;
399434
XWPFTableRow row = table.insertNewTableRow(currentRow[0]);
Binary file not shown.

frontend/sw360-portlet/src/main/java/org/eclipse/sw360/portal/portlets/projects/ProjectPortlet.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,9 @@ private void downloadLicenseInfo(ResourceRequest request, ResourceResponse respo
320320
}
321321

322322
private void sendLicenseInfoResponse(ResourceRequest request, ResourceResponse response, Project project, LicenseInfoFile licenseInfoFile) throws IOException {
323-
OutputFormatInfo outputFormatInfo = licenseInfoFile.getOutputFormatInfo();
324-
String filename = String.format("LicenseInfo-%s%s-%s.%s", project.getName(),
323+
OutputFormatInfo outputFormatInfo = licenseInfoFile.getOutputFormatInfo();
324+
String documentVariant = licenseInfoFile.getOutputFormatInfo().getVariant() == OutputFormatVariant.DISCLOSURE ? "LicenseInfo" : "ProjectClearingReport";
325+
String filename = String.format("%s-%s%s-%s.%s", documentVariant, project.getName(),
325326
StringUtils.isBlank(project.getVersion()) ? "" : "-" + project.getVersion(),
326327
SW360Utils.getCreatedOnTime().replaceAll("\\s", "_").replace(":", "_"),
327328
outputFormatInfo.getFileExtension());

frontend/sw360-portlet/src/main/webapp/html/components/editRelease.jsp

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353

5454
<core_rt:set var="programmingLanguages" value='<%=PortalConstants.PROGRAMMING_LANGUAGES%>'/>
5555
<core_rt:set var="operatingSystemsAutoC" value='<%=PortalConstants.OPERATING_SYSTEMS%>'/>
56+
<core_rt:set var="platformsAutoC" value='<%=PortalConstants.SOFTWARE_PLATFORMS%>'/>
5657

5758
<core_rt:set var="addMode" value="${empty release.id}"/>
5859
<core_rt:set var="cotsMode" value="<%=component.componentType == ComponentType.COTS%>"/>
@@ -179,6 +180,7 @@
179180
Liferay.on('allPortletsReady', function() {
180181
autocomplete.prepareForMultipleHits('programminglanguages', ${programmingLanguages});
181182
autocomplete.prepareForMultipleHits('op_systems', ${operatingSystemsAutoC});
183+
autocomplete.prepareForMultipleHits('platformsTB', ${platformsAutoC});
182184
183185
sw360Validate.validateWithInvalidHandlerNoIgnore('#releaseEditForm');
184186

frontend/sw360-portlet/src/main/webapp/html/components/includes/releases/editReleaseInformation.jspf

+18-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<table class="table info_table" id="ComponentBasicInfo">
1717
<thead>
1818
<tr>
19-
<th colspan="3" class="headlabel">Release Summary</th>
19+
<th colspan="4" class="headlabel">Release Summary</th>
2020
</tr>
2121
</thead>
2222
<tr>
@@ -52,6 +52,17 @@
5252
placeholder="e.g.,Linux,MAC,Windows,..."
5353
value="<sw360:DisplayCollection value="${release.operatingSystems}" />"/>
5454
</td>
55+
<td width="33%">
56+
<label class="textlabel stackedLabel" for="platformsTB">Software Platforms</label>
57+
<input class="toplabelledInput" id="platformsTB"
58+
name="<portlet:namespace/><%=Component._Fields.SOFTWARE_PLATFORMS%>" type="text" align="middle"
59+
placeholder="e.g.,Adobe AIR,.NET,Qt,..."
60+
value="<sw360:DisplayCollection value="${release.softwarePlatforms}" />"/>
61+
</td>
62+
63+
</tr>
64+
65+
<tr>
5566
<td width="33%">
5667
<label class="textlabel stackedLabel" for="comp_id">CPE ID</label>
5768
<input id="comp_id" name="<portlet:namespace/><%=Release._Fields.CPEID%>" type="text"
@@ -61,22 +72,13 @@
6172
<img class="infopic" src="<%=request.getContextPath()%>/images/ic_info.png"
6273
title="The formula for CPE ID creation is &#13;'cpe:2.3:a:VENDORNAME:COMPONENTNAME:VERSION' "/>
6374
</td>
64-
</tr>
65-
66-
<tr>
6775
<td width="33%">
6876
<label class="textlabel stackedLabel" for="releaseDate">Release Date</label>
6977
<input id="releaseDate" class="datepicker" name="<portlet:namespace/><%=Release._Fields.RELEASE_DATE%>" type="text"
7078
placeholder="Enter Release Date"
7179
pattern="\d{4}-\d{2}-\d{2}"
7280
value="<sw360:out value="${release.releaseDate}"/>"/>
7381
</td>
74-
75-
<td width="33%">
76-
<sw360:DisplayMainLicensesEdit id="<%=Release._Fields.MAIN_LICENSE_IDS.toString()%>"
77-
licenseIds="${release.mainLicenseIds}"/>
78-
</td>
79-
8082
<td width="33%">
8183
<label class="textlabel stackedLabel" for="downloadUrl">Download URL</label>
8284
<input id="downloadUrl" name="<portlet:namespace/><%=Release._Fields.DOWNLOADURL%>" type="URL"
@@ -133,6 +135,12 @@
133135
description="Moderators" multiUsers="true" readonly="false"/>
134136
</td>
135137
</tr>
138+
<tr>
139+
<td width="33%">
140+
<sw360:DisplayMainLicensesEdit id="<%=Release._Fields.MAIN_LICENSE_IDS.toString()%>"
141+
licenseIds="${release.mainLicenseIds}"/>
142+
</td>
143+
</tr>
136144
</table>
137145

138146
<script>

libraries/lib-datahandler/src/main/thrift/components.thrift

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ struct Release {
206206
53: optional set<string> operatingSystems,
207207
54: optional COTSDetails cotsDetails,
208208
55: optional EccInformation eccInformation,
209+
56: optional set<string> softwarePlatforms,
209210

210211
65: optional set<string> mainLicenseIds,
211212

0 commit comments

Comments
 (0)