argos/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManage...

265 lines
15 KiB
Java

package eu.eudat.logic.managers;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import eu.eudat.data.dao.criteria.DataManagementPlanCriteria;
import eu.eudat.data.dao.criteria.RequestItem;
import eu.eudat.data.dao.entities.DatasetDao;
import eu.eudat.data.dao.entities.DatasetProfileDao;
import eu.eudat.data.entities.DMPProfile;
import eu.eudat.data.entities.DescriptionTemplate;
import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest;
import eu.eudat.data.query.items.item.dmpprofile.DataManagementPlanProfileCriteriaRequest;
import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest;
import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption;
import eu.eudat.exceptions.dmpblueprint.DmpBlueprintUsedException;
import eu.eudat.logic.services.operations.DatabaseRepository;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.logic.utilities.documents.xml.dmpXml.ExportXmlBuilderDmpBlueprint;
import eu.eudat.logic.utilities.documents.xml.dmpXml.ImportXmlBuilderDmpBlueprint;
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.*;
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory;
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType;
import eu.eudat.models.data.helpermodels.Tuple;
import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem;
import eu.eudat.models.data.helpers.common.DataTableData;
import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel;
import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.queryable.QueryableList;
import eu.eudat.logic.services.ApiContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import javax.activation.MimetypesFileTypeMap;
import javax.xml.xpath.*;
import java.io.*;
import java.nio.file.Files;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Created by ikalyvas on 3/21/2018.
*/
@Component
public class DataManagementProfileManager {
private static final Logger logger = LoggerFactory.getLogger(DataManagementProfileManager.class);
private ApiContext apiContext;
private DatabaseRepository databaseRepository;
private Environment environment;
@Autowired
public DataManagementProfileManager(ApiContext apiContext, Environment environment) {
this.apiContext = apiContext;
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
this.environment = environment;
}
public DataTableData<DataManagementPlanProfileListingModel> getPaged(DataManagementPlanProfileTableRequest dataManagementPlanProfileTableRequest, Principal principal) throws Exception {
QueryableList<DMPProfile> items = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().getWithCriteria(dataManagementPlanProfileTableRequest.getCriteria());
QueryableList<DMPProfile> pagedItems = PaginationManager.applyPaging(items, dataManagementPlanProfileTableRequest);
DataTableData<DataManagementPlanProfileListingModel> dataTable = new DataTableData<DataManagementPlanProfileListingModel>();
CompletableFuture itemsFuture = pagedItems
.selectAsync(item -> new DataManagementPlanProfileListingModel().fromDataModel(item)).whenComplete((resultList, throwable) -> {
dataTable.setData(resultList);
});
CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> {
dataTable.setTotalCount(count);
});
CompletableFuture.allOf(itemsFuture, countFuture).join();
return dataTable;
}
public DataTableData<DataManagementPlanBlueprintListingModel> getPagedBlueprint(DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception {
QueryableList<DMPProfile> items = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().getWithCriteriaBlueprint(dataManagementPlanBlueprintTableRequest.getCriteria());
QueryableList<DMPProfile> pagedItems = PaginationManager.applyPaging(items, dataManagementPlanBlueprintTableRequest);
DataTableData<DataManagementPlanBlueprintListingModel> dataTable = new DataTableData<>();
CompletableFuture itemsFuture = pagedItems
.selectAsync(item -> new DataManagementPlanBlueprintListingModel().fromDataModel(item)).whenComplete((resultList, throwable) -> dataTable.setData(resultList));
CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> dataTable.setTotalCount(count));
CompletableFuture.allOf(itemsFuture, countFuture).join();
return dataTable;
}
public DataManagementPlanProfileListingModel getSingle(String id, Principal principal) throws InstantiationException, IllegalAccessException {
DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id));
DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel = new DataManagementPlanProfileListingModel();
dataManagementPlanProfileListingModel.fromDataModel(dmpProfile);
return dataManagementPlanProfileListingModel;
}
public DataManagementPlanBlueprintListingModel getSingleBlueprint(String id, Principal principal) {
DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id));
DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = new DataManagementPlanBlueprintListingModel();
dataManagementPlanBlueprintListingModel.fromDataModel(dmpProfile);
return dataManagementPlanBlueprintListingModel;
}
public boolean fieldInBlueprint(String id, SystemFieldType type, Principal principal) {
DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id));
return this.fieldInBlueprint(dmpProfile, type, principal);
}
public boolean fieldInBlueprint(DMPProfile dmpProfile, SystemFieldType type, Principal principal) {
DataManagementPlanBlueprintListingModel dmpBlueprint = new DataManagementPlanBlueprintListingModel();
dmpBlueprint.fromDataModel(dmpProfile);
for(Section section: dmpBlueprint.getDefinition().getSections()){
for(FieldModel field: section.getFields()){
if(field.getCategory().equals(FieldCategory.SYSTEM)){
SystemField systemField = field.toSystemField();
if(systemField.getType().equals(type)){
return true;
}
}
}
}
return false;
}
public List<Integer> sectionIndexesForDescriptionTemplate(DMPProfile dmpProfile, UUID descriptionTemplateId) {
DataManagementPlanBlueprintListingModel dmpBlueprint = new DataManagementPlanBlueprintListingModel();
dmpBlueprint.fromDataModel(dmpProfile);
List<Integer> sectionIndexes = new ArrayList<>();
for(int i = 0; i < dmpBlueprint.getDefinition().getSections().size(); i++) {
Section section = dmpBlueprint.getDefinition().getSections().get(i);
if(section.getHasTemplates() && section.getDescriptionTemplates().stream().anyMatch(x -> x.getDescriptionTemplateId().equals(descriptionTemplateId))) sectionIndexes.add(i);
}
return sectionIndexes;
}
public List<DataManagementPlanProfileListingModel> getWithCriteria(DataManagementPlanProfileCriteriaRequest dataManagementPlanProfileCriteriaRequest) throws IllegalAccessException, InstantiationException {
QueryableList<DMPProfile> items = databaseRepository.getDmpProfileDao().getWithCriteria(dataManagementPlanProfileCriteriaRequest.getCriteria());
List<DataManagementPlanProfileListingModel> datamanagementPlans = items.select(item -> new DataManagementPlanProfileListingModel().fromDataModel(item));
return datamanagementPlans;
}
public void createOrUpdate(DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel, Principal principal) throws Exception {
DMPProfile dmpProfile = dataManagementPlanProfileListingModel.toDataModel();
apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile);
}
public void createOrUpdateBlueprint(DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel, Principal principal) throws Exception {
DMPProfile dmpProfile = dataManagementPlanBlueprintListingModel.toDataModel();
apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile);
}
public void inactivate(String id) {
DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id));
DataManagementPlanCriteria dataManagementPlanCriteria = new DataManagementPlanCriteria();
dataManagementPlanCriteria.setProfile(dmpProfile);
if (dmpProfile.getStatus() == DMPProfile.Status.SAVED.getValue() || databaseRepository.getDmpDao().getWithCriteria(dataManagementPlanCriteria).count() == 0) {
dmpProfile.setStatus(DMPProfile.Status.DELETED.getValue());
databaseRepository.getDmpProfileDao().createOrUpdate(dmpProfile);
} else {
throw new DmpBlueprintUsedException("This blueprint can not deleted, because DMPs are associated with it");
}
}
public ResponseEntity<byte[]> getDocument(DataManagementPlanBlueprintListingModel dmpProfile) throws IOException {
FileEnvelope envelope = getXmlDocument(dmpProfile);
InputStream resource = new FileInputStream(envelope.getFile());
logger.info("Mime Type of " + envelope.getFilename() + " is " +
new MimetypesFileTypeMap().getContentType(envelope.getFile()));
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentLength(envelope.getFile().length());
responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
String fileName = envelope.getFilename().replace(" ", "_").replace(",", "_");
responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName + ".xml");
responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");
responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type");
byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource);
resource.close();
Files.deleteIfExists(envelope.getFile().toPath());
return new ResponseEntity<>(content,
responseHeaders,
HttpStatus.OK);
}
public FileEnvelope getXmlDocument(DataManagementPlanBlueprintListingModel dmpProfile) throws IOException {
ExportXmlBuilderDmpBlueprint xmlBuilder = new ExportXmlBuilderDmpBlueprint();
File file = xmlBuilder.build(dmpProfile, environment);
FileEnvelope fileEnvelope = new FileEnvelope();
fileEnvelope.setFile(file);
fileEnvelope.setFilename(dmpProfile.getLabel());
return fileEnvelope;
}
public eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel.DmpBlueprint createDmpProfileFromXml(MultipartFile multiPartFile) {
ImportXmlBuilderDmpBlueprint xmlBuilder = new ImportXmlBuilderDmpBlueprint();
try {
return xmlBuilder.build(convert(multiPartFile));
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
private File convert(MultipartFile file) throws IOException {
File convFile = new File(this.environment.getProperty("temp.temp") + file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
return convFile;
}
public List<Tuple<String, String>> getExternalAutocomplete(RequestItem<AutoCompleteLookupItem> lookupItem) throws XPathExpressionException {
DMPProfile dmpProfile = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().find(UUID.fromString(lookupItem.getCriteria().getProfileID()));
Field field = this.queryForField(dmpProfile.getDefinition(), lookupItem.getCriteria().getFieldID());
DmpProfileExternalAutoComplete data = field.getExternalAutocomplete();
return this.externalAutocompleteRequest(data, lookupItem.getCriteria().getLike());
}
private Field queryForField(String xml, String fieldId) throws XPathExpressionException {
Field field = new Field();
Document document = XmlBuilder.fromXml(xml);
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
XPathExpression expr = xpath.compile("//field[@id='" + fieldId + "']");
Element name = (Element) expr.evaluate(document, XPathConstants.NODE);
field.fromXml(name);
return field;
}
private List<Tuple<String, String>> externalAutocompleteRequest(DmpProfileExternalAutoComplete data, String like) {
return externalAutocompleteRequest(data.getUrl(), data.getOptionsRoot(), data.getLabel(), data.getValue(), like);
}
public static List<Tuple<String, String>> externalAutocompleteRequest(String url, String optionsRoot, String label, String value, String like) {
List<Tuple<String, String>> result = new LinkedList<>();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.valueOf("application/vnd.api+json; charset=utf-8")));
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("parameters", headers);
ResponseEntity<Object> response = restTemplate.exchange(url + "?search=" + like, HttpMethod.GET, entity, Object.class);
DocumentContext jsonContext = JsonPath.parse(response.getBody());
List<Map<String, String>> jsonItems = jsonContext.read(optionsRoot + "['" + label + "','" + value + "']");
jsonItems.forEach(item -> result.add(new Tuple<>(item.get(value), item.get(label))));
return result;
}
}