Skip to content

Commit 7195901

Browse files
author
René Reitmann
authored
Merge pull request #2928 from dzhw/release
Release v1.0.112
2 parents e222844 + cfe1825 commit 7195901

40 files changed

Lines changed: 21537 additions & 377 deletions

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Metadatamanagement",
3-
"version": "1.0.111-HOTFIX",
3+
"version": "1.0.112",
44
"description": "Data Search for Higher Education Research and Science Studies",
55
"private": true,
66
"dependencies": {

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<groupId>eu.dzhw.fdz</groupId>
1313
<artifactId>metadatamanagement</artifactId>
14-
<version>1.0.111-HOTFIX</version>
14+
<version>1.0.112</version>
1515
<packaging>war</packaging>
1616
<name>metadatamanagement</name>
1717

@@ -143,7 +143,7 @@
143143
<dependency>
144144
<groupId>org.apache.commons</groupId>
145145
<artifactId>commons-compress</artifactId>
146-
<version>1.20</version>
146+
<version>1.21</version>
147147
</dependency>
148148
<dependency>
149149
<groupId>org.apache.commons</groupId>

reports/cpd-report.txt

Lines changed: 20158 additions & 0 deletions
Large diffs are not rendered by default.

src/main/java/eu/dzhw/fdz/metadatamanagement/common/domain/Task.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,6 @@ public enum TaskState {
7070
*
7171
*/
7272
public enum TaskType {
73-
DATA_SET_REPORT
73+
DATA_SET_REPORT, DATA_PACKAGE_OVERVIEW
7474
}
7575
}
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
package eu.dzhw.fdz.metadatamanagement.common.service;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.IOException;
6+
import java.io.StringWriter;
7+
import java.io.Writer;
8+
import java.net.URI;
9+
import java.nio.charset.StandardCharsets;
10+
import java.nio.file.FileSystem;
11+
import java.nio.file.FileSystems;
12+
import java.nio.file.Files;
13+
import java.nio.file.Path;
14+
import java.util.ArrayList;
15+
import java.util.HashMap;
16+
import java.util.List;
17+
import java.util.Map;
18+
19+
import org.javers.common.collections.Lists;
20+
import org.springframework.scheduling.annotation.Async;
21+
22+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
23+
import eu.dzhw.fdz.metadatamanagement.common.domain.Task;
24+
import eu.dzhw.fdz.metadatamanagement.common.rest.util.ZipUtil;
25+
import eu.dzhw.fdz.metadatamanagement.datapackagemanagement.service.DataPackageOverviewService;
26+
import eu.dzhw.fdz.metadatamanagement.datasetmanagement.exception.TemplateIncompleteException;
27+
import eu.dzhw.fdz.metadatamanagement.datasetmanagement.service.DataSetReportService;
28+
import eu.dzhw.fdz.metadatamanagement.filemanagement.service.FileService;
29+
import eu.dzhw.fdz.metadatamanagement.variablemanagement.domain.AccessWays;
30+
import freemarker.template.Configuration;
31+
import freemarker.template.Template;
32+
import freemarker.template.TemplateException;
33+
import freemarker.template.TemplateExceptionHandler;
34+
import lombok.RequiredArgsConstructor;
35+
import lombok.extern.slf4j.Slf4j;
36+
37+
/**
38+
* Base class for generating reports like {@link DataSetReportService} and
39+
* {@link DataPackageOverviewService}.
40+
*
41+
* It configures freemarker and executes it. The Model for the templates must be provided by the
42+
* concrete sub classes.
43+
*/
44+
@RequiredArgsConstructor
45+
@Slf4j
46+
public abstract class AbstractReportService {
47+
protected final FileService fileService;
48+
49+
protected final TaskManagementService taskService;
50+
51+
protected final MarkdownHelper markdownHelper;
52+
53+
/**
54+
* The Escape Prefix handles the escaping of special latex signs within data information. This
55+
* Prefix will be copied before the template source code.
56+
*/
57+
protected static final String ESCAPE_PREFIX =
58+
"<#escape x as x?replace(\"\\\\\", \"\\\\textbackslash{}\")"
59+
+ "?replace(\"{\", \"\\\\{\")?replace(\"}\", \"\\\\}\")"
60+
+ "?replace(\"#\", \"\\\\#\")?replace(\"$\", \"\\\\$\")"
61+
+ "?replace(\"%\", \"\\\\%\")?replace(\"&\", \"\\\\&\")"
62+
+ "?replace(\"^\", \"\\\\textasciicircum{}\")?replace(\"_\", \"\\\\_\")"
63+
+ "?replace(\">\", \"\\\\textgreater{}\")?replace(\"<\", \"\\\\textless{}\")"
64+
+ "?replace(\"~\", \"\\\\textasciitilde{}\")" + "?replace(\"\\r\\n\", \"\\\\par \")"
65+
+ "?replace(\"\\n\", \"\\\\par \")>";
66+
67+
/**
68+
* The Escape Suffix closes the escaping prefix. This Prefix will be copied after the template
69+
* source code.
70+
*/
71+
protected static final String ESCAPE_SUFFIX = "</#escape>";
72+
73+
/**
74+
* Zip Mime Content Type.
75+
*/
76+
protected static final String CONTENT_TYPE_ZIP = "application/zip";
77+
78+
/**
79+
* Get all filenames expected to be present in the template zip.
80+
*
81+
* @return List of expected filenames
82+
*/
83+
private List<String> getExpectedFiles() {
84+
return Lists.join(getSimpleTemplateFiles(), getComplexTemplateFiles());
85+
}
86+
87+
/**
88+
* Get all filenames of template which can be simply processed.
89+
*
90+
* @return List of simple to process files.
91+
*/
92+
protected abstract List<String> getSimpleTemplateFiles();
93+
94+
/**
95+
* Get all filenames of template which need to be processed in a more complex way (like
96+
* "Variable.tex").
97+
*
98+
* @return List of simple to process files.
99+
*/
100+
protected abstract List<String> getComplexTemplateFiles();
101+
102+
/**
103+
* This method load all needed objects from the db for filling the tex template.
104+
*
105+
* @param id the id of the dataset or data package.
106+
* @param version The version of the report as it is displayed in the title.
107+
* @return A HashMap with all data for the template filling. The Key is the name of the Object,
108+
* which is used in the template.
109+
*/
110+
protected abstract Map<String, Object> loadDataForTemplateFilling(String id, String version);
111+
112+
/**
113+
* Checks for all files which are included for the tex template.
114+
*
115+
* @param zipFileSystem The zip file as file system
116+
* @return True if all files are included. False min one file is missing.
117+
*/
118+
private List<String> validateZipStructure(FileSystem zipFileSystem) {
119+
List<String> missingTexFiles = new ArrayList<>();
120+
121+
this.getExpectedFiles().forEach(filename -> {
122+
Path file = zipFileSystem.getPath(zipFileSystem.getPath("/").toString(), filename);
123+
if (!Files.exists(file)) {
124+
missingTexFiles.add(filename);
125+
}
126+
});
127+
return missingTexFiles;
128+
}
129+
130+
/**
131+
* This method save a latex file into GridFS/MongoDB based on a byteArrayOutputStream.
132+
*
133+
* @param fileName The name of the file to be saved
134+
* @return return the file name of the saved latex template in the GridFS / MongoDB.
135+
* @throws IOException thrown if a stream cannot be closed
136+
*/
137+
@SuppressFBWarnings("OBL_UNSATISFIED_OBLIGATION")
138+
private String saveCompleteZipFile(File zipFile, String fileName) throws IOException {
139+
// No Update by API, so we have to delete first.
140+
fileService.deleteTempFile(fileName);
141+
// Save tex file
142+
return fileService.saveTempFile(new FileInputStream(zipFile), fileName, CONTENT_TYPE_ZIP);
143+
}
144+
145+
/**
146+
* This method fills the tex templates.
147+
*
148+
* @param templateContent The content of a tex template.
149+
* @param templateConfiguration The configuration for freemarker.
150+
* @param fileName filename of the script which will be filled in this method.
151+
* @return The filled tex templates as byte array.
152+
* @throws IOException Handles IO Exception.
153+
* @throws TemplateException Handles template Exceptions.
154+
*/
155+
protected final String fillTemplate(String templateContent, Configuration templateConfiguration,
156+
Map<String, Object> dataForTemplate, String fileName) throws IOException, TemplateException {
157+
String templateName = "texTemplate";
158+
if (fileName != null && fileName.trim().length() > 0) {
159+
templateName = fileName;
160+
}
161+
162+
// Read Template and escape elements
163+
Template texTemplate = new Template(templateName,
164+
ESCAPE_PREFIX + templateContent + ESCAPE_SUFFIX, templateConfiguration);
165+
166+
try (Writer stringWriter = new StringWriter()) {
167+
texTemplate.process(dataForTemplate, stringWriter);
168+
169+
stringWriter.flush();
170+
return stringWriter.toString();
171+
}
172+
}
173+
174+
/**
175+
* This service method will receive a tex template as a string and an id of a data set. With this
176+
* id, the service will load the data set for receiving all depending information, which are
177+
* needed for filling of the tex template with data.
178+
*
179+
* @param zipTmpFilePath The path to uploaded zip file
180+
* @param originalName the original name of multipartfile
181+
* @param id An id of the dataset or data package.
182+
* @param task the task to update the status of the pro
183+
* @param version The version of the report as it is displayed in the title.
184+
*
185+
* @throws TemplateException Handles templates exceptions.
186+
* @throws IOException Handles IO Exception for the template.
187+
*/
188+
@Async
189+
public void generateReport(Path zipTmpFilePath, String originalName, String id, Task task,
190+
String version) {
191+
log.debug("Start generating report/overview for {} and id {}", originalName, id);
192+
// Configuration, based on Freemarker Version 2.3.23
193+
Configuration templateConfiguration = new Configuration(Configuration.VERSION_2_3_23);
194+
templateConfiguration.setDefaultEncoding(StandardCharsets.UTF_8.toString());
195+
templateConfiguration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
196+
templateConfiguration.setNumberFormat("0.######");
197+
templateConfiguration.setAPIBuiltinEnabled(true);
198+
URI uriOfZipFile = URI.create("jar:" + zipTmpFilePath.toUri());
199+
// Prepare Zip enviroment config
200+
Map<String, String> env = new HashMap<>();
201+
env.put("create", "true");
202+
env.put("encoding", StandardCharsets.UTF_8.name());
203+
try (FileSystem zipFileSystem = FileSystems.newFileSystem(uriOfZipFile, env);) {
204+
// Check missing files.
205+
log.debug("Check missing files.");
206+
List<String> missingTexFiles = this.validateZipStructure(zipFileSystem);
207+
if (!missingTexFiles.isEmpty()) {
208+
String message = "common.error" + ".files-in-template-zip-incomplete";
209+
log.debug(message + missingTexFiles);
210+
throw new TemplateIncompleteException(message, missingTexFiles);
211+
}
212+
// Load data for template only once
213+
Map<String, Object> dataForTemplate = this.loadDataForTemplateFilling(id, version);
214+
215+
dataForTemplate.put("removeMarkdown", markdownHelper.createRemoveMarkdownMethod());
216+
dataForTemplate.put("displayAccessWay", AccessWays.createDisplayAccessWayMethod());
217+
218+
for (String filename : getSimpleTemplateFiles()) {
219+
String template = ZipUtil.readFileFromZip(zipFileSystem.getPath(filename));
220+
String filledTemplate =
221+
this.fillTemplate(template, templateConfiguration, dataForTemplate, filename);
222+
ZipUtil.writeFileToZip(zipFileSystem.getPath(filename), filledTemplate);
223+
}
224+
225+
// Create Variables pages
226+
for (String filename : getComplexTemplateFiles()) {
227+
handleComplexTemplateFile(filename, zipFileSystem, dataForTemplate, templateConfiguration);
228+
}
229+
230+
// Save into MongoDB / GridFS
231+
zipFileSystem.close();
232+
File zipTmpFile = zipTmpFilePath.toFile();
233+
String fileName = this.saveCompleteZipFile(zipTmpFile, originalName);
234+
log.debug("file saved, start #handletaskDone");
235+
taskService.handleTaskDone(task, fileName);
236+
} catch (RuntimeException e) {
237+
log.error("failed generating report", e);
238+
taskService.handleErrorTask(task, e);
239+
throw e;
240+
} catch (Exception e) {
241+
log.error("failed generating report", e);
242+
taskService.handleErrorTask(task, e);
243+
}
244+
}
245+
246+
protected void handleComplexTemplateFile(String templateFilename, FileSystem zipFileSystem,
247+
Map<String, Object> dataForTemplate, Configuration templateConfiguration)
248+
throws IOException, TemplateException {}
249+
}

0 commit comments

Comments
 (0)