Pull request #1: RED-231: Implemented logic
Merge in RED/redaction-report-service from RED-231 to master * commit 'b9ac93aae92270edb13bf9e055c94e39f5fdfb57': RED-231: Implemented logic
This commit is contained in:
commit
1b04d4c668
@ -14,6 +14,11 @@
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.iqser.red.service</groupId>
|
||||
<artifactId>redaction-service-api-v1</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- This dependency contains annotations that are used in specifying REST endpoints. -->
|
||||
<!-- It is optional since not all users of this API might use Feign. -->
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
package com.iqser.red.service.redaction.report.v1.api.model;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.RedactionLog;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class FileRedactionLog {
|
||||
|
||||
private String filename;
|
||||
private RedactionLog redactionLog;
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.iqser.red.service.redaction.report.v1.api.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class MultiFileRedactionLog {
|
||||
|
||||
private List<FileRedactionLog> FileRedactionLogs = new ArrayList<>();
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.iqser.red.service.redaction.report.v1.api.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ReportResult {
|
||||
|
||||
private byte[] document;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.iqser.red.service.redaction.report.v1.api.resource;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.MultiFileRedactionLog;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.ReportResult;
|
||||
|
||||
public interface RedactionReportResource {
|
||||
|
||||
String SERVICE_NAME = "redaction-report-service-v1";
|
||||
|
||||
@PostMapping(value = "/generate", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
ReportResult generateReport(@RequestBody MultiFileRedactionLog multiFileRedactionLog);
|
||||
|
||||
}
|
||||
@ -19,6 +19,21 @@
|
||||
<artifactId>redaction-report-service-api-v1</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>4.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>4.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>4.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.iqser.gin4.commons</groupId>
|
||||
<artifactId>spring-commons</artifactId>
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.MultiFileRedactionLog;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.ReportResult;
|
||||
import com.iqser.red.service.redaction.report.v1.api.resource.RedactionReportResource;
|
||||
import com.iqser.red.service.redaction.report.v1.server.service.ReportGenerationService;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class RedactionReportController implements RedactionReportResource {
|
||||
|
||||
private final ReportGenerationService reportGenerationService;
|
||||
|
||||
public ReportResult generateReport(@RequestBody MultiFileRedactionLog multiFileRedactionLog){
|
||||
return new ReportResult(reportGenerationService.generateReport(multiFileRedactionLog));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.service;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTable;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.MultiFileRedactionLog;
|
||||
import com.iqser.red.service.redaction.report.v1.server.utils.ResourceLoader;
|
||||
|
||||
@Service
|
||||
public class ReportGenerationService {
|
||||
|
||||
private byte[] template;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
|
||||
template = ResourceLoader.load("templates/Appendix A2.docx");
|
||||
}
|
||||
|
||||
|
||||
public byte[] generateReport(MultiFileRedactionLog multiFileRedactionLog) {
|
||||
|
||||
try (ByteArrayInputStream is = new ByteArrayInputStream(template)) {
|
||||
XWPFDocument doc = new XWPFDocument(is);
|
||||
doc = addTableRows(doc, multiFileRedactionLog);
|
||||
return toByteArray(doc);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private XWPFDocument addTableRows(XWPFDocument doc, MultiFileRedactionLog multiFileRedactionLog) {
|
||||
|
||||
XWPFTable table = doc.getTables().get(1);
|
||||
|
||||
multiFileRedactionLog.getFileRedactionLogs().forEach(fileRedactionLog -> {
|
||||
fileRedactionLog.getRedactionLog().getRedactionLogEntry().forEach(redactionLogEntry -> {
|
||||
Set<Integer> pages = new HashSet<>();
|
||||
redactionLogEntry.getPositions().forEach(position -> {
|
||||
pages.add(position.getPage());
|
||||
});
|
||||
pages.forEach(page -> {
|
||||
XWPFTableRow row = table.createRow();
|
||||
row.getCell(0).setText(fileRedactionLog.getFilename());
|
||||
row.getCell(1).setText(String.valueOf(page));
|
||||
row.getCell(2).setText(String.valueOf(redactionLogEntry.getSectionNumber()));
|
||||
row.getCell(3).setText(redactionLogEntry.getReason());
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
private byte[] toByteArray(XWPFDocument doc) throws FileNotFoundException, IOException {
|
||||
|
||||
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
|
||||
doc.write(byteArrayOutputStream);
|
||||
doc.close();
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public class ResourceLoader {
|
||||
|
||||
public byte[] load(String classpathPath) {
|
||||
|
||||
URL resource = ResourceLoader.class.getClassLoader().getResource(classpathPath);
|
||||
if (resource == null) {
|
||||
throw new IllegalArgumentException("could not load classpath resource: " + classpathPath);
|
||||
}
|
||||
try (InputStream is = resource.openStream()){
|
||||
return is.readAllBytes();
|
||||
} catch (IOException e){
|
||||
throw new IllegalArgumentException("could not load classpath resource: " + classpathPath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@ -1,16 +1,53 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.FileRedactionLog;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.MultiFileRedactionLog;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.ReportResult;
|
||||
import com.iqser.red.service.redaction.report.v1.server.controller.RedactionReportController;
|
||||
import com.iqser.red.service.redaction.v1.model.RedactionLog;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = DEFINED_PORT)
|
||||
public class RedactionReportIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
private RedactionReportController redactionReportController;
|
||||
|
||||
|
||||
@Test
|
||||
public void testServiceTemplate() {
|
||||
public void testReportGeneration() throws IOException {
|
||||
|
||||
ClassPathResource redactionLogResource = new ClassPathResource("files/RedactionLog.txt");
|
||||
|
||||
RedactionLog redactionLog = objectMapper.readValue(redactionLogResource.getInputStream(), RedactionLog.class);
|
||||
|
||||
FileRedactionLog fileRedactionLog = new FileRedactionLog("Metholachlor 1", redactionLog);
|
||||
MultiFileRedactionLog multiFileRedactionLog = new MultiFileRedactionLog(List.of(fileRedactionLog));
|
||||
|
||||
ReportResult reportResult = redactionReportController.generateReport(multiFileRedactionLog);
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream("/tmp/document.docx")) {
|
||||
fileOutputStream.write(reportResult.getDocument());
|
||||
}
|
||||
|
||||
assertThat(true).isTrue();
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1 @@
|
||||
{"redactionLogEntry":[{"id":"3080535605f06a5a397c4a9a5e501e9e","type":"address","value":"Regina Dorn","reason":"Applicant information was found","redacted":true,"section":"1.2.1 Name and address of applicant(s) for approval of the active substance","color":[0.0,1.0,1.0],"positions":[{"topLeft":{"x":147.86,"y":226.28998},"width":32.17697,"height":11.017679,"page":1},{"topLeft":{"x":181.79697,"y":226.28998},"width":23.68721,"height":11.017679,"page":1}],"sectionNumber":3,"manual":false,"hint":false},{"id":"b54d906a78a3988c54c67f188acab849","type":"address","value":"Schwarzwaldallee 215 P.O. Box CH-4002 Basel Switzerland","reason":"Applicant information was found","redacted":true,"section":"1.2.1 Name and address of applicant(s) for approval of the active substance","color":[0.0,1.0,1.0],"positions":[{"topLeft":{"x":147.86,"y":289.52997},"width":81.095245,"height":11.017679,"page":1},{"topLeft":{"x":230.73732,"y":289.52997},"width":17.438568,"height":11.017679,"page":1},{"topLeft":{"x":147.86,"y":276.93},"width":20.562881,"height":11.017679,"page":1},{"topLeft":{"x":170.18288,"y":276.93},"width":19.359528,"height":11.017679,"page":1},{"topLeft":{"x":147.86,"y":264.21002},"width":41.950012,"height":11.017679,"page":1},{"topLeft":{"x":191.57,"y":264.21002},"width":25.519852,"height":11.017679,"page":1},{"topLeft":{"x":147.86,"y":251.60999},"width":53.649796,"height":11.017679,"page":1}],"sectionNumber":3,"manual":false,"hint":false},{"id":"7b4ff6e32a8bdaa7de5dcdeb13ff8edd","type":"address","value":"regina.dorn@syngenta.com","reason":"Applicant information was found","redacted":true,"section":"1.2.1 Name and address of applicant(s) for approval of the active substance","color":[0.0,1.0,1.0],"positions":[{"topLeft":{"x":147.86,"y":188.34003},"width":122.451065,"height":11.017679,"page":1}],"sectionNumber":3,"manual":false,"hint":false},{"id":"c357d6781fb4bb7e7020a67dbc63763c","type":"address","value":"Syngenta Crop Protection AG","reason":"Applicant information was found","redacted":true,"section":"1.2.1 Name and address of applicant(s) for approval of the active substance","color":[0.0,1.0,1.0],"positions":[{"topLeft":{"x":147.86,"y":302.25},"width":41.88115,"height":11.017679,"page":1},{"topLeft":{"x":191.50114,"y":302.25},"width":23.080002,"height":11.017679,"page":1},{"topLeft":{"x":216.34114,"y":302.25},"width":46.23088,"height":11.017679,"page":1},{"topLeft":{"x":264.2106,"y":302.25},"width":16.886566,"height":11.017679,"page":1}],"sectionNumber":3,"manual":false,"hint":false},{"id":"946a2cc404d6568d34b1ca9a4c688ec9","type":"address","value":"+41 (61) 323 6358","reason":"Applicant information was found","redacted":true,"section":"1.2.1 Name and address of applicant(s) for approval of the active substance","color":[0.0,1.0,1.0],"positions":[{"topLeft":{"x":147.86,"y":213.65997},"width":18.266571,"height":11.017679,"page":1},{"topLeft":{"x":167.88657,"y":213.65997},"width":19.315353,"height":11.017679,"page":1},{"topLeft":{"x":188.99504,"y":213.65997},"width":17.438568,"height":11.017679,"page":1},{"topLeft":{"x":208.1936,"y":213.65997},"width":23.080017,"height":11.017679,"page":1}],"sectionNumber":3,"manual":false,"hint":false},{"id":"687171974a4fc3aa0f43ec2118256590","type":"address","value":"+41 (61) 323 6155","reason":"Applicant information was found","redacted":true,"section":"1.2.1 Name and address of applicant(s) for approval of the active substance","color":[0.0,1.0,1.0],"positions":[{"topLeft":{"x":147.86,"y":200.94},"width":18.266571,"height":11.017679,"page":1},{"topLeft":{"x":167.88657,"y":200.94},"width":19.315353,"height":11.017679,"page":1},{"topLeft":{"x":188.99504,"y":200.94},"width":17.438568,"height":11.017679,"page":1},{"topLeft":{"x":208.1936,"y":200.94},"width":23.080017,"height":11.017679,"page":1}],"sectionNumber":3,"manual":false,"hint":false}]}
|
||||
Loading…
x
Reference in New Issue
Block a user