367 lines
22 KiB
Java
367 lines
22 KiB
Java
package eu.eudat.logic.managers;
|
|
|
|
import com.jayway.jsonpath.DocumentContext;
|
|
import com.jayway.jsonpath.JsonPath;
|
|
import eu.eudat.data.dao.criteria.DatasetProfileCriteria;
|
|
import eu.eudat.data.entities.DatasetProfile;
|
|
import eu.eudat.data.entities.UserDatasetProfile;
|
|
import eu.eudat.data.entities.UserInfo;
|
|
import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileAutocompleteRequest;
|
|
import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem;
|
|
import eu.eudat.exceptions.datasetprofile.DatasetProfileNewVersionException;
|
|
import eu.eudat.logic.builders.model.models.DataTableDataBuilder;
|
|
import eu.eudat.logic.services.ApiContext;
|
|
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.datasetProfileXml.ExportXmlBuilderDatasetProfile;
|
|
import eu.eudat.logic.utilities.documents.xml.datasetProfileXml.ImportXmlBuilderDatasetProfile;
|
|
import eu.eudat.logic.utilities.helpers.StreamDistinctBy;
|
|
import eu.eudat.models.data.components.commons.datafield.AutoCompleteData;
|
|
import eu.eudat.models.data.datasetprofile.DatasetProfileAutocompleteItem;
|
|
import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel;
|
|
import eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field;
|
|
import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel;
|
|
import eu.eudat.models.data.helpers.common.DataTableData;
|
|
import eu.eudat.models.data.listingmodels.UserInfoListingModel;
|
|
import eu.eudat.models.data.mail.SimpleMail;
|
|
import eu.eudat.models.data.security.Principal;
|
|
import eu.eudat.queryable.QueryableList;
|
|
import eu.eudat.types.Authorities;
|
|
import eu.eudat.types.MetricNames;
|
|
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.*;
|
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
|
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
|
import org.springframework.http.converter.HttpMessageConverter;
|
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.web.client.RestTemplate;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
import org.w3c.dom.Document;
|
|
import org.w3c.dom.Element;
|
|
|
|
import javax.activation.MimetypesFileTypeMap;
|
|
import javax.transaction.Transactional;
|
|
import javax.xml.xpath.*;
|
|
import java.io.*;
|
|
import java.nio.file.Files;
|
|
import java.util.*;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@Component
|
|
public class DatasetProfileManager {
|
|
private static final Logger logger = LoggerFactory.getLogger(DatasetProfileManager.class);
|
|
private static final List<String> cache = new ArrayList<>();
|
|
|
|
private ApiContext apiContext;
|
|
private DatabaseRepository databaseRepository;
|
|
private Environment environment;
|
|
|
|
private final MetricsManager metricsManager;
|
|
|
|
@Autowired
|
|
public DatasetProfileManager(ApiContext apiContext, Environment environment, MetricsManager metricsManager) {
|
|
this.apiContext = apiContext;
|
|
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
|
|
this.environment = environment;
|
|
this.metricsManager = metricsManager;
|
|
}
|
|
|
|
@Transactional
|
|
public eu.eudat.models.data.admin.composite.DatasetProfile getDatasetProfile(String id) {
|
|
eu.eudat.data.entities.DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id));
|
|
eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = AdminManager.generateDatasetProfileModel(profile);
|
|
datasetprofile.setLabel(profile.getLabel());
|
|
datasetprofile.setStatus(profile.getStatus());
|
|
datasetprofile.setDescription(profile.getDescription());
|
|
datasetprofile.setLanguage(profile.getLanguage());
|
|
datasetprofile.setUsers(new ArrayList<>());
|
|
retrieveUsers(profile, datasetprofile);
|
|
return datasetprofile;
|
|
}
|
|
|
|
public List<DatasetProfileAutocompleteItem> getWithCriteria(DatasetProfileAutocompleteRequest datasetProfileAutocompleteRequest) throws IllegalAccessException, InstantiationException {
|
|
QueryableList<DatasetProfile> items = databaseRepository.getDatasetProfileDao().getWithCriteria(datasetProfileAutocompleteRequest.getCriteria());
|
|
QueryableList<DatasetProfile> pagedItems = datasetProfileAutocompleteRequest.applyPaging(items);
|
|
List<DatasetProfileAutocompleteItem> datasetProfiles = pagedItems.select(item -> new DatasetProfileAutocompleteItem().fromDataModel(item));
|
|
return datasetProfiles;
|
|
}
|
|
|
|
public DatasetProfile clone(String id) {
|
|
DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id));
|
|
apiContext.getOperationsContext().getDatabaseRepository().detachEntity(profile);
|
|
profile.setId(null);
|
|
return profile;
|
|
}
|
|
|
|
public DataTableData<DatasetProfileListingModel> getPaged(DatasetProfileTableRequestItem datasetProfileTableRequestItem, Principal principal) throws Exception {
|
|
QueryableList<DatasetProfile> items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria());
|
|
QueryableList<DatasetProfile> authItems = null;
|
|
if (principal.getAuthz().contains(Authorities.ADMIN)) {
|
|
authItems = items;
|
|
} else if (principal.getAuthz().contains(Authorities.DATASET_PROFILE_MANAGER)) {
|
|
List<Integer> roles = Collections.singletonList(1);
|
|
authItems = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getAuthenticated(items, principal.getId(), roles);
|
|
}
|
|
QueryableList<DatasetProfile> pagedItems = PaginationManager.applyPaging(authItems, datasetProfileTableRequestItem);
|
|
List<DatasetProfileListingModel> datasetProfiles = pagedItems.select(item -> new DatasetProfileListingModel().fromDataModel(item));
|
|
return apiContext.getOperationsContext().getBuilderFactory().getBuilder(DataTableDataBuilder.class).data(datasetProfiles).totalCount(items.count()).build();
|
|
}
|
|
|
|
public List<DatasetProfileListingModel> getAll(DatasetProfileTableRequestItem tableRequestItem) throws IllegalAccessException, InstantiationException {
|
|
QueryableList<DatasetProfile> items = databaseRepository.getDatasetProfileDao().getWithCriteria(tableRequestItem.getCriteria());
|
|
List<DatasetProfileListingModel> datasetProfiles = items.select(item -> new DatasetProfileListingModel().fromDataModel(item));
|
|
|
|
return datasetProfiles;
|
|
}
|
|
|
|
public eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field queryForField(String xml, String fieldId) throws XPathExpressionException {
|
|
eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.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;
|
|
}
|
|
|
|
public static List<ExternalAutocompleteFieldModel> getAutocomplete(AutoCompleteData data, String like) {
|
|
List<ExternalAutocompleteFieldModel> result = new LinkedList<>();
|
|
SimpleClientHttpRequestFactory simpleFactory = new SimpleClientHttpRequestFactory();
|
|
|
|
RestTemplate restTemplate = new RestTemplate(simpleFactory);
|
|
HttpHeaders headers = new HttpHeaders();
|
|
DocumentContext jsonContext = null;
|
|
HttpEntity<String> entity;
|
|
ResponseEntity response;
|
|
List<Map<String, String>> jsonItems;
|
|
int i = 0;
|
|
for (AutoCompleteData.AutoCompleteSingleData singleData: data.getAutoCompleteSingleDataList()) {
|
|
switch (AutoCompleteData.AutocompleteType.fromValue(singleData.getAutocompleteType())) {
|
|
case UNCACHED:
|
|
|
|
String url = singleData.getUrl();
|
|
String mediaType = "";
|
|
if (url.contains("openaire") || url.contains("zenodo")) {
|
|
mediaType = "application/json; charset=utf-8";
|
|
if (url.contains("zenodo")) {
|
|
url = url.replace("?", "/?");
|
|
}
|
|
|
|
url = url.replace("{like}", like.equals("") ? "*" : like);
|
|
url = url.replace("%20", " ");
|
|
url = url.replace("%22", "\"");
|
|
url = url.replace("&", "&");
|
|
} else {
|
|
mediaType = "application/vnd.api+json; charset=utf-8";
|
|
url += "?search=" + like;
|
|
}
|
|
|
|
if (!url.contains("zenodo")) {
|
|
headers.setAccept(Collections.singletonList(MediaType.valueOf(mediaType)));
|
|
}
|
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
|
entity = new HttpEntity<>("parameters", headers);
|
|
|
|
|
|
response = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class);
|
|
jsonContext = JsonPath.parse(response.getBody());
|
|
jsonItems = jsonContext.read(singleData.getOptionsRoot() + "['" + singleData.getAutoCompleteOptions().getLabel() + "','" + singleData.getAutoCompleteOptions().getValue() + "','" + singleData.getAutoCompleteOptions().getSource() + "','" + "uri" + "']");
|
|
jsonItems.forEach(item -> result.add(new ExternalAutocompleteFieldModel(parseItem(item.get(singleData.getAutoCompleteOptions().getValue())), parseItem(item.get(singleData.getAutoCompleteOptions().getLabel())), item.get(singleData.getAutoCompleteOptions().getSource()) != null ? parseItem(item.get(singleData.getAutoCompleteOptions().getSource())) : singleData.getAutoCompleteOptions().getSource(), parseItem(item.get("uri")))));
|
|
break;
|
|
case CACHED:
|
|
headers.setAccept(Collections.singletonList(MediaType.valueOf("text/plain; charset=utf-8")));
|
|
headers.setContentType(MediaType.TEXT_PLAIN);
|
|
entity = new HttpEntity<>("parameters", headers);
|
|
|
|
if (cache.size() <= i) {
|
|
response = restTemplate.exchange(singleData.getUrl(), HttpMethod.GET, entity, String.class);
|
|
cache.add((String) response.getBody());
|
|
}
|
|
jsonContext = JsonPath.parse(cache.get(i));
|
|
jsonItems = jsonContext.read(singleData.getOptionsRoot() + "['" + singleData.getAutoCompleteOptions().getLabel() + "','" + singleData.getAutoCompleteOptions().getValue() + "','" + singleData.getAutoCompleteOptions().getSource() + "','" + "uri" + "']");
|
|
jsonItems.stream().filter(item -> item.get(singleData.getAutoCompleteOptions().getLabel()).toLowerCase().contains(like.toLowerCase()))
|
|
.forEach(item -> result.add(new ExternalAutocompleteFieldModel(item.get(singleData.getAutoCompleteOptions().getValue()), item.get(singleData.getAutoCompleteOptions().getLabel()), item.get(singleData.getAutoCompleteOptions().getSource()) != null ? item.get(singleData.getAutoCompleteOptions().getSource()) : singleData.getAutoCompleteOptions().getSource(), item.get("uri"))));
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return result.stream().sorted(Comparator.comparing(ExternalAutocompleteFieldModel::getLabel)).collect(Collectors.toList());
|
|
|
|
//return result;
|
|
}
|
|
|
|
private static String parseItem(Object item) {
|
|
if (item instanceof String) {
|
|
return (String) item;
|
|
}
|
|
if (item instanceof List) {
|
|
List listedItems = (List) item;
|
|
return parseItem(listedItems.get(0));
|
|
}
|
|
if (item instanceof Map) {
|
|
return String.valueOf(((Map)item).get("$"));
|
|
}
|
|
return item != null ? item.toString() : null;
|
|
}
|
|
|
|
public ResponseEntity<byte[]> getDocument(eu.eudat.models.data.user.composite.DatasetProfile datasetProfile, String label) throws IllegalAccessException, IOException, InstantiationException {
|
|
FileEnvelope envelope = getXmlDocument(datasetProfile, label);
|
|
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(eu.eudat.models.data.user.composite.DatasetProfile datatasetProfile, String label) throws InstantiationException, IllegalAccessException, IOException {
|
|
ExportXmlBuilderDatasetProfile xmlBuilder = new ExportXmlBuilderDatasetProfile();
|
|
File file = xmlBuilder.build(datatasetProfile, environment);
|
|
FileEnvelope fileEnvelope = new FileEnvelope();
|
|
fileEnvelope.setFile(file);
|
|
fileEnvelope.setFilename(label);
|
|
return fileEnvelope;
|
|
}
|
|
|
|
public eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel.DatasetProfile createDatasetProfileFromXml(MultipartFile multiPartFile) {
|
|
ImportXmlBuilderDatasetProfile xmlBuilder = new ImportXmlBuilderDatasetProfile();
|
|
try {
|
|
File localFile = convert(multiPartFile);
|
|
eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel.DatasetProfile profile = xmlBuilder.build(localFile);
|
|
Files.deleteIfExists(localFile.toPath());
|
|
metricsManager.increaseValue(MetricNames.DATASET_TEMPLATE, 1, MetricNames.DRAFT);
|
|
return profile;
|
|
} 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 eu.eudat.data.entities.DatasetProfile createNewVersionDatasetProfile(String id, eu.eudat.models.data.admin.composite.DatasetProfile profile) throws Exception {
|
|
// Getting the DatasetProfile which we will create its new version.
|
|
eu.eudat.data.entities.DatasetProfile oldDatasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id));
|
|
|
|
// Getting the DatasetProfile with the latest Version.
|
|
DatasetProfileCriteria criteria = new DatasetProfileCriteria();
|
|
LinkedList<UUID> list = new LinkedList<>();
|
|
list.push(oldDatasetProfile.getGroupId());
|
|
criteria.setGroupIds(list);
|
|
criteria.setAllVersions(false);
|
|
QueryableList<DatasetProfile> datasetProfileQueryableList = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria);
|
|
eu.eudat.data.entities.DatasetProfile latestVersionDatasetProfile = datasetProfileQueryableList.getSingle();
|
|
|
|
if (latestVersionDatasetProfile.getVersion().equals(oldDatasetProfile.getVersion())){
|
|
eu.eudat.models.data.admin.composite.DatasetProfile sortedProfile = profile.toShort();
|
|
eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(sortedProfile, apiContext);
|
|
modelDefinition.setLabel(oldDatasetProfile.getLabel());
|
|
modelDefinition.setVersion((short) (oldDatasetProfile.getVersion() + 1));
|
|
modelDefinition.setGroupId(oldDatasetProfile.getGroupId());
|
|
modelDefinition.setLanguage(oldDatasetProfile.getLanguage());
|
|
apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition);
|
|
eu.eudat.data.entities.DatasetProfile datasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition);
|
|
this.storeDatasetProfileUsers(datasetProfile, profile);
|
|
return modelDefinition;
|
|
} else {
|
|
throw new DatasetProfileNewVersionException("Version to update not the latest.");
|
|
}
|
|
}
|
|
|
|
public void storeDatasetProfileUsers(DatasetProfile entity, eu.eudat.models.data.admin.composite.DatasetProfile model) {
|
|
if (model.getUsers() != null && !model.getUsers().isEmpty()) {
|
|
if (entity.getUsers() == null) {
|
|
entity.setUsers(new HashSet<>());
|
|
}
|
|
model.getUsers().stream().filter(userInfoListingModel -> entity.getUsers().stream()
|
|
.filter(userDatasetProfile -> userDatasetProfile.getUser().getId().equals(userInfoListingModel.getId())).count() == 0)
|
|
.forEach(userInfoListingModel -> {
|
|
UserDatasetProfile userDatasetProfile1 = new UserDatasetProfile();
|
|
userDatasetProfile1.setDatasetProfile(entity);
|
|
UserInfo userInfo1 = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(userInfoListingModel.getId());
|
|
userDatasetProfile1.setUser(userInfo1);
|
|
userDatasetProfile1.setRole(1);
|
|
apiContext.getOperationsContext().getDatabaseRepository().getUserDatasetProfileDao().createOrUpdate(userDatasetProfile1);
|
|
sendJoinMail(userDatasetProfile1);
|
|
});
|
|
entity.getUsers().stream().filter(userDatasetProfile -> model.getUsers().stream()
|
|
.filter(userInfoListingModel -> userDatasetProfile.getUser().getId().equals(userInfoListingModel.getId())).count() > 0
|
|
&& userDatasetProfile.getRole() == 2).forEach(userDatasetProfile -> {
|
|
userDatasetProfile.setRole(1);
|
|
apiContext.getOperationsContext().getDatabaseRepository().getUserDatasetProfileDao().createOrUpdate(userDatasetProfile);
|
|
sendJoinMail(userDatasetProfile);
|
|
});
|
|
}
|
|
if (entity.getUsers() != null && !entity.getUsers().isEmpty()) {
|
|
entity.getUsers().stream().filter(userDatasetProfile -> model.getUsers().stream()
|
|
.filter(userInfoListingModel -> userDatasetProfile.getUser().getId().equals(userInfoListingModel.getId())).count() == 0)
|
|
.forEach(userDatasetProfile -> {
|
|
userDatasetProfile.setRole(2);
|
|
apiContext.getOperationsContext().getDatabaseRepository().getUserDatasetProfileDao().createOrUpdate(userDatasetProfile);
|
|
});
|
|
}
|
|
}
|
|
|
|
@Transactional
|
|
public void retrieveUsers(DatasetProfile entity, eu.eudat.models.data.admin.composite.DatasetProfile model) {
|
|
if (entity.getUsers() != null && !entity.getUsers().isEmpty()) {
|
|
model.setUsers(entity.getUsers().stream().filter(userDatasetProfile -> userDatasetProfile.getRole() < 2).map(userDatasetProfile -> {
|
|
UserInfoListingModel userInfoListingModel = new UserInfoListingModel();
|
|
userInfoListingModel.setId(userDatasetProfile.getUser().getId());
|
|
userInfoListingModel.setName(userDatasetProfile.getUser().getName());
|
|
userInfoListingModel.setEmail(userDatasetProfile.getUser().getEmail());
|
|
userInfoListingModel.setRole(userDatasetProfile.getRole());
|
|
return userInfoListingModel;
|
|
}).collect(Collectors.toList()));
|
|
}
|
|
}
|
|
|
|
private void sendJoinMail(UserDatasetProfile userDatasetProfile) {
|
|
SimpleMail mail = new SimpleMail();
|
|
mail.setSubject(environment.getProperty("admin.mail.subject").replace( "{templateName}", userDatasetProfile.getDatasetProfile().getLabel()));
|
|
String content = apiContext.getUtilitiesService().getMailService().getMailTemplateContent(environment.getProperty("email.dataset.template"));
|
|
content = content.replace("{recipient}", userDatasetProfile.getUser().getName());
|
|
content = content.replace("{templateName}", userDatasetProfile.getDatasetProfile().getLabel());
|
|
content = content.replace("{host}", this.environment.getProperty("dmp.domain"));
|
|
content = content.replace("{templateID}", userDatasetProfile.getDatasetProfile().getId().toString());
|
|
mail.setContent(content);
|
|
mail.setTo(userDatasetProfile.getUser().getEmail());
|
|
try {
|
|
apiContext.getUtilitiesService().getMailService().sendSimpleMail(mail);
|
|
} catch (Exception ex) {
|
|
logger.error(ex.getMessage(), ex);
|
|
}
|
|
|
|
}
|
|
}
|