15
15
import org .apache .log4j .Logger ;
16
16
import org .apache .poi .xwpf .usermodel .*;
17
17
import org .apache .thrift .TException ;
18
+ import org .apache .xmlbeans .XmlCursor ;
18
19
import org .apache .xmlbeans .XmlException ;
19
20
import org .eclipse .sw360 .datahandler .common .CommonUtils ;
20
21
import org .eclipse .sw360 .datahandler .thrift .SW360Exception ;
@@ -46,16 +47,23 @@ public class DocxGenerator extends OutputGenerator<byte[]> {
46
47
private static final Logger LOGGER = Logger .getLogger (DocxGenerator .class );
47
48
private static final String UNKNOWN_LICENSE_NAME = "Unknown license name" ;
48
49
private static final String UNKNOWN_FILE_NAME = "Unknown file name" ;
50
+ private static final String UNKNOWN_LICENSE = "Unknown" ;
49
51
private static final String TODO_DEFAULT_TEXT = "todo not determined so far." ;
50
52
51
53
private static final String DOCX_TEMPLATE_FILE = "/templateFrontpageContent.docx" ;
52
54
private static final String DOCX_TEMPLATE_REPORT_FILE = "/templateReport.docx" ;
53
55
private static final String DOCX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ;
54
56
private static final String DOCX_OUTPUT_TYPE = "docx" ;
55
- public static final String UNKNOWN_LICENSE = "Unknown" ;
57
+
56
58
private static final long ADDITIONAL_REQ_THRESHOLD = 3 ;
57
- public static final int ADDITIONAL_REQ_TABLE_INDEX = 4 ;
59
+
60
+ public static final int OVERVIEW_TABLE_INDEX = 0 ;
61
+ public static final int SPECIAL_OSS_RISKS_TABLE_INDEX = 1 ;
58
62
public static final int DEV_DETAIL_TABLE_INDEX = 2 ;
63
+ public static final int THIRD_PARTY_COMPONENT_OVERVIEW_TABLE_INDEX = 3 ;
64
+ public static final int ADDITIONAL_REQ_TABLE_INDEX = 4 ;
65
+
66
+
59
67
60
68
public DocxGenerator (OutputFormatVariant outputFormatVariant , String description ) {
61
69
super (DOCX_OUTPUT_TYPE , description , true , DOCX_MIME_TYPE , outputFormatVariant );
@@ -134,7 +142,7 @@ private void fillDisclosureDocument(
134
142
fillReleaseBulletList (document , projectLicenseInfoResults );
135
143
fillReleaseDetailList (document , projectLicenseInfoResults , includeObligations );
136
144
fillLicenseList (document , projectLicenseInfoResults );
137
- }
145
+ }
138
146
139
147
private void fillReportDocument (
140
148
XWPFDocument document ,
@@ -145,6 +153,7 @@ private void fillReportDocument(
145
153
Collection <ObligationParsingResult > obligationResults ,
146
154
User user ) throws XmlException , TException {
147
155
156
+ String businessUnit = project .getBusinessUnit ();
148
157
String projectName = project .getName ();
149
158
String projectVersion = project .getVersion ();
150
159
String obligationsText = project .getObligationsText ();
@@ -155,11 +164,13 @@ private void fillReportDocument(
155
164
String deliveryChannelsText = project .getDeliveryChannels ();
156
165
String remarksAdditionalRequirementsText = project .getRemarksAdditionalRequirements ();
157
166
String projectDescription = project .getDescription ();
158
-
167
+ // extract licenses that appear at least ADDITIONAL_REQ_THRESHOLD times
168
+ Set <String > mostLicenses = extractMostCommonLicenses (obligationResults , ADDITIONAL_REQ_THRESHOLD );
159
169
160
170
fillOwnerGroup (document , project );
161
171
fillAttendeesTable (document , project );
162
172
173
+ replaceText (document , "$bunit" , businessUnit );
163
174
replaceText (document , "$license-info-header" , licenseInfoHeaderText );
164
175
replaceText (document , "$project-name" , projectName );
165
176
replaceText (document , "$project-version" , projectVersion );
@@ -175,10 +186,9 @@ private void fillReportDocument(
175
186
fillSpecialOSSRisksTable (document , project , obligationResults );
176
187
fillDevelopmentDetailsTable (document , project , user );
177
188
fillOverview3rdPartyComponentTable (document , projectLicenseInfoResults );
178
- fillAdditionalRequirementsTable (document , obligationResults );
189
+ replaceText (document , "$list_comma_sep_licenses_above_threshold" , String .join (", " , mostLicenses ));
190
+ fillAdditionalRequirementsTable (document , obligationResults , mostLicenses );
179
191
180
- // because of the impossible API component subsections must be the last thing in the docx file
181
- // the rest of the sections must be generated after this
182
192
writeComponentSubsections (document , projectLicenseInfoResults , obligationResults );
183
193
}
184
194
@@ -191,9 +201,9 @@ private void fillOwnerGroup(XWPFDocument document, Project project) throws XmlEx
191
201
}
192
202
193
203
private void fillAttendeesTable (XWPFDocument document , Project project ) throws XmlException , TException {
194
- XWPFTable table = document .getTables ().get (0 );
204
+ XWPFTable table = document .getTables ().get (OVERVIEW_TABLE_INDEX );
195
205
196
- int currentRow = 6 ;
206
+ int currentRow = 7 ;
197
207
198
208
UserService .Iface userClient = new ThriftClients ().makeUserClient ();
199
209
@@ -217,7 +227,12 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X
217
227
continue ;
218
228
}
219
229
220
- User user = userClient .getByEmail (email );
230
+ User user = null ;
231
+ try {
232
+ user = userClient .getByEmail (email );
233
+ } catch (TException te ) {
234
+
235
+ }
221
236
222
237
XWPFTableRow row = table .insertNewTableRow (currentRow ++);
223
238
String name = email ;
@@ -226,7 +241,7 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X
226
241
}
227
242
String department = "N.A." ;
228
243
if (user != null ) {
229
- name = user .getDepartment ();
244
+ department = user .getDepartment ();
230
245
}
231
246
232
247
row .addNewTableCell ().setText (name );
@@ -238,7 +253,7 @@ private void fillAttendeesTable(XWPFDocument document, Project project) throws X
238
253
}
239
254
240
255
private void fillSpecialOSSRisksTable (XWPFDocument document , Project project , Collection <ObligationParsingResult > obligationResults ) throws XmlException , TException {
241
- XWPFTable table = document .getTables ().get (1 );
256
+ XWPFTable table = document .getTables ().get (SPECIAL_OSS_RISKS_TABLE_INDEX );
242
257
final int [] currentRow = new int []{0 };
243
258
244
259
obligationResults .stream ()
@@ -257,7 +272,7 @@ private void fillSpecialOSSRisksTable(XWPFDocument document, Project project, Co
257
272
}
258
273
259
274
private void fillOverview3rdPartyComponentTable (XWPFDocument document , Collection <LicenseInfoParsingResult > projectLicenseInfoResults ) throws XmlException {
260
- XWPFTable table = document .getTables ().get (3 );
275
+ XWPFTable table = document .getTables ().get (THIRD_PARTY_COMPONENT_OVERVIEW_TABLE_INDEX );
261
276
262
277
int currentRow = 1 ;
263
278
for (LicenseInfoParsingResult result : projectLicenseInfoResults ) {
@@ -289,17 +304,31 @@ private static Optional<ObligationParsingResult> obligationsForRelease(Release r
289
304
return obligationResults .stream ().filter (opr -> opr .getRelease () == release ).findFirst ();
290
305
}
291
306
292
- private void writeComponentSubsections (XWPFDocument document , Collection <LicenseInfoParsingResult > projectLicenseInfoResults , Collection <ObligationParsingResult > obligationResults ) throws XmlException {
307
+ private void writeComponentSubsections (XWPFDocument document , Collection <LicenseInfoParsingResult > projectLicenseInfoResults , Collection <ObligationParsingResult > obligationResults ) throws SW360Exception , XmlException {
308
+ XmlCursor cursor = document .getTables ().get (ADDITIONAL_REQ_TABLE_INDEX ).getCTTbl ().newCursor ();
309
+ cursor .toEndToken ();
293
310
294
311
for (LicenseInfoParsingResult result : projectLicenseInfoResults ) {
312
+ while (cursor .currentTokenType () != XmlCursor .TokenType .START && cursor .hasNextToken ()) {
313
+ cursor .toNextToken ();
314
+ }
315
+
316
+ if (cursor .currentTokenType () != XmlCursor .TokenType .START ) {
317
+ throw new SW360Exception ("Corrupt template; unable find start token" );
318
+ }
295
319
296
- XWPFParagraph title = document .createParagraph ( );
320
+ XWPFParagraph title = document .insertNewParagraph ( cursor );
297
321
title .setStyle (STYLE_HEADING_3 );
298
322
title .setNumID (new BigInteger ("2" ));
299
323
XWPFRun titleRun = title .createRun ();
300
324
titleRun .setText (result .getVendor () + " " + result .getName ());
301
325
302
- XWPFParagraph description = document .createParagraph ();
326
+ if (cursor .hasNextToken ()) {
327
+ cursor .toNextToken ();
328
+ } else {
329
+ throw new SW360Exception ("Corrupt template; unable to proceed to next token" );
330
+ }
331
+ XWPFParagraph description = document .insertNewParagraph (cursor );
303
332
XWPFRun descriptionRun = description .createRun ();
304
333
305
334
LicenseInfo licenseInfo = result .getLicenseInfo ();
@@ -328,7 +357,7 @@ private void writeComponentSubsections(XWPFDocument document, Collection<License
328
357
329
358
int currentRow = 0 ;
330
359
Collection <Obligation > obligations = obligationsResult .getObligations ();
331
- XWPFTable table = document .createTable ( );
360
+ XWPFTable table = document .insertNewTbl ( cursor );
332
361
for (Obligation o : obligations ) {
333
362
XWPFTableRow row = table .insertNewTableRow (currentRow ++);
334
363
String licensesString = String .join (" " , o .getLicenseIDs ());
@@ -356,13 +385,13 @@ private void fillDevelopmentDetailsTable(XWPFDocument document, Project project,
356
385
357
386
row .addNewTableCell ().setText (component .getName ());
358
387
359
- String operatingSystems = component .getOperatingSystemsSize () == 0 ? "Unknown operating systems " : String .join (" " , component .getOperatingSystems ());
388
+ String operatingSystems = component .getOperatingSystemsSize () == 0 ? "N/A " : String .join (" " , component .getOperatingSystems ());
360
389
row .addNewTableCell ().setText (operatingSystems );
361
390
362
- String langs = component .getLanguagesSize () == 0 ? "Unknown languages " : String .join (" " , component .getLanguages ());
391
+ String langs = component .getLanguagesSize () == 0 ? "N/A " : String .join (" " , component .getLanguages ());
363
392
row .addNewTableCell ().setText (langs );
364
393
365
- String platforms = component .getSoftwarePlatformsSize () == 0 ? "Unknown platforms " : String .join (" " , component .getSoftwarePlatforms ());
394
+ String platforms = component .getSoftwarePlatformsSize () == 0 ? "N/A " : String .join (" " , component .getSoftwarePlatforms ());
366
395
row .addNewTableCell ().setText (platforms );
367
396
}
368
397
}
@@ -376,21 +405,19 @@ protected static Set<String> extractMostCommonLicenses(Collection<ObligationPars
376
405
.entrySet ().stream ()
377
406
.filter (entry -> entry .getValue ().longValue () >= threshold )
378
407
.map (entry -> entry .getKey ())
408
+ .map (license -> license .replace ("\n " , "" ).replace ("\r " , "" ))
379
409
.collect (Collectors .toSet ());
380
410
}
381
411
382
- private void fillAdditionalRequirementsTable (XWPFDocument document , Collection <ObligationParsingResult > obligationResults ) throws XmlException {
383
- // extract licenses that appear at least ADDITIONAL_REQ_THRESHOLD times
384
- Set <String > mostLicenses = extractMostCommonLicenses (obligationResults , ADDITIONAL_REQ_THRESHOLD );
385
-
412
+ private void fillAdditionalRequirementsTable (XWPFDocument document , Collection <ObligationParsingResult > obligationResults , Set <String > mostLicenses ) throws XmlException {
386
413
XWPFTable table = document .getTables ().get (ADDITIONAL_REQ_TABLE_INDEX );
387
414
final int [] currentRow = new int []{0 };
388
415
389
416
obligationResults .stream ()
390
417
.filter (opr -> opr .getStatus () == ObligationInfoRequestStatus .SUCCESS )
391
418
.flatMap (opr -> opr .getObligations ().stream ())
392
419
.filter (o -> o .getLicenseIDs ().stream ()
393
- .anyMatch (lid -> mostLicenses .parallelStream ().anyMatch (mlid -> mlid .equals (lid ))))
420
+ .anyMatch (lid -> mostLicenses .parallelStream ().anyMatch (mlid -> mlid .equals (lid . replace ( " \n " , "" ). replace ( " \r " , "" ) ))))
394
421
.forEach (o -> {
395
422
currentRow [0 ] = currentRow [0 ] + 1 ;
396
423
XWPFTableRow row = table .insertNewTableRow (currentRow [0 ]);
0 commit comments