This commit is contained in:
Michele Artini 2022-11-23 11:17:50 +01:00
parent 51a3eda4c2
commit f3439a1d52
6 changed files with 137 additions and 20 deletions

View File

@ -1,10 +1,12 @@
package eu.dnetlib.is.resources; package eu.dnetlib.is.resources;
import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -16,10 +18,12 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.is.resource.model.SimpleResource; import eu.dnetlib.is.resource.model.SimpleResource;
import eu.dnetlib.is.resource.repository.SimpleResourceRepository; import eu.dnetlib.is.resource.repository.SimpleResourceRepository;
import eu.dnetlib.is.util.InformationServiceException;
import eu.dnetlib.is.util.OldProfilesImporter; import eu.dnetlib.is.util.OldProfilesImporter;
@RestController @RestController
@ -34,22 +38,42 @@ public class ResourcesRestController {
private static final Log log = LogFactory.getLog(ResourcesRestController.class); private static final Log log = LogFactory.getLog(ResourcesRestController.class);
@DeleteMapping("/{type}/{id}") @GetMapping("/")
public List<SimpleResource> deleteResources(@PathVariable final String type, @PathVariable final String id) { public List<SimpleResource> listResources(@RequestParam final String type) {
log.info("Deleting rewsource: " + id);
simpleResourceRepository.deleteById(id);
return listResources(type);
}
@GetMapping("/{type}")
public List<SimpleResource> listResources(@PathVariable final String type) {
return simpleResourceRepository.findByType(type) return simpleResourceRepository.findByType(type)
.stream() .stream()
.sorted((r1, r2) -> StringUtils.compareIgnoreCase(r1.getName(), r2.getName())) .sorted((r1, r2) -> StringUtils.compareIgnoreCase(r1.getName(), r2.getName()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@PostMapping(value = "/import", consumes = "text/plain") @DeleteMapping("/{id}")
public void deleteResources(@PathVariable final String id) {
log.info("Deleting resource: " + id);
simpleResourceRepository.deleteById(id);
}
@GetMapping("/{id}/metadata")
public SimpleResource getMetadataResource(@PathVariable final String id) throws InformationServiceException {
return simpleResourceRepository.findById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
}
@GetMapping("/{id}/content")
public void getContentResource(@PathVariable final String id, final HttpServletResponse res) throws InformationServiceException {
final SimpleResource sr = simpleResourceRepository.findById(id).orElseThrow(() -> new InformationServiceException("Id not found"));
res.setCharacterEncoding(StandardCharsets.UTF_8.name());
res.setContentType(sr.getContentType());
simpleResourceRepository.getContentById(id);
try {
IOUtils.write(simpleResourceRepository.getContentById(id), res.getOutputStream(), StandardCharsets.UTF_8.name());
} catch (final IOException e) {
throw new InformationServiceException("Error retrieving content", e);
}
}
@PostMapping(value = "/operation/import", consumes = "text/plain")
public SimpleResource importFromOldProfile(final HttpServletRequest request) throws Exception { public SimpleResource importFromOldProfile(final HttpServletRequest request) throws Exception {
final String xml = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8); final String xml = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);

View File

@ -0,0 +1,15 @@
package eu.dnetlib.is.util;
public class InformationServiceException extends Exception {
private static final long serialVersionUID = 3566871386890315850L;
public InformationServiceException(final String message, final Throwable cause) {
super(message, cause);
}
public InformationServiceException(final String message) {
super(message);
}
}

View File

@ -10,6 +10,7 @@ import org.dom4j.Document;
import org.dom4j.Node; import org.dom4j.Node;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import eu.dnetlib.is.resource.model.SimpleResource; import eu.dnetlib.is.resource.model.SimpleResource;
@ -44,7 +45,7 @@ public class OldProfilesImporter {
res.setId(id); res.setId(id);
res.setCreationDate(now); res.setCreationDate(now);
res.setModificationDate(now); res.setModificationDate(now);
res.setContentType("xml"); res.setContentType(MediaType.APPLICATION_XML_VALUE);
String resContent; String resContent;
switch (doc.valueOf("//RESOURCE_TYPE/@value")) { switch (doc.valueOf("//RESOURCE_TYPE/@value")) {

View File

@ -3,11 +3,12 @@ var app = angular.module('resourcesApp', []);
app.controller('resourcesController', function($scope, $http) { app.controller('resourcesController', function($scope, $http) {
$scope.resources = []; $scope.resources = [];
$scope.tmpRes = {}; $scope.tmpRes = {};
$scope.tmpContent = "loading...";
$scope.mode = ''; $scope.mode = '';
$scope.type = typeId(); $scope.type = typeId();
$scope.reload = function() { $scope.reload = function() {
$http.get('./api/resources/' + $scope.type + '?' + $.now()).then(function successCallback(res) { $http.get('./api/resources/?type=' + $scope.type + '&' + $.now()).then(function successCallback(res) {
$scope.resources = res.data; $scope.resources = res.data;
}, function errorCallback(res) { }, function errorCallback(res) {
alert('ERROR: ' + res.data.message); alert('ERROR: ' + res.data.message);
@ -23,12 +24,26 @@ app.controller('resourcesController', function($scope, $http) {
}; };
} }
$scope.prepareEditRes = function(res) { $scope.prepareEditMetadata = function(res) {
$scope.tmpRes = angular.copy(res);
$scope.mode = 'edit'; $scope.mode = 'edit';
}
$scope.prepareEditContent = function(res) {
$scope.tmpRes = angular.copy(res);
$scope.tmpContent = "loading...";
$http.get('./api/resources/' + res.id + '/content?' + $.now()).then(function successCallback(res) {
$scope.tmpContent = res.data;
}, function errorCallback(res) {
alert('ERROR: ' + res.data.message);
});
}
$scope.prepareUploadContent = function(res) {
$scope.tmpRes = angular.copy(res); $scope.tmpRes = angular.copy(res);
} }
$scope.saveResource = function(res) { $scope.saveMetadata = function(res) {
if ($scope.mode == 'new') { if ($scope.mode == 'new') {
var found = false; var found = false;
@ -51,11 +66,26 @@ app.controller('resourcesController', function($scope, $http) {
}); });
}; };
$scope.saveContent = function(id, content) {
$http.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
$http.post('./api/resources/' + id + '/content?' + $.now(), res).then(function successCallback(res) {
alert("Resource saved");
}, function errorCallback(res) {
alert('ERROR: ' + res.data.message);
});
};
$scope.uploadContent = function(id, content) {
// TODO
};
$scope.deleteResource = function(r) { $scope.deleteResource = function(r) {
if (confirm("Are you sure ?")) { if (confirm("Are you sure ?")) {
$http.delete('./api/resources/' + encodeURIComponent(r.type) + '/' + encodeURIComponent(r.id) + '?' + $.now()).then(function successCallback(res) { $http.delete('./api/resources/' + encodeURIComponent(r.id) + '?' + $.now()).then(function successCallback(res) {
$scope.resources = res.data;
alert("Resource deleted"); alert("Resource deleted");
$scope.reload();
}, function errorCallback(res) { }, function errorCallback(res) {
alert('ERROR: ' + res.data.message); alert('ERROR: ' + res.data.message);
}); });

View File

@ -33,7 +33,10 @@
<b>Creation date:</b> {{r.creationDate}}<br /> <b>Creation date:</b> {{r.creationDate}}<br />
<b>Modification date:</b> {{r.modificationDate}} <b>Modification date:</b> {{r.modificationDate}}
</p> </p>
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#editResourceModal" ng-click="prepareEditRes(r)" >edit</button> <button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#editMetadataModal" ng-click="prepareEditMetadata(r)">edit metadata</button>
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#editContentModal" ng-click="prepareEditContent(r)">edit content</button>
<button type="button" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#uploadContentModal" ng-click="prepareUploadContent(r)">upload content file</button>
<a href="./api/resources/{{r.id}}/content" class="btn btn-sm btn-primary" target="_blank">raw content</a>
<button type="button" class="btn btn-sm btn-danger" ng-click="deleteResource(r)">delete</button> <button type="button" class="btn btn-sm btn-danger" ng-click="deleteResource(r)">delete</button>
</div> </div>
</div> </div>
@ -44,7 +47,7 @@
<!-- Modals --> <!-- Modals -->
<div class="modal fade" tabindex="-1" id="editResourceModal"> <div class="modal fade" tabindex="-1" id="editMetadataModal">
<div class="modal-dialog modal-lg"> <div class="modal-dialog modal-lg">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -80,6 +83,50 @@
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" tabindex="-1" id="editContentModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit content</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<form>
<textarea class="form-control small" ng-model="tmpContent" rows="25"></textarea>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="saveContent(tmpRes.id, tmpContent)" ng-disabled="!tmpContent">Submit</button>
</div>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" id="uploadContentModal">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Upload content</h4>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label>Suggested format: <i>{{tmpRes.contentType}}</i></label>
<input type="file" class="form-control-file" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-sm btn-primary" data-dismiss="modal" ng-click="saveResource(tmpRes)" ng-disabled="!tmpContent">Submit</button>
</div>
</div>
</div>
</div>
</body> </body>
<th:block th:replace="fragments/mainParts.html :: scripts"></th:block> <th:block th:replace="fragments/mainParts.html :: scripts"></th:block>

View File

@ -90,7 +90,7 @@ CREATE TABLE resources (
id text PRIMARY KEY, id text PRIMARY KEY,
name text NOT NULL, name text NOT NULL,
description text, description text,
content_type text NOT NULL DEFAULT 'xml', content_type text NOT NULL DEFAULT 'text/plain',
content text NOT NULL DEFAULT '', content text NOT NULL DEFAULT '',
type text NOT NULL REFERENCES resource_types(id), type text NOT NULL REFERENCES resource_types(id),
creation_date timestamp NOT NULL DEFAULT now(), creation_date timestamp NOT NULL DEFAULT now(),