#7528: [NEW] Upload files field type.
1. Datasets.java: In "delete()" method, call also fileManager.markAllFilesOfEntityIdAsDeleted. 2. DatasetManager.java: Added method "deleteOldFilesAndAddNew()" which is called by "createOrUpdate()", to mark as deleted files that are not used any more and save the new ones. 3. DatabaseRepository.java & DatabaseRepositoryImpl.java: Include in DAOs FileUploadDAO. 4. ModelBuilder.java & ViewStyle.java: Incluse "upload" field type. 5. field-data.ts: a. In "getOrdinal()" method return Integer instead of int. b. In "getValidations()" method added null check. c. In methods "fromJsonObject()" and "toMap()" added special if clauses for "upload" field type. 6. application.properties: a. Added property "file.storage", to set the folder where the files will be permanently saved. b. Changed default spring.servlet.multipart.max-file-size and pring.servlet.multipart.max-request-size to 10 MB. 7. UserInvitationController.java: Deleted a print in System.out. 8. New files for upload field type: FileUploadDao.java, FileUploadDaoImpl.java, FileUpload.java, PostgreSQLEnumType.java (necessary for the enum EntityType), FileController.java, FileManager.java, UploadData.java.
This commit is contained in:
parent
744160c84a
commit
2a9d8b8296
|
@ -0,0 +1,9 @@
|
|||
package eu.eudat.data.dao.entities;
|
||||
|
||||
import eu.eudat.data.dao.DatabaseAccessLayer;
|
||||
import eu.eudat.data.entities.FileUpload;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface FileUploadDao extends DatabaseAccessLayer<FileUpload, UUID> {
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package eu.eudat.data.dao.entities;
|
||||
|
||||
import eu.eudat.data.dao.DatabaseAccess;
|
||||
import eu.eudat.data.dao.databaselayer.service.DatabaseService;
|
||||
import eu.eudat.data.entities.FileUpload;
|
||||
import eu.eudat.queryable.QueryableList;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component("FileUploadDao")
|
||||
public class FileUploadDaoImpl extends DatabaseAccess<FileUpload> implements FileUploadDao {
|
||||
|
||||
@Autowired
|
||||
public FileUploadDaoImpl(DatabaseService<FileUpload> databaseService) {
|
||||
super(databaseService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUpload createOrUpdate(FileUpload item) {
|
||||
return getDatabaseService().createOrUpdate(item, FileUpload.class);
|
||||
}
|
||||
//
|
||||
@Override
|
||||
public CompletableFuture<FileUpload> createOrUpdateAsync(FileUpload item) {
|
||||
return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUpload find(UUID id) {
|
||||
return getDatabaseService().getQueryable(FileUpload.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUpload find(UUID id, String hint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(FileUpload item) {
|
||||
this.getDatabaseService().delete(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryableList<FileUpload> asQueryable() {
|
||||
return this.getDatabaseService().getQueryable(FileUpload.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package eu.eudat.data.entities;
|
||||
|
||||
import eu.eudat.data.converters.DateToUTCConverter;
|
||||
import eu.eudat.data.entities.helpers.EntityBinder;
|
||||
import eu.eudat.queryable.queryableentity.DataEntity;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Entity
|
||||
@Table(name = "\"FileUpload\"")
|
||||
public class FileUpload implements DataEntity<FileUpload, UUID> {
|
||||
public enum EntityType {
|
||||
DATASET, DMP
|
||||
}
|
||||
|
||||
@Id
|
||||
@Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
|
||||
private UUID id;
|
||||
|
||||
@Column(name = "\"Name\"", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "\"FileType\"", nullable = false)
|
||||
private String fileType;
|
||||
|
||||
@Column(name = "\"EntityId\"", nullable = false)
|
||||
private UUID entityId;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Type(type = "eu.eudat.configurations.typedefinition.PostgreSQLEnumType")
|
||||
@Column(name = "\"EntityType\"", nullable = false)
|
||||
private EntityType entityType;
|
||||
|
||||
@Column(name = "\"CreatedAt\"", nullable = false)
|
||||
@Convert(converter = DateToUTCConverter.class)
|
||||
private Date createdAt;
|
||||
|
||||
@Column(name = "\"IsDeleted\"", nullable = false)
|
||||
private Boolean isDeleted;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "\"Creator\"")
|
||||
private UserInfo creator;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getFileType() {
|
||||
return fileType;
|
||||
}
|
||||
public void setFileType(String fileType) {
|
||||
this.fileType = fileType;
|
||||
}
|
||||
|
||||
public UUID getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
public void setEntityId(UUID entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public EntityType getEntityType() {
|
||||
return entityType;
|
||||
}
|
||||
public void setEntityType(EntityType entityType) {
|
||||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
public void setCreatedAt(Date createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Boolean getIsDeleted() {
|
||||
return isDeleted;
|
||||
}
|
||||
public void setIsDeleted(Boolean isDeleted) {
|
||||
this.isDeleted = isDeleted;
|
||||
}
|
||||
|
||||
public UserInfo getCreator() {
|
||||
return creator;
|
||||
}
|
||||
public void setCreator(UserInfo creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(FileUpload file) {
|
||||
this.name = file.getName();
|
||||
this.fileType = file.getFileType();
|
||||
this.entityId = file.getEntityId();
|
||||
this.entityType = file.getEntityType();
|
||||
this.createdAt = file.getCreatedAt();
|
||||
this.isDeleted = file.getIsDeleted();
|
||||
this.creator = file.getCreator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getKeys() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUpload buildFromTuple(List<Tuple> tuple, List<String> fields, String base) {
|
||||
String currentBase = base.isEmpty() ? "" : base + ".";
|
||||
if (fields.contains(currentBase + "id")) this.id = EntityBinder.fromTuple(tuple, currentBase + "id");
|
||||
this.creator = tuple.stream().map(x -> new UserInfo().buildFromTuple(tuple, fields , base.isEmpty() ? "creator" : base + "." + "creator")).collect(Collectors.toList()).get(0);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package eu.eudat.configurations.typedefinition;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
public class PostgreSQLEnumType extends org.hibernate.type.EnumType {
|
||||
|
||||
public void nullSafeSet(
|
||||
PreparedStatement st,
|
||||
Object value,
|
||||
int index,
|
||||
SharedSessionContractImplementor session)
|
||||
throws HibernateException, SQLException {
|
||||
st.setObject(
|
||||
index,
|
||||
value != null ?
|
||||
((Enum) value).name() :
|
||||
null,
|
||||
Types.OTHER
|
||||
);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import eu.eudat.exceptions.datasetwizard.DatasetWizardCannotUnlockException;
|
|||
import eu.eudat.exceptions.security.UnauthorisedException;
|
||||
import eu.eudat.logic.managers.DatasetManager;
|
||||
import eu.eudat.logic.managers.DatasetWizardManager;
|
||||
import eu.eudat.logic.managers.FileManager;
|
||||
import eu.eudat.logic.managers.UserManager;
|
||||
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
|
||||
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
||||
|
@ -67,14 +68,17 @@ public class Datasets extends BaseController {
|
|||
private DatasetManager datasetManager;
|
||||
private ConfigLoader configLoader;
|
||||
private UserManager userManager;
|
||||
private FileManager fileManager;
|
||||
|
||||
@Autowired
|
||||
public Datasets(ApiContext apiContext, Environment environment, DatasetManager datasetManager, ConfigLoader configLoader, UserManager userManager) {
|
||||
public Datasets(ApiContext apiContext, Environment environment, DatasetManager datasetManager, ConfigLoader configLoader, UserManager userManager,
|
||||
FileManager fileManager) {
|
||||
super(apiContext);
|
||||
this.environment = environment;
|
||||
this.datasetManager = datasetManager;
|
||||
this.configLoader = configLoader;
|
||||
this.userManager = userManager;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -268,6 +272,7 @@ public class Datasets extends BaseController {
|
|||
public @ResponseBody
|
||||
ResponseEntity<ResponseItem<Dataset>> delete(@PathVariable(value = "id") UUID id, Principal principal) throws Exception {
|
||||
new DatasetWizardManager().delete(this.getApiContext(), id);
|
||||
this.fileManager.markAllFilesOfEntityIdAsDeleted(id);
|
||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Dataset>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted"));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
package eu.eudat.controllers;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.eudat.data.entities.FileUpload;
|
||||
import eu.eudat.exceptions.security.UnauthorisedException;
|
||||
import eu.eudat.logic.managers.DatasetProfileManager;
|
||||
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
||||
import eu.eudat.logic.services.ApiContext;
|
||||
import eu.eudat.logic.services.operations.DatabaseRepository;
|
||||
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
|
||||
import eu.eudat.logic.utilities.json.JsonSearcher;
|
||||
import eu.eudat.models.HintedModelFactory;
|
||||
import eu.eudat.models.data.datasetwizard.DatasetWizardModel;
|
||||
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
||||
import eu.eudat.models.data.security.Principal;
|
||||
import eu.eudat.types.ApiMessageCode;
|
||||
import eu.eudat.types.Authorities;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
@RequestMapping(value = {"/api/file/"})
|
||||
public class FileController {
|
||||
|
||||
private DatasetProfileManager datasetProfileManager;
|
||||
private final Environment environment;
|
||||
private DatabaseRepository databaseRepository;
|
||||
|
||||
@Autowired
|
||||
public FileController(DatasetProfileManager datasetProfileManager, Environment environment, ApiContext apiContext) {
|
||||
this.datasetProfileManager = datasetProfileManager;
|
||||
this.environment = environment;
|
||||
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = {"/upload"})
|
||||
public ResponseEntity<ResponseItem<String>> upload(
|
||||
@RequestParam("file") MultipartFile file, @RequestParam("datasetProfileId") String datasetProfileId, @RequestParam("fieldId") String fieldId,
|
||||
@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER}) Principal principal)
|
||||
throws IllegalAccessException, IOException {
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
|
||||
eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = this.datasetProfileManager.getDatasetProfile(datasetProfileId);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
String json = mapper.writeValueAsString(datasetprofile.getSections());;
|
||||
JsonNode propertiesJson = mapper.readTree(json);
|
||||
Set<JsonNode> fieldNodes = new HashSet<>();
|
||||
fieldNodes.addAll(JsonSearcher.findNodes(propertiesJson, "id", fieldId, false));
|
||||
|
||||
// AtomicReference<String> exceptionMessage = null;
|
||||
AtomicBoolean acceptedFile = new AtomicBoolean(false);
|
||||
fieldNodes.forEach(node -> {
|
||||
JsonNode data = node.get("data");
|
||||
if (data != null && !data.toString().equals("\"\"") && !data.toString().equals("null")) {
|
||||
String stringValue = data.toString().replaceAll("=", ":");
|
||||
JSONObject dataObj = new JSONObject(stringValue);
|
||||
Map<String, Object> dataMap = ((JSONObject) dataObj).toMap();
|
||||
if(dataMap.get("maxFileSizeInMB") != null && !dataMap.get("maxFileSizeInMB").toString().equals("\"\"") && !dataMap.get("maxFileSizeInMB").toString().equals("null")) {
|
||||
if (file.getSize() <= Integer.parseInt(dataMap.get("maxFileSizeInMB").toString())*1048576) {
|
||||
acceptedFile.set(true);
|
||||
}
|
||||
// else {
|
||||
// exceptionMessage.set("The file is too large. Max file upload is " + dataMap.get("maxFileSizeInMB").toString() + " MB.");
|
||||
// }
|
||||
}
|
||||
|
||||
if(acceptedFile.get() && data.get("types") != null && !data.get("types").toString().equals("\"\"") && !data.get("types").toString().equals("null")) {
|
||||
acceptedFile.set(false);
|
||||
|
||||
JSONArray types = new JSONArray(data.get("types").toString());
|
||||
|
||||
types.iterator().forEachRemaining(element -> {
|
||||
Map<String, Object> typesMap = ((JSONObject) element).toMap();
|
||||
if(typesMap.get("value") != null && !typesMap.get("value").toString().equals("\"\"") && !typesMap.get("value").toString().equals("null")) {
|
||||
if(file.getContentType().equals(typesMap.get("value").toString())) {
|
||||
acceptedFile.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// if(!acceptedFile.get()) {
|
||||
// exceptionMessage.set("The file type is not accepted.");
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
if(!acceptedFile.get()) {
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem<String>().status(ApiMessageCode.ERROR_MESSAGE).message("The uploaded file is too large or has an unaccepted type"));
|
||||
}
|
||||
|
||||
|
||||
File convFile = new File(this.environment.getProperty("temp.temp") + uuid);
|
||||
convFile.createNewFile();
|
||||
FileOutputStream fos = new FileOutputStream(convFile);
|
||||
fos.write(file.getBytes());
|
||||
fos.close();
|
||||
|
||||
|
||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<String>().payload(uuid)
|
||||
.status(ApiMessageCode.SUCCESS_MESSAGE).message(""));
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = {"/delete-temp"})
|
||||
public ResponseEntity<ResponseItem<String>> upload(@RequestBody String filename) throws IllegalAccessException, IOException {
|
||||
File convFile = new File(this.environment.getProperty("temp.temp") + filename);
|
||||
// Boolean deleted = convFile.delete();
|
||||
Boolean deleted = Files.deleteIfExists(convFile.toPath());
|
||||
|
||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<String>().payload(deleted.toString())
|
||||
.status(ApiMessageCode.SUCCESS_MESSAGE).message(""));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@RequestMapping(method = RequestMethod.GET, value = {"{id}"}, produces = "application/json")
|
||||
public @ResponseBody
|
||||
ResponseEntity download(@PathVariable String id
|
||||
,@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal
|
||||
) throws IOException {
|
||||
FileUpload fileUpload = databaseRepository.getFileUploadDao().find(UUID.fromString(id));
|
||||
if(fileUpload == null) {
|
||||
throw new NoSuchElementException("File with id "+id+" not found");
|
||||
}
|
||||
|
||||
if(fileUpload.getEntityType().name().equals(FileUpload.EntityType.DATASET.name())) {
|
||||
eu.eudat.data.entities.Dataset datasetEntity = databaseRepository.getDatasetDao().find(fileUpload.getEntityId(), HintedModelFactory.getHint(DatasetWizardModel.class));
|
||||
if (datasetEntity == null) {
|
||||
throw new NoSuchElementException("No dataset with id " + fileUpload.getEntityId() + " found. This dataset was related to the file with id " + id);
|
||||
}
|
||||
if (!datasetEntity.getDmp().isPublic() && datasetEntity.getDmp().getUsers()
|
||||
.stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId())
|
||||
.collect(Collectors.toList()).size() == 0)
|
||||
throw new UnauthorisedException();
|
||||
}
|
||||
|
||||
FileEnvelope fileEnvelope = new FileEnvelope();
|
||||
fileEnvelope.setFilename(fileUpload.getName());
|
||||
File exportFile = new File(this.environment.getProperty("file.storage") + id);
|
||||
fileEnvelope.setFile(exportFile);
|
||||
|
||||
InputStream resource = new FileInputStream(fileEnvelope.getFile());
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
responseHeaders.setContentLength(fileEnvelope.getFile().length());
|
||||
responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
|
||||
String fileName = fileEnvelope.getFilename().replace(" ", "_").replace(",", "_");
|
||||
responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName);
|
||||
responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");
|
||||
responseHeaders.set("Cache-Control", "no-store");
|
||||
responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type");
|
||||
|
||||
byte[] content = IOUtils.toByteArray(resource);
|
||||
resource.close();
|
||||
return new ResponseEntity<>(content,
|
||||
responseHeaders,
|
||||
HttpStatus.OK);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -52,7 +52,6 @@ public class UserInvitationController extends BaseController {
|
|||
public @ResponseBody
|
||||
// ResponseEntity<ResponseItem<List<UserInfoInvitationModel>>> getUsers(Principal principal) throws IllegalAccessException, InstantiationException {
|
||||
ResponseEntity<ResponseItem<List<UserInfoInvitationModel>>> getUsers(Principal principal, @RequestBody UserInfoRequestItem userInfoRequestItem) throws IllegalAccessException, InstantiationException {
|
||||
System.out.println(userInfoRequestItem.getCriteria().getLike());
|
||||
// List<UserInfoInvitationModel> users = invitationsManager.getUsers(principal);
|
||||
List<UserInfoInvitationModel> users = invitationsManager.getUsersWithCriteria(principal, userInfoRequestItem);
|
||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<List<UserInfoInvitationModel>>().status(ApiMessageCode.SUCCESS_MESSAGE).payload(users));
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package eu.eudat.logic.managers;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.eudat.data.dao.criteria.*;
|
||||
|
@ -109,9 +111,11 @@ public class DatasetManager {
|
|||
private ConfigLoader configLoader;
|
||||
private Environment environment;
|
||||
private final MetricsManager metricsManager;
|
||||
private final FileManager fileManager;
|
||||
|
||||
@Autowired
|
||||
public DatasetManager(ApiContext apiContext, UserManager userManager, ConfigLoader configLoader, Environment environment, MetricsManager metricsManager) {
|
||||
public DatasetManager(ApiContext apiContext, UserManager userManager, ConfigLoader configLoader, Environment environment, MetricsManager metricsManager,
|
||||
FileManager fileManager) {
|
||||
this.apiContext = apiContext;
|
||||
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
|
||||
this.datasetRepository = apiContext.getOperationsContext().getElasticRepository().getDatasetRepository();
|
||||
|
@ -120,6 +124,7 @@ public class DatasetManager {
|
|||
this.configLoader = configLoader;
|
||||
this.environment = environment;
|
||||
this.metricsManager = metricsManager;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
public DataTableData<DatasetListingModel> getPaged(DatasetTableRequest datasetTableRequest, Principal principal) throws Exception {
|
||||
|
@ -608,9 +613,51 @@ public class DatasetManager {
|
|||
this.sendNotification(dataset1, dataset1.getDmp(), userInfo, NotificationType.DATASET_MODIFIED_FINALISED);
|
||||
}
|
||||
}
|
||||
|
||||
this.deleteOldFilesAndAddNew(datasetWizardModel, userInfo);
|
||||
|
||||
|
||||
return dataset1;
|
||||
}
|
||||
|
||||
private void deleteOldFilesAndAddNew(DatasetWizardModel datasetWizardModel, UserInfo userInfo) throws JsonProcessingException {
|
||||
// Files in DB for this entityId which are NOT DELETED
|
||||
List<FileUpload> fileUploads = fileManager.getCurrentFileUploadsForEntityId(datasetWizardModel.getId());
|
||||
List<String> fileUploadIds = fileUploads.stream().map(fileUpload -> fileUpload.getId().toString()).collect(Collectors.toList());
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
String json = mapper.writeValueAsString(datasetWizardModel.getDatasetProfileDefinition());;
|
||||
JsonNode propertiesJson = mapper.readTree(json);
|
||||
|
||||
Set<JsonNode> uploadNodes = new HashSet<>();
|
||||
uploadNodes.addAll(JsonSearcher.findNodes(propertiesJson, "renderStyle", "upload", true));
|
||||
|
||||
uploadNodes.forEach(node -> {
|
||||
JsonNode value = node.get("value");
|
||||
if (value != null && !value.toString().equals("\"\"") && !value.toString().equals("null")) {
|
||||
String stringValue = value.toString().replaceAll("=", ":");
|
||||
JSONObject values = new JSONObject(stringValue);
|
||||
Map<String, Object> data = ((JSONObject) values).toMap();
|
||||
|
||||
int index = fileUploadIds.indexOf(data.get("id").toString());
|
||||
if(index != -1) {
|
||||
// file in DB is the same as file in the Dataset
|
||||
fileUploadIds.remove(index);
|
||||
fileUploads.remove(index);
|
||||
} else {
|
||||
// new file
|
||||
this.fileManager.createFile(data.get("id").toString(), data.get("name").toString(), data.get("type").toString(), datasetWizardModel.getId().toString(), FileUpload.EntityType.DATASET, userInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// old files in DB that are not contained anymore in the Dataset -> mark them as Deleted
|
||||
fileUploads.forEach(fileUpload -> {
|
||||
fileManager.markOldFileAsDeleted(fileUpload);
|
||||
});
|
||||
}
|
||||
|
||||
private void sendNotification(Dataset dataset, DMP dmp, UserInfo user, NotificationType notificationType) {
|
||||
List<UserDMP> userDMPS = databaseRepository.getUserDmpDao().asQueryable().where(((builder, root) -> builder.equal(root.get("dmp").get("id"), dmp.getId()))).toList();
|
||||
for (UserDMP userDMP : userDMPS) {
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package eu.eudat.logic.managers;
|
||||
|
||||
import eu.eudat.data.entities.FileUpload;
|
||||
import eu.eudat.data.entities.UserInfo;
|
||||
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
|
||||
import eu.eudat.logic.services.ApiContext;
|
||||
import eu.eudat.logic.services.operations.DatabaseRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class FileManager {
|
||||
private static final Logger logger = LoggerFactory.getLogger(FileManager.class);
|
||||
|
||||
private ApiContext apiContext;
|
||||
private DatabaseRepository databaseRepository;
|
||||
private Environment environment;
|
||||
|
||||
@Autowired
|
||||
public FileManager(ApiContext apiContext, Environment environment) {
|
||||
this.apiContext = apiContext;
|
||||
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public String moveFromTmpToStorage(String filename) {
|
||||
File tempFile = new File(this.environment.getProperty("temp.temp") + filename);
|
||||
File newFile = new File(this.environment.getProperty("file.storage") + filename);
|
||||
try {
|
||||
return Files.move(tempFile.toPath(), newFile.toPath()).toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean deleteFromStorage(String filename) {
|
||||
File toBeDeletedFile = new File(this.environment.getProperty("file.storage") + filename);
|
||||
// toBeDeletedFile.delete();
|
||||
try {
|
||||
return Files.deleteIfExists(toBeDeletedFile.toPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void markOldFileAsDeleted(FileUpload fileUpload) {
|
||||
fileUpload.setIsDeleted(true);
|
||||
databaseRepository.getFileUploadDao().createOrUpdate(fileUpload);
|
||||
}
|
||||
|
||||
public List<FileUpload> getFileUploadsForEntityId(String entityId) {
|
||||
return databaseRepository.getFileUploadDao().asQueryable()
|
||||
.where((builder, root) -> builder.equal(root.get("entityId"), entityId)).toList();
|
||||
}
|
||||
|
||||
public List<FileUpload> getCurrentFileUploadsForEntityId(UUID entityId) {
|
||||
return databaseRepository.getFileUploadDao().asQueryable()
|
||||
.where((builder, root) -> builder.and(
|
||||
builder.equal(root.get("entityId"), entityId),
|
||||
builder.equal(root.get("isDeleted"), false))).toList();
|
||||
}
|
||||
|
||||
public void markAllFilesOfEntityIdAsDeleted(UUID entityId) {
|
||||
List<FileUpload> fileUploads = this.getCurrentFileUploadsForEntityId(entityId);
|
||||
fileUploads.forEach(fileUpload -> {
|
||||
this.markOldFileAsDeleted(fileUpload);
|
||||
});
|
||||
}
|
||||
|
||||
public void createFile(String id, String fileName, String fileType, String entityId, FileUpload.EntityType entityType, UserInfo userInfo) {
|
||||
FileUpload fileUpload = new FileUpload();
|
||||
fileUpload.setId(UUID.fromString(id));
|
||||
fileUpload.setName(fileName);
|
||||
fileUpload.setFileType(fileType);
|
||||
fileUpload.setEntityId(UUID.fromString(entityId));
|
||||
fileUpload.setEntityType(entityType);
|
||||
fileUpload.setCreatedAt(new Date());
|
||||
fileUpload.setIsDeleted(false);
|
||||
fileUpload.setCreator(userInfo);
|
||||
databaseRepository.getFileUploadDao().createOrUpdate(fileUpload);
|
||||
|
||||
this.moveFromTmpToStorage(fileUpload.getId().toString());
|
||||
}
|
||||
}
|
|
@ -58,5 +58,7 @@ public interface DatabaseRepository {
|
|||
|
||||
NotificationDao getNotificationDao();
|
||||
|
||||
FileUploadDao getFileUploadDao();
|
||||
|
||||
<T> void detachEntity(T entity);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository {
|
|||
private FunderDao funderDao;
|
||||
private LockDao lockDao;
|
||||
private NotificationDao notificationDao;
|
||||
private FileUploadDao fileUploadDao;
|
||||
|
||||
private EntityManager entityManager;
|
||||
|
||||
|
@ -306,6 +307,17 @@ public class DatabaseRepositoryImpl implements DatabaseRepository {
|
|||
this.userDatasetProfileDao = userDatasetProfileDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileUploadDao getFileUploadDao() {
|
||||
return fileUploadDao;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setFileUploadDao(FileUploadDao fileUploadDao) {
|
||||
this.fileUploadDao = fileUploadDao;
|
||||
}
|
||||
|
||||
|
||||
public <T> void detachEntity(T entity) {
|
||||
this.entityManager.detach(entity);
|
||||
}
|
||||
|
|
|
@ -85,6 +85,8 @@ public class ModelBuilder {
|
|||
if (type.equals("freetext")) return (FieldData<U>) new FreeTextData().fromData(data);
|
||||
if (type.equals("textarea")) return (FieldData<U>) new TextAreaData().fromData(data);
|
||||
if (type.equals("richTextarea")) return (FieldData<U>) new RichTextAreaData().fromData(data);
|
||||
if (type.equals("upload")) return (FieldData<U>) new UploadData().fromData(data);
|
||||
// if (type.equals("table")) return (FieldData<U>) new TableData().fromData(data);
|
||||
if (type.equals("datePicker")) return (FieldData<U>) new DatePickerData().fromData(data);
|
||||
if (type.equals("externalDatasets")) return (FieldData<U>) new ExternalDatasetsData().fromData(data);
|
||||
if (type.equals("dataRepositories")) return (FieldData<U>) new DataRepositoriesData().fromData(data);
|
||||
|
@ -130,6 +132,8 @@ public class ModelBuilder {
|
|||
if (type.equals("freetext")) return (FieldData<U>) new FreeTextData().fromData(data);
|
||||
if (type.equals("textarea")) return (FieldData<U>) new TextAreaData().fromData(data);
|
||||
if (type.equals("richTextarea")) return (FieldData<U>) new RichTextAreaData().fromData(data);
|
||||
if (type.equals("upload")) return (FieldData<U>) new UploadData().fromData(data);
|
||||
// if (type.equals("table")) return (FieldData<U>) new TableData().fromData(data);
|
||||
if (type.equals("datePicker")) return (FieldData<U>) new DatePickerData().fromData(data);
|
||||
if (type.equals("externalDatasets")) return (FieldData<U>) new ExternalDatasetsData().fromData(data);
|
||||
if (type.equals("dataRepositories")) return (FieldData<U>) new DataRepositoriesData().fromData(data);
|
||||
|
|
|
@ -29,6 +29,8 @@ public class ViewStyle {
|
|||
FREE_TEXT("freetext"),
|
||||
TEXT_AREA("textarea"),
|
||||
RICH_TEXT_AREA("richTextarea"),
|
||||
UPLOAD("upload"),
|
||||
// TABLE("table"),
|
||||
DATE_PICKER("datePicker"),
|
||||
EXTERNAL_DATASETS("externalDatasets"),
|
||||
DATA_REPOSITORIES("dataRepositories"),
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
package eu.eudat.models.data.components.commons.datafield;
|
||||
|
||||
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class UploadData extends FieldData<UploadData> {
|
||||
public class Option implements XmlSerializable<UploadData.Option> {
|
||||
private String label;
|
||||
private String value;
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element toXml(Document doc) {
|
||||
Element option = doc.createElement("option");
|
||||
option.setAttribute("label", this.label);
|
||||
option.setAttribute("value", this.value);
|
||||
return option;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadData.Option fromXml(Element item) {
|
||||
this.label = item.getAttribute("label");
|
||||
this.value = item.getAttribute("value");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private List<UploadData.Option> types;
|
||||
|
||||
public List<UploadData.Option> getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(List<UploadData.Option> types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
private Integer maxFileSizeInMB;
|
||||
|
||||
public Integer getMaxFileSizeInMB() {
|
||||
return maxFileSizeInMB;
|
||||
}
|
||||
|
||||
public void setMaxFileSizeInMB(Integer maxFileSizeInMB) {
|
||||
this.maxFileSizeInMB = maxFileSizeInMB;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadData fromData(Object data) {
|
||||
this.types = new LinkedList();
|
||||
if (data != null) {
|
||||
List<Map<String, String>> types = ((Map<String, List<Map<String, String>>>) data).get("types");
|
||||
for (Map<String, String> map : types) {
|
||||
UploadData.Option newOption = new UploadData.Option();
|
||||
newOption.setLabel(map.get("label"));
|
||||
newOption.setValue(map.get("value"));
|
||||
this.types.add(newOption);
|
||||
}
|
||||
this.setLabel(((Map<String, String>) data).get("label"));
|
||||
this.setMaxFileSizeInMB(((Map<String, Integer>) data).get("maxFileSizeInMB"));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element toXml(Document doc) {
|
||||
Element root = doc.createElement("data");
|
||||
Element element = doc.createElement("types");
|
||||
for (UploadData.Option type : this.types) {
|
||||
element.appendChild(type.toXml(doc));
|
||||
}
|
||||
root.setAttribute("label", this.getLabel());
|
||||
root.setAttribute("maxFileSizeInMB", this.getMaxFileSizeInMB().toString());
|
||||
root.appendChild(element);
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadData fromXml(Element item) {
|
||||
this.types = new LinkedList<>();
|
||||
Element optionsElement = (Element) item.getElementsByTagName("types").item(0);
|
||||
this.setLabel(item.getAttribute("label"));
|
||||
if(item.getAttribute("maxFileSizeInMB") != null) {
|
||||
this.setMaxFileSizeInMB(Integer.parseInt(item.getAttribute("maxFileSizeInMB")));
|
||||
}
|
||||
if (optionsElement != null) {
|
||||
NodeList optionElements = optionsElement.getChildNodes();
|
||||
for (int temp = 0; temp < optionElements.getLength(); temp++) {
|
||||
Node optionElement = optionElements.item(temp);
|
||||
if (optionElement.getNodeType() == Node.ELEMENT_NODE) {
|
||||
this.types.add(new UploadData.Option().fromXml((Element) optionElement));
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> toMap(Element item) {
|
||||
HashMap dataMap = new HashMap();
|
||||
dataMap.put("label", item != null ? item.getAttribute("label") : "");
|
||||
dataMap.put("maxFileSizeInMB", item != null ? item.getAttribute("maxFileSizeInMB") : "");
|
||||
Element optionsElement = (Element) item.getElementsByTagName("types").item(0);
|
||||
List<Map<String,String>> type =new LinkedList<>();
|
||||
|
||||
if (optionsElement != null) {
|
||||
NodeList optionElements = optionsElement.getChildNodes();
|
||||
for (int temp = 0; temp < optionElements.getLength(); temp++) {
|
||||
Node optionElement = optionElements.item(temp);
|
||||
if (optionElement.getNodeType() == Node.ELEMENT_NODE) {
|
||||
type.add(optionToMap((Element) optionElement));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dataMap.put("types", type != null ? type : null);
|
||||
return dataMap;
|
||||
}
|
||||
|
||||
private Map<String, String> optionToMap(Element item){
|
||||
HashMap dataMap = new HashMap();
|
||||
dataMap.put("label",item.getAttribute("label"));
|
||||
dataMap.put("value",item.getAttribute("value"));
|
||||
|
||||
return dataMap;
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public int getOrdinal() {
|
||||
public Integer getOrdinal() {
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,9 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
|
|||
}
|
||||
|
||||
public List<Integer> getValidations() {
|
||||
if(this.validations == null) {
|
||||
return null;
|
||||
}
|
||||
return this.validations.stream().map(item -> (int) item.getValue()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
@ -206,7 +209,11 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
|
|||
List<String> stringList = mapper.readValue(properties.get(this.id).toString(), LinkedList.class);
|
||||
this.value = stringList;
|
||||
} catch (JSONException | NullPointerException | IOException e) {
|
||||
this.value = (String) properties.get(this.id);
|
||||
try {
|
||||
this.value = (String) properties.get(this.id);
|
||||
} catch (ClassCastException ce) {
|
||||
this.value = properties.get(this.id);
|
||||
}
|
||||
}
|
||||
this.multiplicityItems = new LinkedList<>();
|
||||
List<String> compositeKeys = properties.keySet().stream().filter(keys -> keys.startsWith("multiple_" + this.getId())).collect(Collectors.toList());
|
||||
|
@ -250,7 +257,11 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
|
|||
}
|
||||
valueBuilder.append("]");
|
||||
fieldValues.put(this.id, valueBuilder.toString());
|
||||
}*/ else {
|
||||
}*/
|
||||
else if ((this.viewStyle != null && this.viewStyle.getRenderStyle().equals("upload"))) {
|
||||
fieldValues.put(this.id, this.value);
|
||||
}
|
||||
else {
|
||||
fieldValues.put(this.id, this.value.toString());
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -114,6 +114,9 @@ logging.config=classpath:logging/logback-${spring.profiles.active}.xml
|
|||
|
||||
#############TEMP#########
|
||||
temp.temp=tmp/
|
||||
file.storage=uploads/
|
||||
spring.servlet.multipart.max-file-size=10MB
|
||||
spring.servlet.multipart.max-request-size=10MB
|
||||
|
||||
#############ZENODO#########
|
||||
zenodo.affiliation=ARGOS
|
||||
|
|
Loading…
Reference in New Issue