diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/filepath/FilePathsConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/filepath/FilePathsConfiguration.java deleted file mode 100644 index de056ab36..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/configurations/filepath/FilePathsConfiguration.java +++ /dev/null @@ -1,10 +0,0 @@ -package eu.eudat.configurations.filepath; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableConfigurationProperties(FilePathsProperties.class) -public class FilePathsConfiguration { - -} diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/filepath/FilePathsProperties.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/filepath/FilePathsProperties.java deleted file mode 100644 index cee98aaa2..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/configurations/filepath/FilePathsProperties.java +++ /dev/null @@ -1,54 +0,0 @@ -package eu.eudat.configurations.filepath; - - -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties(prefix = "file-paths") -public class FilePathsProperties { - private String externalUrls; - private String semantics; - private String h2020template; - private String h2020DatasetTemplate; - private String pidLinks; - - public String getExternalUrls() { - return externalUrls; - } - - public void setExternalUrls(String externalUrls) { - this.externalUrls = externalUrls; - } - - public String getSemantics() { - return semantics; - } - - public void setSemantics(String semantics) { - this.semantics = semantics; - } - - public String getH2020template() { - return h2020template; - } - - public void setH2020template(String h2020template) { - this.h2020template = h2020template; - } - - public String getH2020DatasetTemplate() { - return h2020DatasetTemplate; - } - - public void setH2020DatasetTemplate(String h2020DatasetTemplate) { - this.h2020DatasetTemplate = h2020DatasetTemplate; - } - - public String getPidLinks() { - return pidLinks; - } - - public void setPidLinks(String pidLinks) { - this.pidLinks = pidLinks; - } -} - diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/types/SQLXMLType.java b/dmp-backend/core/src/main/java/eu/eudat/data/types/SQLXMLType.java new file mode 100644 index 000000000..6f46dcdfd --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/types/SQLXMLType.java @@ -0,0 +1,2 @@ +package eu.eudat.data.types;public class SQLXMLType { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java index a749d12b5..8a55703a6 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java @@ -6,7 +6,6 @@ import eu.eudat.authorization.Permission; import eu.eudat.commons.JsonHandlingService; import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.enums.*; -import eu.eudat.configurations.filepath.FilePathsProperties; import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.types.descriptiontemplate.*; import eu.eudat.commons.types.descriptiontemplate.fielddata.BaseFieldDataEntity; @@ -38,6 +37,7 @@ import eu.eudat.service.fielddatahelper.FieldDataHelperServiceProvider; import eu.eudat.service.mail.MailService; import eu.eudat.service.mail.SimpleMail; import eu.eudat.service.responseutils.ResponseUtilsService; +import eu.eudat.service.storage.StorageFileService; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.deleter.DeleterFactory; @@ -103,7 +103,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic private final MailService mailService; private final Environment environment; private final ResponseUtilsService responseUtilsService; - private final FilePathsProperties filePathsProperties; + private final StorageFileService storageFileService; private final JsonHandlingService jsonHandlingService; @Autowired @@ -115,7 +115,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic ConventionService conventionService, MessageSource messageSource, XmlHandlingService xmlHandlingService, - FieldDataHelperServiceProvider fieldDataHelperServiceProvider, QueryFactory queryFactory, ErrorThesaurusProperties errors, ValidationService validationService, MailService mailService, Environment environment, ResponseUtilsService responseUtilsService, FilePathsProperties filePathsProperties, JsonHandlingService jsonHandlingService) { + FieldDataHelperServiceProvider fieldDataHelperServiceProvider, QueryFactory queryFactory, ErrorThesaurusProperties errors, ValidationService validationService, MailService mailService, Environment environment, ResponseUtilsService responseUtilsService, StorageFileService storageFileService, JsonHandlingService jsonHandlingService) { this.entityManager = entityManager; this.userScope = userScope; this.authorizationService = authorizationService; @@ -131,7 +131,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic this.mailService = mailService; this.environment = environment; this.responseUtilsService = responseUtilsService; - this.filePathsProperties = filePathsProperties; + this.storageFileService = storageFileService; this.jsonHandlingService = jsonHandlingService; } @@ -191,6 +191,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic data.setId(UUID.randomUUID()); data.setIsActive(IsActive.Active); data.setCreatedAt(Instant.now()); + data.setUpdatedAt(Instant.now()); data.setDescriptionTemplateId(id); data.setUserId(user.getUserId()); data.setRole(user.getRole()); @@ -230,6 +231,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic data.setId(UUID.randomUUID()); data.setIsActive(IsActive.Active); data.setCreatedAt(Instant.now()); + data.setUpdatedAt(Instant.now()); data.setRole(UserDescriptionTemplateRole.Owner); data.setUserId(userScope.getUserId()); data.setDescriptionTemplateId(descriptionTemplateEntity.getId()); @@ -826,32 +828,17 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic } private void loadSemantics() throws IOException { - String filePath = this.filePathsProperties.getSemantics(); - logger.info("Loaded also config file: " + filePath); - if (filePath != null) { - InputStream stream = null; + byte[] bytes = this.storageFileService.getSemanticsFile(); + if (bytes != null) { try { - stream = getStreamFromPath(filePath); - String json = new String(getStreamFromPath(filePath).readAllBytes(), StandardCharsets.UTF_8); + String json = new String(bytes, StandardCharsets.UTF_8); semantics = List.of(jsonHandlingService.fromJson(Semantic[].class, json)); } catch (IOException e) { logger.error(e.getMessage(), e); - } - finally { - if (stream != null) stream.close(); } } } - - private InputStream getStreamFromPath(String filePath) { - try { - return new FileInputStream(filePath); - } catch (FileNotFoundException e) { - logger.info("loading from classpath"); - return getClass().getClassLoader().getResourceAsStream(filePath); - } - } //endregion } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/language/LanguageServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/language/LanguageServiceImpl.java index 0605dae11..2975ac6bc 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/language/LanguageServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/language/LanguageServiceImpl.java @@ -11,6 +11,7 @@ import eu.eudat.model.builder.LanguageBuilder; import eu.eudat.model.deleter.LanguageDeleter; import eu.eudat.model.persist.LanguagePersist; import eu.eudat.service.dmpblueprint.DmpBlueprintServiceImpl; +import eu.eudat.service.storage.StorageFileService; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.deleter.DeleterFactory; @@ -27,8 +28,6 @@ import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.env.Environment; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import javax.management.InvalidApplicationException; @@ -52,11 +51,12 @@ public class LanguageServiceImpl implements LanguageService { private final MessageSource messageSource; private final ErrorThesaurusProperties errors; private final Environment environment; + private final StorageFileService storageFileService; public LanguageServiceImpl( EntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory, - ConventionService conventionService, MessageSource messageSource, ErrorThesaurusProperties errors, Environment environment){ + ConventionService conventionService, MessageSource messageSource, ErrorThesaurusProperties errors, Environment environment, StorageFileService storageFileService){ this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; @@ -65,6 +65,7 @@ public class LanguageServiceImpl implements LanguageService { this.messageSource = messageSource; this.errors = errors; this.environment = environment; + this.storageFileService = storageFileService; } @@ -105,12 +106,7 @@ public class LanguageServiceImpl implements LanguageService { public String getPayload(String code) throws IOException { this.authorizationService.authorizeForce(Permission.BrowseLanguage); - String fileName = this.environment.getProperty("language.path") + code + ".json"; - InputStream is = new FileInputStream(fileName); - - byte[] content = new byte[is.available()]; - is.read(content); - is.close(); + byte[] content = this.storageFileService.getLanguage(code); return new String(content, StandardCharsets.UTF_8); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileProperties.java b/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileProperties.java index fe3a0d40d..b19f3a728 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileProperties.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileProperties.java @@ -9,7 +9,9 @@ import java.util.List; @ConfigurationProperties(prefix = "storage.service") public class StorageFileProperties { private List storages; - private List staticFiles; + private StaticFilesConfig staticFiles; + private MaterialConfig materialFiles; + private String defaultLanguage; private int tempStoreLifetimeSeconds; @@ -29,6 +31,30 @@ public class StorageFileProperties { this.tempStoreLifetimeSeconds = tempStoreLifetimeSeconds; } + public StaticFilesConfig getStaticFiles() { + return staticFiles; + } + + public void setStaticFiles(StaticFilesConfig staticFiles) { + this.staticFiles = staticFiles; + } + + public String getDefaultLanguage() { + return defaultLanguage; + } + + public void setDefaultLanguage(String defaultLanguage) { + this.defaultLanguage = defaultLanguage; + } + + public MaterialConfig getMaterialFiles() { + return materialFiles; + } + + public void setMaterialFiles(MaterialConfig materialFiles) { + this.materialFiles = materialFiles; + } + public static class StorageConfig{ private StorageType type; private String basePath; @@ -49,12 +75,132 @@ public class StorageFileProperties { this.basePath = basePath; } } + + public static class MaterialConfig { + private String localizedNameLanguageKey; + private String userGuide; + private String userGuideNamePattern; + private String about; + private String aboutNamePattern; + private String termsOfService; + private String termsOfServiceNamePattern; + private String glossary; + private String glossaryNamePattern; + private String language; + private String languageNamePattern; + private String faq; + private String faqNamePattern; + + public String getLocalizedNameLanguageKey() { + return localizedNameLanguageKey; + } + + public void setLocalizedNameLanguageKey(String localizedNameLanguageKey) { + this.localizedNameLanguageKey = localizedNameLanguageKey; + } + + public String getUserGuide() { + return userGuide; + } + + public void setUserGuide(String userGuide) { + this.userGuide = userGuide; + } + + public String getAbout() { + return about; + } + + public void setAbout(String about) { + this.about = about; + } + + public String getTermsOfService() { + return termsOfService; + } + + public void setTermsOfService(String termsOfService) { + this.termsOfService = termsOfService; + } + + public String getGlossary() { + return glossary; + } + + public void setGlossary(String glossary) { + this.glossary = glossary; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getFaq() { + return faq; + } + + public void setFaq(String faq) { + this.faq = faq; + } + + public String getUserGuideNamePattern() { + return userGuideNamePattern; + } + + public void setUserGuideNamePattern(String userGuideNamePattern) { + this.userGuideNamePattern = userGuideNamePattern; + } + + public String getAboutNamePattern() { + return aboutNamePattern; + } + + public void setAboutNamePattern(String aboutNamePattern) { + this.aboutNamePattern = aboutNamePattern; + } + + public String getTermsOfServiceNamePattern() { + return termsOfServiceNamePattern; + } + + public void setTermsOfServiceNamePattern(String termsOfServiceNamePattern) { + this.termsOfServiceNamePattern = termsOfServiceNamePattern; + } + + public String getGlossaryNamePattern() { + return glossaryNamePattern; + } + + public void setGlossaryNamePattern(String glossaryNamePattern) { + this.glossaryNamePattern = glossaryNamePattern; + } + + public String getLanguageNamePattern() { + return languageNamePattern; + } + + public void setLanguageNamePattern(String languageNamePattern) { + this.languageNamePattern = languageNamePattern; + } + + public String getFaqNamePattern() { + return faqNamePattern; + } + + public void setFaqNamePattern(String faqNamePattern) { + this.faqNamePattern = faqNamePattern; + } + } public static class StaticFilesConfig{ private String externalUrls; private String semantics; - private String h2020template; - private String h2020DatasetTemplate; + private String h2020Template; + private String h2020DescriptionTemplate; private String pidLinks; public String getExternalUrls() { @@ -73,20 +219,20 @@ public class StorageFileProperties { this.semantics = semantics; } - public String getH2020template() { - return h2020template; + public String getH2020Template() { + return h2020Template; } - public void setH2020template(String h2020template) { - this.h2020template = h2020template; + public void setH2020Template(String h2020Template) { + this.h2020Template = h2020Template; } - public String getH2020DatasetTemplate() { - return h2020DatasetTemplate; + public String getH2020DescriptionTemplate() { + return h2020DescriptionTemplate; } - public void setH2020DatasetTemplate(String h2020DatasetTemplate) { - this.h2020DatasetTemplate = h2020DatasetTemplate; + public void setH2020DescriptionTemplate(String h2020DescriptionTemplate) { + this.h2020DescriptionTemplate = h2020DescriptionTemplate; } public String getPidLinks() { diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java b/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java index abdad52b3..abf5dc94e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/storage/StorageFileService.java @@ -7,6 +7,7 @@ import gr.cite.tools.fieldset.FieldSet; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; +import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.time.Instant; @@ -28,4 +29,40 @@ public interface StorageFileService extends ApplicationListener 0; if (!fileCopied) return false; return file.delete(); @@ -144,10 +144,10 @@ public class StorageFileServiceImpl implements StorageFileService { if (storageFile == null) return false; this.authorizeForce(storageFile, StorageFilePermission.Read); - File file = ResourceUtils.getFile(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); + File file = new File(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); if (!file.exists()) return false; - File destinationFile = ResourceUtils.getFile(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); + File destinationFile = new File(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); return FileCopyUtils.copy(file, destinationFile) > 0; } catch (Exception ex) { @@ -163,7 +163,7 @@ public class StorageFileServiceImpl implements StorageFileService { if (storageFile == null) return false; this.authorizeForce(storageFile, StorageFilePermission.Read); - File file = ResourceUtils.getFile(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); + File file = new File(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); return file.exists(); } @@ -177,7 +177,7 @@ public class StorageFileServiceImpl implements StorageFileService { public boolean fileRefExists(String fileRef, StorageType storageType) { File file = null; try { - file = ResourceUtils.getFile(this.filePath(fileRef, storageType)); + file = new File(this.filePath(fileRef, storageType)); return file.exists(); } catch (Exception ex) { logger.warn("problem reading byte content of storage file " + fileRef, ex); @@ -207,7 +207,7 @@ public class StorageFileServiceImpl implements StorageFileService { this.entityManager.merge(storageFile); this.entityManager.flush(); - File file = ResourceUtils.getFile(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); + File file = new File(this.filePath(storageFile.getFileRef(), storageFile.getStorageType())); if (!file.exists()) return true; return file.delete(); @@ -249,20 +249,13 @@ public class StorageFileServiceImpl implements StorageFileService { @Override public byte[] readByFileRefAsBytesSafe(String fileRef, StorageType storageType) { - - byte[] bytes = null; try { - File file = ResourceUtils.getFile(this.filePath(fileRef, storageType)); - if (!file.exists()) return null; - try(InputStream inputStream = new FileInputStream(file)){ - bytes = inputStream.readAllBytes(); - }; - + return this.readFileBytes(this.filePath(fileRef, storageType)); } catch (Exception ex) { logger.warn("problem reading byte content of storage file " + fileRef, ex); + return null; } - return bytes; } private String filePath(String fileRef, StorageType storageType) @@ -278,4 +271,179 @@ public class StorageFileServiceImpl implements StorageFileService { } this.authorizationService.authorizeForce(Permission.BrowseStorageFile); } + + public byte[] readFileBytes(String path) throws IOException { + + byte[] bytes; + File file = new File(path); + if (!file.exists()) return null; + try(InputStream inputStream = new FileInputStream(file)){ + bytes = inputStream.readAllBytes(); + }; + + return bytes; + } + + //endregion + + //region file paths + + @Override + public byte[] getSemanticsFile() { + try { + return this.readFileBytes(this.config.getStaticFiles().getSemantics()); + } + catch (Exception ex) { + logger.warn("problem reading semantics file", ex); + return null; + } + } + + @Override + public byte[] getExternalUrlsFile() { + try { + return this.readFileBytes(this.config.getStaticFiles().getExternalUrls()); + } + catch (Exception ex) { + logger.warn("problem reading ExternalUrls file", ex); + return null; + } + } + + @Override + public byte[] getPidLinksFile() { + try { + return this.readFileBytes(this.config.getStaticFiles().getPidLinks()); + } + catch (Exception ex) { + logger.warn("problem reading PidLinks file", ex); + return null; + } + } + + @Override + public byte[] getH2020TemplateFile() { + try { + return this.readFileBytes(this.config.getStaticFiles().getH2020Template()); + } + catch (Exception ex) { + logger.warn("problem reading H2020Template file", ex); + return null; + } + } + + @Override + public byte[] getH2020DescriptionTemplateFile() { + try { + return this.readFileBytes(this.config.getStaticFiles().getH2020DescriptionTemplate()); + } + catch (Exception ex) { + logger.warn("problem reading H2020DescriptionTemplate file", ex); + return null; + } + } + + //endregion + + //region materials + + @Override + public byte[] getUserGuide(String language) { + return this.getLocalized(this.config.getMaterialFiles().getUserGuide(), this.config.getMaterialFiles().getUserGuideNamePattern(), language); + } + + @Override + public void setUserGuide(String language, byte[] payload) { + this.setLocalized(this.config.getMaterialFiles().getUserGuide(), this.config.getMaterialFiles().getUserGuideNamePattern(), language, payload); + } + + @Override + public byte[] getAbout(String language) { + return this.getLocalized(this.config.getMaterialFiles().getAbout(), this.config.getMaterialFiles().getAboutNamePattern(), language); + } + + @Override + public void setAbout(String language, byte[] payload) { + this.setLocalized(this.config.getMaterialFiles().getAbout(), this.config.getMaterialFiles().getAboutNamePattern(), language, payload); + } + + @Override + public byte[] getTermsOfService(String language) { + return this.getLocalized(this.config.getMaterialFiles().getTermsOfService(), this.config.getMaterialFiles().getTermsOfServiceNamePattern(), language); + } + + @Override + public void setTermsOfService(String language, byte[] payload) { + this.setLocalized(this.config.getMaterialFiles().getTermsOfService(), this.config.getMaterialFiles().getTermsOfServiceNamePattern(), language, payload); + } + + @Override + public byte[] getGlossary(String language) { + return this.getLocalized(this.config.getMaterialFiles().getGlossary(), this.config.getMaterialFiles().getGlossaryNamePattern(), language); + } + + @Override + public void setGlossary(String language, byte[] payload) { + this.setLocalized(this.config.getMaterialFiles().getGlossary(), this.config.getMaterialFiles().getGlossaryNamePattern(), language, payload); + } + + @Override + public byte[] getLanguage(String language) { + return this.getLocalized(this.config.getMaterialFiles().getLanguage(), this.config.getMaterialFiles().getLanguageNamePattern(), language); + } + + @Override + public File getLanguageFileName(String language) { + return this.getLocalizedFile(this.config.getMaterialFiles().getLanguage(), this.config.getMaterialFiles().getLanguageNamePattern(), language); + } + @Override + public void setLanguage(String language, byte[] payload) { + this.setLocalized(this.config.getMaterialFiles().getLanguage(), this.config.getMaterialFiles().getLanguageNamePattern(), language, payload); + } + + @Override + public byte[] getFaq(String language) { + return this.getLocalized(this.config.getMaterialFiles().getFaq(), this.config.getMaterialFiles().getFaqNamePattern(), language); + } + + @Override + public void setFaq(String language, byte[] payload) { + this.setLocalized(this.config.getMaterialFiles().getFaq(), this.config.getMaterialFiles().getFaqNamePattern(), language, payload); + } + + private byte[] getLocalized(String baseDir, String pattern, String language) { + try { + File file = this.getLocalizedFile(baseDir, pattern, language); + if (!file.exists()) file = this.getLocalizedFile(baseDir, pattern, this.config.getDefaultLanguage()); + if (!file.exists()) return null; + return this.readFileBytes(file.getAbsolutePath()); + } + catch (Exception ex) { + logger.warn("problem reading " + baseDir + " " + language, ex); + return null; + } + } + + private File getLocalizedFile(String baseDir, String pattern, String language) { + return new File(baseDir + this.getLocalizedNamePattern(pattern, language)); + } + + private void setLocalized(String baseDir, String pattern, String language, byte[] payload) { + try { + File file = this.getLocalizedFile(baseDir, pattern, language); + try (FileOutputStream fos = new FileOutputStream(file)) { + fos.write(payload); + } + } + catch (Exception ex) { + logger.warn("problem write " + baseDir + " " + language, ex); + } + } + + private String getLocalizedNamePattern(String pattern, String language){ + return pattern.replace(this.config.getMaterialFiles().getLocalizedNameLanguageKey(), language); + } + + + //endregion } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java index c942fe3c4..69aeeef48 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java @@ -2,6 +2,7 @@ package eu.eudat.controllers; import eu.eudat.authorization.Permission; import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.service.storage.StorageFileService; import eu.eudat.types.ApiMessageCode; import gr.cite.commons.web.authz.service.AuthorizationService; import org.springframework.beans.factory.annotation.Autowired; @@ -21,22 +22,22 @@ public class LanguageController { private Environment environment; private final AuthorizationService authorizationService; + private final StorageFileService storageFileService; @Autowired - public LanguageController(Environment environment, AuthorizationService authorizationService) { + public LanguageController(Environment environment, AuthorizationService authorizationService, StorageFileService storageFileService) { this.environment = environment; this.authorizationService = authorizationService; + this.storageFileService = storageFileService; } @RequestMapping(value = "update/{lang}", method = RequestMethod.POST) public @ResponseBody ResponseEntity> updateLang(@PathVariable String lang, @RequestBody String json) throws Exception { this.authorizationService.authorizeForce(Permission.EditLanguage); + + this.storageFileService.setLanguage(lang, lang.getBytes()); - String fileName = this.environment.getProperty("language.path") + lang + ".json"; - OutputStream os = new FileOutputStream(fileName); - os.write(json.getBytes()); - os.close(); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Updated").payload("Updated")); } @@ -45,19 +46,16 @@ public class LanguageController { this.authorizationService.authorizeForce(Permission.BrowseLanguage); - String fileName = this.environment.getProperty("language.path") + lang + ".json"; - InputStream is = new FileInputStream(fileName); + File file = this.storageFileService.getLanguageFileName(lang); + byte[] content = this.storageFileService.getLanguage(lang); HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(is.available()); + responseHeaders.setContentLength(content.length); responseHeaders.setContentType(MediaType.APPLICATION_JSON); - responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName); + responseHeaders.set("Content-Disposition", "attachment;filename=" + file.getName()); responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - byte[] content = new byte[is.available()]; - is.read(content); - is.close(); return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java index 1718d9ad9..e8082f9ae 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java @@ -2,9 +2,9 @@ package eu.eudat.logic.proxy.config.configloaders; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.configurations.filepath.FilePathsProperties; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.models.data.pid.PidLinks; +import eu.eudat.service.storage.StorageFileService; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +25,7 @@ import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.*; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; @@ -41,104 +42,77 @@ public class DefaultConfigLoader implements ConfigLoader { private Map keyToSourceMap; @Autowired - private FilePathsProperties config; + private StorageFileService storageFileService; private void setExternalUrls() { - String fileUrl = this.config.getExternalUrls(); - logger.info("Loaded also config file: " + fileUrl); - InputStream is = null; + byte[] bytes = this.storageFileService.getExternalUrlsFile(); try { JAXBContext jaxbContext = JAXBContext.newInstance(ExternalUrls.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - is = getStreamFromPath(fileUrl); - externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(is); + externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(new ByteArrayInputStream(bytes)); } catch (Exception ex) { logger.error("Cannot find resource", ex); - } finally { - try { - if (is != null) is.close(); - } catch (IOException | NullPointerException e) { - logger.warn("Warning: Could not close a stream after reading from file: " + fileUrl, e); - } - } + } } private void setDocument() { - String filePath = this.config.getH2020template(); - logger.info("Loaded also config file: " + filePath); - InputStream is = null; + byte[] bytes = this.storageFileService.getH2020TemplateFile(); try { - is = getStreamFromPath(filePath); - this.document = new XWPFDocument(is); - } catch (IOException | NullPointerException e) { - logger.error(e.getMessage(), e); - } finally { - try { - if (is != null) is.close(); - } catch (IOException e) { - logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); - } + this.document = new XWPFDocument(new ByteArrayInputStream(bytes)); + } catch (Exception ex) { + logger.error("Cannot find resource", ex); } } private void setDatasetDocument() { - String filePath = this.config.getH2020DatasetTemplate(); - logger.info("Loaded also config file: " + filePath); - InputStream is = null; + byte[] bytes = this.storageFileService.getH2020DescriptionTemplateFile(); try { - is = getStreamFromPath(filePath); - this.datasetDocument = new XWPFDocument(is); - } catch (IOException | NullPointerException e) { - logger.error(e.getMessage(), e); - } finally { - try { - if (is != null) is.close(); - } catch (IOException e) { - logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); - } + this.datasetDocument = new XWPFDocument(new ByteArrayInputStream(bytes)); + } catch (Exception ex) { + logger.error("Cannot find resource", ex); } } private void setPidLinks() { - String filePath = this.config.getPidLinks(); - logger.info("Loaded also config file: " + filePath); - InputStream is = null; + byte[] bytes = this.storageFileService.getPidLinksFile(); try { - is = getStreamFromPath(filePath); ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - this.pidLinks = mapper.readValue(is, PidLinks.class); - } catch (IOException | NullPointerException e) { - logger.error(e.getMessage(), e); - } finally { - try { - if (is != null) is.close(); - } catch (IOException e) { - logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); - } + this.pidLinks = mapper.readValue(new ByteArrayInputStream(bytes), PidLinks.class); + } catch (Exception ex) { + logger.error("Cannot find resource", ex); } } private void setKeyToSourceMap() { - String filePath = this.config.getExternalUrls(); - logger.info("Loaded also config file: " + filePath); - Document doc = getXmlDocumentFromFilePath(filePath); - if (doc == null) { - this.keyToSourceMap = null; - return; - } - String xpathExpression = "//key"; - Map keysToSourceMap = new HashMap<>(); - List keys = getXmlValuesFromXPath(doc, xpathExpression); - keys = keys.stream().distinct().collect(Collectors.toList()); - for (String key : keys) { - String sourceExpression = String.format("//urlConfig[key='%s']/label", key); - List sources = getXmlValuesFromXPath(doc, sourceExpression); - if (sources.size() != 0) { - keysToSourceMap.put(key, sources.get(0)); + byte[] bytes = this.storageFileService.getExternalUrlsFile(); + + try { + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.pidLinks = mapper.readValue(new ByteArrayInputStream(bytes), PidLinks.class); + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document doc = documentBuilder.parse(new ByteArrayInputStream(bytes)); + if (doc == null) { + this.keyToSourceMap = null; + return; } + String xpathExpression = "//key"; + Map keysToSourceMap = new HashMap<>(); + List keys = getXmlValuesFromXPath(doc, xpathExpression); + keys = keys.stream().distinct().collect(Collectors.toList()); + for (String key : keys) { + String sourceExpression = String.format("//urlConfig[key='%s']/label", key); + List sources = getXmlValuesFromXPath(doc, sourceExpression); + if (sources.size() != 0) { + keysToSourceMap.put(key, sources.get(0)); + } + } + this.keyToSourceMap = keysToSourceMap; + + } catch (Exception ex) { + logger.error("Cannot find resource", ex); } - this.keyToSourceMap = keysToSourceMap; } diff --git a/dmp-backend/web/src/main/resources/config/application.yml b/dmp-backend/web/src/main/resources/config/application.yml index a4491436a..9d826cb3a 100644 --- a/dmp-backend/web/src/main/resources/config/application.yml +++ b/dmp-backend/web/src/main/resources/config/application.yml @@ -13,7 +13,6 @@ spring: optional:classpath:config/actuator.yml[.yml], optional:classpath:config/actuator-${spring.profiles.active}.yml[.yml], optional:file:../config/actuator-${spring.profiles.active}.yml[.yml], optional:classpath:config/email.yml[.yml], optional:classpath:config/email-${spring.profiles.active}.yml[.yml], optional:file:../config/email-${spring.profiles.active}.yml[.yml], optional:classpath:config/elasticsearch.yml[.yml], optional:classpath:config/elasticsearch-${spring.profiles.active}.yml[.yml], optional:file:../config/elasticsearch-${spring.profiles.active}.yml[.yml], - optional:classpath:config/file-path.yml[.yml], optional:classpath:config/file-path-${spring.profiles.active}.yml[.yml], optional:file:../config/file-path-${spring.profiles.active}.yml[.yml], optional:classpath:config/idpclaims.yml[.yml], optional:classpath:config/idpclaims-${spring.profiles.active}.yml[.yml], optional:file:../config/idpclaims-${spring.profiles.active}.yml[.yml], optional:classpath:config/external.yml[.yml], optional:classpath:config/external-${spring.profiles.active}.yml[.yml], optional:file:../config/external-${spring.profiles.active}.yml[.yml], optional:classpath:config/cors.yml[.yml], optional:classpath:config/cors-${spring.profiles.active}.yml[.yml], optional:file:../config/cors-${spring.profiles.active}.yml[.yml], diff --git a/dmp-backend/web/src/main/resources/config/file-path.yml b/dmp-backend/web/src/main/resources/config/file-path.yml deleted file mode 100644 index 4cab21415..000000000 --- a/dmp-backend/web/src/main/resources/config/file-path.yml +++ /dev/null @@ -1,30 +0,0 @@ -file-paths: - externalUrls: externalUrls/ExternalUrls.xml - semantics: Semantics.json - h2020template: documents/h2020.docx - h2020DatasetTemplate: documents/h2020_dataset.docx - pidLinks: pidLinks.json - -userguide: - path: dmp-backend/web/src/main/resources/material/user-guide - -about: - path: dmp-backend/web/src/main/resources/material/about - -termsofservice: - path: dmp-backend/web/src/main/resources/material/terms-of-service - -glossary: - path: dmp-backend/web/src/main/resources/material/glossary - -faq: - path: dmp-backend/web/src/main/resources/material/faq - -temp: - temp: ${TEMP_STORAGE:} - -file: - storage: ${FILE_STORAGE:} - -language: - path: dmp-frontend/src/assets/i18n/ \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/config/storage-devel.yml b/dmp-backend/web/src/main/resources/config/storage-devel.yml index 4c9edee77..cee91a319 100644 --- a/dmp-backend/web/src/main/resources/config/storage-devel.yml +++ b/dmp-backend/web/src/main/resources/config/storage-devel.yml @@ -1,7 +1,21 @@ storage: service: + defaultLanguage: en storages: - type: Temp basePath: ./storage/temp - type: Main basePath: ./storage/main + static-files: + externalUrls: externalUrls/ExternalUrls.xml + semantics: Semantics.json + h2020Template: documents/h2020.docx + h2020DescriptionTemplate: documents/h2020_dataset.docx + pidLinks: pidLinks.json + material-files: + userGuide: dmp-backend/web/src/main/resources/material/user-guide/ + about: dmp-backend/web/src/main/resources/material/about/ + termsOfService: dmp-backend/web/src/main/resources/material/terms-of-service/ + glossary: dmp-backend/web/src/main/resources/material/glossary/ + faq: dmp-backend/web/src/main/resources/material/faq/ + language: dmp-frontend/src/assets/i18n/ diff --git a/dmp-backend/web/src/main/resources/config/storage.yml b/dmp-backend/web/src/main/resources/config/storage.yml index 649c39240..eece13a50 100644 --- a/dmp-backend/web/src/main/resources/config/storage.yml +++ b/dmp-backend/web/src/main/resources/config/storage.yml @@ -4,3 +4,11 @@ storage: intervalSeconds: 600 service: tempStoreLifetimeSeconds: 7200 + material-files: + localizedNameLanguageKey: "{lang}" + userGuideNamePattern: "UserGuide_{lang}.html" + aboutNamePattern: "About_{lang}.html" + termsOfServiceNamePattern: "TermsOfService_{lang}.html" + glossaryNamePattern: "Glossary_{lang}.html" + faqNamePattern: "Faq_{lang}.html" + languageNamePattern: "{lang}.json"